first init
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
<FilesMatch ".*">
|
||||
Order Deny,Allow
|
||||
Deny from All
|
||||
</FilesMatch>
|
||||
@@ -0,0 +1,443 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Inherit Smarty-Class and extend it
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/smarty/Smarty.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/db.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/labels.inc.php');
|
||||
|
||||
class OcSmarty extends Smarty
|
||||
{
|
||||
var $name = 'sys_nothing';
|
||||
var $main_template = 'sys_main';
|
||||
var $bench = null;
|
||||
var $compile_id = null;
|
||||
var $cache_id = null;
|
||||
var $title = '';
|
||||
var $menuitem = null;
|
||||
var $nowpsearch = false;
|
||||
|
||||
// no header, menu or footer
|
||||
var $popup = false;
|
||||
|
||||
// show a thin border when using popup
|
||||
// disable popupmargin to appear fullscreen
|
||||
var $popupmargin = true;
|
||||
|
||||
// url to call if login is required
|
||||
var $target = '';
|
||||
|
||||
var $header_javascript = array();
|
||||
var $body_load = array();
|
||||
var $body_unload = array();
|
||||
|
||||
function OcSmarty()
|
||||
{
|
||||
global $opt, $sqldebugger;
|
||||
require_once($opt['rootpath'] . 'lib2/bench.inc.php');
|
||||
$this->bench = new CBench();
|
||||
$this->bench->start();
|
||||
|
||||
// configuration
|
||||
$this->template_dir = $opt['stylepath'];
|
||||
$this->compile_dir = $opt['rootpath'] . 'cache2/smarty/compiled/';
|
||||
$this->cache_dir = $opt['rootpath'] . 'cache2/smarty/cache/';
|
||||
$this->plugins_dir = array('plugins', 'ocplugins');
|
||||
|
||||
// disable caching ... if caching is enabled, 1 hour is default
|
||||
$this->caching = false;
|
||||
$this->cache_lifetime = 3600; // default
|
||||
|
||||
// register additional functions
|
||||
require_once($opt['rootpath'] . 'lib2/smarty/ocplugins/block.nocache.php');
|
||||
$this->register_block('nocache', 'smarty_block_nocache', false);
|
||||
$this->load_filter('pre', 't');
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
$this->load_filter('output', 'session');
|
||||
|
||||
// cache control
|
||||
if (($opt['debug'] & DEBUG_TEMPLATES) == DEBUG_TEMPLATES)
|
||||
$this->force_compile = true;
|
||||
|
||||
// process debug level
|
||||
if (($opt['debug'] & DEBUG_SQLDEBUGGER) == DEBUG_SQLDEBUGGER)
|
||||
{
|
||||
require_once($opt['rootpath'] . 'lib2/sqldebugger.class.php');
|
||||
}
|
||||
else if (($opt['debug'] & DEBUG_OUTOFSERVICE) == DEBUG_OUTOFSERVICE)
|
||||
{
|
||||
$this->name = 'sys_outofservice';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/* set login target
|
||||
*/
|
||||
if (isset($_REQUEST['target']))
|
||||
{
|
||||
$this->target = trim($_REQUEST['target']);
|
||||
if (strtolower(substr($this->target, 0, 7)) == 'http://')
|
||||
$this->target = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$target = basename($_SERVER['PHP_SELF']) . '?';
|
||||
|
||||
// REQUEST-Variablen durchlaufen und an target anhaengen
|
||||
reset($_REQUEST);
|
||||
while (list($varname, $varvalue) = each($_REQUEST))
|
||||
if (in_array($varname, $opt['logic']['targetvars']))
|
||||
$target .= urlencode($varname) . '=' . urlencode($varvalue) . '&';
|
||||
reset($_REQUEST);
|
||||
|
||||
if (mb_substr($target, -1) == '?' || mb_substr($target, -1) == '&')
|
||||
$target = mb_substr($target, 0, -1);
|
||||
|
||||
$this->target = $target;
|
||||
}
|
||||
}
|
||||
|
||||
/* ATTENTION: copied from internal implementation!
|
||||
*/
|
||||
function compile($resource_name, $compile_id = null)
|
||||
{
|
||||
if (!isset($compile_id)) {
|
||||
$compile_id = $this->compile_id;
|
||||
}
|
||||
|
||||
$this->_compile_id = $compile_id;
|
||||
|
||||
// load filters that are marked as autoload
|
||||
if (count($this->autoload_filters)) {
|
||||
foreach ($this->autoload_filters as $_filter_type => $_filters) {
|
||||
foreach ($_filters as $_filter) {
|
||||
$this->load_filter($_filter_type, $_filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$_smarty_compile_path = $this->_get_compile_path($resource_name);
|
||||
|
||||
// if we just need to display the results, don't perform output
|
||||
// buffering - for speed
|
||||
$_cache_including = $this->_cache_including;
|
||||
$this->_cache_including = false;
|
||||
|
||||
// compile the resource
|
||||
if (!$this->_is_compiled($resource_name, $_smarty_compile_path))
|
||||
$this->_compile_resource($resource_name, $_smarty_compile_path);
|
||||
|
||||
$this->_cache_including = $_cache_including;
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
global $opt, $db, $cookie, $login, $menu, $sqldebugger, $translate;
|
||||
$cookie->close();
|
||||
|
||||
// // if the user is an admin, dont cache the content
|
||||
// if (isset($login))
|
||||
// if ($login->admin)
|
||||
// $this->caching = false;
|
||||
|
||||
//Give Smarty access to the whole options array.
|
||||
$this->assign('siteSettings', $opt);
|
||||
|
||||
//Should we remove this whole block since we now have
|
||||
//access using the siteSettings above?
|
||||
// assign main template vars
|
||||
// ... and some of the $opt
|
||||
$optn['debug'] = $opt['debug'];
|
||||
$optn['template']['locales'] = $opt['template']['locales'];
|
||||
$optn['template']['locale'] = $opt['template']['locale'];
|
||||
$optn['template']['style'] = $opt['template']['style'];
|
||||
$optn['template']['country'] = $login->getUserCountry();
|
||||
$optn['page']['subtitle1'] = isset($opt['locale'][$opt['template']['locale']]['page']['subtitle1']) ? $opt['locale'][$opt['template']['locale']]['page']['subtitle1'] : $opt['page']['subtitle1'];
|
||||
$optn['page']['subtitle2'] = isset($opt['locale'][$opt['template']['locale']]['page']['subtitle2']) ? $opt['locale'][$opt['template']['locale']]['page']['subtitle2'] : $opt['page']['subtitle2'];
|
||||
$optn['page']['max_logins_per_hour'] = $opt['page']['max_logins_per_hour'];
|
||||
$optn['page']['absolute_url'] = $opt['page']['absolute_url'];
|
||||
$optn['page']['target'] = $this->target;
|
||||
$optn['page']['showdonations'] = $opt['page']['showdonations'];
|
||||
$optn['page']['title'] = $opt['page']['title'];
|
||||
$optn['page']['nowpsearch'] = $this->nowpsearch;
|
||||
$optn['page']['header_javascript'] = $this->header_javascript;
|
||||
$optn['page']['body_load'] = $this->body_load;
|
||||
$optn['page']['body_unload'] = $this->body_unload;
|
||||
$optn['page']['sponsor'] = $opt['page']['sponsor'];
|
||||
$optn['template']['title'] = $this->title;
|
||||
$optn['template']['caching'] = $this->caching;
|
||||
$optn['template']['popup'] = $this->popup;
|
||||
$optn['template']['popupmargin'] = $this->popupmargin;
|
||||
$optn['format'] = $opt['locale'][$opt['template']['locale']]['format'];
|
||||
$optn['mail'] = $opt['mail'];
|
||||
$optn['lib'] = $opt['lib'];
|
||||
$optn['cms'] = $opt['cms'];
|
||||
$optn['geokrety'] = $opt['geokrety'];
|
||||
$optn['template']['usercountrieslist'] = labels::getLabels('usercountrieslist');
|
||||
|
||||
// url-sessions? (for session timout display)
|
||||
$optn['session']['url'] = false;
|
||||
if ($opt['session']['mode']==SAVE_SESSION && $login->userid!=0)
|
||||
{
|
||||
if (isset($_GET['SESSION']) || isset($_POST['SESSION']))
|
||||
{
|
||||
$optn['session']['url'] = true;
|
||||
}
|
||||
|
||||
$optn['session']['id'] = session_id();
|
||||
}
|
||||
|
||||
if (isset($login))
|
||||
{
|
||||
$loginn['username'] = $login->username;
|
||||
$loginn['userid'] = $login->userid;
|
||||
$loginn['admin'] = $login->admin;
|
||||
}
|
||||
else
|
||||
{
|
||||
$loginn['username'] = '';
|
||||
$loginn['userid'] = '';
|
||||
$loginn['admin'] = '';
|
||||
}
|
||||
|
||||
// build menu
|
||||
if ($this->menuitem == null)
|
||||
$menu->SetSelectItem(MNU_ROOT);
|
||||
else
|
||||
$menu->SetSelectItem($this->menuitem);
|
||||
|
||||
$this->assign('topmenu', $menu->getTopMenu());
|
||||
$this->assign('submenu', $menu->getSubMenu());
|
||||
$this->assign('breadcrumb', $menu->getBreadcrumb());
|
||||
$this->assign('menucolor', $menu->getMenuColor());
|
||||
|
||||
if ($this->title == '')
|
||||
$optn['template']['title'] = $menu->GetMenuTitle();
|
||||
|
||||
$this->assign('opt', $optn);
|
||||
$this->assign('login', $loginn);
|
||||
|
||||
if ($db['connected'] == true)
|
||||
$this->assign('sys_dbconnected', true);
|
||||
else
|
||||
$this->assign('sys_dbconnected', false);
|
||||
$this->assign('sys_dbslave', ($db['slave_id'] != -1));
|
||||
|
||||
if ($this->template_exists($this->name . '.tpl'))
|
||||
$this->assign('template', $this->name);
|
||||
else if ($this->name != 'sys_error')
|
||||
$this->error(ERROR_TEMPLATE_NOT_FOUND);
|
||||
|
||||
$this->bench->stop();
|
||||
$this->assign('sys_runtime', $this->bench->diff());
|
||||
|
||||
// check if the template is compiled
|
||||
// if not, check if translation works correct
|
||||
$_smarty_compile_path = $this->_get_compile_path($this->name);
|
||||
if (!$this->_is_compiled($this->name, $_smarty_compile_path) && $this->name != 'error')
|
||||
{
|
||||
$internal_lang = $translate->t('INTERNAL_LANG', 'all', 'OcSmarty.class.php', '');
|
||||
if (($internal_lang != $opt['template']['locale']) && ($internal_lang != 'INTERNAL_LANG'))
|
||||
$this->error(ERROR_COMPILATION_FAILED);
|
||||
}
|
||||
|
||||
if ($this->is_cached() == true)
|
||||
$this->assign('sys_cached', true);
|
||||
else
|
||||
$this->assign('sys_cached', false);
|
||||
|
||||
if (($opt['debug'] & DEBUG_SQLDEBUGGER) == DEBUG_SQLDEBUGGER)
|
||||
{
|
||||
parent::fetch($this->main_template . '.tpl', $this->get_cache_id(), $this->get_compile_id());
|
||||
|
||||
$this->clear_all_assign();
|
||||
$this->main_template = 'sys_sqldebugger';
|
||||
$this->assign('commands', $sqldebugger->getCommands());
|
||||
$this->assign('cancel', $sqldebugger->getCancel());
|
||||
unset($sqldebugger);
|
||||
|
||||
$this->assign('opt', $optn);
|
||||
$this->assign('login', $loginn);
|
||||
|
||||
$this->caching = false;
|
||||
|
||||
// unset sqldebugger to allow proper translation of sqldebugger template
|
||||
$opt['debug'] = $opt['debug'] & ~DEBUG_SQLDEBUGGER;
|
||||
|
||||
$this->header();
|
||||
parent::display($this->main_template . '.tpl');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->header();
|
||||
parent::display($this->main_template . '.tpl', $this->get_cache_id(), $this->get_compile_id());
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// show an error dialog
|
||||
function error($id)
|
||||
{
|
||||
$this->clear_all_assign();
|
||||
$this->caching = false;
|
||||
|
||||
$this->assign('page', $this->name);
|
||||
$this->assign('id', $id);
|
||||
|
||||
if ($this->menuitem == null)
|
||||
$this->menuitem = MNU_ERROR;
|
||||
|
||||
$args = func_get_args();
|
||||
unset($args[0]);
|
||||
for ($i = 1; isset($args[$i]); $i++)
|
||||
$this->assign('p' . $i, $args[$i]);
|
||||
|
||||
$this->name = 'error';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
// check if this template is valid
|
||||
function is_cached()
|
||||
{
|
||||
global $login;
|
||||
|
||||
// if the user is an admin, dont cache the content
|
||||
if (isset($login))
|
||||
if ($login->admin)
|
||||
return false;
|
||||
|
||||
return parent::is_cached($this->main_template . '.tpl', $this->get_cache_id(), $this->get_compile_id());
|
||||
}
|
||||
|
||||
function get_cache_id()
|
||||
{
|
||||
global $opt;
|
||||
return $this->name . '|' . $this->cache_id;
|
||||
}
|
||||
|
||||
function get_compile_id()
|
||||
{
|
||||
global $opt;
|
||||
return $opt['template']['style'] . '|' . $opt['template']['locale'] . '|' . $this->compile_id;
|
||||
}
|
||||
|
||||
function redirect($page)
|
||||
{
|
||||
global $cookie, $opt;
|
||||
$cookie->close();
|
||||
|
||||
// close db-connection
|
||||
sql_disconnect();
|
||||
|
||||
$this->header();
|
||||
|
||||
if (strpos($page, "\n") !== false)
|
||||
$page = substr($page, 0, strpos($page, "\n"));
|
||||
|
||||
// redirect
|
||||
if (substr($page, 0, 7) != 'http://')
|
||||
{
|
||||
if (substr($page, 0, 1) == '/') $page = substr($page, 1);
|
||||
$page = $opt['page']['absolute_url'] . $page;
|
||||
}
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
if (defined('SID') && SID != '' && session_id() != '')
|
||||
{
|
||||
if (strpos($page, '?') === false)
|
||||
header("Location: " . $page . '?' . urlencode(session_name()) . '=' . urlencode(session_id()));
|
||||
else
|
||||
header("Location: " . $page . '&' . urlencode(session_name()) . '=' . urlencode(session_id()));
|
||||
}
|
||||
else
|
||||
header("Location: " . $page);
|
||||
}
|
||||
else
|
||||
header("Location: " . $page);
|
||||
exit;
|
||||
}
|
||||
|
||||
function redirect_login()
|
||||
{
|
||||
// we cannot redirect the POST-data
|
||||
if (count($_POST) > 0)
|
||||
$this->error(ERROR_LOGIN_REQUIRED);
|
||||
|
||||
// ok ... redirect the get-data
|
||||
$target = 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
|
||||
$this->redirect('login.php?target=' . urlencode($target));
|
||||
}
|
||||
|
||||
function assign_rs($name, $rs)
|
||||
{
|
||||
$items = array();
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$items[] = $r;
|
||||
$this->assign($name, $items);
|
||||
}
|
||||
|
||||
function add_header_javascript($src)
|
||||
{
|
||||
$this->header_javascript[] = $src;
|
||||
}
|
||||
|
||||
function add_body_load($script)
|
||||
{
|
||||
$this->body_load[] = $script;
|
||||
}
|
||||
|
||||
function add_body_unload($script)
|
||||
{
|
||||
$this->body_unload[] = $script;
|
||||
}
|
||||
|
||||
function header()
|
||||
{
|
||||
global $opt;
|
||||
global $cookie;
|
||||
|
||||
if ($opt['gui'] == GUI_HTML)
|
||||
{
|
||||
// charset setzen
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
|
||||
// HTTP/1.1
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
// HTTP/1.0
|
||||
header("Pragma: no-cache");
|
||||
// Date in the past
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
// always modified
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
|
||||
// set the cookie
|
||||
$cookie->header();
|
||||
}
|
||||
}
|
||||
|
||||
/* - trim target and strip newlines
|
||||
* - use sDefault if sTarget is absolute and sDefault!=null
|
||||
*/
|
||||
function checkTarget($sTarget, $sDefault=null)
|
||||
{
|
||||
if (mb_strpos($sTarget, "\n") !== false)
|
||||
$sTarget = mb_substr($sTarget, 0, mb_strpos($sTarget, "\n"));
|
||||
|
||||
$sTarget = mb_trim($sTarget);
|
||||
|
||||
if (mb_strtolower(mb_substr($sTarget, 0, 7)) == 'http://' || $sTarget=='')
|
||||
if ($sDefault != null)
|
||||
return $sDefault;
|
||||
|
||||
return $sTarget;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,730 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP Class b2evo_captcha Version 1.3.1, released 27-Jan-2006
|
||||
*
|
||||
* a PHP Class for creating and testing captchas used in b2evolution
|
||||
*
|
||||
* Author : Ben Franske, ben@franske.com, http://ben.franske.com
|
||||
*
|
||||
* Based on hn_captcha Version 1.2 by Horst Nogajski, horst@nogajski.de
|
||||
* - hn_captcha is a fork of ocr_captcha by Julien Pachet
|
||||
*
|
||||
* License: GNU GPL (http://www.opensource.org/licenses/gpl-license.html)
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
*
|
||||
* changes in version 1.3.1:
|
||||
* - removed unrequired double quotes
|
||||
* - use function_exists() to check for some required functions
|
||||
*
|
||||
* changes in version 1.3:
|
||||
* - modified for use in b2evolution and to make more of a standalone class:
|
||||
* - stripped code so only image generation and testing remain
|
||||
* - removed code for multiple attempts, one shot per image only (K.I.S.S.)
|
||||
* - automatically select from multiple random fonts from the fonts folder
|
||||
* - support for random captcha length
|
||||
* - support for easily selecting valid characters and number of characters
|
||||
* - added built-in garbage cleanup
|
||||
* - support for case sensitive captchas
|
||||
* - upgraded from rand() functions to mt_rand() functions
|
||||
* - support for full md5 hashes instead of hash substrings
|
||||
* - made it easier to drop in different image generation function
|
||||
*
|
||||
* changes in version 1.2:
|
||||
* - added a new configuration-variable: secretposition
|
||||
* - once more modified the function get_try(): generate a string of 32 chars length,
|
||||
* where at secretposition is the number of current-try.
|
||||
* Hopefully this is enough for hackprevention.
|
||||
*
|
||||
* changes in version 1.1:
|
||||
* - added a new configuration-variable: maxrotation
|
||||
* - added a new configuration-variable: secretstring
|
||||
* - modified function get_try(): now ever returns a string of 16 chars
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* License: GNU GPL (http://www.opensource.org/licenses/gpl-license.html)
|
||||
*
|
||||
* This program is free software;
|
||||
*
|
||||
* you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
class b2evo_captcha
|
||||
{
|
||||
|
||||
////////////////////////////////
|
||||
//
|
||||
// Default options, can be overridden from the calling code
|
||||
//
|
||||
|
||||
var $public_key='';
|
||||
var $prefix = '';
|
||||
|
||||
/**
|
||||
* Absolute path to a Tempfolder (with trailing slash!). This must be writeable for PHP and also accessible via HTTP, because the image will be stored there.
|
||||
*
|
||||
**/
|
||||
var $tempfolder;
|
||||
|
||||
/**
|
||||
* Absolute path to folder with TrueTypeFonts (with trailing slash!). This must be readable by PHP.
|
||||
*
|
||||
**/
|
||||
var $TTF_folder;
|
||||
|
||||
/**
|
||||
* The minimum number of characters to use for the captcha
|
||||
* Set to the same as maxchars to use fixed length captchas
|
||||
**/
|
||||
var $minchars = 5;
|
||||
|
||||
/**
|
||||
* The maximum number of characters to use for the captcha
|
||||
* Set to the same as minchars to use fixed length captchas
|
||||
**/
|
||||
var $maxchars = 7;
|
||||
|
||||
/**
|
||||
* The minimum font size to use
|
||||
*
|
||||
**/
|
||||
var $minsize = 20;
|
||||
|
||||
/**
|
||||
* The maximum font size to use
|
||||
*
|
||||
**/
|
||||
var $maxsize = 30;
|
||||
|
||||
/**
|
||||
* The maximum degrees a Char should be rotated. Set it to 30 means a random rotation between -30 and 30.
|
||||
*
|
||||
**/
|
||||
var $maxrotation = 25;
|
||||
|
||||
/**
|
||||
* Background noise On/Off (if is FALSE, a grid will be created)
|
||||
*
|
||||
**/
|
||||
var $noise = TRUE;
|
||||
|
||||
/**
|
||||
* This will only use the 216 websafe color pallette for the image.
|
||||
*
|
||||
**/
|
||||
var $websafecolors = FALSE;
|
||||
|
||||
/**
|
||||
* Outputs configuration values for testing
|
||||
*
|
||||
**/
|
||||
var $debug = FALSE;
|
||||
|
||||
/**
|
||||
* Filename of garbage collector counter which is stored in the tempfolder
|
||||
*
|
||||
**/
|
||||
var $counter_filename = 'b2evo_captcha_counter.txt';
|
||||
|
||||
/**
|
||||
* Prefix of captcha image filenames
|
||||
*
|
||||
**/
|
||||
var $filename_prefix = 'b2evo_captcha_';
|
||||
|
||||
/**
|
||||
* Number of captchas to generate before garbage collection is done
|
||||
*
|
||||
**/
|
||||
var $collect_garbage_after = 100;
|
||||
|
||||
/**
|
||||
* Maximum lifetime of a captcha (in seconds) before being deleted during garbage collection
|
||||
*
|
||||
**/
|
||||
var $maxlifetime = 600;
|
||||
|
||||
/**
|
||||
* Make all letters uppercase (does not preclude symbols)
|
||||
*
|
||||
**/
|
||||
var $case_sensitive = TRUE;
|
||||
|
||||
////////////////////////////////
|
||||
//
|
||||
// Private options, these are fixed options
|
||||
//
|
||||
|
||||
/**
|
||||
* String of valid characters which may appear in the captcha
|
||||
*
|
||||
**/
|
||||
var $validchars = 'abcdefghjkmnpqrstuvwxyz23456789?@#$%&*ABCDEFGHJKLMNPQRSTUVWXYZ23456789?@#$%&*';
|
||||
|
||||
/**
|
||||
* Picture width
|
||||
*
|
||||
**/
|
||||
var $lx;
|
||||
|
||||
/**
|
||||
* Picture height
|
||||
*
|
||||
**/
|
||||
var $ly;
|
||||
|
||||
/**
|
||||
* JPEG Image quality
|
||||
*
|
||||
**/
|
||||
var $jpegquality = 80;
|
||||
|
||||
/**
|
||||
* Noise multiplier (number of characters gets multipled by this to define noise)
|
||||
* Note: This doesn't quite make sense, do you really want less noise in a smaller captcha?
|
||||
**/
|
||||
var $noisefactor = 9;
|
||||
|
||||
/**
|
||||
* Number of backgrond noise characters
|
||||
*
|
||||
**/
|
||||
var $nb_noise;
|
||||
|
||||
/**
|
||||
* Holds the list of possible fonts
|
||||
*
|
||||
**/
|
||||
var $TTF_RANGE;
|
||||
|
||||
/**
|
||||
* Holds the currently selected font filename
|
||||
*
|
||||
**/
|
||||
var $TTF_file;
|
||||
|
||||
/**
|
||||
* Holds the number of characters in the captcha
|
||||
*
|
||||
**/
|
||||
var $chars;
|
||||
|
||||
var $public_K;
|
||||
var $private_K;
|
||||
|
||||
/**
|
||||
* Captcha filename
|
||||
*
|
||||
**/
|
||||
var $filename;
|
||||
|
||||
/**
|
||||
* Holds the version number of the GD-Library
|
||||
*
|
||||
**/
|
||||
var $gd_version;
|
||||
|
||||
var $r;
|
||||
var $g;
|
||||
var $b;
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//
|
||||
// CONSTRUCTOR
|
||||
//
|
||||
|
||||
/**
|
||||
* Extracts the config array and overrides default settings.
|
||||
*
|
||||
**/
|
||||
function b2evo_captcha($config,$secure=TRUE)
|
||||
{
|
||||
|
||||
// Test for GD-Library(-Version)
|
||||
$this->gd_version = $this->get_gd_version();
|
||||
if($this->gd_version == 0) die('There is no GD-Library-Support enabled. The b2evo captcha class cannot be used!');
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: The available GD-Library has major version ".$this->gd_version;
|
||||
|
||||
// extracts config array
|
||||
if(is_array($config))
|
||||
{
|
||||
if($secure && (!function_exists('version_compare') || version_compare(phpversion(), '4.2.0', '< ')) && function_exists(array_key_exists))
|
||||
{
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Extracts Config-Array in secure-mode!";
|
||||
$valid = get_class_vars(get_class($this));
|
||||
foreach($config as $k=>$v)
|
||||
{
|
||||
if(array_key_exists($k,$valid)) $this->$k = $v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Extracts Config-Array in unsecure-mode!";
|
||||
foreach($config as $k=>$v) $this->$k = $v;
|
||||
}
|
||||
}
|
||||
|
||||
// check vars for min-max-chars and min-max-size
|
||||
if($this->minchars > $this->maxchars)
|
||||
{
|
||||
$temp = $this->minchars;
|
||||
$this->minchars = $this->maxchars;
|
||||
$this->maxchars = $temp;
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Arrghh! What do you think I mean with min and max? Switch minchars with maxchars.";
|
||||
}
|
||||
if($this->minsize > $this->maxsize)
|
||||
{
|
||||
$temp = $this->minsize;
|
||||
$this->minsize = $this->maxsize;
|
||||
$this->maxsize = $temp;
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Arrghh! What do you think I mean with min and max? Switch minsize with maxsize.";
|
||||
}
|
||||
|
||||
|
||||
// check TrueTypeFonts
|
||||
$this->TTF_RANGE = array('0');
|
||||
if ($handle = opendir($this->TTF_folder)) {
|
||||
$i=0;
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
//You could add a regex to this if to make sure the files are all *.ttf
|
||||
if ($file != '.' && $file != '..') {
|
||||
if (is_file($this->TTF_folder . $file)) {
|
||||
$this->TTF_RANGE[$i]=$file;
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Found font file (".$file.')';
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
if(is_array($this->TTF_RANGE))
|
||||
{
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Checking given TrueType-Array! (".count($this->TTF_RANGE).')';
|
||||
$temp = array();
|
||||
foreach($this->TTF_RANGE as $k=>$v)
|
||||
{
|
||||
if(is_readable($this->TTF_folder.$v)) $temp[] = $v;
|
||||
}
|
||||
$this->TTF_RANGE = $temp;
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Valid TrueType-files: (".count($this->TTF_RANGE).')';
|
||||
if(count($this->TTF_RANGE) < 1) die('No Truetype fonts available for the CaptchaClass.');
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Check given TrueType-File! (".$this->TTF_RANGE.')';
|
||||
if(!is_readable($this->TTF_folder.$this->TTF_RANGE)) die('No Truetypefont available for the b2evo captcha class.');
|
||||
}
|
||||
|
||||
// select first TrueTypeFont
|
||||
$this->change_TTF();
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Set current TrueType-File: (".$this->TTF_file.")";
|
||||
|
||||
|
||||
// get number of noise-chars for background if is enabled
|
||||
$this->nb_noise = $this->noise ? ($this->chars * $this->noisefactor) : 0;
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Set number of noise characters to: (".$this->nb_noise.')';
|
||||
|
||||
// seed the random number generator if less than php 4.2.0
|
||||
if( !function_exists('version_compare') || version_compare(phpversion(), '4.2.0', '< ') )
|
||||
{
|
||||
mt_srand((double)microtime()*1000000);
|
||||
}
|
||||
|
||||
// specify counter-filename
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: The counterfilename is (".$this->tempfolder.$this->counter_filename.')';
|
||||
|
||||
// retrieve last counter-value
|
||||
$test = $this->txt_counter($this->tempfolder.$this->counter_filename);
|
||||
|
||||
// set and retrieve current counter-value
|
||||
$counter = $this->txt_counter($this->tempfolder.$this->counter_filename,TRUE);
|
||||
|
||||
// check if counter works correct
|
||||
if(($counter !== FALSE) && ($counter - $test == 1))
|
||||
{
|
||||
// Counter works perfect, =:)
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Current counter-value is ($counter). Garbage-collector should start at (".$this->collect_garbage_after.')';
|
||||
|
||||
// check if garbage-collector should run
|
||||
if($counter >= $this->collect_garbage_after)
|
||||
{
|
||||
// Reset counter
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Reset the counter-value. (0)";
|
||||
$this->txt_counter($this->tempfolder.$this->counter_filename,TRUE,0);
|
||||
|
||||
// start garbage-collector
|
||||
$this->garbage_collector_error = $this->collect_garbage() ? FALSE : TRUE;
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: ERROR! SOME TRASHFILES COULD NOT BE DELETED!";
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Counter-ERROR!
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: ERROR! NO COUNTER-VALUE AVAILABLE!";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//
|
||||
// PUBLIC METHODS
|
||||
//
|
||||
|
||||
/**
|
||||
* Generates a captcha image and returns the complete path to the image
|
||||
*
|
||||
**/
|
||||
function get_b2evo_captcha()
|
||||
{
|
||||
$this->make_captcha();
|
||||
if(!isset($public) || $public=='') $public = $this->public_key;
|
||||
return str_replace($_SERVER['DOCUMENT_ROOT'],'',$this->tempfolder).$this->filename_prefix.$public.'.jpg';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Validates submission and returns result
|
||||
* Returns 0 = invalid sumbit | 1 = valid submit
|
||||
*
|
||||
**/
|
||||
function validate_submit($image,$attempt)
|
||||
{
|
||||
$correct_hash = substr($image,-36,32);
|
||||
if($this->case_sensitive==0) $attempt = strtoupper($attempt);
|
||||
if($this->check_captcha($correct_hash,$attempt))
|
||||
{
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Validating submitted form returns: (1)";
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Validating submitted form returns: (0)";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//
|
||||
// PRIVATE METHODS
|
||||
//
|
||||
|
||||
/** @private **/
|
||||
function make_captcha($private_key='')
|
||||
{
|
||||
if($private_key=='') $private_key = $this->generate_keypair();
|
||||
|
||||
// set dimension of image
|
||||
$this->lx = (strlen($private_key) + 1) * (int)(($this->maxsize + $this->minsize) / 1.5);
|
||||
$this->ly = (int)(2.4 * $this->maxsize);
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Set image dimension to: (".$this->lx.' x '.$this->ly.')';
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Generate private key: ($private_key)";
|
||||
|
||||
// set number of noise-chars for background if is enabled
|
||||
$this->nb_noise = $this->noise ? (strlen($private_key) * $this->noisefactor) : 0;
|
||||
if($this->debug) echo "\n<br>-b2evo-Captcha-Debug: Set number of noise characters to: (".$this->nb_noise.')';
|
||||
|
||||
// create Image and set the apropriate function depending on GD-Version & websafecolor-value
|
||||
if($this->gd_version >= 2 && !$this->websafecolors)
|
||||
{
|
||||
$func1 = 'imagecreatetruecolor';
|
||||
$func2 = 'imagecolorallocate';
|
||||
}
|
||||
else
|
||||
{
|
||||
$func1 = 'imageCreate';
|
||||
$func2 = 'imagecolorclosest';
|
||||
}
|
||||
$image = $func1($this->lx,$this->ly);
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Generate ImageStream with: ($func1())";
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: For colordefinitions we use: ($func2())";
|
||||
|
||||
|
||||
// Set Backgroundcolor
|
||||
$this->random_color(224, 255);
|
||||
$back = @imagecolorallocate($image, $this->r, $this->g, $this->b);
|
||||
@ImageFilledRectangle($image,0,0,$this->lx,$this->ly,$back);
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: We allocate one color for Background: (".$this->r.'-'.$this->g.'-'.$this->b.')';
|
||||
|
||||
// allocates the 216 websafe color palette to the image
|
||||
if($this->gd_version < 2 || $this->websafecolors) $this->makeWebsafeColors($image);
|
||||
|
||||
|
||||
// fill with noise or grid
|
||||
if($this->nb_noise > 0)
|
||||
{
|
||||
// random characters in background with random position, angle, color
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Fill background with noise: (".$this->nb_noise.')';
|
||||
for($i=0; $i < $this->nb_noise; $i++)
|
||||
{
|
||||
$size = intval(mt_rand((int)($this->minsize / 2.3), (int)($this->maxsize / 1.7)));
|
||||
$angle = intval(mt_rand(0, 360));
|
||||
$x = intval(mt_rand(0, $this->lx));
|
||||
$y = intval(mt_rand(0, (int)($this->ly - ($size / 5))));
|
||||
$this->random_color(160, 224);
|
||||
$color = $func2($image, $this->r, $this->g, $this->b);
|
||||
$text = chr(intval(mt_rand(45,250)));
|
||||
@ImageTTFText($image, $size, $angle, $x, $y, $color, $this->change_TTF(), $text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// generate grid
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Fill background with x-gridlines: (".(int)($this->lx / (int)($this->minsize / 1.5)).')';
|
||||
for($i=0; $i < $this->lx; $i += (int)($this->minsize / 1.5))
|
||||
{
|
||||
$this->random_color(160, 224);
|
||||
$color = $func2($image, $this->r, $this->g, $this->b);
|
||||
@imageline($image, $i, 0, $i, $this->ly, $color);
|
||||
}
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Fill background with y-gridlines: (".(int)($this->ly / (int)(($this->minsize / 1.8))).')';
|
||||
for($i=0 ; $i < $this->ly; $i += (int)($this->minsize / 1.8))
|
||||
{
|
||||
$this->random_color(160, 224);
|
||||
$color = $func2($image, $this->r, $this->g, $this->b);
|
||||
@imageline($image, 0, $i, $this->lx, $i, $color);
|
||||
}
|
||||
}
|
||||
|
||||
// generate Text
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Fill forground with chars and shadows: (".$this->chars.')';
|
||||
for($i=0, $x = intval(mt_rand($this->minsize,$this->maxsize)); $i < strlen($private_key); $i++)
|
||||
{
|
||||
$text = substr($private_key, $i, 1);
|
||||
$angle = intval(mt_rand(($this->maxrotation * -1), $this->maxrotation));
|
||||
$size = intval(mt_rand($this->minsize, $this->maxsize));
|
||||
$y = intval(mt_rand((int)($size * 1.5), (int)($this->ly - ($size / 7))));
|
||||
$this->random_color(0, 127);
|
||||
$color = $func2($image, $this->r, $this->g, $this->b);
|
||||
$this->random_color(0, 127);
|
||||
$shadow = $func2($image, $this->r + 127, $this->g + 127, $this->b + 127);
|
||||
@ImageTTFText($image, $size, $angle, $x + (int)($size / 15), $y, $shadow, $this->change_TTF(), $text);
|
||||
@ImageTTFText($image, $size, $angle, $x, $y - (int)($size / 15), $color, $this->TTF_file, $text);
|
||||
$x += (int)($size + ($this->minsize / 5));
|
||||
}
|
||||
@ImageJPEG($image, $this->get_filename(), $this->jpegquality);
|
||||
$res = file_exists($this->get_filename());
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Save Image with quality [".$this->jpegquality.'] as ('.$this->get_filename().') returns: ('.($res ? 'TRUE' : 'FALSE').')';
|
||||
@ImageDestroy($image);
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Destroy Imagestream.";
|
||||
if(!$res) die('Unable to save captcha-image.');
|
||||
}
|
||||
|
||||
/** @private **/
|
||||
function makeWebsafeColors(&$image)
|
||||
{
|
||||
//$a = array();
|
||||
for($r = 0; $r <= 255; $r += 51)
|
||||
{
|
||||
for($g = 0; $g <= 255; $g += 51)
|
||||
{
|
||||
for($b = 0; $b <= 255; $b += 51)
|
||||
{
|
||||
$color = imagecolorallocate($image, $r, $g, $b);
|
||||
//$a[$color] = array('r'=>$r,'g'=>$g,'b'=>$b);
|
||||
}
|
||||
}
|
||||
}
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Allocate 216 websafe colors to image: (".imagecolorstotal($image).')';
|
||||
//return $a;
|
||||
}
|
||||
|
||||
/** @private **/
|
||||
function random_color($min,$max)
|
||||
{
|
||||
$this->r = intval(mt_rand($min,$max));
|
||||
$this->g = intval(mt_rand($min,$max));
|
||||
$this->b = intval(mt_rand($min,$max));
|
||||
//echo ' ('.$this->r.'-'.$this->g.'-'.$this->b.') ';
|
||||
}
|
||||
|
||||
/** @private **/
|
||||
function change_TTF()
|
||||
{
|
||||
if(is_array($this->TTF_RANGE))
|
||||
{
|
||||
$key = array_rand($this->TTF_RANGE);
|
||||
$this->TTF_file = $this->TTF_folder.$this->TTF_RANGE[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->TTF_file = $this->TTF_folder.$this->TTF_RANGE;
|
||||
}
|
||||
return $this->TTF_file;
|
||||
}
|
||||
|
||||
/** @private **/
|
||||
function check_captcha($correct_hash,$attempt)
|
||||
{
|
||||
// when check, destroy picture on disk
|
||||
if(file_exists($this->get_filename($correct_hash)))
|
||||
{
|
||||
$res = @unlink($this->get_filename($correct_hash)) ? 'TRUE' : 'FALSE';
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Delete image (".$this->get_filename($correct_hash).") returns: ($res)";
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
$res = (md5($attempt)===$correct_hash) ? 'TRUE' : 'FALSE';
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Comparing public with private key returns: ($res)";
|
||||
return $res == 'TRUE' ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/** @private **/
|
||||
function get_filename($public='')
|
||||
{
|
||||
if($public=='') $public=$this->public_key;
|
||||
return $this->tempfolder.$this->filename_prefix.$public.'.jpg';
|
||||
}
|
||||
|
||||
/** @private **/
|
||||
function get_filename_url($public="")
|
||||
{
|
||||
if($public=='') $public = $this->public_key;
|
||||
return str_replace($_SERVER['DOCUMENT_ROOT'],'',$this->tempfolder).$this->filename_prefix.$public.'.jpg';
|
||||
}
|
||||
|
||||
/** @private **/
|
||||
function get_gd_version()
|
||||
{
|
||||
if (!function_exists('imagejpeg')) {
|
||||
$gd_version_number = 0;
|
||||
} else {
|
||||
static $gd_version_number = null;
|
||||
if($gd_version_number === null)
|
||||
{
|
||||
ob_start();
|
||||
phpinfo(8);
|
||||
$module_info = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if(preg_match("/\bgd\s+version\b[^\d\n\r]+?([\d\.]+)/i", $module_info, $matches))
|
||||
{
|
||||
$gd_version_number = $matches[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$gd_version_number = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $gd_version_number;
|
||||
}
|
||||
|
||||
|
||||
// this is where the actual text and public hash is generated and stored
|
||||
function generate_keypair()
|
||||
{
|
||||
$key = '';
|
||||
$this->chars = mt_rand($this->minchars,$this->maxchars);
|
||||
for($i=0; $i < $this->chars; $i++) {
|
||||
$key .= $this->validchars{mt_rand(1,strlen($this->validchars))-1};
|
||||
}
|
||||
if($this->case_sensitive==0) $key = strtoupper($key);
|
||||
$this->public_key = md5($key);
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Generate Keys, private key is: (".$key.')';
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: Generate Keys, public key is: (".$this->public_key.')';
|
||||
return $key;
|
||||
}
|
||||
|
||||
//Store/Retrieve a counter-value in/from a textfile. Optionally count it up or store a (as third param) specified value.
|
||||
// Returns counter-value
|
||||
function txt_counter($filename,$add=FALSE,$fixvalue=FALSE)
|
||||
{
|
||||
if(is_file($filename) ? TRUE : touch($filename))
|
||||
{
|
||||
if(is_readable($filename) && is_writable($filename))
|
||||
{
|
||||
$fp = @fopen($filename, 'r');
|
||||
if($fp)
|
||||
{
|
||||
$counter = (int)trim(fgets($fp));
|
||||
fclose($fp);
|
||||
|
||||
if($add)
|
||||
{
|
||||
if($fixvalue !== FALSE)
|
||||
{
|
||||
$counter = (int)$fixvalue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$counter++;
|
||||
}
|
||||
$fp = @fopen($filename, 'w');
|
||||
if($fp)
|
||||
{
|
||||
fputs($fp,$counter);
|
||||
fclose($fp);
|
||||
return $counter;
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $counter;
|
||||
}
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
|
||||
// Scanns the tempfolder for jpeg-files with nameprefix used by the class and trash them if they are older than maxlifetime.
|
||||
function collect_garbage()
|
||||
{
|
||||
$OK = FALSE;
|
||||
$captchas = 0;
|
||||
$trashed = 0;
|
||||
if($handle = @opendir($this->tempfolder))
|
||||
{
|
||||
$OK = TRUE;
|
||||
while(false !== ($file = readdir($handle)))
|
||||
{
|
||||
if(!is_file($this->tempfolder.$file)) continue;
|
||||
// check for name-prefix, extension and filetime
|
||||
if(substr($file,0,strlen($this->prefix)) == $this->prefix)
|
||||
{
|
||||
if(strrchr($file, '.') == '.jpg')
|
||||
{
|
||||
$captchas++;
|
||||
if((time() - filemtime($this->tempfolder.$file)) >= $this->maxlifetime)
|
||||
{
|
||||
$trashed++;
|
||||
$res = @unlink($this->tempfolder.$file);
|
||||
if(!$res) $OK = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
if($this->debug) echo "\n<br>-Captcha-Debug: There are ($captchas) captcha-images in tempfolder, where ($trashed) are seems to be lost.";
|
||||
return $OK;
|
||||
}
|
||||
|
||||
} // END CLASS b2evo_captcha
|
||||
|
||||
?>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
see http://sourceforge.net/projects/b2evo-captcha
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Exact time mesurement
|
||||
***************************************************************************/
|
||||
|
||||
class Cbench
|
||||
{
|
||||
var $start;
|
||||
var $stop;
|
||||
|
||||
function CBench()
|
||||
{
|
||||
$this->start = 0;
|
||||
$this->stop = 0;
|
||||
}
|
||||
function getmicrotime()
|
||||
{
|
||||
list($usec, $sec) = explode(' ', microtime());
|
||||
return ((float)$usec + (float)$sec);
|
||||
}
|
||||
function start()
|
||||
{
|
||||
$this->start = $this->getmicrotime();
|
||||
}
|
||||
|
||||
function stop()
|
||||
{
|
||||
$this->stop = $this->getmicrotime();
|
||||
}
|
||||
|
||||
function diff()
|
||||
{
|
||||
$result = $this->stop - $this->start;
|
||||
return $result;
|
||||
}
|
||||
function runTime()
|
||||
{
|
||||
$result = $this->getmicrotime() - $this->start;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
$cli = new cli();
|
||||
|
||||
class cli
|
||||
{
|
||||
function out($str)
|
||||
{
|
||||
echo $str . "\n";
|
||||
}
|
||||
|
||||
function debug($str)
|
||||
{
|
||||
global $opt;
|
||||
if (($opt['debug'] & DEBUG_CLI) == DEBUG_CLI)
|
||||
echo 'DEBUG: ' . $str . "\n";
|
||||
}
|
||||
|
||||
function warn($str)
|
||||
{
|
||||
echo 'WARN: ' . $str . "\n";
|
||||
}
|
||||
|
||||
function error($str)
|
||||
{
|
||||
echo 'ERROR: ' . $str . "\n";
|
||||
}
|
||||
|
||||
function fatal($str)
|
||||
{
|
||||
echo 'FATAL: ' . $str . "\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* This module is included by each site with HTML-output and contains
|
||||
* functions that are specific to HTML-output. common.inc.php is included
|
||||
* and will do the setup.
|
||||
*
|
||||
* If you include this script from any subdir, you have to set the
|
||||
* variable $opt['rootpath'], so that it points (relative or absolute)
|
||||
* to the root.
|
||||
***************************************************************************/
|
||||
|
||||
// setup rootpath
|
||||
if (!isset($opt['rootpath'])) $opt['rootpath'] = './';
|
||||
|
||||
// chicken-egg problem ...
|
||||
require($opt['rootpath'] . 'lib2/const.inc.php');
|
||||
|
||||
// do all output in text format
|
||||
$opt['gui'] = GUI_TEXT;
|
||||
|
||||
// include the main library
|
||||
require($opt['rootpath'] . 'lib2/common.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/cli.class.php');
|
||||
|
||||
if (($opt['debug'] & DEBUG_OUTOFSERVICE) == DEBUG_OUTOFSERVICE)
|
||||
{
|
||||
$cli->debug('exit because DEBUG_OUTOFSERVICE is set');
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* This module contains the main initalisation routine and often used
|
||||
* functions. It is included by web.inc.php and cli.inc.php.
|
||||
*
|
||||
* TODO: accept-language des Browser auswerten
|
||||
***************************************************************************/
|
||||
|
||||
function __autoload($class_name)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if (!preg_match('/^[\w]{1,}$/', $class_name))
|
||||
return;
|
||||
|
||||
$class_name = str_replace('_', '/', $class_name);
|
||||
|
||||
$file = $opt['rootpath'] . '../lib/classes/' . $class_name . '.php';
|
||||
if (file_exists($file))
|
||||
require_once($file);
|
||||
}
|
||||
|
||||
// yepp, we will use UTF-8
|
||||
mb_internal_encoding('UTF-8');
|
||||
mb_regex_encoding('UTF-8');
|
||||
|
||||
// if magic_quotes is enabled, fix it
|
||||
fix_magic_quotes_gpc();
|
||||
|
||||
// set options
|
||||
require($opt['rootpath'] . 'config2/settings-dist.inc.php');
|
||||
require($opt['rootpath'] . 'config2/settings.inc.php');
|
||||
|
||||
set_domain();
|
||||
|
||||
if (!(isset($_REQUEST['sqldebug']) && $_REQUEST['sqldebug']=='1'))
|
||||
$opt['debug'] = $opt['debug'] & ~DEBUG_SQLDEBUGGER;
|
||||
|
||||
if (($opt['debug'] & DEBUG_FORCE_TRANSLATE) != DEBUG_FORCE_TRANSLATE)
|
||||
{
|
||||
if (($opt['debug'] & DEBUG_TRANSLATE) == DEBUG_TRANSLATE && isset($_REQUEST['trans']) && $_REQUEST['trans']=='1')
|
||||
$opt['debug'] = $opt['debug'] | DEBUG_TEMPLATES;
|
||||
else
|
||||
$opt['debug'] = $opt['debug'] & ~DEBUG_TRANSLATE;
|
||||
}
|
||||
|
||||
configure_php();
|
||||
|
||||
require($opt['rootpath'] . 'lib2/cookie.class.php');
|
||||
normalize_settings();
|
||||
set_language();
|
||||
set_usercountry();
|
||||
|
||||
// set stylepath and langpath
|
||||
if (isset($opt['template']['style']))
|
||||
{
|
||||
if (strpos($opt['template']['style'], '.') !== false ||
|
||||
strpos($opt['template']['style'], '/') !== false)
|
||||
$opt['template']['style'] = $opt['template']['default']['style'];
|
||||
|
||||
if (!is_dir($opt['rootpath'] . 'templates2/' . $opt['template']['style']))
|
||||
$opt['template']['style'] = $opt['template']['default']['style'];
|
||||
}
|
||||
else
|
||||
$opt['template']['style'] = $opt['template']['default']['style'];
|
||||
$opt['stylepath'] = $opt['rootpath'] . 'templates2/' . $opt['template']['style'] . '/';
|
||||
|
||||
/* setup smarty
|
||||
*
|
||||
*/
|
||||
require($opt['rootpath'] . 'lib2/OcSmarty.class.php');
|
||||
$tpl = new OcSmarty();
|
||||
|
||||
// include all we need
|
||||
require_once($opt['rootpath'] . 'lib2/logic/const.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/geomath.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/error.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/util.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/db.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/login.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/menu.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/labels.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/throttle.inc.php');
|
||||
|
||||
// apply post configuration
|
||||
if (function_exists('post_config'))
|
||||
post_config();
|
||||
|
||||
// normalize important settings
|
||||
function normalize_settings()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$opt['charset']['iconv'] = strtoupper($opt['charset']['iconv']);
|
||||
if (substr($opt['page']['absolute_url'], -1, 1) != '/')
|
||||
$opt['page']['absolute_url'] .= '/';
|
||||
if (substr($opt['logic']['pictures']['url'], -1, 1) != '/')
|
||||
$opt['logic']['pictures']['url'] .= '/';
|
||||
if (substr($opt['logic']['pictures']['dir'], -1, 1) != '/')
|
||||
$opt['logic']['pictures']['dir'] .= '/';
|
||||
if (substr($opt['logic']['podcasts']['url'], -1, 1) != '/')
|
||||
$opt['logic']['podcasts']['url'] .= '/';
|
||||
if (substr($opt['logic']['podcasts']['dir'], -1, 1) != '/')
|
||||
$opt['logic']['podcasts']['dir'] .= '/';
|
||||
}
|
||||
|
||||
function configure_php()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($opt['php']['debug'] == PHP_DEBUG_SKIP)
|
||||
{
|
||||
}
|
||||
if ($opt['php']['debug'] == PHP_DEBUG_ON)
|
||||
{
|
||||
ini_set('display_errors', true);
|
||||
ini_set('error_reporting', E_ALL);
|
||||
ini_set('mysql.trace_mode', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ini_set('display_errors', false);
|
||||
ini_set('error_reporting', E_ALL & ~E_NOTICE);
|
||||
ini_set('mysql.trace_mode', false);
|
||||
}
|
||||
}
|
||||
|
||||
function set_domain()
|
||||
{
|
||||
global $opt;
|
||||
if (!isset($opt['domain']))
|
||||
return;
|
||||
|
||||
$domain = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
|
||||
if ($domain == '')
|
||||
return;
|
||||
|
||||
if (isset($opt['domain'][$domain]))
|
||||
{
|
||||
if (isset($opt['domain'][$domain]['url']))
|
||||
$opt['page']['absolute_url'] = $opt['domain'][$domain]['url'];
|
||||
|
||||
if (isset($opt['domain'][$domain]['locale']))
|
||||
$opt['template']['default']['locale'] = $opt['domain'][$domain]['locale'];
|
||||
|
||||
if (isset($opt['domain'][$domain]['country']))
|
||||
$opt['template']['default']['country'] = $opt['domain'][$domain]['country'];
|
||||
|
||||
if (isset($opt['domain'][$domain]['style']))
|
||||
$opt['template']['default']['style'] = $opt['domain'][$domain]['style'];
|
||||
|
||||
if (isset($opt['domain'][$domain]['cookiedomain']))
|
||||
$opt['session']['domain'] = $opt['domain'][$domain]['cookiedomain'];
|
||||
}
|
||||
}
|
||||
|
||||
function set_language()
|
||||
{
|
||||
global $opt, $cookie;
|
||||
|
||||
if (isset($_REQUEST['locale']))
|
||||
$opt['template']['locale'] = strtoupper($_REQUEST['locale']);
|
||||
else
|
||||
$opt['template']['locale'] = strtoupper($cookie->get('locale', $opt['template']['default']['locale']));
|
||||
|
||||
if (isset($opt['template']['locale']) && $opt['template']['locale'] != '')
|
||||
{
|
||||
if (strpos($opt['template']['locale'], '.') !== false ||
|
||||
strpos($opt['template']['locale'], '/') !== false)
|
||||
$opt['template']['locale'] = $opt['template']['default']['locale'];
|
||||
|
||||
if (!isset($opt['locale'][$opt['template']['locale']]))
|
||||
$opt['template']['locale'] = $opt['template']['default']['locale'];
|
||||
}
|
||||
else
|
||||
$opt['template']['locale'] = $opt['template']['default']['locale'];
|
||||
|
||||
$cookie->set('locale', $opt['template']['locale'], $opt['template']['default']['locale']);
|
||||
|
||||
bindtextdomain('messages', $opt['rootpath'] . 'cache2/translate');
|
||||
|
||||
// setup the PHP locale
|
||||
setlocale(LC_MONETARY, $opt['locale'][$opt['template']['locale']]['locales']);
|
||||
setlocale(LC_TIME, $opt['locale'][$opt['template']['locale']]['locales']);
|
||||
if (defined('LC_MESSAGES'))
|
||||
setlocale(LC_MESSAGES, $opt['locale'][$opt['template']['locale']]['locales']);
|
||||
|
||||
// no localisation!
|
||||
setlocale(LC_COLLATE, $opt['locale']['EN']['locales']);
|
||||
setlocale(LC_CTYPE, $opt['locale']['EN']['locales']);
|
||||
setlocale(LC_NUMERIC, $opt['locale']['EN']['locales']); // important for mysql-queries!
|
||||
|
||||
textdomain('messages');
|
||||
}
|
||||
|
||||
function set_usercountry()
|
||||
{
|
||||
global $cookie;
|
||||
|
||||
if (isset($_REQUEST['usercountry']))
|
||||
$cookie->set('usercountry', $_REQUEST['usercountry']);
|
||||
}
|
||||
|
||||
function fix_magic_quotes_gpc()
|
||||
{
|
||||
// Disable magic_quotes_runtime
|
||||
@set_magic_quotes_runtime(0);
|
||||
|
||||
if (get_magic_quotes_gpc())
|
||||
{
|
||||
if (is_array($_GET))
|
||||
{
|
||||
while (list($k, $v) = each($_GET))
|
||||
{
|
||||
if (is_array($_GET[$k]))
|
||||
{
|
||||
while (list($k2, $v2) = each($_GET[$k]))
|
||||
{
|
||||
$_GET[$k][$k2] = stripslashes($v2);
|
||||
}
|
||||
@reset($_GET[$k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$_GET[$k] = stripslashes($v);
|
||||
}
|
||||
}
|
||||
@reset($_GET);
|
||||
}
|
||||
|
||||
if (is_array($_POST))
|
||||
{
|
||||
while (list($k, $v) = each($_POST))
|
||||
{
|
||||
if (is_array($_POST[$k]))
|
||||
{
|
||||
while (list($k2, $v2) = each($_POST[$k]))
|
||||
{
|
||||
$_POST[$k][$k2] = stripslashes($v2);
|
||||
}
|
||||
@reset($_POST[$k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$_POST[$k] = stripslashes($v);
|
||||
}
|
||||
}
|
||||
@reset($_POST);
|
||||
}
|
||||
|
||||
if (is_array($_REQUEST))
|
||||
{
|
||||
while (list($k, $v) = each($_REQUEST))
|
||||
{
|
||||
if (is_array($_REQUEST[$k]))
|
||||
{
|
||||
while (list($k2, $v2) = each($_REQUEST[$k]))
|
||||
{
|
||||
$_REQUEST[$k][$k2] = stripslashes($v2);
|
||||
}
|
||||
@reset($_REQUEST[$k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$_REQUEST[$k] = stripslashes($v);
|
||||
}
|
||||
}
|
||||
@reset($_REQUEST);
|
||||
}
|
||||
|
||||
if (is_array($_COOKIE))
|
||||
{
|
||||
while (list($k, $v) = each($_COOKIE))
|
||||
{
|
||||
if (is_array($_COOKIE[$k]))
|
||||
{
|
||||
while (list($k2, $v2) = each($_COOKIE[$k]))
|
||||
{
|
||||
$_COOKIE[$k][$k2] = stripslashes($v2);
|
||||
}
|
||||
@reset($_COOKIE[$k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$_COOKIE[$k] = stripslashes($v);
|
||||
}
|
||||
}
|
||||
@reset($_COOKIE);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Constant definitions
|
||||
***************************************************************************/
|
||||
|
||||
define('GUI_HTML', 0);
|
||||
define('GUI_TEXT', 1);
|
||||
define('GUI_NUSOAP', 2);
|
||||
|
||||
define('DEBUG_NO', 0);
|
||||
define('DEBUG_DEVELOPER', 1);
|
||||
define('DEBUG_TEMPLATES', 2);
|
||||
define('DEBUG_OUTOFSERVICE', 4 | DEBUG_TEMPLATES);
|
||||
define('DEBUG_TESTING', 8 | DEBUG_TEMPLATES);
|
||||
define('DEBUG_SQLDEBUGGER', 16);
|
||||
define('DEBUG_TRANSLATE', 32); // DEBUG_TEMPLATES added in common.inc.php
|
||||
define('DEBUG_FORCE_TRANSLATE', 64 | DEBUG_TRANSLATE);
|
||||
define('DEBUG_CLI', 128);
|
||||
|
||||
define('PHP_DEBUG_OFF', 0);
|
||||
define('PHP_DEBUG_ON', 1);
|
||||
define('PHP_DEBUG_SKIP', -1);
|
||||
|
||||
define('SAVE_COOKIE', 0);
|
||||
define('SAVE_SESSION', 1);
|
||||
|
||||
define('DB_MODE_FRAMEWORK', 0);
|
||||
define('DB_MODE_BUSINESSLAYER', 1);
|
||||
define('DB_MODE_USER', 2);
|
||||
define('DB_DATE_FORMAT', '%Y-%m-%d %H:%M:%S');
|
||||
|
||||
// constants for user options (must match values in DB!)
|
||||
define('USR_OPT_GMZOOM', 1);
|
||||
define('USR_OPT_SHOWSTATS', 5);
|
||||
define('USR_OPT_TRANSLANG', 6);
|
||||
?>
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Cookie handling
|
||||
***************************************************************************/
|
||||
|
||||
$cookie = new cookie();
|
||||
|
||||
class cookie
|
||||
{
|
||||
var $changed = false;
|
||||
var $values = array();
|
||||
var $session_initalized = false;
|
||||
|
||||
function cookie()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
if (isset($_REQUEST['SESSION']) && $_REQUEST['SESSION'] != '')
|
||||
{
|
||||
$this->init_session();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($_COOKIE[$opt['session']['cookiename'] . 'data']))
|
||||
{
|
||||
//get the cookievars-array
|
||||
$decoded = base64_decode($_COOKIE[$opt['session']['cookiename'] . 'data']);
|
||||
|
||||
if ($decoded !== false)
|
||||
{
|
||||
$this->values = @unserialize($decoded);
|
||||
if (!is_array($this->values))
|
||||
$this->values = array();
|
||||
}
|
||||
else
|
||||
$this->values = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init_session()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($this->session_initalized != true)
|
||||
{
|
||||
session_name('SESSION');
|
||||
session_set_cookie_params($opt['session']['expire']['cookie'], $opt['session']['path'], $opt['session']['domain']);
|
||||
session_start();
|
||||
|
||||
if ($opt['session']['check_referer'])
|
||||
if (isset($_SERVER['REFERER']))
|
||||
if (strtolower(substr($_SERVER['REFERER'], 0, strlen($opt['page']['absolute_url']))) != strtolower($opt['page']['absolute_url']))
|
||||
$this->createNewSession();
|
||||
|
||||
if ((isset($_GET['SESSION']) || isset($_POST['SESSION'])) && count($_SESSION) > 0)
|
||||
{
|
||||
// comapre and set timestamp
|
||||
if (isset($_SESSION['lastcall']))
|
||||
{
|
||||
if (abs(time() - $_SESSION['lastcall']) > $opt['session']['expire']['url'])
|
||||
{
|
||||
$this->createNewSession();
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION['lastcall'] = time();
|
||||
}
|
||||
|
||||
$this->session_initalized = true;
|
||||
}
|
||||
}
|
||||
|
||||
function createNewSession()
|
||||
{
|
||||
session_regenerate_id();
|
||||
$locale = isset($_SESSION['locale']) ? $_SESSION['locale'] : '';
|
||||
foreach ($_SESSION AS $k => $v)
|
||||
{
|
||||
unset($_SESSION[$k]);
|
||||
}
|
||||
if ($locale != '')
|
||||
$_SESSION['locale'] = $locale;
|
||||
}
|
||||
|
||||
function set($name, $value, $default=null)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
if (!isset($_SESSION[$name]) || $_SESSION[$name] != $value)
|
||||
{
|
||||
if ($value == $default)
|
||||
{
|
||||
if (isset($_SESSION[$name]))
|
||||
{
|
||||
unset($_SESSION[$name]);
|
||||
$this->changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->init_session();
|
||||
$_SESSION[$name] = $value;
|
||||
$this->changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($this->values[$name]) || $this->values[$name] != $value)
|
||||
{
|
||||
if ($value == $default)
|
||||
{
|
||||
if (isset($this->values[$name]))
|
||||
{
|
||||
unset($this->values[$name]);
|
||||
$this->changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->values[$name] = $value;
|
||||
$this->changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function get($name, $default='')
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
return isset($_SESSION[$name]) ? $_SESSION[$name] : $default;
|
||||
}
|
||||
else
|
||||
{
|
||||
return isset($this->values[$name]) ? $this->values[$name] : $default;
|
||||
}
|
||||
}
|
||||
|
||||
function is_set($name)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
return isset($_SESSION[$name]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return isset($this->values[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
function un_set($name)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
if (isset($_SESSION[$name]))
|
||||
{
|
||||
unset($_SESSION[$name]);
|
||||
$this->changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($this->values[$name]))
|
||||
{
|
||||
unset($this->values[$name]);
|
||||
$this->changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function header()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
// is autmatically sent
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->changed == true)
|
||||
{
|
||||
if (count($this->values) == 0)
|
||||
setcookie($opt['session']['cookiename'] . 'data', false, time() + 31536000, $opt['session']['path'], $opt['session']['domain'], 0);
|
||||
else
|
||||
setcookie($opt['session']['cookiename'] . 'data', base64_encode(serialize($this->values)), time() + 31536000, $opt['session']['path'], $opt['session']['domain'], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function debug()
|
||||
{
|
||||
global $opt;
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
print_r($_SESSION);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_r($this->values);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
function close()
|
||||
{
|
||||
global $opt;
|
||||
if ($opt['session']['mode'] == SAVE_SESSION)
|
||||
{
|
||||
if ($this->session_initalized == true)
|
||||
{
|
||||
if (count($_SESSION) == 0)
|
||||
@session_destroy();
|
||||
else
|
||||
session_write_close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Common error messages
|
||||
***************************************************************************/
|
||||
|
||||
define('ERROR_UNKNOWN', 1000);
|
||||
define('ERROR_TEMPLATE_NOT_FOUND', 1001);
|
||||
define('ERROR_COMPILATION_FAILED', 1002);
|
||||
define('ERROR_NO_ACCESS', 1003);
|
||||
define('ERROR_INVALID_OPERATION', 1004);
|
||||
define('ERROR_LOGIN_REQUIRED', 1005);
|
||||
define('ERROR_MAIL_TEMPLATE_NOT_FOUND', 1006);
|
||||
define('ERROR_NO_COOKIES', 1007);
|
||||
define('ERROR_ALREADY_LOGGEDIN', 1008);
|
||||
define('ERROR_USER_NOT_ACTIVE', 1009);
|
||||
define('ERROR_USER_NO_EMAIL', 1010);
|
||||
define('ERROR_CACHE_NOT_PUBLISHED', 1011);
|
||||
define('ERROR_CACHE_LOCKED', 1012);
|
||||
|
||||
define('ERROR_SEARCHPLUGIN_WAYPOINT_FORMAT', 1013);
|
||||
define('ERROR_SEARCHPLUGIN_WAYPOINT_MANY', 1014);
|
||||
define('ERROR_SEARCHPLUGIN_WAYPOINT_NOTFOUND', 1015);
|
||||
|
||||
define('ERROR_DB_COULD_NOT_RECONNECT', 1016);
|
||||
define('ERROR_DB_NO_ROOT', 1017);
|
||||
|
||||
define('ERROR_USER_NOT_EXISTS', 1018);
|
||||
define('ERROR_CACHE_NOT_EXISTS', 1019);
|
||||
define('ERROR_CACHELOG_NOT_EXISTS', 1020);
|
||||
define('ERROR_PICTURE_NOT_EXISTS', 1021);
|
||||
|
||||
define('ERROR_UPLOAD_ERR_NO_FILE', 1022);
|
||||
define('ERROR_UPLOAD_ERR_SIZE', 1023);
|
||||
define('ERROR_UPLOAD_ERR_TYPE', 1024);
|
||||
define('ERROR_UPLOAD_UNKNOWN', 1025);
|
||||
define('ERROR_UPLOAD_ERR_BAD_FORMAT', 1026);
|
||||
?>
|
||||
@@ -0,0 +1,46 @@
|
||||
abysta at yandex.ru
|
||||
Adrian Schroeter
|
||||
Andrey Valentinovich Panov
|
||||
Ben Laenen
|
||||
Besarion Gugushvili
|
||||
Bhikkhu Pesala
|
||||
Clayborne Arevalo
|
||||
Dafydd Harries
|
||||
Danilo Segan
|
||||
Davide Viti
|
||||
David Jez
|
||||
David Lawrence Ramsey
|
||||
Denis Jacquerye
|
||||
Dwayne Bailey
|
||||
Eugeniy Meshcheryakov
|
||||
Gee Fung Sit
|
||||
Heikki Lindroos
|
||||
James Cloos
|
||||
James Crippen
|
||||
John Karp
|
||||
Keenan Pepper
|
||||
Lars Naesbye Christensen
|
||||
Mashrab Kuvatov
|
||||
Max Berger
|
||||
Mederic Boquien
|
||||
Michael Everson
|
||||
Misu Moldovan
|
||||
Nguyen Thai Ngoc Duy
|
||||
Nicolas Mailhot
|
||||
Ognyan Kulev
|
||||
Ondrej Koala Vacha
|
||||
Peter Cernak
|
||||
Remy Oudompheng
|
||||
Roozbeh Pournader
|
||||
Sahak Petrosyan
|
||||
Sander Vesik
|
||||
Stepan Roh
|
||||
Stephen Hartke
|
||||
Steve Tinney
|
||||
Tavmjong Bah
|
||||
Tim May
|
||||
Valentin Stoykov
|
||||
Vasek Stodulka
|
||||
Wesley Transue
|
||||
|
||||
$Id: AUTHORS 2344 2009-03-08 13:02:37Z moyogo $
|
||||
@@ -0,0 +1,3 @@
|
||||
See http://dejavu.sourceforge.net/wiki/index.php/Bugs
|
||||
|
||||
$Id: BUGS 80 2004-11-13 13:12:02Z src $
|
||||
@@ -0,0 +1,99 @@
|
||||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||
|
||||
Bitstream Vera Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
||||
a trademark of Bitstream, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute the
|
||||
Font Software, including without limitation the rights to use, copy, merge,
|
||||
publish, distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice shall
|
||||
be included in all copies of one or more of the Font Software typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in particular
|
||||
the designs of glyphs or characters in the Fonts may be modified and
|
||||
additional glyphs or characters may be added to the Fonts, only if the fonts
|
||||
are renamed to names not containing either the words "Bitstream" or the word
|
||||
"Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts or Font
|
||||
Software that has been modified and is distributed under the "Bitstream
|
||||
Vera" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but no
|
||||
copy of one or more of the Font Software typefaces may be sold by itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
||||
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
||||
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
||||
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
||||
FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font Software
|
||||
without prior written authorization from the Gnome Foundation or Bitstream
|
||||
Inc., respectively. For further information, contact: fonts at gnome dot
|
||||
org.
|
||||
|
||||
Arev Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and
|
||||
associated documentation files (the "Font Software"), to reproduce
|
||||
and distribute the modifications to the Bitstream Vera Font Software,
|
||||
including without limitation the rights to use, copy, merge, publish,
|
||||
distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Tavmjong Bah" or the word "Arev".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Tavmjong Bah Arev" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Tavmjong Bah shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
||||
. fr.
|
||||
|
||||
$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
DejaVu fonts 2.30 (c)2004-2009 DejaVu fonts team
|
||||
------------------------------------------------
|
||||
|
||||
The DejaVu fonts are a font family based on the Bitstream Vera Fonts
|
||||
(http://gnome.org/fonts/). Its purpose is to provide a wider range of
|
||||
characters (see status.txt for more information) while maintaining the
|
||||
original look and feel.
|
||||
|
||||
DejaVu fonts are based on Bitstream Vera fonts version 1.10.
|
||||
|
||||
Available fonts (Sans = sans serif, Mono = monospaced):
|
||||
|
||||
DejaVu Sans Mono
|
||||
DejaVu Sans Mono Bold
|
||||
DejaVu Sans Mono Bold Oblique
|
||||
DejaVu Sans Mono Oblique
|
||||
DejaVu Sans
|
||||
DejaVu Sans Bold
|
||||
DejaVu Sans Bold Oblique
|
||||
DejaVu Sans Oblique
|
||||
DejaVu Sans ExtraLight (experimental)
|
||||
DejaVu Serif
|
||||
DejaVu Serif Bold
|
||||
DejaVu Serif Bold Italic (experimental)
|
||||
DejaVu Serif Italic (experimental)
|
||||
DejaVu Sans Condensed (experimental)
|
||||
DejaVu Sans Condensed Bold (experimental)
|
||||
DejaVu Sans Condensed Bold Oblique (experimental)
|
||||
DejaVu Sans Condensed Oblique (experimental)
|
||||
DejaVu Serif Condensed (experimental)
|
||||
DejaVu Serif Condensed Bold (experimental)
|
||||
DejaVu Serif Condensed Bold Italic (experimental)
|
||||
DejaVu Serif Condensed Italic (experimental)
|
||||
|
||||
All fonts are also available as derivative called DejaVu LGC with support
|
||||
only for Latin, Greek and Cyrillic scripts.
|
||||
|
||||
For license information see LICENSE. What's new is described in NEWS. Known
|
||||
bugs are in BUGS. All authors are mentioned in AUTHORS.
|
||||
|
||||
Fonts are published in source form as SFD files (Spline Font Database from
|
||||
FontForge - http://fontforge.sf.net/) and in compiled form as TTF files
|
||||
(TrueType fonts).
|
||||
|
||||
For more information go to http://dejavu.sourceforge.net/.
|
||||
|
||||
Characters from Arev fonts, Copyright (c) 2006 by Tavmjong Bah:
|
||||
---------------------------
|
||||
U+01BA, U+01BF, U+01F7, U+021C-U+021D, U+0220, U+0222-U+0223,
|
||||
U+02B9, U+02BA, U+02BD, U+02C2-U+02C5, U+02d4-U+02D5,
|
||||
U+02D7, U+02EC-U+02EE, U+0346-U+034E, U+0360, U+0362,
|
||||
U+03E2-03EF, U+0460-0463, U+0466-U+0486, U+0488-U+0489, U+04A8-U+04A9,
|
||||
U+0500-U+050F, U+2055-205E, U+20B0, U+20B2-U+20B3, U+2102, U+210D, U+210F,
|
||||
U+2111, U+2113, U+2115, U+2118-U+211A, U+211C-U+211D, U+2124, U+2135,
|
||||
U+213C-U+2140, U+2295-U+2298, U+2308-U+230B, U+26A2-U+26B1, U+2701-U+2704,
|
||||
U+2706-U+2709, U+270C-U+274B, U+2758-U+275A, U+2761-U+2775, U+2780-U+2794,
|
||||
U+2798-U+27AF, U+27B1-U+27BE, U+FB05-U+FB06
|
||||
|
||||
$Id: README 2359 2009-08-27 14:13:16Z ben_laenen $
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
|
||||
<fontconfig>
|
||||
<!-- /etc/fonts/conf.d/20-unhint-small-dejavu-sans-mono.conf
|
||||
|
||||
Disable hinting manually at smaller sizes (< 8ppem)
|
||||
This is a copy of the Bistream Vera fonts fonts rule, as DejaVu is
|
||||
derived from Vera.
|
||||
|
||||
The Bistream Vera fonts have GASP entries suggesting that hinting be
|
||||
disabled below 8 ppem, but FreeType ignores those, preferring to use
|
||||
the data found in the instructed hints. The initial Vera release
|
||||
didn't include the right instructions in the 'prep' table.
|
||||
-->
|
||||
<match target="font">
|
||||
<test name="family">
|
||||
<string>DejaVu Sans Mono</string>
|
||||
</test>
|
||||
<test compare="less" name="pixelsize">
|
||||
<double>7.5</double>
|
||||
</test>
|
||||
<edit name="hinting">
|
||||
<bool>false</bool>
|
||||
</edit>
|
||||
</match>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
|
||||
<fontconfig>
|
||||
<!-- /etc/fonts/conf.d/20-unhint-small-dejavu-sans.conf
|
||||
|
||||
Disable hinting manually at smaller sizes (< 8ppem)
|
||||
This is a copy of the Bistream Vera fonts fonts rule, as DejaVu is
|
||||
derived from Vera.
|
||||
|
||||
The Bistream Vera fonts have GASP entries suggesting that hinting be
|
||||
disabled below 8 ppem, but FreeType ignores those, preferring to use
|
||||
the data found in the instructed hints. The initial Vera release
|
||||
didn't include the right instructions in the 'prep' table.
|
||||
-->
|
||||
<match target="font">
|
||||
<test name="family">
|
||||
<string>DejaVu Sans</string>
|
||||
</test>
|
||||
<test compare="less" name="pixelsize">
|
||||
<double>7.5</double>
|
||||
</test>
|
||||
<edit name="hinting">
|
||||
<bool>false</bool>
|
||||
</edit>
|
||||
</match>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
|
||||
<fontconfig>
|
||||
<!-- /etc/fonts/conf.d/20-unhint-small-dejavu-serif.conf
|
||||
|
||||
Disable hinting manually at smaller sizes (< 8ppem)
|
||||
This is a copy of the Bistream Vera fonts fonts rule, as DejaVu is
|
||||
derived from Vera.
|
||||
|
||||
The Bistream Vera fonts have GASP entries suggesting that hinting be
|
||||
disabled below 8 ppem, but FreeType ignores those, preferring to use
|
||||
the data found in the instructed hints. The initial Vera release
|
||||
didn't include the right instructions in the 'prep' table.
|
||||
-->
|
||||
<match target="font">
|
||||
<test name="family">
|
||||
<string>DejaVu Serif</string>
|
||||
</test>
|
||||
<test compare="less" name="pixelsize">
|
||||
<double>7.5</double>
|
||||
</test>
|
||||
<edit name="hinting">
|
||||
<bool>false</bool>
|
||||
</edit>
|
||||
</match>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
|
||||
<!-- /etc/fonts/conf.d/57-dejavu-sans-mono.conf
|
||||
|
||||
Define aliasing and other fontconfig settings for
|
||||
DejaVu Sans Mono.
|
||||
|
||||
© 2006-2008 Nicolas Mailhot <nicolas.mailhot at laposte.net>
|
||||
-->
|
||||
<fontconfig>
|
||||
<!-- Font substitution rules -->
|
||||
<alias binding="same">
|
||||
<family>Bepa Mono</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Bitstream Prima Sans Mono</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Bitstream Vera Sans Mono</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>DejaVu LGC Sans Mono</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Olwen Sans Mono</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>SUSE Sans Mono</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<!-- Generic name assignment -->
|
||||
<alias>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<default>
|
||||
<family>monospace</family>
|
||||
</default>
|
||||
</alias>
|
||||
<!-- Generic name aliasing -->
|
||||
<alias>
|
||||
<family>monospace</family>
|
||||
<prefer>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
|
||||
<!-- /etc/fonts/conf.d/57-dejavu-sans.conf
|
||||
|
||||
Define aliasing and other fontconfig settings for
|
||||
DejaVu Sans.
|
||||
|
||||
© 2006-2008 Nicolas Mailhot <nicolas.mailhot at laposte.net>
|
||||
-->
|
||||
<fontconfig>
|
||||
<!-- Font substitution rules -->
|
||||
<alias binding="same">
|
||||
<family>Arev Sans</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Bepa</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Bitstream Prima Sans</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Bitstream Vera Sans</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>DejaVu LGC Sans</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Hunky Sans</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Olwen Sans</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>SUSE Sans</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Verajja</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<!-- In case VerajjaPDA stops declaring itself as Verajja -->
|
||||
<alias binding="same">
|
||||
<family>VerajjaPDA</family>
|
||||
<accept>
|
||||
<family>DejaVu Sans</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<!-- Generic name assignment -->
|
||||
<alias>
|
||||
<family>DejaVu Sans</family>
|
||||
<default>
|
||||
<family>sans-serif</family>
|
||||
</default>
|
||||
</alias>
|
||||
<!-- Generic name aliasing -->
|
||||
<alias>
|
||||
<family>sans-serif</family>
|
||||
<prefer>
|
||||
<family>DejaVu Sans</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
|
||||
<!-- /etc/fonts/conf.d/57-dejavu-serif.conf
|
||||
|
||||
Define aliasing and other fontconfig settings for
|
||||
DejaVu Serif.
|
||||
|
||||
© 2006-2008 Nicolas Mailhot <nicolas.mailhot at laposte.net>
|
||||
-->
|
||||
<fontconfig>
|
||||
<!-- Font substitution rules -->
|
||||
<alias binding="same">
|
||||
<family>Bitstream Prima Serif</family>
|
||||
<accept>
|
||||
<family>DejaVu Serif</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Bitstream Vera Serif</family>
|
||||
<accept>
|
||||
<family>DejaVu Serif</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>DejaVu LGC Serif</family>
|
||||
<accept>
|
||||
<family>DejaVu Serif</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Hunky Serif</family>
|
||||
<accept>
|
||||
<family>DejaVu Serif</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>Olwen Serif</family>
|
||||
<accept>
|
||||
<family>DejaVu Serif</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<alias binding="same">
|
||||
<family>SUSE Serif</family>
|
||||
<accept>
|
||||
<family>DejaVu Serif</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<!-- In case Verajja Serif stops declaring itself as DejaVu Serif -->
|
||||
<alias binding="same">
|
||||
<family>Verajja Serif</family>
|
||||
<accept>
|
||||
<family>DejaVu Serif</family>
|
||||
</accept>
|
||||
</alias>
|
||||
<!-- Generic name assignment -->
|
||||
<alias>
|
||||
<family>DejaVu Serif</family>
|
||||
<default>
|
||||
<family>serif</family>
|
||||
</default>
|
||||
</alias>
|
||||
<!-- Generic name aliasing -->
|
||||
<alias>
|
||||
<family>serif</family>
|
||||
<prefer>
|
||||
<family>DejaVu Serif</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,242 @@
|
||||
This is the language coverage file for DejaVu fonts
|
||||
($Id$)
|
||||
|
||||
Sans Serif Sans Mono
|
||||
aa Afar 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
ab Abkhazia 100% (90/90) 93% (84/90) 84% (76/90)
|
||||
af Afrikaans 100% (69/69) 100% (69/69) 100% (69/69)
|
||||
ak Akan 100% (73/73) 100% (73/73) 100% (73/73)
|
||||
am Amharic (0/264) (0/264) (0/264)
|
||||
an Aragonese 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
ar Arabic 100% (125/125) (0/125) 100% (125/125)
|
||||
as Assamese (0/64) (0/64) (0/64)
|
||||
ast Asturian/Bable/Leonese/Asturleonese 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
av Avaric 100% (67/67) 100% (67/67) 100% (67/67)
|
||||
ay Aymara 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
az-az Azerbaijani in Azerbaijan 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
az-ir Azerbaijani in Iran 100% (130/130) (0/130) 100% (130/130)
|
||||
ba Bashkir 100% (82/82) 100% (82/82) 97% (80/82)
|
||||
be Byelorussian 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
ber-dz Berber in Algeria 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ber-ma Berber in Morocco 100% (32/32) (0/32) (0/32)
|
||||
bg Bulgarian 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
bh Bihari (Devanagari script) (0/68) (0/68) (0/68)
|
||||
bho Bhojpuri (Devanagari script) (0/68) (0/68) (0/68)
|
||||
bi Bislama 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
bin Edo or Bini 100% (78/78) 100% (78/78) 100% (78/78)
|
||||
bm Bambara 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
bn Bengali (0/63) (0/63) (0/63)
|
||||
bo Tibetan (0/95) (0/95) (0/95)
|
||||
br Breton 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
bs Bosnian 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
bua Buriat (Buryat) 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
byn Blin/Bilin (0/255) (0/255) (0/255)
|
||||
ca Catalan 100% (74/74) 100% (74/74) 100% (74/74)
|
||||
ce Chechen 100% (67/67) 100% (67/67) 100% (67/67)
|
||||
ch Chamorro 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
chm Mari (Lower Cheremis / Upper Cheremis) 100% (76/76) 100% (76/76) 97% (74/76)
|
||||
chr Cherokee (0/85) (0/85) (0/85)
|
||||
co Corsican 100% (84/84) 100% (84/84) 100% (84/84)
|
||||
crh Crimean Tatar/Crimean Turkish 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
cs Czech 100% (82/82) 100% (82/82) 100% (82/82)
|
||||
csb Kashubian 100% (74/74) 100% (74/74) 100% (74/74)
|
||||
cu Old Church Slavonic 100% (103/103) 86% (89/103) 78% (81/103)
|
||||
cv Chuvash 100% (74/74) 100% (74/74) 100% (74/74)
|
||||
cy Welsh 100% (78/78) 100% (78/78) 100% (78/78)
|
||||
da Danish 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
de German 100% (59/59) 100% (59/59) 100% (59/59)
|
||||
dv Divehi/Dhivehi/Maldivian (0/49) (0/49) (0/49)
|
||||
dz Dzongkha (0/95) (0/95) (0/95)
|
||||
ee Ewe 100% (99/99) 100% (99/99) 100% (99/99)
|
||||
el Greek 100% (69/69) 100% (69/69) 100% (69/69)
|
||||
en English 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
eo Esperanto 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
es Spanish 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
et Estonian 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
eu Basque 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
fa Persian 100% (129/129) (0/129) 100% (129/129)
|
||||
fat Fanti 100% (73/73) 100% (73/73) 100% (73/73)
|
||||
ff Fulah (Fula) 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
fi Finnish 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
fil Filipino 100% (84/84) 100% (84/84) 100% (84/84)
|
||||
fj Fijian 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
fo Faroese 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
fr French 100% (84/84) 100% (84/84) 100% (84/84)
|
||||
fur Friulian 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
fy Frisian 100% (75/75) 100% (75/75) 100% (75/75)
|
||||
ga Irish 100% (80/80) 100% (80/80) 100% (80/80)
|
||||
gd Scots Gaelic 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
gez Ethiopic (Geez) (0/218) (0/218) (0/218)
|
||||
gl Galician 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
gn Guarani 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
gu Gujarati (0/68) (0/68) (0/68)
|
||||
gv Manx Gaelic 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
ha Hausa 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
haw Hawaiian 100% (63/63) 100% (63/63) 100% (63/63)
|
||||
he Hebrew 100% (27/27) (0/27) (0/27)
|
||||
hi Hindi (Devanagari script) (0/68) (0/68) (0/68)
|
||||
hne Chhattisgarhi (0/68) (0/68) (0/68)
|
||||
ho Hiri Motu 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
hr Croatian 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
hsb Upper Sorbian 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
ht Haitian/Haitian Creole 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
hu Hungarian 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
hy Armenian 100% (77/77) (0/77) (0/77)
|
||||
hz Herero 100% (57/57) 100% (57/57) 100% (57/57)
|
||||
ia Interlingua 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
id Indonesian 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
ie Interlingue 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
ig Igbo 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
ii Sichuan Yi/Nuosu (0/1165) (0/1165) (0/1165)
|
||||
ik Inupiaq (Inupiak, Eskimo) 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
io Ido 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
is Icelandic 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
it Italian 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
iu Inuktitut 100% (161/161) (0/161) (0/161)
|
||||
ja Japanese (0/6537) (0/6537) (0/6537)
|
||||
jv Javanese 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
ka Georgian 100% (33/33) 100% (33/33) 100% (33/33)
|
||||
kaa Kara-Kalpak (Karakalpak) 100% (78/78) 100% (78/78) 100% (78/78)
|
||||
kab Kabyle 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ki Kikuyu 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
kj Kuanyama/Kwanyama 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
kk Kazakh 100% (77/77) 100% (77/77) 100% (77/77)
|
||||
kl Greenlandic 100% (81/81) 100% (81/81) 100% (81/81)
|
||||
km Central Khmer (0/63) (0/63) (0/63)
|
||||
kn Kannada (0/70) (0/70) (0/70)
|
||||
ko Korean (0/2443) (0/2443) (0/2443)
|
||||
kok Kokani (Devanagari script) (0/68) (0/68) (0/68)
|
||||
kr Kanuri 100% (56/56) 96% (54/56) 100% (56/56)
|
||||
ks Kashmiri 94% (137/145) (0/145) 97% (141/145)
|
||||
ku-am Kurdish in Armenia 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
ku-iq Kurdish in Iraq 100% (32/32) (0/32) 87% (28/32)
|
||||
ku-ir Kurdish in Iran 100% (32/32) (0/32) 87% (28/32)
|
||||
ku-tr Kurdish in Turkey 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
kum Kumyk 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
kv Komi (Komi-Permyak/Komi-Siryan) 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
kw Cornish 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
kwm Kwambi 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
ky Kirgiz 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
la Latin 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
lah Lahnda 94% (137/145) (0/145) 97% (141/145)
|
||||
lb Luxembourgish (Letzeburgesch) 100% (75/75) 100% (75/75) 100% (75/75)
|
||||
lez Lezghian (Lezgian) 100% (67/67) 100% (67/67) 100% (67/67)
|
||||
lg Ganda 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
li Limburgan/Limburger/Limburgish 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
ln Lingala 100% (81/81) 100% (81/81) 100% (81/81)
|
||||
lo Lao 100% (55/55) (0/55) 83% (46/55)
|
||||
lt Lithuanian 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
lv Latvian 100% (78/78) 100% (78/78) 100% (78/78)
|
||||
mai Maithili (Devanagari script) (0/68) (0/68) (0/68)
|
||||
mg Malagasy 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
mh Marshallese 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
mi Maori 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
mk Macedonian 100% (42/42) 100% (42/42) 100% (42/42)
|
||||
ml Malayalam (0/68) (0/68) (0/68)
|
||||
mn-cn Mongolian in China (0/130) (0/130) (0/130)
|
||||
mn-mn Mongolian in Mongolia 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
mo Moldavian 100% (128/128) 100% (128/128) 100% (128/128)
|
||||
mr Marathi (Devanagari script) (0/68) (0/68) (0/68)
|
||||
ms Malay 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
mt Maltese 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
my Burmese (Myanmar) (0/48) (0/48) (0/48)
|
||||
na Nauru 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
nb Norwegian Bokmal 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
nds Low Saxon 100% (59/59) 100% (59/59) 100% (59/59)
|
||||
ne Nepali (Devanagari script) (0/68) (0/68) (0/68)
|
||||
ng Ndonga 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
nl Dutch 100% (82/82) 100% (82/82) 100% (82/82)
|
||||
nn Norwegian Nynorsk 100% (76/76) 100% (76/76) 100% (76/76)
|
||||
no Norwegian (Bokmal) 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
nr Ndebele, South 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
nso Northern Sotho 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
nv Navajo/Navaho 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
ny Chichewa 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
oc Occitan 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
om Oromo or Galla 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
or Oriya (0/68) (0/68) (0/68)
|
||||
os Ossetic 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
ota Ottoman Turkish 97% (36/37) (0/37) 97% (36/37)
|
||||
pa Panjabi/Punjabi (0/63) (0/63) (0/63)
|
||||
pa-pk Panjabi/Punjabi in Pakistan 94% (137/145) (0/145) 97% (141/145)
|
||||
pap-an Papiamento in Netherlands Antilles 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
pap-aw Papiamento in Aruba 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
pl Polish 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ps-af Pashto in Afghanistan 83% (41/49) (0/49) 77% (38/49)
|
||||
ps-pk Pashto in Pakistan 81% (40/49) (0/49) 75% (37/49)
|
||||
pt Portuguese 100% (82/82) 100% (82/82) 100% (82/82)
|
||||
qu Quechua 100% (55/55) 100% (55/55) 100% (55/55)
|
||||
rm Rhaeto-Romance (Romansch) 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
rn Rundi 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
ro Romanian 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
ru Russian 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
rw Kinyarwanda 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
sa Sanskrit (Devanagari script) (0/68) (0/68) (0/68)
|
||||
sah Yakut 100% (76/76) 100% (76/76) 97% (74/76)
|
||||
sc Sardinian 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
sco Scots 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
sd Sindhi 81% (44/54) (0/54) 79% (43/54)
|
||||
se North Sami 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
sel Selkup (Ostyak-Samoyed) 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
sg Sango 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
sh Serbo-Croatian 100% (156/156) 100% (156/156) 98% (154/156)
|
||||
shs Secwepemctsin 100% (48/48) 100% (48/48) 100% (48/48)
|
||||
si Sinhala/Sinhalese (0/73) (0/73) (0/73)
|
||||
sid Sidamo (0/281) (0/281) (0/281)
|
||||
sk Slovak 100% (86/86) 100% (86/86) 100% (86/86)
|
||||
sl Slovenian 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
sm Samoan 100% (53/53) 100% (53/53) 100% (53/53)
|
||||
sma South Sami 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
smj Lule Sami 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
smn Inari Sami 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
sms Skolt Sami 100% (80/80) 100% (80/80) 97% (78/80)
|
||||
sn Shona 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
so Somali 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
sq Albanian 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
sr Serbian 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
ss Swati 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
st Sotho, Southern 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
su Sundanese 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
sv Swedish 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
sw Swahili 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
syr Syriac (0/45) (0/45) (0/45)
|
||||
ta Tamil (0/48) (0/48) (0/48)
|
||||
te Telugu (0/70) (0/70) (0/70)
|
||||
tg Tajik 100% (78/78) 100% (78/78) 97% (76/78)
|
||||
th Thai 1% (1/74) (0/74) (0/74)
|
||||
ti-er Eritrean Tigrinya (0/255) (0/255) (0/255)
|
||||
ti-et Ethiopian Tigrinya (0/281) (0/281) (0/281)
|
||||
tig Tigre (0/221) (0/221) (0/221)
|
||||
tk Turkmen 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
tl Tagalog 100% (84/84) 100% (84/84) 100% (84/84)
|
||||
tn Tswana 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
to Tonga 100% (53/53) 100% (53/53) 100% (53/53)
|
||||
tr Turkish 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ts Tsonga 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
tt Tatar 100% (76/76) 100% (76/76) 100% (76/76)
|
||||
tw Twi 100% (73/73) 100% (73/73) 100% (73/73)
|
||||
ty Tahitian 100% (65/65) 100% (65/65) 100% (65/65)
|
||||
tyv Tuvinian 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ug Uighur 100% (125/125) (0/125) 100% (125/125)
|
||||
uk Ukrainian 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
ur Urdu 94% (137/145) (0/145) 97% (141/145)
|
||||
uz Uzbek 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
ve Venda 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
vi Vietnamese 100% (194/194) 77% (150/194) 76% (148/194)
|
||||
vo Volapuk 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
vot Votic 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
wa Walloon 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
wal Wolaitta/Wolaytta (0/281) (0/281) (0/281)
|
||||
wen Sorbian languages (lower and upper) 100% (76/76) 100% (76/76) 100% (76/76)
|
||||
wo Wolof 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
xh Xhosa 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
yap Yapese 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
yi Yiddish 100% (27/27) (0/27) (0/27)
|
||||
yo Yoruba 100% (119/119) 100% (119/119) 100% (119/119)
|
||||
za Zhuang/Chuang 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
zh-cn Chinese (simplified) 0% (2/6765) 0% (2/6765) 0% (2/6765)
|
||||
zh-hk Chinese Hong Kong Supplementary Character Set (0/2213) (0/2213) (0/2213)
|
||||
zh-mo Chinese in Macau (0/2213) (0/2213) (0/2213)
|
||||
zh-sg Chinese in Singapore 0% (2/6765) 0% (2/6765) 0% (2/6765)
|
||||
zh-tw Chinese (traditional) (0/13063) (0/13063) (0/13063)
|
||||
zu Zulu 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,177 @@
|
||||
This is the Unicode coverage file for DejaVu fonts
|
||||
($Id$)
|
||||
|
||||
Control and similar characters are discounted from totals.
|
||||
|
||||
Sans Serif Sans Mono
|
||||
U+0000 Basic Latin 100% (95/95) 100% (95/95) 100% (95/95)
|
||||
U+0080 Latin-1 Supplement 100% (96/96) 100% (96/96) 100% (96/96)
|
||||
U+0100 Latin Extended-A 100% (128/128) 100% (128/128) 100% (128/128)
|
||||
U+0180 Latin Extended-B 100% (208/208) 91% (191/208) 86% (179/208)
|
||||
U+0250 IPA Extensions 100% (96/96) 100% (96/96) 100% (96/96)
|
||||
U+02b0 Spacing Modifier Letters 78% (63/80) 56% (45/80) 60% (48/80)
|
||||
U+0300 Combining Diacritical Marks 83% (93/112) 60% (68/112) 59% (67/112)
|
||||
U+0370 Greek and Coptic 100% (134/134) 85% (115/134) 82% (110/134)
|
||||
U+0400 Cyrillic 100% (256/256) 78% (200/256) 69% (178/256)
|
||||
U+0500 Cyrillic Supplement 94% (34/36) 27% (10/36) 16% (6/36)
|
||||
U+0530 Armenian 100% (86/86) (0/86) (0/86)
|
||||
U+0590 Hebrew 62% (54/87) (0/87) (0/87)
|
||||
U+0600 Arabic 46% (115/250) (0/250) 39% (99/250)
|
||||
U+0700 Syriac (0/77) (0/77) (0/77)
|
||||
U+0750 Arabic Supplement (0/48) (0/48) (0/48)
|
||||
U+0780 Thaana (0/50) (0/50) (0/50)
|
||||
U+07c0 NKo 91% (54/59) (0/59) (0/59)
|
||||
U+0900 Devanagari (0/113) (0/113) (0/113)
|
||||
U+0980 Bengali (0/91) (0/91) (0/91)
|
||||
U+0a00 Gurmukhi (0/79) (0/79) (0/79)
|
||||
U+0a80 Gujarati (0/83) (0/83) (0/83)
|
||||
U+0b00 Oriya (0/84) (0/84) (0/84)
|
||||
U+0b80 Tamil (0/72) (0/72) (0/72)
|
||||
U+0c00 Telugu (0/93) (0/93) (0/93)
|
||||
U+0c80 Kannada (0/86) (0/86) (0/86)
|
||||
U+0d00 Malayalam (0/95) (0/95) (0/95)
|
||||
U+0d80 Sinhala (0/80) (0/80) (0/80)
|
||||
U+0e00 Thai 1% (1/87) (0/87) (0/87)
|
||||
U+0e80 Lao 100% (65/65) (0/65) 70% (46/65)
|
||||
U+0f00 Tibetan (0/201) (0/201) (0/201)
|
||||
U+1000 Myanmar (0/156) (0/156) (0/156)
|
||||
U+10a0 Georgian 100% (83/83) 100% (83/83) 54% (45/83)
|
||||
U+1100 Hangul Jamo (0/240) (0/240) (0/240)
|
||||
U+1200 Ethiopic (0/356) (0/356) (0/356)
|
||||
U+1380 Ethiopic Supplement (0/26) (0/26) (0/26)
|
||||
U+13a0 Cherokee (0/85) (0/85) (0/85)
|
||||
U+1400 Unified Canadian Aboriginal Syllabics 64% (404/630) (0/630) (0/630)
|
||||
U+1680 Ogham 100% (29/29) (0/29) (0/29)
|
||||
U+16a0 Runic (0/81) (0/81) (0/81)
|
||||
U+1700 Tagalog (0/20) (0/20) (0/20)
|
||||
U+1720 Hanunoo (0/23) (0/23) (0/23)
|
||||
U+1740 Buhid (0/20) (0/20) (0/20)
|
||||
U+1760 Tagbanwa (0/18) (0/18) (0/18)
|
||||
U+1780 Khmer (0/114) (0/114) (0/114)
|
||||
U+1800 Mongolian (0/156) (0/156) (0/156)
|
||||
U+1900 Limbu (0/66) (0/66) (0/66)
|
||||
U+1950 Tai Le (0/35) (0/35) (0/35)
|
||||
U+1980 New Tai Lue (0/80) (0/80) (0/80)
|
||||
U+19e0 Khmer Symbols (0/32) (0/32) (0/32)
|
||||
U+1a00 Buginese (0/30) (0/30) (0/30)
|
||||
U+1b00 Balinese (0/121) (0/121) (0/121)
|
||||
U+1b80 Sundanese (0/55) (0/55) (0/55)
|
||||
U+1c00 Lepcha (0/74) (0/74) (0/74)
|
||||
U+1c50 Ol Chiki (0/48) (0/48) (0/48)
|
||||
U+1d00 Phonetic Extensions 82% (105/128) 48% (62/128) 48% (62/128)
|
||||
U+1d80 Phonetic Extensions Supplement 59% (38/64) 57% (37/64) 57% (37/64)
|
||||
U+1dc0 Combining Diacritical Marks Supplement 14% (6/41) 14% (6/41) (0/41)
|
||||
U+1e00 Latin Extended Additional 96% (248/256) 76% (196/256) 71% (182/256)
|
||||
U+1f00 Greek Extended 100% (233/233) 100% (233/233) 100% (233/233)
|
||||
U+2000 General Punctuation 98% (105/107) 81% (87/107) 47% (51/107)
|
||||
U+2070 Superscripts and Subscripts 100% (34/34) 100% (34/34) 100% (34/34)
|
||||
U+20a0 Currency Symbols 100% (22/22) 27% (6/22) 100% (22/22)
|
||||
U+20d0 Combining Diacritical Marks for Symbols 21% (7/33) (0/33) (0/33)
|
||||
U+2100 Letterlike Symbols 93% (75/80) 40% (32/80) 21% (17/80)
|
||||
U+2150 Number Forms 92% (50/54) 92% (50/54) 24% (13/54)
|
||||
U+2190 Arrows 100% (112/112) 100% (112/112) 100% (112/112)
|
||||
U+2200 Mathematical Operators 100% (256/256) 39% (100/256) 58% (151/256)
|
||||
U+2300 Miscellaneous Technical 27% (64/232) 6% (16/232) 50% (117/232)
|
||||
U+2400 Control Pictures 5% (2/39) 2% (1/39) 2% (1/39)
|
||||
U+2440 Optical Character Recognition (0/11) (0/11) (0/11)
|
||||
U+2460 Enclosed Alphanumerics 6% (10/160) (0/160) (0/160)
|
||||
U+2500 Box Drawing 100% (128/128) 100% (128/128) 100% (128/128)
|
||||
U+2580 Block Elements 100% (32/32) 100% (32/32) 100% (32/32)
|
||||
U+25a0 Geometric Shapes 100% (96/96) 100% (96/96) 100% (96/96)
|
||||
U+2600 Miscellaneous Symbols 95% (182/191) 15% (30/191) 78% (149/191)
|
||||
U+2700 Dingbats 100% (174/174) 0% (1/174) 82% (144/174)
|
||||
U+27c0 Miscellaneous Mathematical Symbols-A 20% (9/44) 11% (5/44) 11% (5/44)
|
||||
U+27f0 Supplemental Arrows-A 100% (16/16) 100% (16/16) (0/16)
|
||||
U+2800 Braille Patterns 100% (256/256) 100% (256/256) (0/256)
|
||||
U+2900 Supplemental Arrows-B 4% (6/128) 100% (128/128) (0/128)
|
||||
U+2980 Miscellaneous Mathematical Symbols-B 10% (13/128) 0% (1/128) 2% (3/128)
|
||||
U+2a00 Supplemental Mathematical Operators 28% (72/256) 1% (4/256) 0% (1/256)
|
||||
U+2b00 Miscellaneous Symbols and Arrows 42% (35/82) 32% (27/82) 10% (9/82)
|
||||
U+2c00 Glagolitic (0/94) (0/94) (0/94)
|
||||
U+2c60 Latin Extended-C 96% (28/29) 55% (16/29) 34% (10/29)
|
||||
U+2c80 Coptic (0/114) (0/114) (0/114)
|
||||
U+2d00 Georgian Supplement (0/38) 100% (38/38) (0/38)
|
||||
U+2d30 Tifinagh 100% (55/55) (0/55) (0/55)
|
||||
U+2d80 Ethiopic Extended (0/79) (0/79) (0/79)
|
||||
U+2de0 Cyrillic Extended-A (0/32) (0/32) (0/32)
|
||||
U+2e00 Supplemental Punctuation 12% (6/49) 12% (6/49) 12% (6/49)
|
||||
U+2e80 CJK Radicals Supplement (0/115) (0/115) (0/115)
|
||||
U+2f00 Kangxi Radicals (0/214) (0/214) (0/214)
|
||||
U+2ff0 Ideographic Description Characters (0/12) (0/12) (0/12)
|
||||
U+3000 CJK Symbols and Punctuation (0/64) (0/64) (0/64)
|
||||
U+3040 Hiragana (0/93) (0/93) (0/93)
|
||||
U+30a0 Katakana (0/96) (0/96) (0/96)
|
||||
U+3100 Bopomofo (0/41) (0/41) (0/41)
|
||||
U+3130 Hangul Compatibility Jamo (0/94) (0/94) (0/94)
|
||||
U+3190 Kanbun (0/16) (0/16) (0/16)
|
||||
U+31a0 Bopomofo Extended (0/24) (0/24) (0/24)
|
||||
U+31c0 CJK Strokes (0/36) (0/36) (0/36)
|
||||
U+31f0 Katakana Phonetic Extensions (0/16) (0/16) (0/16)
|
||||
U+3200 Enclosed CJK Letters and Months (0/242) (0/242) (0/242)
|
||||
U+3300 CJK Compatibility (0/256) (0/256) (0/256)
|
||||
U+3400 CJK Unified Ideographs Extension A (0/0) (0/0) (0/0)
|
||||
U+4dc0 Yijing Hexagram Symbols 100% (64/64) (0/64) (0/64)
|
||||
U+4e00 CJK Unified Ideographs (0/0) (0/0) (0/0)
|
||||
U+a000 Yi Syllables (0/1165) (0/1165) (0/1165)
|
||||
U+a490 Yi Radicals (0/55) (0/55) (0/55)
|
||||
U+a500 Vai (0/300) (0/300) (0/300)
|
||||
U+a640 Cyrillic Extended-B 39% (31/78) 12% (10/78) (0/78)
|
||||
U+a700 Modifier Tone Letters 62% (20/32) 62% (20/32) 62% (20/32)
|
||||
U+a720 Latin Extended-D 37% (43/114) 1% (2/114) 5% (6/114)
|
||||
U+a800 Syloti Nagri (0/44) (0/44) (0/44)
|
||||
U+a840 Phags-pa (0/56) (0/56) (0/56)
|
||||
U+a880 Saurashtra (0/81) (0/81) (0/81)
|
||||
U+a900 Kayah Li (0/48) (0/48) (0/48)
|
||||
U+a930 Rejang (0/37) (0/37) (0/37)
|
||||
U+aa00 Cham (0/83) (0/83) (0/83)
|
||||
U+ac00 Hangul Syllables (0/0) (0/0) (0/0)
|
||||
U+d800 High Surrogates (0/0) (0/0) (0/0)
|
||||
U+db80 High Private Use Surrogates (0/0) (0/0) (0/0)
|
||||
U+dc00 Low Surrogates (0/0) (0/0) (0/0)
|
||||
U+e000 Private Use Area (0/0) (0/0) (0/0)
|
||||
U+f900 CJK Compatibility Ideographs (0/467) (0/467) (0/467)
|
||||
U+fb00 Alphabetic Presentation Forms 100% (58/58) 12% (7/58) 3% (2/58)
|
||||
U+fb50 Arabic Presentation Forms-A 11% (70/595) (0/595) 12% (72/595)
|
||||
U+fe00 Variation Selectors 100% (16/16) 100% (16/16) (0/16)
|
||||
U+fe10 Vertical Forms (0/10) (0/10) (0/10)
|
||||
U+fe20 Combining Half Marks 57% (4/7) (0/7) (0/7)
|
||||
U+fe30 CJK Compatibility Forms (0/32) (0/32) (0/32)
|
||||
U+fe50 Small Form Variants (0/26) (0/26) (0/26)
|
||||
U+fe70 Arabic Presentation Forms-B 100% (141/141) (0/141) 100% (141/141)
|
||||
U+ff00 Halfwidth and Fullwidth Forms (0/225) (0/225) (0/225)
|
||||
U+fff0 Specials 100% (5/5) 100% (5/5) 100% (5/5)
|
||||
U+10000 Linear B Syllabary (0/88) (0/88) (0/88)
|
||||
U+10080 Linear B Ideograms (0/123) (0/123) (0/123)
|
||||
U+10100 Aegean Numbers (0/57) (0/57) (0/57)
|
||||
U+10140 Ancient Greek Numbers (0/75) (0/75) (0/75)
|
||||
U+10190 Ancient Symbols (0/12) (0/12) (0/12)
|
||||
U+101d0 Phaistos Disc (0/46) (0/46) (0/46)
|
||||
U+10280 Lycian (0/29) (0/29) (0/29)
|
||||
U+102a0 Carian (0/49) (0/49) (0/49)
|
||||
U+10300 Old Italic (0/35) (0/35) (0/35)
|
||||
U+10330 Gothic (0/27) (0/27) (0/27)
|
||||
U+10380 Ugaritic (0/31) (0/31) (0/31)
|
||||
U+103a0 Old Persian (0/50) (0/50) (0/50)
|
||||
U+10400 Deseret (0/80) (0/80) (0/80)
|
||||
U+10450 Shavian (0/48) (0/48) (0/48)
|
||||
U+10480 Osmanya (0/40) (0/40) (0/40)
|
||||
U+10800 Cypriot Syllabary (0/55) (0/55) (0/55)
|
||||
U+10900 Phoenician (0/27) (0/27) (0/27)
|
||||
U+10920 Lydian (0/27) (0/27) (0/27)
|
||||
U+10a00 Kharoshthi (0/65) (0/65) (0/65)
|
||||
U+12000 Cuneiform (0/879) (0/879) (0/879)
|
||||
U+12400 Cuneiform Numbers and Punctuation (0/103) (0/103) (0/103)
|
||||
U+1d000 Byzantine Musical Symbols (0/246) (0/246) (0/246)
|
||||
U+1d100 Musical Symbols (0/220) (0/220) (0/220)
|
||||
U+1d200 Ancient Greek Musical Notation (0/70) (0/70) (0/70)
|
||||
U+1d300 Tai Xuan Jing Symbols 100% (87/87) (0/87) (0/87)
|
||||
U+1d360 Counting Rod Numerals (0/18) (0/18) (0/18)
|
||||
U+1d400 Mathematical Alphanumeric Symbols 11% (117/996) 5% (55/996) 6% (62/996)
|
||||
U+1f000 Mahjong Tiles (0/44) (0/44) (0/44)
|
||||
U+1f030 Domino Tiles (0/100) (0/100) (0/100)
|
||||
U+20000 CJK Unified Ideographs Extension B (0/0) (0/0) (0/0)
|
||||
U+2f800 CJK Compatibility Ideographs Supplement (0/542) (0/542) (0/542)
|
||||
U+e0000 Tags (0/98) (0/98) (0/98)
|
||||
U+e0100 Variation Selectors Supplement (0/240) (0/240) (0/240)
|
||||
U+f0000 Supplementary Private Use Area-A (0/0) (0/0) (0/0)
|
||||
U+100000 Supplementary Private Use Area-B (0/0) (0/0) (0/0)
|
||||
@@ -0,0 +1,489 @@
|
||||
<?php
|
||||
|
||||
/*************************************************************************
|
||||
* *
|
||||
* class.html2text.inc *
|
||||
* *
|
||||
*************************************************************************
|
||||
* *
|
||||
* Converts HTML to formatted plain text *
|
||||
* *
|
||||
* Copyright (c) 2005-2007 Jon Abernathy <jon@chuggnutt.com> *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This script is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* The GNU General Public License can be found at *
|
||||
* http://www.gnu.org/copyleft/gpl.html. *
|
||||
* *
|
||||
* This script 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 General Public License for more details. *
|
||||
* *
|
||||
* Author(s): Jon Abernathy <jon@chuggnutt.com> *
|
||||
* *
|
||||
* Last modified: 08/08/07 *
|
||||
* *
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Takes HTML and converts it to formatted, plain text.
|
||||
*
|
||||
* Thanks to Alexander Krug (http://www.krugar.de/) to pointing out and
|
||||
* correcting an error in the regexp search array. Fixed 7/30/03.
|
||||
*
|
||||
* Updated set_html() function's file reading mechanism, 9/25/03.
|
||||
*
|
||||
* Thanks to Joss Sanglier (http://www.dancingbear.co.uk/) for adding
|
||||
* several more HTML entity codes to the $search and $replace arrays.
|
||||
* Updated 11/7/03.
|
||||
*
|
||||
* Thanks to Darius Kasperavicius (http://www.dar.dar.lt/) for
|
||||
* suggesting the addition of $allowed_tags and its supporting function
|
||||
* (which I slightly modified). Updated 3/12/04.
|
||||
*
|
||||
* Thanks to Justin Dearing for pointing out that a replacement for the
|
||||
* <TH> tag was missing, and suggesting an appropriate fix.
|
||||
* Updated 8/25/04.
|
||||
*
|
||||
* Thanks to Mathieu Collas (http://www.myefarm.com/) for finding a
|
||||
* display/formatting bug in the _build_link_list() function: email
|
||||
* readers would show the left bracket and number ("[1") as part of the
|
||||
* rendered email address.
|
||||
* Updated 12/16/04.
|
||||
*
|
||||
* Thanks to Wojciech Bajon (http://histeria.pl/) for submitting code
|
||||
* to handle relative links, which I hadn't considered. I modified his
|
||||
* code a bit to handle normal HTTP links and MAILTO links. Also for
|
||||
* suggesting three additional HTML entity codes to search for.
|
||||
* Updated 03/02/05.
|
||||
*
|
||||
* Thanks to Jacob Chandler for pointing out another link condition
|
||||
* for the _build_link_list() function: "https".
|
||||
* Updated 04/06/05.
|
||||
*
|
||||
* Thanks to Marc Bertrand (http://www.dresdensky.com/) for
|
||||
* suggesting a revision to the word wrapping functionality; if you
|
||||
* specify a $width of 0 or less, word wrapping will be ignored.
|
||||
* Updated 11/02/06.
|
||||
*
|
||||
* *** Big housecleaning updates below:
|
||||
*
|
||||
* Thanks to Colin Brown (http://www.sparkdriver.co.uk/) for
|
||||
* suggesting the fix to handle </li> and blank lines (whitespace).
|
||||
* Christian Basedau (http://www.movetheweb.de/) also suggested the
|
||||
* blank lines fix.
|
||||
*
|
||||
* Special thanks to Marcus Bointon (http://www.synchromedia.co.uk/),
|
||||
* Christian Basedau, Norbert Laposa (http://ln5.co.uk/),
|
||||
* Bas van de Weijer, and Marijn van Butselaar
|
||||
* for pointing out my glaring error in the <th> handling. Marcus also
|
||||
* supplied a host of fixes.
|
||||
*
|
||||
* Thanks to Jeffrey Silverman (http://www.newtnotes.com/) for pointing
|
||||
* out that extra spaces should be compressed--a problem addressed with
|
||||
* Marcus Bointon's fixes but that I had not yet incorporated.
|
||||
*
|
||||
* Thanks to Daniel Schledermann (http://www.typoconsult.dk/) for
|
||||
* suggesting a valuable fix with <a> tag handling.
|
||||
*
|
||||
* Thanks to Wojciech Bajon (again!) for suggesting fixes and additions,
|
||||
* including the <a> tag handling that Daniel Schledermann pointed
|
||||
* out but that I had not yet incorporated. I haven't (yet)
|
||||
* incorporated all of Wojciech's changes, though I may at some
|
||||
* future time.
|
||||
*
|
||||
* *** End of the housecleaning updates. Updated 08/08/07.
|
||||
*
|
||||
* @author Jon Abernathy <jon@chuggnutt.com>
|
||||
* @version 1.0.0
|
||||
* @since PHP 4.0.2
|
||||
*/
|
||||
class html2text
|
||||
{
|
||||
|
||||
/**
|
||||
* Contains the HTML content to convert.
|
||||
*
|
||||
* @var string $html
|
||||
* @access public
|
||||
*/
|
||||
var $html;
|
||||
|
||||
/**
|
||||
* Contains the converted, formatted text.
|
||||
*
|
||||
* @var string $text
|
||||
* @access public
|
||||
*/
|
||||
var $text;
|
||||
|
||||
/**
|
||||
* Maximum width of the formatted text, in columns.
|
||||
*
|
||||
* Set this value to 0 (or less) to ignore word wrapping
|
||||
* and not constrain text to a fixed-width column.
|
||||
*
|
||||
* @var integer $width
|
||||
* @access public
|
||||
*/
|
||||
var $width = 70;
|
||||
|
||||
/**
|
||||
* List of preg* regular expression patterns to search for,
|
||||
* used in conjunction with $replace.
|
||||
*
|
||||
* @var array $search
|
||||
* @access public
|
||||
* @see $replace
|
||||
*/
|
||||
var $search = array(
|
||||
"/\r/", // Non-legal carriage return
|
||||
"/[\n\t]+/", // Newlines and tabs
|
||||
'/[ ]{2,}/', // Runs of spaces, pre-handling
|
||||
'/<script[^>]*>.*?<\/script>/i', // <script>s -- which strip_tags supposedly has problems with
|
||||
'/<style[^>]*>.*?<\/style>/i', // <style>s -- which strip_tags supposedly has problems with
|
||||
//'/<!-- .* -->/', // Comments -- which strip_tags might have problem a with
|
||||
'/<h[123][^>]*>(.*?)<\/h[123]>/ie', // H1 - H3
|
||||
'/<h[456][^>]*>(.*?)<\/h[456]>/ie', // H4 - H6
|
||||
'/<p[^>]*>/i', // <P>
|
||||
'/<br[^>]*>/i', // <br>
|
||||
'/<b[^>]*>(.*?)<\/b>/ie', // <b>
|
||||
'/<strong[^>]*>(.*?)<\/strong>/ie', // <strong>
|
||||
'/<i[^>]*>(.*?)<\/i>/i', // <i>
|
||||
'/<em[^>]*>(.*?)<\/em>/i', // <em>
|
||||
'/(<ul[^>]*>|<\/ul>)/i', // <ul> and </ul>
|
||||
'/(<ol[^>]*>|<\/ol>)/i', // <ol> and </ol>
|
||||
'/<li[^>]*>(.*?)<\/li>/i', // <li> and </li>
|
||||
'/<li[^>]*>/i', // <li>
|
||||
'/<a [^>]*href="([^"]+)"[^>]*>(.*?)<\/a>/ie',
|
||||
// <a href="">
|
||||
'/<hr[^>]*>/i', // <hr>
|
||||
'/(<table[^>]*>|<\/table>)/i', // <table> and </table>
|
||||
'/(<tr[^>]*>|<\/tr>)/i', // <tr> and </tr>
|
||||
'/<td[^>]*>(.*?)<\/td>/i', // <td> and </td>
|
||||
'/<th[^>]*>(.*?)<\/th>/ie', // <th> and </th>
|
||||
'/&(nbsp|#160);/i', // Non-breaking space
|
||||
'/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i',
|
||||
// Double quotes
|
||||
'/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes
|
||||
'/>/i', // Greater-than
|
||||
'/</i', // Less-than
|
||||
'/&(amp|#38);/i', // Ampersand
|
||||
'/&(copy|#169);/i', // Copyright
|
||||
'/&(trade|#8482|#153);/i', // Trademark
|
||||
'/&(reg|#174);/i', // Registered
|
||||
'/&(mdash|#151|#8212);/i', // mdash
|
||||
'/&(ndash|minus|#8211|#8722);/i', // ndash
|
||||
'/&(bull|#149|#8226);/i', // Bullet
|
||||
'/&(pound|#163);/i', // Pound sign
|
||||
'/&(euro|#8364);/i', // Euro sign
|
||||
'/&[^&;]+;/i', // Unknown/unhandled entities
|
||||
'/[ ]{2,}/' // Runs of spaces, post-handling
|
||||
);
|
||||
|
||||
/**
|
||||
* List of pattern replacements corresponding to patterns searched.
|
||||
*
|
||||
* @var array $replace
|
||||
* @access public
|
||||
* @see $search
|
||||
*/
|
||||
var $replace = array(
|
||||
'', // Non-legal carriage return
|
||||
' ', // Newlines and tabs
|
||||
' ', // Runs of spaces, pre-handling
|
||||
'', // <script>s -- which strip_tags supposedly has problems with
|
||||
'', // <style>s -- which strip_tags supposedly has problems with
|
||||
//'', // Comments -- which strip_tags might have problem a with
|
||||
"strtoupper(\"\n\n\\1\n\n\")", // H1 - H3
|
||||
"ucwords(\"\n\n\\1\n\n\")", // H4 - H6
|
||||
"\n\n\t", // <P>
|
||||
"\n", // <br>
|
||||
'strtoupper("\\1")', // <b>
|
||||
'strtoupper("\\1")', // <strong>
|
||||
'_\\1_', // <i>
|
||||
'_\\1_', // <em>
|
||||
"\n\n", // <ul> and </ul>
|
||||
"\n\n", // <ol> and </ol>
|
||||
"\t* \\1\n", // <li> and </li>
|
||||
"\n\t* ", // <li>
|
||||
'$this->_build_link_list("\\1", "\\2")',
|
||||
// <a href="">
|
||||
"\n-------------------------\n", // <hr>
|
||||
"\n\n", // <table> and </table>
|
||||
"\n", // <tr> and </tr>
|
||||
"\t\t\\1\n", // <td> and </td>
|
||||
"strtoupper(\"\t\t\\1\n\")", // <th> and </th>
|
||||
' ', // Non-breaking space
|
||||
'"', // Double quotes
|
||||
"'", // Single quotes
|
||||
'>',
|
||||
'<',
|
||||
'&',
|
||||
'(c)',
|
||||
'(tm)',
|
||||
'(R)',
|
||||
'--',
|
||||
'-',
|
||||
'*',
|
||||
'£',
|
||||
'EUR', // Euro sign. € ?
|
||||
'', // Unknown/unhandled entities
|
||||
' ' // Runs of spaces, post-handling
|
||||
);
|
||||
|
||||
/**
|
||||
* Contains a list of HTML tags to allow in the resulting text.
|
||||
*
|
||||
* @var string $allowed_tags
|
||||
* @access public
|
||||
* @see set_allowed_tags()
|
||||
*/
|
||||
var $allowed_tags = '';
|
||||
|
||||
/**
|
||||
* Contains the base URL that relative links should resolve to.
|
||||
*
|
||||
* @var string $url
|
||||
* @access public
|
||||
*/
|
||||
var $url;
|
||||
|
||||
/**
|
||||
* Indicates whether content in the $html variable has been converted yet.
|
||||
*
|
||||
* @var boolean $_converted
|
||||
* @access private
|
||||
* @see $html, $text
|
||||
*/
|
||||
var $_converted = false;
|
||||
|
||||
/**
|
||||
* Contains URL addresses from links to be rendered in plain text.
|
||||
*
|
||||
* @var string $_link_list
|
||||
* @access private
|
||||
* @see _build_link_list()
|
||||
*/
|
||||
var $_link_list = '';
|
||||
|
||||
/**
|
||||
* Number of valid links detected in the text, used for plain text
|
||||
* display (rendered similar to footnotes).
|
||||
*
|
||||
* @var integer $_link_count
|
||||
* @access private
|
||||
* @see _build_link_list()
|
||||
*/
|
||||
var $_link_count = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* If the HTML source string (or file) is supplied, the class
|
||||
* will instantiate with that source propagated, all that has
|
||||
* to be done it to call get_text().
|
||||
*
|
||||
* @param string $source HTML content
|
||||
* @param boolean $from_file Indicates $source is a file to pull content from
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function html2text( $source = '', $from_file = false )
|
||||
{
|
||||
if ( !empty($source) ) {
|
||||
$this->set_html($source, $from_file);
|
||||
}
|
||||
$this->set_base_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads source HTML into memory, either from $source string or a file.
|
||||
*
|
||||
* @param string $source HTML content
|
||||
* @param boolean $from_file Indicates $source is a file to pull content from
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function set_html( $source, $from_file = false )
|
||||
{
|
||||
$this->html = $source;
|
||||
|
||||
if ( $from_file && file_exists($source) ) {
|
||||
$fp = fopen($source, 'r');
|
||||
$this->html = fread($fp, filesize($source));
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
$this->_converted = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text, converted from HTML.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function get_text()
|
||||
{
|
||||
if ( !$this->_converted ) {
|
||||
$this->_convert();
|
||||
}
|
||||
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the text, converted from HTML.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function print_text()
|
||||
{
|
||||
print $this->get_text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias to print_text(), operates identically.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @see print_text()
|
||||
*/
|
||||
function p()
|
||||
{
|
||||
print $this->get_text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the allowed HTML tags to pass through to the resulting text.
|
||||
*
|
||||
* Tags should be in the form "<p>", with no corresponding closing tag.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function set_allowed_tags( $allowed_tags = '' )
|
||||
{
|
||||
if ( !empty($allowed_tags) ) {
|
||||
$this->allowed_tags = $allowed_tags;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a base URL to handle relative links.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function set_base_url( $url = '' )
|
||||
{
|
||||
if ( empty($url) ) {
|
||||
if ( !empty($_SERVER['HTTP_HOST']) ) {
|
||||
$this->url = 'http://' . $_SERVER['HTTP_HOST'];
|
||||
} else {
|
||||
$this->url = '';
|
||||
}
|
||||
} else {
|
||||
// Strip any trailing slashes for consistency (relative
|
||||
// URLs may already start with a slash like "/file.html")
|
||||
if ( substr($url, -1) == '/' ) {
|
||||
$url = substr($url, 0, -1);
|
||||
}
|
||||
$this->url = $url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Workhorse function that does actual conversion.
|
||||
*
|
||||
* First performs custom tag replacement specified by $search and
|
||||
* $replace arrays. Then strips any remaining HTML tags, reduces whitespace
|
||||
* and newlines to a readable format, and word wraps the text to
|
||||
* $width characters.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _convert()
|
||||
{
|
||||
// Variables used for building the link list
|
||||
$this->_link_count = 0;
|
||||
$this->_link_list = '';
|
||||
|
||||
$text = trim(stripslashes($this->html));
|
||||
|
||||
// Run our defined search-and-replace
|
||||
$text = preg_replace($this->search, $this->replace, $text);
|
||||
|
||||
// Strip any other HTML tags
|
||||
$text = strip_tags($text, $this->allowed_tags);
|
||||
|
||||
// Bring down number of empty lines to 2 max
|
||||
$text = preg_replace("/\n\s+\n/", "\n\n", $text);
|
||||
$text = preg_replace("/[\n]{3,}/", "\n\n", $text);
|
||||
|
||||
// Add link list
|
||||
if ( !empty($this->_link_list) ) {
|
||||
$text .= "\n\nLinks:\n------\n" . $this->_link_list;
|
||||
}
|
||||
|
||||
// Wrap the text to a readable format
|
||||
// for PHP versions >= 4.0.2. Default width is 75
|
||||
// If width is 0 or less, don't wrap the text.
|
||||
if ( $this->width > 0 ) {
|
||||
$text = wordwrap($text, $this->width);
|
||||
}
|
||||
|
||||
$this->text = $text;
|
||||
|
||||
$this->_converted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function called by preg_replace() on link replacement.
|
||||
*
|
||||
* Maintains an internal list of links to be displayed at the end of the
|
||||
* text, with numeric indices to the original point in the text they
|
||||
* appeared. Also makes an effort at identifying and handling absolute
|
||||
* and relative links.
|
||||
*
|
||||
* @param string $link URL of the link
|
||||
* @param string $display Part of the text to associate number with
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _build_link_list( $link, $display )
|
||||
{
|
||||
if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' ||
|
||||
substr($link, 0, 7) == 'mailto:' ) {
|
||||
$this->_link_count++;
|
||||
$this->_link_list .= "[" . $this->_link_count . "] $link\n";
|
||||
$additional = ' [' . $this->_link_count . ']';
|
||||
} elseif ( substr($link, 0, 11) == 'javascript:' ) {
|
||||
// Don't count the link; ignore it
|
||||
$additional = '';
|
||||
// what about href="#anchor" ?
|
||||
} else {
|
||||
$this->_link_count++;
|
||||
$this->_link_list .= "[" . $this->_link_count . "] " . $this->url;
|
||||
if ( substr($link, 0, 1) != '/' ) {
|
||||
$this->_link_list .= '/';
|
||||
}
|
||||
$this->_link_list .= "$link\n";
|
||||
$additional = ' [' . $this->_link_count . ']';
|
||||
}
|
||||
|
||||
return $display . $additional;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,529 @@
|
||||
<?
|
||||
/*
|
||||
*------------------------------------------------------------
|
||||
* BMP Image functions
|
||||
*------------------------------------------------------------
|
||||
* By JPEXS
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*------------------------------------------------------------
|
||||
* ImageBMP
|
||||
*------------------------------------------------------------
|
||||
* - Creates new BMP file
|
||||
*
|
||||
* Parameters: $img - Target image
|
||||
* $file - Target file to store
|
||||
* - if not specified, bmp is returned
|
||||
*
|
||||
* Returns: if $file specified - true if OK
|
||||
if $file not specified - image data
|
||||
*/
|
||||
function imagebmp($img,$file="",$RLE=0)
|
||||
{
|
||||
|
||||
|
||||
$ColorCount=imagecolorstotal($img);
|
||||
|
||||
$Transparent=imagecolortransparent($img);
|
||||
$IsTransparent=$Transparent!=-1;
|
||||
|
||||
|
||||
if($IsTransparent) $ColorCount--;
|
||||
|
||||
if($ColorCount==0) {$ColorCount=0; $BitCount=24;};
|
||||
if(($ColorCount>0)and($ColorCount<=2)) {$ColorCount=2; $BitCount=1;};
|
||||
if(($ColorCount>2)and($ColorCount<=16)) { $ColorCount=16; $BitCount=4;};
|
||||
if(($ColorCount>16)and($ColorCount<=256)) { $ColorCount=0; $BitCount=8;};
|
||||
|
||||
|
||||
$Width=imagesx($img);
|
||||
$Height=imagesy($img);
|
||||
|
||||
$Zbytek=(4-($Width/(8/$BitCount))%4)%4;
|
||||
|
||||
if($BitCount<24) $palsize=pow(2,$BitCount)*4;
|
||||
|
||||
$size=(floor($Width/(8/$BitCount))+$Zbytek)*$Height+54;
|
||||
$size+=$palsize;
|
||||
$offset=54+$palsize;
|
||||
|
||||
// Bitmap File Header
|
||||
$ret = 'BM'; // header (2b)
|
||||
$ret .= int_to_dword($size); // size of file (4b)
|
||||
$ret .= int_to_dword(0); // reserved (4b)
|
||||
$ret .= int_to_dword($offset); // byte location in the file which is first byte of IMAGE (4b)
|
||||
// Bitmap Info Header
|
||||
$ret .= int_to_dword(40); // Size of BITMAPINFOHEADER (4b)
|
||||
$ret .= int_to_dword($Width); // width of bitmap (4b)
|
||||
$ret .= int_to_dword($Height); // height of bitmap (4b)
|
||||
$ret .= int_to_word(1); // biPlanes = 1 (2b)
|
||||
$ret .= int_to_word($BitCount); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b)
|
||||
$ret .= int_to_dword($RLE); // RLE COMPRESSION (4b)
|
||||
$ret .= int_to_dword(0); // width x height (4b)
|
||||
$ret .= int_to_dword(0); // biXPelsPerMeter (4b)
|
||||
$ret .= int_to_dword(0); // biYPelsPerMeter (4b)
|
||||
$ret .= int_to_dword(0); // Number of palettes used (4b)
|
||||
$ret .= int_to_dword(0); // Number of important colour (4b)
|
||||
// image data
|
||||
|
||||
$CC=$ColorCount;
|
||||
$sl1=strlen($ret);
|
||||
if($CC==0) $CC=256;
|
||||
if($BitCount<24)
|
||||
{
|
||||
$ColorTotal=imagecolorstotal($img);
|
||||
if($IsTransparent) $ColorTotal--;
|
||||
|
||||
for($p=0;$p<$ColorTotal;$p++)
|
||||
{
|
||||
$color=imagecolorsforindex($img,$p);
|
||||
$ret.=inttobyte($color["blue"]);
|
||||
$ret.=inttobyte($color["green"]);
|
||||
$ret.=inttobyte($color["red"]);
|
||||
$ret.=inttobyte(0); //RESERVED
|
||||
};
|
||||
|
||||
$CT=$ColorTotal;
|
||||
for($p=$ColorTotal;$p<$CC;$p++)
|
||||
{
|
||||
$ret.=inttobyte(0);
|
||||
$ret.=inttobyte(0);
|
||||
$ret.=inttobyte(0);
|
||||
$ret.=inttobyte(0); //RESERVED
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
if($BitCount<=8)
|
||||
{
|
||||
|
||||
for($y=$Height-1;$y>=0;$y--)
|
||||
{
|
||||
$bWrite="";
|
||||
for($x=0;$x<$Width;$x++)
|
||||
{
|
||||
$color=imagecolorat($img,$x,$y);
|
||||
$bWrite.=decbinx($color,$BitCount);
|
||||
if(strlen($bWrite)==8)
|
||||
{
|
||||
$retd.=inttobyte(bindec($bWrite));
|
||||
$bWrite="";
|
||||
};
|
||||
};
|
||||
|
||||
if((strlen($bWrite)<8)and(strlen($bWrite)!=0))
|
||||
{
|
||||
$sl=strlen($bWrite);
|
||||
for($t=0;$t<8-$sl;$t++)
|
||||
$sl.="0";
|
||||
$retd.=inttobyte(bindec($bWrite));
|
||||
};
|
||||
for($z=0;$z<$Zbytek;$z++)
|
||||
$retd.=inttobyte(0);
|
||||
};
|
||||
};
|
||||
|
||||
if(($RLE==1)and($BitCount==8))
|
||||
{
|
||||
for($t=0;$t<strlen($retd);$t+=4)
|
||||
{
|
||||
if($t!=0)
|
||||
if(($t)%$Width==0)
|
||||
$ret.=chr(0).chr(0);
|
||||
|
||||
if(($t+5)%$Width==0)
|
||||
{
|
||||
$ret.=chr(0).chr(5).substr($retd,$t,5).chr(0);
|
||||
$t+=1;
|
||||
}
|
||||
if(($t+6)%$Width==0)
|
||||
{
|
||||
$ret.=chr(0).chr(6).substr($retd,$t,6);
|
||||
$t+=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret.=chr(0).chr(4).substr($retd,$t,4);
|
||||
};
|
||||
};
|
||||
$ret.=chr(0).chr(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret.=$retd;
|
||||
};
|
||||
|
||||
|
||||
if($BitCount==24)
|
||||
{
|
||||
for($z=0;$z<$Zbytek;$z++)
|
||||
$Dopl.=chr(0);
|
||||
|
||||
for($y=$Height-1;$y>=0;$y--)
|
||||
{
|
||||
for($x=0;$x<$Width;$x++)
|
||||
{
|
||||
$color=imagecolorsforindex($img,ImageColorAt($img,$x,$y));
|
||||
$ret.=chr($color["blue"]).chr($color["green"]).chr($color["red"]);
|
||||
}
|
||||
$ret.=$Dopl;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
if($file!="")
|
||||
{
|
||||
$r=($f=fopen($file,"w"));
|
||||
$r=$r and fwrite($f,$ret);
|
||||
$r=$r and fclose($f);
|
||||
return $r;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $ret;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*------------------------------------------------------------
|
||||
* ImageCreateFromBmp
|
||||
*------------------------------------------------------------
|
||||
* - Reads image from a BMP file
|
||||
*
|
||||
* Parameters: $file - Target file to load
|
||||
*
|
||||
* Returns: Image ID
|
||||
*/
|
||||
|
||||
function imagecreatefrombmp($file)
|
||||
{
|
||||
global $CurrentBit, $echoMode;
|
||||
|
||||
$f=fopen($file,"r");
|
||||
$Header=fread($f,2);
|
||||
|
||||
if($Header=="BM")
|
||||
{
|
||||
$Size=freaddword($f);
|
||||
$Reserved1=freadword($f);
|
||||
$Reserved2=freadword($f);
|
||||
$FirstByteOfImage=freaddword($f);
|
||||
|
||||
$SizeBITMAPINFOHEADER=freaddword($f);
|
||||
$Width=freaddword($f);
|
||||
$Height=freaddword($f);
|
||||
$biPlanes=freadword($f);
|
||||
$biBitCount=freadword($f);
|
||||
$RLECompression=freaddword($f);
|
||||
$WidthxHeight=freaddword($f);
|
||||
$biXPelsPerMeter=freaddword($f);
|
||||
$biYPelsPerMeter=freaddword($f);
|
||||
$NumberOfPalettesUsed=freaddword($f);
|
||||
$NumberOfImportantColors=freaddword($f);
|
||||
|
||||
if($biBitCount<24)
|
||||
{
|
||||
$img=imagecreate($Width,$Height);
|
||||
$Colors=pow(2,$biBitCount);
|
||||
for($p=0;$p<$Colors;$p++)
|
||||
{
|
||||
$B=freadbyte($f);
|
||||
$G=freadbyte($f);
|
||||
$R=freadbyte($f);
|
||||
$Reserved=freadbyte($f);
|
||||
$Palette[]=imagecolorallocate($img,$R,$G,$B);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
if($RLECompression==0)
|
||||
{
|
||||
$Zbytek=(4-ceil(($Width/(8/$biBitCount)))%4)%4;
|
||||
|
||||
for($y=$Height-1;$y>=0;$y--)
|
||||
{
|
||||
$CurrentBit=0;
|
||||
for($x=0;$x<$Width;$x++)
|
||||
{
|
||||
$C=freadbits($f,$biBitCount);
|
||||
imagesetpixel($img,$x,$y,$Palette[$C]);
|
||||
};
|
||||
if($CurrentBit!=0) {freadbyte($f);};
|
||||
for($g=0;$g<$Zbytek;$g++)
|
||||
freadbyte($f);
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
if($RLECompression==1) //$BI_RLE8
|
||||
{
|
||||
$y=$Height;
|
||||
|
||||
$pocetb=0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
$y--;
|
||||
$prefix=freadbyte($f);
|
||||
$suffix=freadbyte($f);
|
||||
$pocetb+=2;
|
||||
|
||||
$echoit=false;
|
||||
|
||||
if($echoit)echo "Prefix: $prefix Suffix: $suffix<BR>";
|
||||
if(($prefix==0)and($suffix==1)) break;
|
||||
if(feof($f)) break;
|
||||
|
||||
while(!(($prefix==0)and($suffix==0)))
|
||||
{
|
||||
if($prefix==0)
|
||||
{
|
||||
$pocet=$suffix;
|
||||
$Data.=fread($f,$pocet);
|
||||
$pocetb+=$pocet;
|
||||
if($pocetb%2==1) {freadbyte($f); $pocetb++;};
|
||||
};
|
||||
if($prefix>0)
|
||||
{
|
||||
$pocet=$prefix;
|
||||
for($r=0;$r<$pocet;$r++)
|
||||
$Data.=chr($suffix);
|
||||
};
|
||||
$prefix=freadbyte($f);
|
||||
$suffix=freadbyte($f);
|
||||
$pocetb+=2;
|
||||
if($echoit) echo "Prefix: $prefix Suffix: $suffix<BR>";
|
||||
};
|
||||
|
||||
for($x=0;$x<strlen($Data);$x++)
|
||||
{
|
||||
imagesetpixel($img,$x,$y,$Palette[ord($Data[$x])]);
|
||||
};
|
||||
$Data="";
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
if($RLECompression==2) //$BI_RLE4
|
||||
{
|
||||
$y=$Height;
|
||||
$pocetb=0;
|
||||
|
||||
/*while(!feof($f))
|
||||
echo freadbyte($f)."_".freadbyte($f)."<BR>";*/
|
||||
while(true)
|
||||
{
|
||||
//break;
|
||||
$y--;
|
||||
$prefix=freadbyte($f);
|
||||
$suffix=freadbyte($f);
|
||||
$pocetb+=2;
|
||||
|
||||
$echoit=false;
|
||||
|
||||
if($echoit)echo "Prefix: $prefix Suffix: $suffix<BR>";
|
||||
if(($prefix==0)and($suffix==1)) break;
|
||||
if(feof($f)) break;
|
||||
|
||||
while(!(($prefix==0)and($suffix==0)))
|
||||
{
|
||||
if($prefix==0)
|
||||
{
|
||||
$pocet=$suffix;
|
||||
|
||||
$CurrentBit=0;
|
||||
for($h=0;$h<$pocet;$h++)
|
||||
$Data.=chr(freadbits($f,4));
|
||||
if($CurrentBit!=0) freadbits($f,4);
|
||||
$pocetb+=ceil(($pocet/2));
|
||||
if($pocetb%2==1) {freadbyte($f); $pocetb++;};
|
||||
};
|
||||
if($prefix>0)
|
||||
{
|
||||
$pocet=$prefix;
|
||||
$i=0;
|
||||
for($r=0;$r<$pocet;$r++)
|
||||
{
|
||||
if($i%2==0)
|
||||
{
|
||||
$Data.=chr($suffix%16);
|
||||
}
|
||||
else
|
||||
{
|
||||
$Data.=chr(floor($suffix/16));
|
||||
};
|
||||
$i++;
|
||||
};
|
||||
};
|
||||
$prefix=freadbyte($f);
|
||||
$suffix=freadbyte($f);
|
||||
$pocetb+=2;
|
||||
if($echoit) echo "Prefix: $prefix Suffix: $suffix<BR>";
|
||||
};
|
||||
|
||||
for($x=0;$x<strlen($Data);$x++)
|
||||
{
|
||||
imagesetpixel($img,$x,$y,$Palette[ord($Data[$x])]);
|
||||
};
|
||||
$Data="";
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
if($biBitCount==24)
|
||||
{
|
||||
$img=imagecreatetruecolor($Width,$Height);
|
||||
$Zbytek=$Width%4;
|
||||
|
||||
for($y=$Height-1;$y>=0;$y--)
|
||||
{
|
||||
for($x=0;$x<$Width;$x++)
|
||||
{
|
||||
$B=freadbyte($f);
|
||||
$G=freadbyte($f);
|
||||
$R=freadbyte($f);
|
||||
$color=imagecolorexact($img,$R,$G,$B);
|
||||
if($color==-1) $color=imagecolorallocate($img,$R,$G,$B);
|
||||
imagesetpixel($img,$x,$y,$color);
|
||||
}
|
||||
for($z=0;$z<$Zbytek;$z++)
|
||||
freadbyte($f);
|
||||
};
|
||||
};
|
||||
return $img;
|
||||
|
||||
};
|
||||
|
||||
|
||||
fclose($f);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Helping functions:
|
||||
*-------------------------
|
||||
*
|
||||
* freadbyte($file) - reads 1 byte from $file
|
||||
* freadword($file) - reads 2 bytes (1 word) from $file
|
||||
* freaddword($file) - reads 4 bytes (1 dword) from $file
|
||||
* freadlngint($file) - same as freaddword($file)
|
||||
* decbin8($d) - returns binary string of d zero filled to 8
|
||||
* RetBits($byte,$start,$len) - returns bits $start->$start+$len from $byte
|
||||
* freadbits($file,$count) - reads next $count bits from $file
|
||||
* RGBToHex($R,$G,$B) - convert $R, $G, $B to hex
|
||||
* int_to_dword($n) - returns 4 byte representation of $n
|
||||
* int_to_word($n) - returns 2 byte representation of $n
|
||||
*/
|
||||
|
||||
function freadbyte($f)
|
||||
{
|
||||
return ord(fread($f,1));
|
||||
};
|
||||
|
||||
function freadword($f)
|
||||
{
|
||||
$b1=freadbyte($f);
|
||||
$b2=freadbyte($f);
|
||||
return $b2*256+$b1;
|
||||
};
|
||||
|
||||
|
||||
function freadlngint($f)
|
||||
{
|
||||
return freaddword($f);
|
||||
};
|
||||
|
||||
function freaddword($f)
|
||||
{
|
||||
$b1=freadword($f);
|
||||
$b2=freadword($f);
|
||||
return $b2*65536+$b1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
function RetBits($byte,$start,$len)
|
||||
{
|
||||
$bin=decbin8($byte);
|
||||
$r=bindec(substr($bin,$start,$len));
|
||||
return $r;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
$CurrentBit=0;
|
||||
function freadbits($f,$count)
|
||||
{
|
||||
global $CurrentBit,$SMode;
|
||||
$Byte=freadbyte($f);
|
||||
$LastCBit=$CurrentBit;
|
||||
$CurrentBit+=$count;
|
||||
if($CurrentBit==8)
|
||||
{
|
||||
$CurrentBit=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek($f,ftell($f)-1);
|
||||
};
|
||||
return RetBits($Byte,$LastCBit,$count);
|
||||
};
|
||||
|
||||
|
||||
|
||||
function RGBToHex($Red,$Green,$Blue)
|
||||
{
|
||||
$hRed=dechex($Red);if(strlen($hRed)==1) $hRed="0$hRed";
|
||||
$hGreen=dechex($Green);if(strlen($hGreen)==1) $hGreen="0$hGreen";
|
||||
$hBlue=dechex($Blue);if(strlen($hBlue)==1) $hBlue="0$hBlue";
|
||||
return($hRed.$hGreen.$hBlue);
|
||||
};
|
||||
|
||||
function int_to_dword($n)
|
||||
{
|
||||
return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255);
|
||||
}
|
||||
function int_to_word($n)
|
||||
{
|
||||
return chr($n & 255).chr(($n >> 8) & 255);
|
||||
}
|
||||
|
||||
|
||||
function decbin8($d)
|
||||
{
|
||||
return decbinx($d,8);
|
||||
};
|
||||
|
||||
function decbinx($d,$n)
|
||||
{
|
||||
$bin=decbin($d);
|
||||
$sbin=strlen($bin);
|
||||
for($j=0;$j<$n-$sbin;$j++)
|
||||
$bin="0$bin";
|
||||
return $bin;
|
||||
};
|
||||
|
||||
function inttobyte($n)
|
||||
{
|
||||
return chr($n);
|
||||
};
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
class attribute
|
||||
{
|
||||
/* array with all attributes grouped by attribute group */
|
||||
static function getAttrbutesListArray()
|
||||
{
|
||||
return attribute::getAttrbutesListArrayInternal(0, false);
|
||||
}
|
||||
|
||||
static function getSelectableAttrbutesListArray()
|
||||
{
|
||||
return attribute::getAttrbutesListArrayInternal(0, true);
|
||||
}
|
||||
|
||||
static function getAttrbutesListArrayByCacheId($cacheId)
|
||||
{
|
||||
return attribute::getAttrbutesListArrayInternal($cacheId, false);
|
||||
}
|
||||
|
||||
static function getAttrbutesListArrayInternal($cacheId, $bOnlySelectable)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$attributes = array();
|
||||
$rsAttrGroup = sql("SELECT `attribute_groups`.`id`,
|
||||
IFNULL(`tt1`.`text`, `attribute_groups`.`name`) AS `name`,
|
||||
IFNULL(`tt2`.`text`, `attribute_categories`.`name`) AS `category`,
|
||||
`attribute_categories`.`color`
|
||||
FROM `attribute_groups`
|
||||
INNER JOIN `attribute_categories` ON `attribute_groups`.`category_id`=`attribute_categories`.`id`
|
||||
LEFT JOIN `sys_trans` AS `t1` ON `attribute_groups`.`trans_id`=`t1`.`id` AND `attribute_groups`.`name`=`t1`.`text`
|
||||
LEFT JOIN `sys_trans_text` AS `tt1` ON `t1`.`id`=`tt1`.`trans_id` AND `tt1`.`lang`='&1'
|
||||
LEFT JOIN `sys_trans` AS `t2` ON `attribute_categories`.`trans_id`=`t2`.`id` AND `attribute_categories`.`name`=`t2`.`text`
|
||||
LEFT JOIN `sys_trans_text` AS `tt2` ON `t2`.`id`=`tt2`.`trans_id` AND `tt2`.`lang`='&1'
|
||||
ORDER BY `attribute_groups`.`id` ASC", $opt['template']['locale']);
|
||||
while ($rAttrGroup = sql_fetch_assoc($rsAttrGroup))
|
||||
{
|
||||
$attr = array();
|
||||
$bFirst = true;
|
||||
|
||||
if ($cacheId == 0)
|
||||
{
|
||||
$sAddWhereSql = '';
|
||||
if ($bOnlySelectable == true)
|
||||
$sAddWhereSql = ' AND `cache_attrib`.`selectable`=1';
|
||||
|
||||
$rsAttr = sql("SELECT `cache_attrib`.`id`, IFNULL(`tt1`.`text`, `cache_attrib`.`name`) AS `name`,
|
||||
IFNULL(`tt2`.`text`, `cache_attrib`.`html_desc`) AS `html_desc`, `cache_attrib`.`icon`
|
||||
FROM `cache_attrib`
|
||||
LEFT JOIN `sys_trans` AS `t1` ON `cache_attrib`.`trans_id`=`t1`.`id` AND `cache_attrib`.`name`=`t1`.`text`
|
||||
LEFT JOIN `sys_trans_text` AS `tt1` ON `t1`.`id`=`tt1`.`trans_id` AND `tt1`.`lang`='&1'
|
||||
LEFT JOIN `sys_trans` AS `t2` ON `cache_attrib`.`html_desc_trans_id`=`t2`.`id`
|
||||
LEFT JOIN `sys_trans_text` AS `tt2` ON `t2`.`id`=`tt2`.`trans_id` AND `tt2`.`lang`='&1'
|
||||
WHERE `cache_attrib`.`group_id`='&2'
|
||||
AND NOT IFNULL(`cache_attrib`.`hidden`, 0)=1
|
||||
ORDER BY `cache_attrib`.`group_id` ASC", $opt['template']['locale'], $rAttrGroup['id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$rsAttr = sql("SELECT `cache_attrib`.`id`, IFNULL(`tt1`.`text`, `cache_attrib`.`name`) AS `name`,
|
||||
IFNULL(`tt2`.`text`, `cache_attrib`.`html_desc`) AS `html_desc`, `cache_attrib`.`icon`
|
||||
FROM `caches_attributes`
|
||||
INNER JOIN `cache_attrib` ON `caches_attributes`.`attrib_id`=`cache_attrib`.`id`
|
||||
LEFT JOIN `sys_trans` AS `t1` ON `cache_attrib`.`trans_id`=`t1`.`id` AND `cache_attrib`.`name`=`t1`.`text`
|
||||
LEFT JOIN `sys_trans_text` AS `tt1` ON `t1`.`id`=`tt1`.`trans_id` AND `tt1`.`lang`='&2'
|
||||
LEFT JOIN `sys_trans` AS `t2` ON `cache_attrib`.`html_desc_trans_id`=`t2`.`id`
|
||||
LEFT JOIN `sys_trans_text` AS `tt2` ON `t2`.`id`=`tt2`.`trans_id` AND `tt2`.`lang`='&2'
|
||||
WHERE `caches_attributes`.`cache_id`='&1' AND `cache_attrib`.`group_id`='&3'
|
||||
AND NOT IFNULL(`cache_attrib`.`hidden`, 0)=1
|
||||
ORDER BY `cache_attrib`.`group_id` ASC", $cacheId, $opt['template']['locale'], $rAttrGroup['id']);
|
||||
}
|
||||
while ($rAttr = sql_fetch_assoc($rsAttr))
|
||||
$attr[] = $rAttr;
|
||||
sql_free_result($rsAttr);
|
||||
|
||||
if (count($attr) > 0)
|
||||
$attributes[] = array('name' => $rAttrGroup['name'],
|
||||
'color' => $rAttrGroup['color'],
|
||||
'category' => $rAttrGroup['category'],
|
||||
'attr' => $attr);
|
||||
}
|
||||
sql_free_result($rsAttrGroup);
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,429 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* get/set has to be commited with save
|
||||
* add/remove etc. is executed instantly
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/logic/rowEditor.class.php');
|
||||
|
||||
class cache
|
||||
{
|
||||
var $nCacheId = 0;
|
||||
|
||||
var $reCache;
|
||||
|
||||
static function cacheIdFromWP($wp)
|
||||
{
|
||||
$cacheid = 0;
|
||||
if (mb_strtoupper(mb_substr($wp, 0, 2)) == 'GC')
|
||||
{
|
||||
$rs = sql("SELECT `cache_id` FROM `caches` WHERE `wp_gc`='&1'", $wp);
|
||||
if (sql_num_rows($rs) != 1)
|
||||
{
|
||||
sql_free_result($rs);
|
||||
return null;
|
||||
}
|
||||
$r = sql_fetch_assoc($rs);
|
||||
sql_free_result($rs);
|
||||
|
||||
$cacheid = $r['cache_id'];
|
||||
}
|
||||
else if (mb_strtoupper(mb_substr($wp, 0, 1)) == 'N')
|
||||
{
|
||||
$rs = sql("SELECT `cache_id` FROM `caches` WHERE `wp_nc`='&1'", $wp);
|
||||
if (sql_num_rows($rs) != 1)
|
||||
{
|
||||
sql_free_result($rs);
|
||||
return null;
|
||||
}
|
||||
$r = sql_fetch_assoc($rs);
|
||||
sql_free_result($rs);
|
||||
|
||||
$cacheid = $r['cache_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$cacheid = sql_value("SELECT `cache_id` FROM `caches` WHERE `wp_oc`='&1'", 0, $wp);
|
||||
}
|
||||
|
||||
return $cacheid;
|
||||
}
|
||||
|
||||
static function fromWP($wp)
|
||||
{
|
||||
$cacheid = cache::cacheIdFromWP($wp);
|
||||
if ($cacheid == 0)
|
||||
return null;
|
||||
|
||||
return new cache($cacheid);
|
||||
}
|
||||
|
||||
static function cacheIdFromUUID($uuid)
|
||||
{
|
||||
$cacheid = sql_value("SELECT `cache_id` FROM `caches` WHERE `uuid`='&1'", 0, $uuid);
|
||||
return $cacheid;
|
||||
}
|
||||
|
||||
static function fromUUID($uuid)
|
||||
{
|
||||
$cacheid = cache::cacheIdFromUUID($uuid);
|
||||
if ($cacheid == 0)
|
||||
return null;
|
||||
|
||||
return new cache($cacheid);
|
||||
}
|
||||
|
||||
function __construct($nNewCacheId=ID_NEW)
|
||||
{
|
||||
$this->reCache = new rowEditor('caches');
|
||||
$this->reCache->addPKInt('cache_id', null, false, RE_INSERT_AUTOINCREMENT);
|
||||
$this->reCache->addString('uuid', '', false, RE_INSERT_OVERWRITE|RE_INSERT_UUID);
|
||||
$this->reCache->addInt('node', 0, false);
|
||||
$this->reCache->addDate('date_created', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reCache->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reCache->addInt('user_id', 0, false);
|
||||
$this->reCache->addString('name', '', false);
|
||||
$this->reCache->addDouble('longitude', 0, false);
|
||||
$this->reCache->addDouble('latitude', 0, false);
|
||||
$this->reCache->addInt('type', 1, false);
|
||||
$this->reCache->addInt('status', 5, false);
|
||||
$this->reCache->addString('country', '', false);
|
||||
$this->reCache->addDate('date_hidden', time(), false);
|
||||
$this->reCache->addInt('size', 1, false);
|
||||
$this->reCache->addFloat('difficulty', 1, false);
|
||||
$this->reCache->addFloat('terrain', 1, false);
|
||||
$this->reCache->addString('logpw', '', false);
|
||||
$this->reCache->addFloat('search_time', 0, false);
|
||||
$this->reCache->addFloat('way_length', 0, false);
|
||||
$this->reCache->addString('wp_oc', null, true);
|
||||
$this->reCache->addString('wp_gc', '', false);
|
||||
$this->reCache->addString('wp_nc', '', false);
|
||||
$this->reCache->addString('desc_languages', '', false, RE_INSERT_IGNORE);
|
||||
$this->reCache->addString('default_desclang', '', false);
|
||||
$this->reCache->addDate('date_activate', null, true);
|
||||
$this->reCache->addInt('need_npa_recalc', 1, false, RE_INSERT_IGNORE);
|
||||
|
||||
$this->nCacheId = $nNewCacheId+0;
|
||||
|
||||
if ($nNewCacheId == ID_NEW)
|
||||
{
|
||||
$this->reCache->addNew(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->reCache->load($this->nCacheId);
|
||||
}
|
||||
}
|
||||
|
||||
function exist()
|
||||
{
|
||||
return $this->reCache->exist();
|
||||
}
|
||||
|
||||
function getCacheId()
|
||||
{
|
||||
return $this->nCacheId;
|
||||
}
|
||||
function getStatus()
|
||||
{
|
||||
return $this->reCache->getValue('status');
|
||||
}
|
||||
function getType()
|
||||
{
|
||||
return $this->reCache->getValue('type');
|
||||
}
|
||||
function getName()
|
||||
{
|
||||
return $this->reCache->getValue('name');
|
||||
}
|
||||
function getLongitude()
|
||||
{
|
||||
return $this->reCache->getValue('longitude');
|
||||
}
|
||||
function getLatitude()
|
||||
{
|
||||
return $this->reCache->getValue('latitude');
|
||||
}
|
||||
function getUserId()
|
||||
{
|
||||
return $this->reCache->getValue('user_id');
|
||||
}
|
||||
function getUsername()
|
||||
{
|
||||
return sql_value("SELECT `username` FROM `user` WHERE `user_id`='&1'", '', $this->getUserId());
|
||||
}
|
||||
function getWPOC()
|
||||
{
|
||||
return $this->reCache->getValue('wp_oc');
|
||||
}
|
||||
function getWPGC()
|
||||
{
|
||||
return $this->reCache->getValue('wp_gc');
|
||||
}
|
||||
function getWPNC()
|
||||
{
|
||||
return $this->reCache->getValue('wp_nc');
|
||||
}
|
||||
|
||||
function getUUID()
|
||||
{
|
||||
return $this->reCache->getValue('uuid');
|
||||
}
|
||||
function getLastModified()
|
||||
{
|
||||
return $this->reCache->getValue('last_modified');
|
||||
}
|
||||
function getDateCreated()
|
||||
{
|
||||
return $this->reCache->getValue('date_created');
|
||||
}
|
||||
function getNode()
|
||||
{
|
||||
return $this->reCache->getValue('node');
|
||||
}
|
||||
function setNode($value)
|
||||
{
|
||||
return $this->reCache->setValue('node', $value);
|
||||
}
|
||||
function setStatus($value)
|
||||
{
|
||||
if (sql_value("SELECT COUNT(*) FROM `cache_status` WHERE `id`='&1'", 0, $value) == 1)
|
||||
{
|
||||
return $this->reCache->setValue('status', $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getAnyChanged()
|
||||
{
|
||||
return $this->reCache->getAnyChanged();
|
||||
}
|
||||
|
||||
// return if successfull (with insert)
|
||||
function save()
|
||||
{
|
||||
if ($this->reCache->save())
|
||||
{
|
||||
sql_slave_exclude();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function requireLogPW()
|
||||
{
|
||||
return $this->reCache->getValue('logpw') != '';
|
||||
}
|
||||
|
||||
// TODO: use prepared one way hash
|
||||
function validateLogPW($nLogType, $sLogPW)
|
||||
{
|
||||
if ($sLogPW == '')
|
||||
return true;
|
||||
|
||||
if (sql_value("SELECT `require_password` FROM `log_types` WHERE `id`='&1'", 0, $nLogType) == 0)
|
||||
return true;
|
||||
|
||||
return ($sLogPW == $this->reCache->getValue('logpw'));
|
||||
}
|
||||
|
||||
static function visitCounter($nVisitUserId, $sRemoteAddr, $nCacheId)
|
||||
{
|
||||
// delete cache_visits older 1 day 60*60*24 = 86400
|
||||
sql("DELETE FROM `cache_visits` WHERE `cache_id`='&1' AND `user_id_ip`!='0' AND NOW()-`last_modified`>86400", $nCacheId);
|
||||
|
||||
if ($nVisitUserId==0)
|
||||
$sIdentifier = $sRemoteAddr;
|
||||
else
|
||||
$sIdentifier = $nVisitUserId;
|
||||
|
||||
// note the visit of this user
|
||||
sql("INSERT INTO `cache_visits` (`cache_id`, `user_id_ip`, `count`) VALUES (&1, '&2', 1)
|
||||
ON DUPLICATE KEY UPDATE `count`=`count`+1", $nCacheId, $sIdentifier);
|
||||
|
||||
// if the previous statement does an INSERT, it was the first visit for this user
|
||||
if (sql_affected_rows() == 1)
|
||||
{
|
||||
if ($nVisitUserId != sql_value("SELECT `user_id` FROM `caches` WHERE `cache_id`='&1'", 0, $nCacheId))
|
||||
{
|
||||
// increment the counter for this cache
|
||||
sql("INSERT INTO `cache_visits` (`cache_id`, `user_id_ip`, `count`) VALUES (&1, '0', 1)
|
||||
ON DUPLICATE KEY UPDATE `count`=`count`+1", $nCacheId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function getLogsCount($cacheid)
|
||||
{
|
||||
//prepare the logs
|
||||
$rsLogs = sql("SELECT COUNT(*) FROM `cache_logs` WHERE `cache_id`='&1'", $cacheid);
|
||||
$rLog = sql_fetch_assoc($rsLogs);
|
||||
sql_free_result($rsLogs);
|
||||
|
||||
return $rLog;
|
||||
}
|
||||
|
||||
|
||||
static function getLogsArray($cacheid, $start, $count)
|
||||
{
|
||||
//prepare the logs
|
||||
$rsLogs = sql("
|
||||
SELECT `cache_logs`.`user_id` AS `userid`,
|
||||
`cache_logs`.`id` AS `id`,
|
||||
`cache_logs`.`uuid` AS `uuid`,
|
||||
`cache_logs`.`date` AS `date`,
|
||||
`cache_logs`.`type` AS `type`,
|
||||
`cache_logs`.`text` AS `text`,
|
||||
`cache_logs`.`text_html` AS `texthtml`,
|
||||
`cache_logs`.`picture`,
|
||||
`user`.`username` AS `username`,
|
||||
IF(ISNULL(`cache_rating`.`cache_id`), 0, 1) AS `recommended`
|
||||
FROM `cache_logs`
|
||||
INNER JOIN `user` ON `user`.`user_id` = `cache_logs`.`user_id`
|
||||
LEFT JOIN `cache_rating` ON `cache_logs`.`cache_id`=`cache_rating`.`cache_id` AND `cache_logs`.`user_id`=`cache_rating`.`user_id`
|
||||
WHERE `cache_logs`.`cache_id`='&1'
|
||||
ORDER BY `cache_logs`.`date` DESC, `cache_logs`.`Id` DESC LIMIT &2, &3", $cacheid, $start+0, $count+0);
|
||||
|
||||
$logs = array();
|
||||
while ($rLog = sql_fetch_assoc($rsLogs))
|
||||
{
|
||||
$pictures = array();
|
||||
$rsPictures = sql("SELECT `url`, `title`, `uuid` FROM `pictures` WHERE `object_id`='&1' AND `object_type`=1", $rLog['id']);
|
||||
while ($rPicture = sql_fetch_assoc($rsPictures))
|
||||
$pictures[] = $rPicture;
|
||||
sql_free_result($rsPictures);
|
||||
$rLog['pictures'] = $pictures;
|
||||
|
||||
$logs[] = $rLog;
|
||||
}
|
||||
sql_free_result($rsLogs);
|
||||
|
||||
return $logs;
|
||||
}
|
||||
|
||||
function report($userid, $reportreason, $reportnote)
|
||||
{
|
||||
sql("INSERT INTO cache_reports (`cacheid`, `userid`, `reason`, `note`)
|
||||
VALUES(&1, &2, &3, '&4')",
|
||||
$this->nCacheId, $userid, $reportreason, $reportnote);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function addAdoption($userid)
|
||||
{
|
||||
if ($this->allowEdit() == false)
|
||||
return false;
|
||||
|
||||
if (sql_value("SELECT COUNT(*) FROM `user` WHERE `user_id`='&1' AND `is_active_flag`=1", 0, $userid) == 0)
|
||||
return false;
|
||||
|
||||
// same user?
|
||||
if ($this->getUserId() == $userid)
|
||||
return false;
|
||||
|
||||
sql("INSERT IGNORE INTO `cache_adoption` (`cache_id`, `user_id`) VALUES ('&1', '&2')", $this->nCacheId, $userid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function cancelAdoption($userid)
|
||||
{
|
||||
global $login;
|
||||
|
||||
if ($this->allowEdit() == false && $login->userid != $userid)
|
||||
return false;
|
||||
|
||||
sql("DELETE FROM `cache_adoption` WHERE `user_id`='&1' AND `cache_id`='&2'", $userid, $this->nCacheId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function commitAdoption($userid)
|
||||
{
|
||||
global $login;
|
||||
|
||||
// cache_adoption exists?
|
||||
if (sql_value("SELECT COUNT(*) FROM `cache_adoption` WHERE `cache_id`='&1' AND `user_id`='&2'", 0, $this->nCacheId, $userid) == 0)
|
||||
return false;
|
||||
|
||||
// new user active?
|
||||
if (sql_value("SELECT `is_active_flag` FROM `user` WHERE `user_id`='&1'", 0, $userid) != 1)
|
||||
return false;
|
||||
|
||||
sql("INSERT INTO `logentries` (`module`, `eventid`, `userid`, `objectid1`, `objectid2`, `logtext`)
|
||||
VALUES ('cache', 5, '&1', '&2', '&3', '&4')",
|
||||
$login->userid, $this->nCacheId, 0,
|
||||
'Cache ' . sql_escape($this->nCacheId) . ' has changed the owner from userid ' . sql_escape($this->getUserId()) . ' to ' . sql_escape($userid) . ' by ' . sql_escape($login->userid));
|
||||
sql("UPDATE `caches` SET `user_id`='&1' WHERE `cache_id`='&2'", $userid, $this->nCacheId);
|
||||
sql("DELETE FROM `cache_adoption` WHERE `cache_id`='&1'", $this->nCacheId);
|
||||
|
||||
$this->reCache->setValue('user_id', $userid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// true if anyone can view the cache
|
||||
function isPublic()
|
||||
{
|
||||
return (sql_value("SELECT `allow_user_view` FROM `cache_status` WHERE `id`='&1'", 0, $this->getStatus()) == 1);
|
||||
}
|
||||
function allowView()
|
||||
{
|
||||
global $login;
|
||||
|
||||
if ($this->isPublic())
|
||||
return true;
|
||||
|
||||
$login->verify();
|
||||
|
||||
if (($login->admin & ADMIN_USER) == ADMIN_USER)
|
||||
return true;
|
||||
else if ($this->getUserId() == $login->userid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
function allowEdit()
|
||||
{
|
||||
global $login;
|
||||
|
||||
$login->verify();
|
||||
if ($this->getUserId() == $login->userid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
function allowLog()
|
||||
{
|
||||
global $login;
|
||||
|
||||
$login->verify();
|
||||
if ($this->getUserId() == $login->userid)
|
||||
return true;
|
||||
|
||||
return (sql_value("SELECT `allow_user_log` FROM `cache_status` WHERE `id`='&1'", 0, $this->getStatus()) == 1);
|
||||
}
|
||||
|
||||
function isRecommendedByUser($nUserId)
|
||||
{
|
||||
return (sql_value("SELECT COUNT(*) FROM `cache_rating` WHERE `cache_id`='&1' AND `user_id`='&2'", 0, $this->nCacheId, $nUserId) > 0);
|
||||
}
|
||||
function addRecommendation($nUserId)
|
||||
{
|
||||
sql("INSERT IGNORE INTO `cache_rating` (`cache_id`, `user_id`) VALUES ('&1', '&2')", $this->nCacheId, $nUserId);
|
||||
}
|
||||
function removeRecommendation($nUserId)
|
||||
{
|
||||
sql("DELETE FROM `cache_rating` WHERE `cache_id`='&1' AND `user_id`='&2'", $this->nCacheId, $nUserId);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
function getCacheIcon($user_id, $cache_id, $cache_status, $cache_userid, $iconname)
|
||||
{
|
||||
$cacheicon_searchable = false;
|
||||
$cacheicon_type = "";
|
||||
$inactive = false;
|
||||
|
||||
// mark if found
|
||||
if(isset($user_id))
|
||||
{
|
||||
$found = 0;
|
||||
$resp = sqll("SELECT `type` FROM `cache_logs` WHERE `cache_id`='&1' AND `user_id`='&2' ORDER BY `type`", $cache_id, $user_id);
|
||||
while($row = sql_fetch_assoc($resp))
|
||||
{
|
||||
if($found <= 0)
|
||||
{
|
||||
switch($row['type'])
|
||||
{
|
||||
case 1:
|
||||
case 7:
|
||||
$found = $row['type'];
|
||||
$cacheicon_type = "-found";
|
||||
$inactive = true;
|
||||
break;
|
||||
case 2:
|
||||
$found = $row['type'];
|
||||
$cacheicon_type = "-dnf";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($cache_userid == $user_id)
|
||||
{
|
||||
$cacheicon_type = "-owner";
|
||||
$inactive = true;
|
||||
switch($cache_status)
|
||||
{
|
||||
case 1: $cacheicon_searchable = "-s"; break;
|
||||
case 2: $cacheicon_searchable = "-n"; break;
|
||||
case 3: $cacheicon_searchable = "-a"; break;
|
||||
case 4: $cacheicon_searchable = "-a"; break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch($cache_status)
|
||||
{
|
||||
case 1: $cacheicon_searchable = "-s"; break;
|
||||
case 2: $inactive = true; $cacheicon_searchable = "-n"; break;
|
||||
case 3: $inactive = true; $cacheicon_searchable = "-a"; break;
|
||||
case 4: $inactive = true; $cacheicon_searchable = "-a"; break;
|
||||
}
|
||||
}
|
||||
|
||||
// cacheicon
|
||||
$iconname = mb_eregi_replace("\..*", "", $iconname);
|
||||
$iconname .= $cacheicon_searchable . $cacheicon_type . ".gif";
|
||||
|
||||
return array($iconname, $inactive);
|
||||
}
|
||||
|
||||
function getSmallCacheIcon($iconname)
|
||||
{
|
||||
$iconname = mb_eregi_replace('([^/]+)$', '16x16-\1', $iconname);
|
||||
return $iconname;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* get/set has to be commited with save
|
||||
* add/remove etc. is executed instantly
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/logic/rowEditor.class.php');
|
||||
|
||||
class user
|
||||
{
|
||||
var $nCacheDescId = 0;
|
||||
var $reCacheDesc;
|
||||
|
||||
function __construct($nNewCacheDescId=ID_NEW)
|
||||
{
|
||||
$this->reUser = new rowEditor('cache_desc');
|
||||
$this->reUser->addPKInt('id', null, false, RE_INSERT_AUTOINCREMENT);
|
||||
$this->reUser->addString('uuid', '', false, RE_INSERT_OVERWRITE|RE_INSERT_UUID);
|
||||
$this->reUser->addInt('node', 0, false);
|
||||
$this->reUser->addDate('date_created', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reUser->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reUser->addInt('cache_id', 0, false);
|
||||
$this->reUser->addString('language', '', false);
|
||||
$this->reUser->addString('desc', '', false);
|
||||
$this->reUser->addInt('desc_html', 0, false);
|
||||
$this->reUser->addInt('desc_htmledit', 0, false);
|
||||
$this->reUser->addString('hint', '', false);
|
||||
$this->reUser->addString('short_desc', '', false);
|
||||
|
||||
$this->nCacheDescId = $nNewCacheDescId+0;
|
||||
|
||||
if ($nNewCacheDescId == ID_NEW)
|
||||
{
|
||||
$this->reCacheDesc->addNew(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->reCacheDesc->load($this->nCacheDescId);
|
||||
}
|
||||
}
|
||||
|
||||
function exist()
|
||||
{
|
||||
return $this->reCacheDesc->exist();
|
||||
}
|
||||
|
||||
function getId()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('id');
|
||||
}
|
||||
function getUUID()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('uuid');
|
||||
}
|
||||
function getNode()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('node');
|
||||
}
|
||||
function setNode($value)
|
||||
{
|
||||
return $this->reCacheDesc->setValue('node', $value);
|
||||
}
|
||||
function getDateCreated()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('date_created');
|
||||
}
|
||||
function getLastModified()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('last_modified');
|
||||
}
|
||||
function getCacheId()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('cache_id');
|
||||
}
|
||||
function getLanguage()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('language');
|
||||
}
|
||||
function getDescAsHtml()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('desc');
|
||||
}
|
||||
function getIsDescHtml()
|
||||
{
|
||||
return ($this->reCacheDesc->getValue('desc_html')!=0);
|
||||
}
|
||||
function getDescHtmlEdit()
|
||||
{
|
||||
return ($this->reCacheDesc->getValue('desc_htmledit')!=0);
|
||||
}
|
||||
function getHint()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('hint');
|
||||
}
|
||||
function getShortDesc()
|
||||
{
|
||||
return $this->reCacheDesc->getValue('short_desc');
|
||||
}
|
||||
|
||||
function getAnyChanged()
|
||||
{
|
||||
return $this->reCacheDesc->getAnyChanged();
|
||||
}
|
||||
|
||||
// return if successfull (with insert)
|
||||
function save()
|
||||
{
|
||||
sql_slave_exclude();
|
||||
return $this->reCacheDesc->save();
|
||||
}
|
||||
|
||||
function reload()
|
||||
{
|
||||
$this->reCacheDesc->reload();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* get/set has to be commited with save
|
||||
* add/remove etc. is executed instantly
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/logic/rowEditor.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/cache.class.php');
|
||||
|
||||
class cachelog
|
||||
{
|
||||
var $nLogId = 0;
|
||||
|
||||
var $reCacheLog;
|
||||
|
||||
static function logIdFromUUID($uuid)
|
||||
{
|
||||
$cacheid = sql_value("SELECT `id` FROM `cache_logs` WHERE `uuid`='&1'", 0, $uuid);
|
||||
return $cacheid;
|
||||
}
|
||||
|
||||
static function fromUUID($uuid)
|
||||
{
|
||||
$logid = cachelog::logIdFromUUID($uuid);
|
||||
if ($logid == 0)
|
||||
return null;
|
||||
|
||||
return new cachelog($logid);
|
||||
}
|
||||
|
||||
static function createNew($nCacheId, $nUserId)
|
||||
{
|
||||
// check if user is allowed to log this cache!
|
||||
$cache = new cache($nCacheId);
|
||||
if ($cache->exist() == false)
|
||||
return false;
|
||||
if ($cache->allowLog() == false)
|
||||
return false;
|
||||
|
||||
$oCacheLog = new cachelog(ID_NEW);
|
||||
$oCacheLog->setUserId($nUserId);
|
||||
$oCacheLog->setCacheId($nCacheId);
|
||||
return $oCacheLog;
|
||||
}
|
||||
|
||||
function __construct($nNewLogId=ID_NEW)
|
||||
{
|
||||
$this->reCacheLog = new rowEditor('cache_logs');
|
||||
$this->reCacheLog->addPKInt('id', null, false, RE_INSERT_AUTOINCREMENT);
|
||||
$this->reCacheLog->addString('uuid', '', false, RE_INSERT_OVERWRITE|RE_INSERT_UUID);
|
||||
$this->reCacheLog->addInt('node', 0, false);
|
||||
$this->reCacheLog->addDate('date_created', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reCacheLog->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reCacheLog->addInt('cache_id', 0, false);
|
||||
$this->reCacheLog->addInt('user_id', 0, false);
|
||||
$this->reCacheLog->addInt('type', 0, false);
|
||||
$this->reCacheLog->addDate('date', time(), false);
|
||||
$this->reCacheLog->addString('text', '', false);
|
||||
$this->reCacheLog->addInt('text_html', 0, false);
|
||||
$this->reCacheLog->addInt('text_htmledit', 0, false);
|
||||
$this->reCacheLog->addInt('owner_notified', 0, false);
|
||||
$this->reCacheLog->addInt('picture', 0, false);
|
||||
|
||||
$this->nLogId = $nNewLogId+0;
|
||||
|
||||
if ($nNewLogId == ID_NEW)
|
||||
{
|
||||
$this->reCacheLog->addNew(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->reCacheLog->load($this->nLogId);
|
||||
}
|
||||
}
|
||||
|
||||
function exist()
|
||||
{
|
||||
return $this->reCacheLog->exist();
|
||||
}
|
||||
|
||||
function getLogId()
|
||||
{
|
||||
return $this->nLogId;
|
||||
}
|
||||
function getUserId()
|
||||
{
|
||||
return $this->reCacheLog->getValue('user_id');
|
||||
}
|
||||
function setUserId($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('user_id', $value);
|
||||
}
|
||||
function getCacheId()
|
||||
{
|
||||
return $this->reCacheLog->getValue('cache_id');
|
||||
}
|
||||
function setCacheId($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('cache_id', $value);
|
||||
}
|
||||
function getType()
|
||||
{
|
||||
return $this->reCacheLog->getValue('type');
|
||||
}
|
||||
function setType($value)
|
||||
{
|
||||
$nValidLogTypes = $this->getValidLogTypes();
|
||||
if (array_search($value, $nValidLogTypes) === false)
|
||||
return false;
|
||||
|
||||
return $this->reCacheLog->setValue('type', $value);
|
||||
}
|
||||
function getDate()
|
||||
{
|
||||
return $this->reCacheLog->getValue('date');
|
||||
}
|
||||
function setDate($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('date', $value);
|
||||
}
|
||||
function getText()
|
||||
{
|
||||
return $this->reCacheLog->getValue('text');
|
||||
}
|
||||
function setText($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('text', $value);
|
||||
}
|
||||
function getTextHtml()
|
||||
{
|
||||
return $this->reCacheLog->getValue('text_html');
|
||||
}
|
||||
function setTextHtml($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('text_html', $value);
|
||||
}
|
||||
function getTextHtmlEdit()
|
||||
{
|
||||
return $this->reCacheLog->getValue('text_html');
|
||||
}
|
||||
function setTextHtmlEdit($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('text_htmledit', $value);
|
||||
}
|
||||
|
||||
function getUUID()
|
||||
{
|
||||
return $this->reCacheLog->getValue('uuid');
|
||||
}
|
||||
function getLastModified()
|
||||
{
|
||||
return $this->reCacheLog->getValue('last_modified');
|
||||
}
|
||||
function getDateCreated()
|
||||
{
|
||||
return $this->reCacheLog->getValue('date_created');
|
||||
}
|
||||
function getNode()
|
||||
{
|
||||
return $this->reCacheLog->getValue('node');
|
||||
}
|
||||
function setNode($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('node', $value);
|
||||
}
|
||||
|
||||
function getAnyChanged()
|
||||
{
|
||||
return $this->reCacheLog->getAnyChanged();
|
||||
}
|
||||
|
||||
// return if successfull (with insert)
|
||||
function save()
|
||||
{
|
||||
sql_slave_exclude();
|
||||
return $this->reCacheLog->save();
|
||||
}
|
||||
|
||||
function allowView()
|
||||
{
|
||||
global $login;
|
||||
|
||||
$login->verify();
|
||||
if (sql_value("SELECT `cache_status`.`allow_user_view` FROM `caches` INNER JOIN `cache_status` ON `caches`.`status`=`cache_status`.`id` WHERE `caches`.`cache_id`='&1'", 0, $this->getCacheId()) == 1)
|
||||
return true;
|
||||
else if ($login->userid == sql_value("SELECT `user_id` FROM `caches` WHERE `cache_id`='&1'", 0, $this->getCacheId()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function allowEdit()
|
||||
{
|
||||
global $login;
|
||||
|
||||
$login->verify();
|
||||
if ($this->getUserId() == $login->userid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* will depend on userid in future e.g. maintainance-logs etc. */
|
||||
function getValidLogTypes()
|
||||
{
|
||||
$cache = new cache($this->getCacheId());
|
||||
if ($cache->exist() == false)
|
||||
return array();
|
||||
if ($cache->allowLog() == false)
|
||||
return array();
|
||||
|
||||
$nTypes = array();
|
||||
$rs = sql("SELECT `log_type_id` FROM `cache_logtype` WHERE `cache_type_id`='&1'", $cache->getType());
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$nTypes[] = $r['log_type_id'];
|
||||
sql_free_result($rs);
|
||||
|
||||
return $nTypes;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
/* generate configuration
|
||||
*/
|
||||
|
||||
//Change these settings to change the way the captcha generation works and match your server settings
|
||||
|
||||
//Folder Path where image files can be stored, must be readable and writable by the web server
|
||||
//Don't forget the trailing slash
|
||||
$tempfolder = 'cache2/captcha/';
|
||||
|
||||
//Folder Path where your captcha font files are stored, must be readable by the web server
|
||||
//Don't forget the trailing slash
|
||||
$TTF_folder = 'lib2/b2evo-captcha/b2evo_captcha_fonts/';
|
||||
|
||||
//The minimum number of characters to use for the captcha
|
||||
//Set to the same as maxchars to use fixed length captchas
|
||||
$minchars = 5;
|
||||
|
||||
//The maximum number of characters to use for the captcha
|
||||
//Set to the same as minchars to use fixed length captchas
|
||||
$maxchars = 7;
|
||||
|
||||
//The minimum character font size to use for the captcha
|
||||
//Set to the same as maxsize to use fixed font size
|
||||
$minsize = 20;
|
||||
|
||||
//The maximum character font size to use for the captcha
|
||||
//Set to the same as minsize to use fixed font size
|
||||
$maxsize = 30;
|
||||
|
||||
//The maximum rotation (in degrees) for each character
|
||||
$maxrotation = 25;
|
||||
|
||||
//Use background noise instead of a grid
|
||||
$noise = TRUE;
|
||||
|
||||
//Use web safe colors (only 216 colors)
|
||||
$websafecolors = TRUE;
|
||||
|
||||
//Enable debug messages
|
||||
$debug = FALSE;
|
||||
|
||||
//Filename of garbage collector counter which is stored in the tempfolder
|
||||
$counter_filename = 'b2evo_captcha_counter.txt';
|
||||
|
||||
//Prefix of captcha image filenames
|
||||
$filename_prefix = '';
|
||||
|
||||
//Number of captchas to generate before garbage collection is done
|
||||
$collect_garbage_after = 50;
|
||||
|
||||
//Maximum lifetime of a captcha (in seconds) before being deleted during garbage collection
|
||||
$maxlifetime = 1800;
|
||||
|
||||
//Make all letters uppercase (does not preclude symbols)
|
||||
$case_sensitive = FALSE;
|
||||
|
||||
//////////////////////////////////////////
|
||||
//DO NOT EDIT ANYTHING BELOW THIS LINE!
|
||||
//
|
||||
//
|
||||
|
||||
//$folder_root = substr(__FILE__,0,(strpos(__FILE__,'.php')));
|
||||
$folder_root = $opt['rootpath'];
|
||||
|
||||
$CAPTCHA_CONFIG = array('tempfolder'=>$folder_root.$tempfolder,'TTF_folder'=>$folder_root.$TTF_folder,'minchars'=>$minchars,'maxchars'=>$maxchars,'minsize'=>$minsize,'maxsize'=>$maxsize,'maxrotation'=>$maxrotation,'noise'=>$noise,'websafecolors'=>$websafecolors,'debug'=>$debug,'counter_filename'=>$counter_filename,'filename_prefix'=>$filename_prefix,'collect_garbage_after'=>$collect_garbage_after,'maxlifetime'=>$maxlifetime,'case_sensitive'=>$case_sensitive);
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/b2evo-captcha/b2evo_captcha.class.php');
|
||||
|
||||
// return true/false
|
||||
function checkCaptcha($id, $string)
|
||||
{
|
||||
global $CAPTCHA_CONFIG;
|
||||
$captcha =& new b2evo_captcha($CAPTCHA_CONFIG);
|
||||
|
||||
// additional check ... id and string can only contain [a-f0-9]
|
||||
if (mb_ereg_match('^[0-9a-f]{32}$', $id) == false)
|
||||
return false;
|
||||
|
||||
if ($captcha->validate_submit($id . '.jpg', $string) == 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// return array(id, filename)
|
||||
function createCaptcha()
|
||||
{
|
||||
global $CAPTCHA_CONFIG;
|
||||
$captcha =& new b2evo_captcha($CAPTCHA_CONFIG);
|
||||
$ret['filename'] = $captcha->get_b2evo_captcha();
|
||||
$ret['id'] = substr($ret['filename'], -36, 32);
|
||||
return $ret;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,569 @@
|
||||
<?php
|
||||
|
||||
// Unicode Reminder メモ
|
||||
|
||||
$allowedtags = mb_split(',', 'a,b,i,p,q,s,u,br,dd,dl,dt,em,h1,h2,h3,h4,h5,h6,hr,li,td,th,tr,tt,ol,ul,big,bdo,col,dfn,del,dir,div,ins,img,kbd,map,pre,sub,sup,var,abbr,area,cite,code,font,menu,samp,span,small,thead,tfoot,tbody,table,strong,center,strike,acronym,address,caption,isindex,colgroup,fieldset');
|
||||
$allowedattr = mb_split(',', 'id,src,alt,dir,rel,rev,abbr,axis,char,cite,face,href,lang,name,size,span,type,align,class,clear,color,frame,ismap,rules,scope,shape,start,style,title,value,width,border,coords,height,hspace,nowrap,nohref,target,usemap,vspace,valign,bgcolor,charoff,charset,colspan,compact,headers,noshade,rowspan,summary,longdesc,hreflang,datetime,tabindex,accesskey,background,cellspacing,cellpadding');
|
||||
|
||||
|
||||
/** @class: InputFilter (PHP4 & PHP5, with comments)
|
||||
* @project: PHP Input Filter
|
||||
* @date: 10-05-2005
|
||||
* @version: 1.2.2_php4/php5
|
||||
* @author: Daniel Morris
|
||||
* @contributors: Gianpaolo Racca, Ghislain Picard, Marco Wandschneider, Chris Tobin and Andrew Eddie.
|
||||
* @copyright: Daniel Morris
|
||||
* @email: dan@rootcube.com
|
||||
* @license: GNU General Public License (GPL)
|
||||
*/
|
||||
class InputFilter
|
||||
{
|
||||
var $tagsArray; // default = empty array
|
||||
var $attrArray; // default = empty array
|
||||
|
||||
var $tagsMethod; // default = 0
|
||||
var $attrMethod; // default = 0
|
||||
|
||||
var $xssAuto; // default = 1
|
||||
var $tagBlacklist = array('applet', 'body', 'bgsound', 'base', 'basefont', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml');
|
||||
var $attrBlacklist = array('action', 'codebase', 'dynsrc', 'lowsrc'); // also will strip ALL event handlers
|
||||
|
||||
/**
|
||||
* Constructor for inputFilter class. Only first parameter is required.
|
||||
* @access constructor
|
||||
* @param Array $tagsArray - list of user-defined tags
|
||||
* @param Array $attrArray - list of user-defined attributes
|
||||
* @param int $tagsMethod - 0= allow just user-defined, 1= allow all but user-defined
|
||||
* @param int $attrMethod - 0= allow just user-defined, 1= allow all but user-defined
|
||||
* @param int $xssAuto - 0= only auto clean essentials, 1= allow clean blacklisted tags/attr
|
||||
*/
|
||||
function inputFilter($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1) {
|
||||
// make sure user defined arrays are in lowercase
|
||||
for ($i = 0; $i < count($tagsArray); $i++)
|
||||
$tagsArray[$i] = mb_strtolower($tagsArray[$i]);
|
||||
|
||||
for ($i = 0; $i < count($attrArray); $i++)
|
||||
$attrArray[$i] = mb_strtolower($attrArray[$i]);
|
||||
|
||||
// assign to member vars
|
||||
$this->tagsArray = (array)$tagsArray;
|
||||
$this->attrArray = (array)$attrArray;
|
||||
$this->tagsMethod = $tagsMethod;
|
||||
$this->attrMethod = $attrMethod;
|
||||
$this->xssAuto = $xssAuto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be called by another php script. Processes for XSS and specified bad code.
|
||||
* @access public
|
||||
* @param Mixed $source - input string/array-of-string to be 'cleaned'
|
||||
* @return String $source - 'cleaned' version of input parameter
|
||||
*/
|
||||
function process($source)
|
||||
{
|
||||
// clean all elements in this array
|
||||
if (is_array($source))
|
||||
{
|
||||
// filter element for XSS and other 'bad' code etc.
|
||||
foreach($source as $key => $value)
|
||||
if (is_string($value)) $source[$key] = $this->remove($this->decode($value));
|
||||
|
||||
return $source;
|
||||
|
||||
// clean this string
|
||||
}
|
||||
else if (is_string($source))
|
||||
{
|
||||
// filter source for XSS and other 'bad' code etc.
|
||||
return $this->remove($this->decode($source));
|
||||
|
||||
// return parameter as given
|
||||
}
|
||||
else
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to iteratively remove all unwanted tags and attributes
|
||||
* @access protected
|
||||
* @param String $source - input string to be 'cleaned'
|
||||
* @return String $source - 'cleaned' version of input parameter
|
||||
*/
|
||||
function remove($source)
|
||||
{
|
||||
$loopCounter=0;
|
||||
|
||||
// provides nested-tag protection
|
||||
while($source != $this->filterTags($source))
|
||||
{
|
||||
$source = $this->filterTags($source);
|
||||
$loopCounter++;
|
||||
}
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to strip a string of certain tags
|
||||
* @access protected
|
||||
* @param String $source - input string to be 'cleaned'
|
||||
* @return String $source - 'cleaned' version of input parameter
|
||||
*/
|
||||
function filterTags($source)
|
||||
{
|
||||
// filter pass setup
|
||||
$preTag = NULL;
|
||||
$postTag = $source;
|
||||
|
||||
// find initial tag's position
|
||||
$tagOpen_start = mb_strpos($source, '<');
|
||||
|
||||
// interate through string until no tags left
|
||||
while($tagOpen_start !== FALSE)
|
||||
{
|
||||
// process tag interatively
|
||||
$preTag .= mb_substr($postTag, 0, $tagOpen_start);
|
||||
$postTag = mb_substr($postTag, $tagOpen_start);
|
||||
$fromTagOpen = mb_substr($postTag, 1);
|
||||
|
||||
// end of tag
|
||||
$tagOpen_end = mb_strpos($fromTagOpen, '>');
|
||||
if ($tagOpen_end === false) break;
|
||||
|
||||
// next start of tag (for nested tag assessment)
|
||||
$tagOpen_nested = mb_strpos($fromTagOpen, '<');
|
||||
if (($tagOpen_nested !== false) && ($tagOpen_nested < $tagOpen_end))
|
||||
{
|
||||
$preTag .= mb_substr($postTag, 0, ($tagOpen_nested+1));
|
||||
$postTag = mb_substr($postTag, ($tagOpen_nested+1));
|
||||
$tagOpen_start = mb_strpos($postTag+1, '<');
|
||||
continue;
|
||||
}
|
||||
|
||||
$tagOpen_nested = (mb_strpos($fromTagOpen, '<') + $tagOpen_start + 1);
|
||||
$currentTag = mb_substr($fromTagOpen, 0, $tagOpen_end);
|
||||
$tagLength = mb_strlen($currentTag);
|
||||
if (!$tagOpen_end)
|
||||
{
|
||||
$preTag .= $postTag;
|
||||
$tagOpen_start = mb_strpos($postTag, '<');
|
||||
}
|
||||
|
||||
// this is needed when additional spaces between attrname and attrvalue or tagname and first attrname
|
||||
$currentTag = $this->wellFormTagWithAttr($currentTag);
|
||||
|
||||
// iterate through tag finding attribute pairs - setup
|
||||
$tagLeft = $currentTag;
|
||||
$attrSet = array();
|
||||
$currentSpace = mb_strpos($tagLeft, ' ');
|
||||
|
||||
// is end tag
|
||||
if (mb_substr($currentTag, 0, 1) == "/")
|
||||
{
|
||||
$isCloseTag = TRUE;
|
||||
list($tagName) = mb_split(' ', $currentTag);
|
||||
$tagName = mb_substr($tagName, 1);
|
||||
|
||||
// is start tag
|
||||
}
|
||||
else
|
||||
{
|
||||
$isCloseTag = FALSE;
|
||||
list($tagName) = mb_split(' ', $currentTag);
|
||||
}
|
||||
|
||||
// excludes all "non-regular" tagnames OR no tagname OR remove if xssauto is on and tag is blacklisted
|
||||
if ((!mb_eregi("^[a-z][a-z0-9]*$",$tagName)) || (!$tagName) || ((in_array(mb_strtolower($tagName), $this->tagBlacklist)) && ($this->xssAuto)))
|
||||
{
|
||||
$postTag = mb_substr($postTag, ($tagLength + 2));
|
||||
$tagOpen_start = mb_strpos($postTag, '<');
|
||||
|
||||
// don't append this tag
|
||||
continue;
|
||||
}
|
||||
|
||||
// this while is needed to support attribute values with spaces in!
|
||||
while ($currentSpace !== FALSE)
|
||||
{
|
||||
$fromSpace = mb_substr($tagLeft, ($currentSpace+1));
|
||||
$nextSpace = mb_strpos($fromSpace, ' ');
|
||||
$openQuotes = mb_strpos($fromSpace, '"');
|
||||
$closeQuotes = mb_strpos(mb_substr($fromSpace, ($openQuotes+1)), '"') + $openQuotes + 1;
|
||||
|
||||
// another equals exists
|
||||
if (mb_strpos($fromSpace, '=') !== FALSE)
|
||||
{
|
||||
if (($openQuotes !== FALSE) && (mb_strpos(mb_substr($fromSpace, ($openQuotes+1)), '"') !== FALSE) && ($openQuotes < $nextSpace))
|
||||
{
|
||||
// opening and closing quotes exists
|
||||
$attr = mb_substr($fromSpace, 0, ($closeQuotes + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// one or neither exist
|
||||
$attr = mb_substr($fromSpace, 0, $nextSpace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no more equals exist
|
||||
$attr = mb_substr($fromSpace, 0, $nextSpace);
|
||||
}
|
||||
|
||||
// last attr pair
|
||||
if (!$attr) $attr = $fromSpace;
|
||||
|
||||
// add to attribute pairs array
|
||||
$attrSet[] = $attr;
|
||||
|
||||
// next inc
|
||||
$tagLeft = mb_substr($fromSpace, mb_strlen($attr));
|
||||
$currentSpace = mb_strpos($tagLeft, ' ');
|
||||
}
|
||||
|
||||
// check the last element of attrSet ... maybe empty or attr="value"/
|
||||
if (count($attrSet) > 0)
|
||||
{
|
||||
if ($attrSet[count($attrSet) - 1] == '')
|
||||
unset($attrSet[count($attrSet) - 1]);
|
||||
|
||||
if (mb_substr($attrSet[count($attrSet) - 1], -1) == '/')
|
||||
$attrSet[count($attrSet) - 1] = mb_substr($attrSet[count($attrSet) - 1], 0, mb_strlen($attrSet[count($attrSet) - 1]) - 1);
|
||||
}
|
||||
|
||||
// appears in array specified by user
|
||||
$tagFound = in_array(mb_strtolower($tagName), $this->tagsArray);
|
||||
|
||||
// remove this tag on condition
|
||||
if ((!$tagFound && $this->tagsMethod) || ($tagFound && !$this->tagsMethod))
|
||||
{
|
||||
// reconstruct tag with allowed attributes
|
||||
if (!$isCloseTag)
|
||||
{
|
||||
$attrSet = $this->filterAttr($attrSet);
|
||||
$preTag .= '<' . $tagName;
|
||||
|
||||
for ($i = 0; $i < count($attrSet); $i++)
|
||||
$preTag .= ' ' . $attrSet[$i];
|
||||
|
||||
// reformat single tags to XHTML
|
||||
if (mb_strpos($fromTagOpen, "</" . $tagName))
|
||||
$preTag .= '>';
|
||||
else
|
||||
$preTag .= ' />';
|
||||
|
||||
// just the tagname
|
||||
}
|
||||
else
|
||||
$preTag .= '</' . $tagName . '>';
|
||||
}
|
||||
|
||||
// find next tag's start
|
||||
$postTag = mb_substr($postTag, ($tagLength + 2));
|
||||
$tagOpen_start = mb_strpos($postTag, '<');
|
||||
}
|
||||
|
||||
// append any code after end of tags
|
||||
$preTag .= $postTag;
|
||||
return $preTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to strip a tag of certain attributes
|
||||
* @access protected
|
||||
* @param Array $attrSet
|
||||
* @return Array $newSet
|
||||
*/
|
||||
function filterAttr($attrSet)
|
||||
{
|
||||
$newSet = array();
|
||||
|
||||
// process attributes
|
||||
for ($i = 0; $i <count($attrSet); $i++)
|
||||
{
|
||||
// skip blank spaces in tag
|
||||
if (!$attrSet[$i]) continue;
|
||||
|
||||
// split into attr name and value
|
||||
$attrSubSet = mb_split('=', trim($attrSet[$i]));
|
||||
list($attrSubSet[0]) = mb_split(' ', $attrSubSet[0]);
|
||||
|
||||
// bugfix ... '=' inside attributes
|
||||
$aCount = count($attrSubSet);
|
||||
for ($aN = 2; $aN < $aCount; $aN++)
|
||||
$attrSubSet[1] .= '=' . $attrSubSet[$aN];
|
||||
while (count($attrSubSet) > 2)
|
||||
unset($attrSubSet[count($attrSubSet) - 1]);
|
||||
|
||||
// removes all "non-regular" attr names AND also attr blacklisted
|
||||
if ((!mb_eregi("^[a-z]*$",$attrSubSet[0])) || (($this->xssAuto) && ((in_array(mb_strtolower($attrSubSet[0]), $this->attrBlacklist)) || (mb_substr($attrSubSet[0], 0, 2) == 'on'))))
|
||||
continue;
|
||||
|
||||
// xss attr value filtering
|
||||
if ($attrSubSet[1])
|
||||
{
|
||||
// strips unicode, hex, etc
|
||||
$attrSubSet[1] = mb_ereg_replace('&#', '', $attrSubSet[1]);
|
||||
|
||||
// strip normal newline within attr value
|
||||
$attrSubSet[1] = mb_ereg_replace('[\t\n\r\f]+', '', $attrSubSet[1]);
|
||||
|
||||
// strip double quotes
|
||||
$attrSubSet[1] = mb_ereg_replace('"', '', $attrSubSet[1]);
|
||||
|
||||
// [requested feature] convert single quotes from either side to doubles (Single quotes shouldn't be used to pad attr value)
|
||||
if ((mb_substr($attrSubSet[1], 0, 1) == "'") && (mb_substr($attrSubSet[1], (mb_strlen($attrSubSet[1]) - 1), 1) == "'"))
|
||||
$attrSubSet[1] = mb_substr($attrSubSet[1], 1, (mb_strlen($attrSubSet[1]) - 2));
|
||||
|
||||
// strip slashes
|
||||
$attrSubSet[1] = stripslashes($attrSubSet[1]);
|
||||
}
|
||||
|
||||
// auto strip attr's with "javascript:
|
||||
if ( ((mb_strpos(mb_strtolower($attrSubSet[1]), 'expression') !== false) && (mb_strtolower($attrSubSet[0]) == 'style')) ||
|
||||
(mb_strpos(mb_strtolower($attrSubSet[1]), 'javascript:') !== false) ||
|
||||
(mb_strpos(mb_strtolower($attrSubSet[1]), 'behaviour:') !== false) ||
|
||||
(mb_strpos(mb_strtolower($attrSubSet[1]), 'vbscript:') !== false) ||
|
||||
(mb_strpos(mb_strtolower($attrSubSet[1]), 'mocha:') !== false) ||
|
||||
(mb_strpos(mb_strtolower($attrSubSet[1]), 'livescript:') !== false)
|
||||
) continue;
|
||||
|
||||
// if matches user defined array
|
||||
$attrFound = in_array(mb_strtolower($attrSubSet[0]), $this->attrArray);
|
||||
|
||||
// keep this attr on condition
|
||||
if ((!$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod))
|
||||
{
|
||||
// attr has value
|
||||
if (isset($attrSubSet[1]))
|
||||
{
|
||||
$newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
// reformat single attributes to XHTML
|
||||
$newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $newSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to convert to plaintext
|
||||
* @access protected
|
||||
* @param String $source
|
||||
* @return String $source
|
||||
*/
|
||||
function decode($source) {
|
||||
// url decode
|
||||
// $source = html_entity_decode($source, ENT_QUOTES, "UTF-8");
|
||||
|
||||
// convert decimal
|
||||
// $source = mb_ereg_replace('&#(\d+);',"chr(\\1)", $source); // decimal notation
|
||||
|
||||
// convert hex
|
||||
// $source = mb_eregi_replace('&#x([a-f0-9]+);',"chr(0x\\1)", $source); // hex notation
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be called by another php script. Processes for SQL injection
|
||||
* @access public
|
||||
* @param Mixed $source - input string/array-of-string to be 'cleaned'
|
||||
* @param Buffer $connection - An open MySQL connection
|
||||
* @return String $source - 'cleaned' version of input parameter
|
||||
*/
|
||||
function safeSQL($source, &$connection)
|
||||
{
|
||||
// clean all elements in this array
|
||||
if (is_array($source))
|
||||
{
|
||||
// filter element for SQL injection
|
||||
foreach($source as $key => $value)
|
||||
if (is_string($value))
|
||||
$source[$key] = $this->quoteSmart($this->decode($value), $connection);
|
||||
|
||||
return $source;
|
||||
|
||||
// clean this string
|
||||
}
|
||||
else if (is_string($source))
|
||||
{
|
||||
// filter source for SQL injection
|
||||
if (is_string($source)) return $this->quoteSmart($this->decode($source), $connection);
|
||||
|
||||
// return parameter as given
|
||||
}
|
||||
else
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Chris Tobin
|
||||
* @author Daniel Morris
|
||||
* @access protected
|
||||
* @param String $source
|
||||
* @param Resource $connection - An open MySQL connection
|
||||
* @return String $source
|
||||
*/
|
||||
function quoteSmart($source, &$connection)
|
||||
{
|
||||
// strip slashes
|
||||
if (get_magic_quotes_gpc()) $source = stripslashes($source);
|
||||
|
||||
// quote both numeric and text
|
||||
$source = $this->escapeString($source, $connection);
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Chris Tobin
|
||||
* @author Daniel Morris
|
||||
* @access protected
|
||||
* @param String $source
|
||||
* @param Resource $connection - An open MySQL connection
|
||||
* @return String $source
|
||||
*/
|
||||
function escapeString($string, &$connection)
|
||||
{
|
||||
// depreciated function
|
||||
if (version_compare(phpversion(),"4.3.0", "<"))
|
||||
{
|
||||
mysql_escape_string($string);
|
||||
// current function
|
||||
}
|
||||
else
|
||||
mysql_real_escape_string($string);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Oliver Dietz
|
||||
* @access protected
|
||||
* @param String $tag
|
||||
* @return String $tag
|
||||
*
|
||||
* this function well forms the attrlist
|
||||
*
|
||||
* examples
|
||||
* input ' a href = "abc" '
|
||||
* output 'a href="abc"'
|
||||
*
|
||||
* input ' / a href = "abc" '
|
||||
* output '/a'
|
||||
*
|
||||
* input ' a href = abc '
|
||||
* output 'a href=abc'
|
||||
*
|
||||
*/
|
||||
function wellFormTagWithAttr($tag)
|
||||
{
|
||||
/** replace ' ' by ' '
|
||||
* remove ' ' left and right from '='
|
||||
* remove ' ' from beginning and end
|
||||
* add a single or double quote if last quote is not terminated
|
||||
* remove all attrs from closing tags
|
||||
* remove cr's, lf's tab's and such things
|
||||
* and do all that things (expect the last) only outside (single or double) quotes
|
||||
*/
|
||||
|
||||
$tag = mb_ereg_replace('[\t\n\r\f]+', '', $tag);
|
||||
|
||||
$pos = 0;
|
||||
$retval = '';
|
||||
$appendTermchar = false;
|
||||
|
||||
while ($pos < mb_strlen($tag))
|
||||
{
|
||||
$nextdPos = mb_strpos($tag, '"', $pos);
|
||||
$nextsPos = mb_strpos($tag, '\'', $pos);
|
||||
|
||||
if (($nextdPos === false) && ($nextsPos === false))
|
||||
{
|
||||
// keine weiteren Tags ... bis zum ende filtern
|
||||
$filter_len = mb_strlen($tag) - $pos;
|
||||
$no_filter_len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ($nextdPos === false) $nextdPos = mb_strlen($tag) + 1;
|
||||
if ($nextsPos === false) $nextsPos = mb_strlen($tag) + 1;
|
||||
|
||||
if ($nextsPos < $nextdPos)
|
||||
{
|
||||
$nextPos = $nextsPos;
|
||||
$termchar = '\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$nextPos = $nextdPos;
|
||||
$termchar = '"';
|
||||
}
|
||||
$filter_len = $nextPos - $pos + 1;
|
||||
|
||||
// ok, wir haben einen Anfang ... nach dem Ende suchen
|
||||
$endFilter = mb_strpos($tag, $termchar, $nextPos + 1);
|
||||
|
||||
if ($endFilter === false)
|
||||
{
|
||||
$appendTermchar = true;
|
||||
$no_filter_len = mb_strlen($tag) - $nextPos - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$no_filter_len = $endFilter - $nextPos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
$retval .= $this->spaceReplace(mb_substr($tag, $pos, $filter_len));
|
||||
$pos += $filter_len;
|
||||
|
||||
$retval .= mb_substr($tag, $pos, $no_filter_len);
|
||||
$pos += $no_filter_len;
|
||||
}
|
||||
|
||||
if ($appendTermchar == true)
|
||||
$retval .= $termchar;
|
||||
|
||||
if (mb_substr($retval, 0, 1) == '/')
|
||||
{
|
||||
//alle Attribute entfernen
|
||||
$spacePos = mb_strpos($retval, ' ');
|
||||
|
||||
if ($spacePos !== false)
|
||||
$retval = mb_substr($retval, 0, $spacePos);
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function spaceReplace($str)
|
||||
{
|
||||
while (mb_strpos($str, ' ') !== false)
|
||||
$str = mb_ereg_replace(' ', ' ', $str);
|
||||
|
||||
if (mb_substr($str, 0, 1) == ' ')
|
||||
$str = mb_substr($str, 1);
|
||||
|
||||
if (mb_substr($str, -1) == ' ')
|
||||
$str = mb_substr($str, 0, mb_strlen($str) - 1);
|
||||
|
||||
$str = mb_ereg_replace(' =', '=', $str);
|
||||
$str = mb_ereg_replace('= ', '=', $str);
|
||||
$str = mb_ereg_replace('/ ', '/', $str);
|
||||
|
||||
if (mb_substr($str, -1) == '/')
|
||||
if (mb_substr($str, -2) != ' /')
|
||||
$str = mb_substr($str, 0, mb_strlen($str) - 1);
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Business layer constant definitions
|
||||
***************************************************************************/
|
||||
|
||||
define('ID_NEW', -1);
|
||||
|
||||
define('RE_TYPE_INT', 1);
|
||||
define('RE_TYPE_STRING', 2);
|
||||
define('RE_TYPE_BOOLEAN', 3);
|
||||
define('RE_TYPE_DATE', 4);
|
||||
define('RE_TYPE_FLOAT', 5);
|
||||
define('RE_TYPE_DOUBLE', 6);
|
||||
|
||||
define('RE_INSERT_NOTHING', 0); //
|
||||
define('RE_INSERT_OVERWRITE', 1); // ignore given values and use function
|
||||
define('RE_INSERT_IGNORE', 2); // dont use this column on insert
|
||||
define('RE_INSERT_AUTOINCREMENT', 4); // column is an auto increment column
|
||||
define('RE_INSERT_UUID', 8); // UUID()
|
||||
define('RE_INSERT_NOW', 16); // NOW()
|
||||
|
||||
define('REGEX_USERNAME', '^[a-zA-Z0-9\.\-_@äüöÄÜÖ=)(\/\\\&*+~#][a-zA-Z0-9\.\-_ @äüöÄÜÖ=)(\/\\\&*+~#]{2,58}[a-zA-Z0-9\.\-_@äüöÄÜÖ=)(\/\\\&*+~#]$');
|
||||
define('REGEX_PASSWORD', '^[a-zA-Z0-9\.\-_ @äüöÄÜÖ=)(\/\\\&*+~#]{3,60}$');
|
||||
define('REGEX_LAST_NAME', '^[a-zA-Z][a-zA-Z0-9\.\- äüöÄÜÖ]{1,59}$');
|
||||
define('REGEX_FIRST_NAME', '^[a-zA-Z][a-zA-Z0-9\.\- äüöÄÜÖ]{1,59}$');
|
||||
define('REGEX_STATPIC_TEXT', '^[a-zA-Z0-9\.\-_ @äüöÄÜÖß=)(\/\\\&*\$+~#!§%;,-?:\[\]{}¹²³\'\"`\|µ°\%]{0,30}$');
|
||||
|
||||
define('ADMIN_TRANSLATE', 1); // edit translation
|
||||
define('ADMIN_MAINTAINANCE', 2); // check table etc.
|
||||
define('ADMIN_USER', 4); // drop users, caches etc.
|
||||
define('ADMIN_NEWS', 8); // approve news entries
|
||||
define('ADMIN_ROOT', 128 | 127); // root + all previous rights
|
||||
|
||||
define('ATTRIB_SELECTED', 1);
|
||||
define('ATTRIB_UNSELECTED', 2);
|
||||
define('ATTRIB_UNDEF', 3);
|
||||
|
||||
define('OBJECT_CACHELOG', 1);
|
||||
define('OBJECT_CACHE', 2);
|
||||
define('OBJECT_CACHEDESC', 3);
|
||||
define('OBJECT_USER', 4);
|
||||
define('OBJECT_TRAVELER', 5);
|
||||
define('OBJECT_PICTURE', 6);
|
||||
define('OBJECT_REMOVEDOBJECT', 7);
|
||||
?>
|
||||
@@ -0,0 +1,347 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
/* $opt['bin']['cs2cs'] must be set!
|
||||
*/
|
||||
|
||||
class coordinate
|
||||
{
|
||||
var $nLat = 0;
|
||||
var $nLon = 0;
|
||||
|
||||
function __construct($nNewLat, $nNewLon)
|
||||
{
|
||||
$this->nLat = $nNewLat;
|
||||
$this->nLon = $nNewLon;
|
||||
}
|
||||
|
||||
static function fromGK($rechts, $hoch)
|
||||
{
|
||||
//$zone = round($this->nLon/3);
|
||||
//$falseeasting = $zone * 1000000 + 500000;
|
||||
|
||||
$zone = round(($rechts - 500000) / 1000000);
|
||||
$falseeasting = $zone * 1000000 + 500000;
|
||||
|
||||
$cs2csresult = self::getCoreCommand($rechts, $hoch, "+proj=tmerc +lat_0=0 +lon_0=" . ($zone*3) . " +k=1.000000 +x_0=" . $falseeasting . " +y_0=0 +ellps=bessel +towgs84=606,23,413 +units=m +no_defs +to +proj=latlong +datum=WGS84");
|
||||
//$cs2csresult = self::getCoreCommand($rechts, $hoch, "+proj=tmerc +lat_0=0 +lon_0=9 +k=1.000000 +x_0=3500000 +y_0=0 +ellps=bessel +towgs84=591.28,81.35,396.39,1.477,-0.0736,-1.458,9.82 +units=m +no_defs +to +proj=latlong +datum=WGS84");
|
||||
|
||||
preg_match('/^(\d+)d(\d+)\'(\d+\.\d+)"E$/', $cs2csresult[0], $aLon);
|
||||
$lon = $aLon[1] + ($aLon[2]/60) + ($aLon[3]/3600);
|
||||
|
||||
preg_match('/^(\d+)d(\d+)\'(\d+\.\d+)"N$/', $cs2csresult[1], $aLat);
|
||||
$lat = $aLat[1] + ($aLat[2]/60) + ($aLat[3]/3600);
|
||||
|
||||
return new coordinate($lat, $lon);
|
||||
}
|
||||
|
||||
/* get-Functions return array([lat] => string, [lon] => string)
|
||||
*/
|
||||
|
||||
function getFloat()
|
||||
{
|
||||
return array('lat' => $this->nLat, 'lon' => $this->nLon);
|
||||
}
|
||||
|
||||
// d.ddddd°
|
||||
function getDecimal()
|
||||
{
|
||||
if ($this->nLat < 0)
|
||||
$sLat = 'S ' . sprintf('%08.5f', -$this->nLat) . '°';
|
||||
else
|
||||
$sLat = 'N ' . sprintf('%08.5f', $this->nLat) . '°';
|
||||
|
||||
if ($this->nLon < 0)
|
||||
$sLon = 'W ' . sprintf('%09.5f', -$this->nLon) . '°';
|
||||
else
|
||||
$sLon = 'E ' . sprintf('%09.5f', $this->nLon) . '°';
|
||||
|
||||
return array('lat' => $sLat, 'lon' => $sLon);
|
||||
}
|
||||
|
||||
// d° mm.mmm
|
||||
function getDecimalMinutes()
|
||||
{
|
||||
$nLat = $this->nLat;
|
||||
$bLatN = ($nLat < 0) ? false : true;
|
||||
if (!$bLatN) $nLat = -$nLat;
|
||||
$nLatDeg = floor($nLat);
|
||||
$nLatMin = ($nLat - $nLatDeg) * 60;
|
||||
if ($bLatN)
|
||||
$sLat = 'N ' . sprintf("%02d", $nLatDeg) . '° ' . sprintf("%06.3f", $nLatMin) . '\'';
|
||||
else
|
||||
$sLat = 'S ' . sprintf("%02d", $nLatDeg) . '° ' . sprintf("%06.3f", $nLatMin) . '\'';
|
||||
|
||||
$nLon = $this->nLon;
|
||||
$bLonE = ($nLon < 0) ? false : true;
|
||||
if (!$bLonE) $nLon = -$nLon;
|
||||
$nLonDeg = floor($nLon);
|
||||
$nLonMin = ($nLon - $nLonDeg) * 60;
|
||||
if ($bLonE)
|
||||
$sLon = 'E ' . sprintf("%03d", $nLonDeg) . '° ' . sprintf("%06.3f", $nLonMin) . '\'';
|
||||
else
|
||||
$sLon = 'W ' . sprintf("%03d", $nLonDeg) . '° ' . sprintf("%06.3f", $nLonMin) . '\'';
|
||||
|
||||
return array('lat' => $sLat, 'lon' => $sLon);
|
||||
}
|
||||
|
||||
// d° mm ss
|
||||
function getDecimalMinutesSeconds()
|
||||
{
|
||||
$nLat = $this->nLat;
|
||||
$bLatN = ($nLat < 0) ? false : true;
|
||||
if (!$bLatN) $nLat = -$nLat;
|
||||
$nLatDeg = floor($nLat);
|
||||
$nLatMin = ($nLat - $nLatDeg) * 60;
|
||||
$nLatSec = $nLatMin - floor($nLatMin);
|
||||
$nLatMin = ($nLatMin - $nLatSec);
|
||||
$nLatSec = $nLatSec * 60;
|
||||
if ($bLatN)
|
||||
$sLat = 'N ' . sprintf("%02d", $nLatDeg) . '° ' . sprintf("%02d", $nLatMin) . '\' ' . sprintf("%02d", $nLatSec) . '\'\'';
|
||||
else
|
||||
$sLat = 'S ' . sprintf("%02d", $nLatDeg) . '° ' . sprintf("%02d", $nLatMin) . '\' ' . sprintf("%02d", $nLatSec) . '\'\'';
|
||||
|
||||
$nLon = $this->nLon;
|
||||
$bLonE = ($nLon < 0) ? false : true;
|
||||
if (!$bLonE) $nLon = -$nLon;
|
||||
$nLonDeg = floor($nLon);
|
||||
$nLonMin = ($nLon - $nLonDeg) * 60;
|
||||
$nLonSec = $nLonMin - floor($nLonMin);
|
||||
$nLonMin = ($nLonMin - $nLonSec);
|
||||
$nLonSec = $nLonSec * 60;
|
||||
if ($bLonE)
|
||||
$sLon = 'E ' . sprintf("%03d", $nLonDeg) . '° ' . sprintf("%02d", $nLonMin) . '\' ' . sprintf("%02d", $nLonSec) . '\'\'';
|
||||
else
|
||||
$sLon = 'W ' . sprintf("%03d", $nLonDeg) . '° ' . sprintf("%02d", $nLonMin) . '\' ' . sprintf("%02d", $nLonSec) . '\'\'';
|
||||
|
||||
return array('lat' => $sLat, 'lon' => $sLon);
|
||||
}
|
||||
|
||||
// array(zone, letter, north, east)
|
||||
function getUTM()
|
||||
{
|
||||
// get UTM letter
|
||||
if ( $this->nLat <= 84.0 && $this->nLat >= 72.0 )
|
||||
$utmLetter = 'X';
|
||||
else if ( $this->nLat < 72.0 && $this->nLat >= 64.0 )
|
||||
$utmLetter = 'W';
|
||||
else if ( $this->nLat < 64.0 && $this->nLat >= 56.0 )
|
||||
$utmLetter = 'V';
|
||||
else if ( $this->nLat < 56.0 && $this->nLat >= 48.0 )
|
||||
$utmLetter = 'U';
|
||||
else if ( $this->nLat < 48.0 && $this->nLat >= 40.0 )
|
||||
$utmLetter = 'T';
|
||||
else if ( $this->nLat < 40.0 && $this->nLat >= 32.0 )
|
||||
$utmLetter = 'S';
|
||||
else if ( $this->nLat < 32.0 && $this->nLat >= 24.0 )
|
||||
$utmLetter = 'R';
|
||||
else if ( $this->nLat < 24.0 && $this->nLat >= 16.0 )
|
||||
$utmLetter = 'Q';
|
||||
else if ( $this->nLat < 16.0 && $this->nLat >= 8.0 )
|
||||
$utmLetter = 'P';
|
||||
else if ( $this->nLat < 8.0 && $this->nLat >= 0.0 )
|
||||
$utmLetter = 'N';
|
||||
else if ( $this->nLat < 0.0 && $this->nLat >= -8.0 )
|
||||
$utmLetter = 'M';
|
||||
else if ( $this->nLat < -8.0 && $this->nLat >= -16.0 )
|
||||
$utmLetter = 'L';
|
||||
else if ( $this->nLat < -16.0 && $this->nLat >= -24.0 )
|
||||
$utmLetter = 'K';
|
||||
else if ( $this->nLat < -24.0 && $this->nLat >= -32.0 )
|
||||
$utmLetter = 'J';
|
||||
else if ( $this->nLat < -32.0 && $this->nLat >= -40.0 )
|
||||
$utmLetter = 'H';
|
||||
else if ( $this->nLat < -40.0 && $this->nLat >= -48.0 )
|
||||
$utmLetter = 'G';
|
||||
else if ( $this->nLat < -48.0 && $this->nLat >= -56.0 )
|
||||
$utmLetter = 'F';
|
||||
else if ( $this->nLat < -56.0 && $this->nLat >= -64.0 )
|
||||
$utmLetter = 'E';
|
||||
else if ( $this->nLat < -64.0 && $this->nLat >= -72.0 )
|
||||
$utmLetter = 'D';
|
||||
else if ( $this->nLat < -72.0 && $this->nLat >= -80.0 )
|
||||
$utmLetter = 'C';
|
||||
else
|
||||
$utmLetter = 'Z'; //returns 'Z' if the lat is outside the UTM limits of 84N to 80S
|
||||
|
||||
$zone = (int) ( ( $this->nLon + 180 ) / 6 ) + 1;
|
||||
|
||||
if ( $this->nLat >= 56.0 && $this->nLat < 64.0 && $this->nLon >= 3.0 && $this->nLon < 12.0 ) $zone = 32;
|
||||
|
||||
// Special zones for Svalbard.
|
||||
if ($this->nLat >= 72.0 && $this->nLat < 84.0 )
|
||||
{
|
||||
if ( $this->nLon >= 0.0 && $this->nLon < 9.0 )
|
||||
$zone = 31;
|
||||
else if ( $this->nLon >= 9.0 && $this->nLon < 21.0 )
|
||||
$zone = 33;
|
||||
else if ( $this->nLon >= 21.0 && $this->nLon < 33.0 )
|
||||
$zone = 35;
|
||||
else if ( $this->nLon >= 33.0 && $this->nLon < 42.0 )
|
||||
$zone = 37;
|
||||
}
|
||||
|
||||
$cs2csresult = $this->getCore("+proj=utm +datum=WGS84 +zone=$zone");
|
||||
|
||||
return Array('zone' => $zone, 'letter' => $utmLetter, 'north' => 'N ' . floor($cs2csresult[1]), 'east' => 'E ' . floor($cs2csresult[0]));
|
||||
}
|
||||
|
||||
// return string
|
||||
function getGK()
|
||||
{
|
||||
$zone = round($this->nLon/3);
|
||||
$falseeasting = $zone * 1000000 + 500000;
|
||||
|
||||
$cs2csresult = $this->getCore("+proj=tmerc +ellps=bessel +lat_0=0 +lon_0=".($zone*3)." +x_0=".$falseeasting." +towgs84=606,23,413 ");
|
||||
|
||||
return 'R ' . floor($cs2csresult[0]) . ' H ' . floor($cs2csresult[1]);
|
||||
}
|
||||
|
||||
// return string
|
||||
function getRD()
|
||||
{
|
||||
$cs2csresult = $this->getCore("+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +towgs84=565.040,49.910,465.840,-0.40939,0.35971,-1.86849,4.0772 +ellps=bessel ");
|
||||
return 'X ' . floor($cs2csresult[0]) . ' Y ' . floor($cs2csresult[1]);
|
||||
}
|
||||
|
||||
// returns string
|
||||
function getQTH()
|
||||
{
|
||||
$lon = $this->nLon;
|
||||
$lat = $this->nLat;
|
||||
|
||||
$lon += 180;
|
||||
$l[0] = floor($lon/20);
|
||||
$lon -= 20*$l[0];
|
||||
$l[2] = floor($lon/2);
|
||||
$lon -= 2 *$l[2];
|
||||
$l[4] = floor($lon*60/5);
|
||||
|
||||
$lat += 90;
|
||||
$l[1] = floor($lat/10);
|
||||
$lat -= 10*$l[1];
|
||||
$l[3] = floor($lat);
|
||||
$lat -= $l[3];
|
||||
$l[5] = floor($lat*120/5);
|
||||
|
||||
return sprintf("%c%c%c%c%c%c", $l[0]+65, $l[1]+65, $l[2]+48, $l[3]+48, $l[4]+65, $l[5]+65);
|
||||
}
|
||||
|
||||
// return string
|
||||
function getSwissGrid()
|
||||
{
|
||||
$nLat = $this->nLat * 3600;
|
||||
$nLon = $this->nLon * 3600;
|
||||
|
||||
// Quelle: http://www.swisstopo.admin.ch/internet/swisstopo/de/home/apps/calc.html
|
||||
// Hilfsgrössen
|
||||
$b = ($nLat - 169028.66) / 10000.0;
|
||||
$l = ($nLon - 26782.5) / 10000.0;
|
||||
|
||||
// Nord x
|
||||
$x = 200147.07 + 308807.95 * $b + 3745.25 * $l * $l + 76.63 * $b * $b + 119.79 * $b * $b * $b - 194.56 * $b * $l * $l;
|
||||
$x = floor($x);
|
||||
|
||||
// Ost y
|
||||
$y = 600072.37 + 211455.93 * $l - 10938.51 * $l * $b - 0.36 * $l * $b * $b - 44.54 * $l * $l * $l;
|
||||
$y = floor($y);
|
||||
|
||||
// Namen: "CH1903", "Schweizer Landeskoordinaten" oder "Swiss Grid"
|
||||
$swissgrid = "$y / $x";
|
||||
// Karten Links
|
||||
$mapplus = "<a href=\"http://www.mapplus.ch/frame.php?map=&x=$y&y=$x&zl=13\" target=\"_blank\">MapPlus</a>";
|
||||
$mapsearch = "<a href=\"http://map.search.ch/$y,$x\" target=\"_blank\">map.search.ch</a>";
|
||||
|
||||
return array('coord' => $swissgrid, $mapplus, $mapsearch);
|
||||
}
|
||||
|
||||
function getCore($to)
|
||||
{
|
||||
return $this->getCoreCommand($this->nLon, $this->nLat, " +proj=latlong +datum=WGS84 +to " . $to);
|
||||
}
|
||||
|
||||
static function getCoreCommand($x, $y, $command)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$descriptorspec = array(
|
||||
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
|
||||
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
|
||||
2 => array("pipe", "w") // stderr is a pipe that the child will write to
|
||||
);
|
||||
|
||||
if (mb_eregi('^[a-z0-9_ ,\+\-=\.]*$', $command) == 0)
|
||||
die("invalid arguments in command: " . $command ."\n");
|
||||
|
||||
$command = $opt['bin']['cs2cs'] . " " . $command;
|
||||
|
||||
$process = proc_open($command, $descriptorspec, $pipes);
|
||||
|
||||
if (is_resource($process))
|
||||
{
|
||||
fwrite($pipes[0], $x . " " . $y);
|
||||
fclose($pipes[0]);
|
||||
|
||||
$stdout = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
|
||||
$stderr = stream_get_contents($pipes[2]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
//
|
||||
// $procstat = proc_get_status($process);
|
||||
//
|
||||
// neither proc_close nor proc_get_status return reasonable results with PHP5 and linux 2.6.11,
|
||||
// see http://bugs.php.net/bug.php?id=32533
|
||||
//
|
||||
// as temporary (?) workaround, check stderr output.
|
||||
// (Vinnie, 2006-02-09)
|
||||
|
||||
if ($stderr)
|
||||
die("proc_open() failed:<br>command='$command'<br>stderr='" . $stderr . "'");
|
||||
|
||||
proc_close($process);
|
||||
|
||||
return explode_multi(mb_trim($stdout), "\t\n ");
|
||||
}
|
||||
else
|
||||
die("proc_open() failed, command=$command\n");
|
||||
}
|
||||
|
||||
static function parseRequestLat($name)
|
||||
{
|
||||
if (!isset($_REQUEST[$name . 'NS']) || !isset($_REQUEST[$name . 'Lat']) || !isset($_REQUEST[$name . 'LatMin']))
|
||||
return false;
|
||||
|
||||
$coordNS = $_REQUEST[$name . 'NS'];
|
||||
$coordLat = $_REQUEST[$name . 'Lat']+0;
|
||||
$coordLatMin = str_replace(',', '.', $_REQUEST[$name . 'LatMin'])+0;
|
||||
|
||||
$lat = $coordLat + $coordLatMin/60;
|
||||
if ($coordNS == 'S')
|
||||
$lat = -$lat;
|
||||
|
||||
return $lat;
|
||||
}
|
||||
|
||||
static function parseRequestLon($name)
|
||||
{
|
||||
if (!isset($_REQUEST[$name . 'EW']) || !isset($_REQUEST[$name . 'Lon']) || !isset($_REQUEST[$name . 'LonMin']))
|
||||
return false;
|
||||
|
||||
$coordEW = $_REQUEST[$name . 'EW'];
|
||||
$coordLon = $_REQUEST[$name . 'Lon']+0;
|
||||
$coordLonMin = str_replace(',', '.', $_REQUEST[$name . 'LonMin'])+0;
|
||||
|
||||
$lon = $coordLon + $coordLonMin/60;
|
||||
if ($coordEW == 'W')
|
||||
$lon = -$lon;
|
||||
|
||||
return $lon;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
/* $opt['bin']['cs2cs'] must be set!
|
||||
*/
|
||||
|
||||
class coordinate_batch
|
||||
{
|
||||
var $pipes = array();
|
||||
var $process;
|
||||
|
||||
function writeGK($x, $y)
|
||||
{
|
||||
fwrite($this->pipes[0], $x . " " . $y . "\n");
|
||||
}
|
||||
|
||||
function analyseOutput()
|
||||
{
|
||||
$retval = array();
|
||||
|
||||
fclose($this->pipes[0]);
|
||||
|
||||
$stdout = stream_get_contents($this->pipes[1]);
|
||||
fclose($this->pipes[1]);
|
||||
|
||||
$stderr = stream_get_contents($this->pipes[2]);
|
||||
fclose($this->pipes[2]);
|
||||
|
||||
proc_close($this->process);
|
||||
|
||||
if ($stderr != '')
|
||||
die('Stderr is not empty!' . "\n");
|
||||
|
||||
$output = explode("\n", $stdout);
|
||||
for ($n = 0; $n < count($output); $n++)
|
||||
if ($output[$n] != '')
|
||||
$retval[] = $this->parseOutputLine($output[$n]);
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function parseOutputLine($str)
|
||||
{
|
||||
$nLon = 0;
|
||||
$nLat = 0;
|
||||
|
||||
$parts = explode_multi(mb_trim($str), "\t\n ");
|
||||
if (count($parts) == 3)
|
||||
{
|
||||
if (strpos($parts[0], '\'') === false)
|
||||
{
|
||||
preg_match('/^(\d+)dE$/', $parts[0], $aLon);
|
||||
$nLon = $aLon[1];
|
||||
}
|
||||
else if (strpos($parts[0], '"') === false)
|
||||
{
|
||||
preg_match('/^(\d+)d(\d+)\'E$/', $parts[0], $aLon);
|
||||
$nLon = $aLon[1] + ($aLon[2]/60);
|
||||
}
|
||||
else
|
||||
{
|
||||
preg_match('/^(\d+)d(\d+)\'([\d\.]+)"E$/', $parts[0], $aLon);
|
||||
$nLon = $aLon[1] + ($aLon[2]/60) + ($aLon[3]/3600);
|
||||
}
|
||||
|
||||
if (strpos($parts[1], '\'') === false)
|
||||
{
|
||||
preg_match('/^(\d+)dN$/', $parts[1], $aLat);
|
||||
$nLat = $aLat[1];
|
||||
}
|
||||
else if (strpos($parts[1], '"') === false)
|
||||
{
|
||||
preg_match('/^(\d+)d(\d+)\'N$/', $parts[1], $aLat);
|
||||
$nLat = $aLat[1] + ($aLat[2]/60);
|
||||
}
|
||||
else
|
||||
{
|
||||
preg_match('/^(\d+)d(\d+)\'([\d+\.]+)"N$/', $parts[1], $aLat);
|
||||
$nLat = $aLat[1] + ($aLat[2]/60) + ($aLat[3]/3600);
|
||||
}
|
||||
}
|
||||
|
||||
$coord = array('lon' => $nLon, 'lat' => $nLat);
|
||||
return $coord;
|
||||
}
|
||||
|
||||
function openGK()
|
||||
{
|
||||
$rechts = 3515222;
|
||||
$zone = round(($rechts - 500000) / 1000000);
|
||||
$falseeasting = $zone * 1000000 + 500000;
|
||||
$this->open("+proj=tmerc +lat_0=0 +lon_0=" . ($zone*3) . " +k=1.000000 +x_0=" . $falseeasting . " +y_0=0 +ellps=bessel +towgs84=606,23,413 +units=m +no_defs +to +proj=latlong +datum=WGS84");
|
||||
}
|
||||
|
||||
function open($command)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$descriptorspec = array(
|
||||
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
|
||||
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
|
||||
2 => array("pipe", "w") // stderr is a pipe that the child will write to
|
||||
);
|
||||
|
||||
if (mb_eregi('^[a-z0-9_ ,\+\-=\.]*$', $command) == 0)
|
||||
die("invalid arguments in command: " . $command ."\n");
|
||||
|
||||
$command = $opt['bin']['cs2cs'] . " " . $command;
|
||||
|
||||
$this->process = proc_open($command, $descriptorspec, $this->pipes);
|
||||
|
||||
if (!is_resource($this->process))
|
||||
die("proc_open() failed, command=$command\n");
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
class countriesList
|
||||
{
|
||||
var $locale;
|
||||
var $bDefaultUsed = false;
|
||||
|
||||
function __construct($locale=null)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($locale === null)
|
||||
$this->locale = $opt['template']['locale'];
|
||||
else
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
function defaultUsed()
|
||||
{
|
||||
return $this->bDefaultUsed;
|
||||
}
|
||||
|
||||
function isDefault($id)
|
||||
{
|
||||
if (sql_value("SELECT COUNT(*) FROM `countries_list_default` WHERE `lang`='&1' AND `show`='&2'", 0, $this->locale, $id) == 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
function getDefaultRS()
|
||||
{
|
||||
if (sql_value("SELECT COUNT(*) FROM `countries_list_default` WHERE `lang`='&1'", 0, $this->locale) == 0)
|
||||
return $this->getAllRS();
|
||||
|
||||
$this->bDefaultUsed = true;
|
||||
|
||||
return sql("SELECT `countries`.`short` AS `id`, IFNULL(`sys_trans_text`.`text`, `countries`.`name`) AS `name` FROM `countries` INNER JOIN `countries_list_default` ON `countries`.`short`=`countries_list_default`.`show` AND `countries_list_default`.`lang`='&1' LEFT JOIN `sys_trans` ON `countries`.`trans_id`=`sys_trans`.`id` AND `countries`.`name`=`sys_trans`.`text` LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1' ORDER BY `name`", $this->locale);
|
||||
}
|
||||
|
||||
function getAllRS()
|
||||
{
|
||||
$this->bDefaultUsed = false;
|
||||
return sql("SELECT `countries`.`short` AS `id`, IFNULL(`sys_trans_text`.`text`, `countries`.`name`) AS `name` FROM `countries` LEFT JOIN `sys_trans` ON `countries`.`trans_id`=`sys_trans`.`id` AND `countries`.`name`=`sys_trans`.`text` LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1' ORDER BY `name`", $this->locale);
|
||||
}
|
||||
|
||||
function getRS($selectedId, $showall)
|
||||
{
|
||||
if ($showall != false)
|
||||
return $this->getAllRS();
|
||||
|
||||
if ($selectedId !== null && !$this->isDefault($selectedId))
|
||||
return $this->getAllRS();
|
||||
|
||||
return $this->getDefaultRS();
|
||||
}
|
||||
|
||||
static function getCountryLocaleName($id)
|
||||
{
|
||||
global $opt;
|
||||
return sql_value("SELECT IFNULL(`sys_trans_text`.`text`, `countries`.`name`) FROM `countries` LEFT JOIN `sys_trans` ON `countries`.`trans_id`=`sys_trans`.`id` LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&2' WHERE `countries`.`short`='&1'", '', $id, $opt['template']['locale']);;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
/* check if a password is complex enough
|
||||
*
|
||||
* length min. 6 chars
|
||||
* min. 4 different chars
|
||||
*
|
||||
* if cracklib is available run dictionary check
|
||||
* Attention: if you use a too large wordlist,
|
||||
* your users may be unhappy to search
|
||||
* for a strong enough password
|
||||
*
|
||||
* $pw may not contain one of $addwords[]
|
||||
* one of $addwords[] may not contain $pw
|
||||
*
|
||||
* return value
|
||||
* true ... complex enough
|
||||
* false ... not complex enough
|
||||
*/
|
||||
function cracklib_checkpw($pw, $addwords)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
// length min. 6 chars
|
||||
if (strlen($pw) < 6)
|
||||
return false;
|
||||
|
||||
// min. 4 different chars
|
||||
$chars = array();
|
||||
for ($i = 0; $i < mb_strlen($pw); $i++)
|
||||
$chars[mb_substr($pw, $i, 1)] = true;
|
||||
|
||||
if (count($chars) <= 4)
|
||||
return false;
|
||||
unset($chars);
|
||||
|
||||
// prepare $addwords
|
||||
$wordlist = array();
|
||||
foreach ($addwords AS $word)
|
||||
{
|
||||
$word = mb_strtolower($word);
|
||||
|
||||
$word = mb_ereg_replace('\\?', ' ', $word);
|
||||
$word = mb_ereg_replace('\\)', ' ', $word);
|
||||
$word = mb_ereg_replace('\\(', ' ', $word);
|
||||
$word = mb_ereg_replace('\\.', ' ', $word);
|
||||
$word = mb_ereg_replace('´', ' ', $word);
|
||||
$word = mb_ereg_replace('`', ' ', $word);
|
||||
$word = mb_ereg_replace('\'', ' ', $word);
|
||||
$word = mb_ereg_replace('/', ' ', $word);
|
||||
$word = mb_ereg_replace(':', ' ', $word);
|
||||
$word = mb_ereg_replace('-', ' ', $word);
|
||||
$word = mb_ereg_replace(',', ' ', $word);
|
||||
$word = mb_ereg_replace("\r\n", ' ', $word);
|
||||
$word = mb_ereg_replace("\n", ' ', $word);
|
||||
$word = mb_ereg_replace("\r", ' ', $word);
|
||||
|
||||
$wordlist = array_merge($wordlist, mb_split(' ', $word));
|
||||
}
|
||||
foreach ($wordlist AS $k => $v)
|
||||
if (mb_strlen($v) < 3)
|
||||
unset($wordlist[$k]);
|
||||
|
||||
$pw_lc = mb_strtolower($pw);
|
||||
|
||||
// $pw may not contain one of $addwords[]
|
||||
foreach ($wordlist AS $v)
|
||||
if (mb_strpos($pw_lc, $v) !== false)
|
||||
return false;
|
||||
|
||||
// one of $addwords[] may not contain $pw
|
||||
foreach ($wordlist AS $v)
|
||||
if (mb_strpos($v, $pw_lc) !== false)
|
||||
return false;
|
||||
|
||||
if ($opt['logic']['cracklib'] == true)
|
||||
{
|
||||
// load cracklib
|
||||
if (!function_exists('crack_check'))
|
||||
@dl('crack.so');
|
||||
|
||||
// cracklib loaded?
|
||||
if (function_exists('crack_check'))
|
||||
if (!crack_check($pw))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
function geodb_setAllCacheLocations()
|
||||
{
|
||||
$rs = sqll("SELECT `caches`.`cache_id` FROM `caches` LEFT JOIN `cache_location` ON `caches`.`cache_id`=`cache_location`.`cache_id` WHERE ISNULL(`cache_location`.`cache_id`) OR `cache_location`.`last_modified`!=`caches`.`last_modified`");
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
{
|
||||
geodb_setCacheLocation($r['cache_id']);
|
||||
}
|
||||
sql_free_result($rs);
|
||||
|
||||
sqll("DELETE FROM `cache_location` WHERE `cache_id` NOT IN (SELECT `cache_id` FROM `caches`)");
|
||||
}
|
||||
|
||||
function geodb_setCacheLocation($cache_id)
|
||||
{
|
||||
echo $cache_id . "\n";
|
||||
$rs = sqll("SELECT `latitude`, `longitude`, `last_modified` FROM `caches` WHERE `cache_id`='&1'", $cache_id);
|
||||
if ($r = sql_fetch_array($rs))
|
||||
{
|
||||
$nLocId = geodb_locidFromCoords($r['longitude'], $r['latitude']);
|
||||
|
||||
if ($nLocId != 0)
|
||||
{
|
||||
$sAdm1 = geodb_landFromLocid($nLocId);
|
||||
$sAdm2 = geodb_regierungsbezirkFromLocid($nLocId);
|
||||
$sAdm3 = geodb_landkreisFromLocid($nLocId);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sAdm1 = null;
|
||||
$sAdm2 = null;
|
||||
$sAdm3 = null;
|
||||
}
|
||||
|
||||
if ($sAdm1 == '') $sAdm1 = null;
|
||||
if ($sAdm2 == '') $sAdm2 = null;
|
||||
if ($sAdm3 == '') $sAdm3 = null;
|
||||
|
||||
sqll("INSERT INTO `cache_location` (`cache_id`, `last_modified`, `adm1`, `adm2`, `adm3`) VALUES ('&1', '&2', '&3', '&4', '&5') ON DUPLICATE KEY UPDATE `cache_id`='&1', `last_modified`='&2', `adm1`='&3', `adm2`='&4', `adm3`='&5'", $cache_id, $r['last_modified'], $sAdm1, $sAdm2, $sAdm3);
|
||||
}
|
||||
sql_free_result($rs);
|
||||
}
|
||||
|
||||
function geodb_locidFromCoords($lon, $lat)
|
||||
{
|
||||
if (!is_numeric($lon)) return 0;
|
||||
if (!is_numeric($lat)) return 0;
|
||||
$lon = $lon + 0;
|
||||
$lat = $lat + 0;
|
||||
|
||||
$rs = sqll(' SELECT `geodb_coordinates`.`loc_id` `loc_id`,
|
||||
(( ' . $lon . ' - `geodb_coordinates`.`lon` ) * ( ' . $lon . ' - `geodb_coordinates`.`lon` ) +
|
||||
( ' . $lat . ' - `geodb_coordinates`.`lat` ) * ( ' . $lat . ' - `geodb_coordinates`.`lat` )) `dist`
|
||||
FROM `geodb_coordinates`
|
||||
INNER JOIN `geodb_locations` ON `geodb_coordinates`.`loc_id`=`geodb_locations`.`loc_id`
|
||||
WHERE `geodb_locations`.`loc_type`=100700000
|
||||
AND `geodb_coordinates`.`lon` > ' . ($lon - 0.15) . '
|
||||
AND `geodb_coordinates`.`lon` < ' . ($lon + 0.15) . '
|
||||
AND `geodb_coordinates`.`lat` > ' . ($lat - 0.15) . '
|
||||
AND `geodb_coordinates`.`lat` < ' . ($lat + 0.15) . '
|
||||
ORDER BY `dist` ASC
|
||||
LIMIT 1');
|
||||
if ($r = sql_fetch_array($rs))
|
||||
return $r['loc_id'];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
function geodb_landFromLocid($locid)
|
||||
{
|
||||
if (!is_numeric($locid)) return 0;
|
||||
$locid = $locid + 0;
|
||||
|
||||
$rs = sqll("SELECT `ld`.`text_val` `land` FROM `geodb_textdata` `ct`, `geodb_textdata` `ld`, `geodb_hierarchies` `hr` WHERE `ct`.`loc_id`=`hr`.`loc_id` AND `hr`.`id_lvl2`=`ld`.`loc_id` AND `ct`.`text_type`=500100000 AND `ld`.`text_locale`='DE' AND `ld`.`text_type`=500100000 AND `ct`.`loc_id`='&1' AND `hr`.`id_lvl2`!=0", $locid);
|
||||
if ($r = sql_fetch_array($rs))
|
||||
return $r['land'];
|
||||
else
|
||||
return '';
|
||||
}
|
||||
|
||||
function geodb_regierungsbezirkFromLocid($locid)
|
||||
{
|
||||
if (!is_numeric($locid)) return 0;
|
||||
$locid = $locid + 0;
|
||||
|
||||
$rs = sqll("SELECT `rb`.`text_val` `regierungsbezirk` FROM `geodb_textdata` `ct`, `geodb_textdata` `rb`, `geodb_hierarchies` `hr` WHERE `ct`.`loc_id`=`hr`.`loc_id` AND `hr`.`id_lvl4`=`rb`.`loc_id` AND `ct`.`text_type`=500100000 AND `rb`.`text_type`=500100000 AND `ct`.`loc_id`='&1' AND `hr`.`id_lvl4`!=0", $locid);
|
||||
if ($r = sql_fetch_array($rs))
|
||||
return $r['regierungsbezirk'];
|
||||
else
|
||||
return '';
|
||||
}
|
||||
|
||||
function geodb_landkreisFromLocid($locid)
|
||||
{
|
||||
if (!is_numeric($locid)) return 0;
|
||||
$locid = $locid + 0;
|
||||
|
||||
$rs = sqll("SELECT `rb`.`text_val` `regierungsbezirk` FROM `geodb_textdata` `ct`, `geodb_textdata` `rb`, `geodb_hierarchies` `hr` WHERE `ct`.`loc_id`=`hr`.`loc_id` AND `hr`.`id_lvl5`=`rb`.`loc_id` AND `ct`.`text_type`=500100000 AND `rb`.`text_type`=500100000 AND `ct`.`loc_id`='&1' AND `hr`.`id_lvl5`!=0", $locid);
|
||||
if ($r = sql_fetch_array($rs))
|
||||
return $r['regierungsbezirk'];
|
||||
else
|
||||
return '';
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
class geomath
|
||||
{
|
||||
static function calcBearing($lat1, $lon1, $lat2, $lon2)
|
||||
{
|
||||
// Input sind Breite/Laenge in Altgrad
|
||||
// Der Fall lat/lon1 == lat/lon2 sollte vorher abgefangen werden,
|
||||
// zB. ueber die Abfrage der Distanz, dass Bearing nur bei Distanz > 5m
|
||||
// geholt wird, sonst = false gesetzt wird...
|
||||
if ($lat1 == $lat2 && $lon1 == $lon2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$pi = 3.141592653589793238462643383279502884197;
|
||||
|
||||
if ($lat1 == $lat2) $lat1 += 0.0000166;
|
||||
if ($lon1 == $lon2) $lon1 += 0.0000166;
|
||||
|
||||
$rad_lat1 = $lat1 / 180.0 * $pi;
|
||||
$rad_lon1 = $lon1 / 180.0 * $pi;
|
||||
$rad_lat2 = $lat2 / 180.0 * $pi;
|
||||
$rad_lon2 = $lon2 / 180.0 * $pi;
|
||||
|
||||
$delta_lon = $rad_lon2 - $rad_lon1;
|
||||
$bearing = atan2 ( sin ( $delta_lon ) * cos ( $rad_lat2 ),
|
||||
cos ( $rad_lat1 ) * sin ( $rad_lat2 ) - sin ( $rad_lat1 ) * cos ( $rad_lat2 ) * cos ( $delta_lon ) );
|
||||
$bearing = 180.0 * $bearing / $pi;
|
||||
|
||||
// Output Richtung von lat/lon1 nach lat/lon2 in Altgrad von -180 bis +180
|
||||
// wenn man Output von 0 bis 360 haben moechte, kann man dies machen:
|
||||
if ( $bearing < 0.0 ) $bearing = $bearing + 360.0;
|
||||
|
||||
return $bearing;
|
||||
}
|
||||
}
|
||||
|
||||
static function Bearing2Text($parBearing, $parShortText = 0)
|
||||
{
|
||||
if ($parShortText == 0)
|
||||
{
|
||||
if ($parBearing == '-')
|
||||
{
|
||||
return 'N/A';
|
||||
}
|
||||
elseif (($parBearing < 11.25) || ($parBearing > 348.75))
|
||||
return 'Nord';
|
||||
elseif ($parBearing < 33.75)
|
||||
return 'Nord/Nordost';
|
||||
elseif ($parBearing < 56.25)
|
||||
return 'Nordost';
|
||||
elseif ($parBearing < 78.75)
|
||||
return 'Ost/Nordost';
|
||||
elseif ($parBearing < 101.25)
|
||||
return 'Ost';
|
||||
elseif ($parBearing < 123.75)
|
||||
return 'Ost/Südost';
|
||||
elseif ($parBearing < 146.25)
|
||||
return 'Südost';
|
||||
elseif ($parBearing < 168.75)
|
||||
return 'Süd/Südost';
|
||||
elseif ($parBearing < 191.25)
|
||||
return 'Süd';
|
||||
elseif ($parBearing < 213.75)
|
||||
return 'Süd/Südwest';
|
||||
elseif ($parBearing < 236.25)
|
||||
return 'Südwest';
|
||||
elseif ($parBearing < 258.75)
|
||||
return 'West/Südwest';
|
||||
elseif ($parBearing < 281.25)
|
||||
return 'West';
|
||||
elseif ($parBearing < 303.75)
|
||||
return 'West/Nordwest';
|
||||
elseif ($parBearing < 326.25)
|
||||
return 'Nordwest';
|
||||
elseif ($parBearing <= 348.75)
|
||||
return 'Nord/Nordwest';
|
||||
else return 'N/A';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($parBearing == '-')
|
||||
{
|
||||
return 'N/A';
|
||||
}
|
||||
elseif (($parBearing < 11.25) || ($parBearing > 348.75))
|
||||
return 'N';
|
||||
elseif ($parBearing < 33.75)
|
||||
return 'NNO';
|
||||
elseif ($parBearing < 56.25)
|
||||
return 'NO';
|
||||
elseif ($parBearing < 78.75)
|
||||
return 'ONO';
|
||||
elseif ($parBearing < 101.25)
|
||||
return 'O';
|
||||
elseif ($parBearing < 123.75)
|
||||
return 'OSO';
|
||||
elseif ($parBearing < 146.25)
|
||||
return 'SO';
|
||||
elseif ($parBearing < 168.75)
|
||||
return 'SSO';
|
||||
elseif ($parBearing < 191.25)
|
||||
return 'S';
|
||||
elseif ($parBearing < 213.75)
|
||||
return 'SSW';
|
||||
elseif ($parBearing < 236.25)
|
||||
return 'SW';
|
||||
elseif ($parBearing < 258.75)
|
||||
return 'WSW';
|
||||
elseif ($parBearing < 281.25)
|
||||
return 'W';
|
||||
elseif ($parBearing < 303.75)
|
||||
return 'WNW';
|
||||
elseif ($parBearing < 326.25)
|
||||
return 'NW';
|
||||
elseif ($parBearing <= 348.75)
|
||||
return 'NNW';
|
||||
else return 'N/A';
|
||||
}
|
||||
}
|
||||
|
||||
static function calcDistance($latFrom, $lonFrom, $latTo, $lonTo, $distanceMultiplier=1)
|
||||
{
|
||||
return acos(cos((90-$latFrom) * 3.14159 / 180) * cos((90-$latTo) * 3.14159 / 180) + sin((90-$latFrom) * 3.14159 / 180) * sin((90-$latTo) * 3.14159 / 180) * cos(($lonFrom-$lonTo) * 3.14159 / 180)) * 6370 * $distanceMultiplier;
|
||||
}
|
||||
|
||||
static function getSqlDistanceFormula($lonFrom, $latFrom, $maxDistance, $distanceMultiplier=1, $lonField='longitude', $latField='latitude', $tableName = 'caches')
|
||||
{
|
||||
$lonFrom = $lonFrom + 0;
|
||||
$latFrom = $latFrom + 0;
|
||||
$maxDistance = $maxDistance + 0;
|
||||
$distanceMultiplier = $distanceMultiplier + 0;
|
||||
|
||||
if (!mb_ereg_match('^[a-zA-Z][a-zA-Z0-9_]{0,59}$', $lonField))
|
||||
die('Fatal Error: invalid lonField');
|
||||
if (!mb_ereg_match('^[a-zA-Z][a-zA-Z0-9_]{0,59}$', $latField))
|
||||
die('Fatal Error: invalid latField');
|
||||
if (!mb_ereg_match('^[a-zA-Z][a-zA-Z0-9_]{0,59}$', $tableName))
|
||||
die('Fatal Error: invalid tableName');
|
||||
|
||||
$b1_rad = sprintf('%01.5f', (90 - $latFrom) * 3.14159 / 180);
|
||||
$l1_deg = sprintf('%01.5f', $lonFrom);
|
||||
|
||||
$lonField = '`' . sql_escape_backtick($tableName) . '`.`' . sql_escape_backtick($lonField) . '`';
|
||||
$latField = '`' . sql_escape_backtick($tableName) . '`.`' . sql_escape_backtick($latField) . '`';
|
||||
|
||||
$r = 6370 * $distanceMultiplier;
|
||||
|
||||
$retval = 'acos(cos(' . $b1_rad . ') * cos((90-' . $latField . ') * 3.14159 / 180) + sin(' . $b1_rad . ') * sin((90-' . $latField . ') * 3.14159 / 180) * cos((' . $l1_deg . '-' . $lonField . ') * 3.14159 / 180)) * ' . $r;
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
static function getMaxLat($lon, $lat, $distance, $distanceMultiplier=1)
|
||||
{
|
||||
return $lat + $distance / (111.12 * $distanceMultiplier);
|
||||
}
|
||||
|
||||
static function getMinLat($lon, $lat, $distance, $distanceMultiplier=1)
|
||||
{
|
||||
return $lat - $distance / (111.12 * $distanceMultiplier);
|
||||
}
|
||||
|
||||
static function getMaxLon($lon, $lat, $distance, $distanceMultiplier=1)
|
||||
{
|
||||
return $lon + $distance * 180 / (abs(sin((90 - $lat) * 3.14159 / 180 )) * 6378 * $distanceMultiplier * 3.14159);
|
||||
}
|
||||
|
||||
static function getMinLon($lon, $lat, $distance, $distanceMultiplier=1)
|
||||
{
|
||||
return $lon - $distance * 180 / (abs(sin((90 - $lat) * 3.14159 / 180 )) * 6378 * $distanceMultiplier * 3.14159);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
class gis
|
||||
{
|
||||
static function ptInLineRing($sGeometry, $sPoint)
|
||||
{
|
||||
// thanks to Roger Boily, Gis Consulant
|
||||
// posted at http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html
|
||||
|
||||
$counter = 0;
|
||||
// get rid of unnecessary stuff
|
||||
$sGeometry = str_replace("LINESTRING", "", $sGeometry);
|
||||
$sGeometry = str_replace("(", "", $sGeometry);
|
||||
$sGeometry = str_replace(")", "", $sGeometry);
|
||||
$sPoint = str_replace("POINT", "", $sPoint);
|
||||
$sPoint = str_replace("(", "", $sPoint);
|
||||
$sPoint = str_replace(")", "", $sPoint);
|
||||
|
||||
// make an array of points of the polygon
|
||||
$polygon = explode(",", $sGeometry);
|
||||
|
||||
// get the x and y coordinate of the point
|
||||
$p = explode(" ", $sPoint);
|
||||
$px = $p[0];
|
||||
$py = $p[1];
|
||||
|
||||
// number of points in the polygon
|
||||
$n = count($polygon);
|
||||
$poly1 = $polygon[0];
|
||||
for ($i=1; $i <= $n; $i++)
|
||||
{
|
||||
$poly1XY = explode(" ",$poly1);
|
||||
$poly1x = $poly1XY[0];
|
||||
$poly1y = $poly1XY[1];
|
||||
$poly2 = $polygon[$i % $n];
|
||||
$poly2XY = explode(" ",$poly2);
|
||||
$poly2x = $poly2XY[0];
|
||||
$poly2y = $poly2XY[1];
|
||||
|
||||
if ($py > min($poly1y,$poly2y))
|
||||
{
|
||||
if ($py <= max($poly1y,$poly2y))
|
||||
{
|
||||
if ($px <= max($poly1x,$poly2x))
|
||||
{
|
||||
if ($poly1y != $poly2y)
|
||||
{
|
||||
$xinters = ($py-$poly1y)*($poly2x-$poly1x)/($poly2y-$poly1y)+$poly1x;
|
||||
if ($poly1x == $poly2x || $px <= $xinters)
|
||||
{
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$poly1 = $poly2;
|
||||
} // end of While each polygon
|
||||
|
||||
if ($counter % 2 == 0)
|
||||
{
|
||||
return(false); // outside
|
||||
}
|
||||
else
|
||||
{
|
||||
return(true); // inside
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
// try to include cache file
|
||||
if (!file_exists($opt['rootpath'] . 'cache2/labels-' . $opt['template']['locale'] . '.inc.php'))
|
||||
labels::CreateCacheFile();
|
||||
|
||||
require($opt['rootpath'] . 'cache2/labels-' . $opt['template']['locale'] . '.inc.php');
|
||||
|
||||
class labels
|
||||
{
|
||||
static $aLabels = array();
|
||||
|
||||
static function CreateCacheFile()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$f = fopen($opt['rootpath'] . 'cache2/labels-' . $opt['template']['locale'] . '.inc.php', 'w');
|
||||
fwrite($f, "<?php\n");
|
||||
|
||||
$a = array();
|
||||
$rs = sql("SELECT `cache_attrib`.`id`, IFNULL(`sys_trans_text`.`text`, `cache_attrib`.`name`) AS `name`
|
||||
FROM `cache_attrib`
|
||||
LEFT JOIN `sys_trans` ON `cache_attrib`.`trans_id`=`sys_trans`.`id` AND `cache_attrib`.`name`=`sys_trans`.`text`
|
||||
LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1'",
|
||||
$opt['template']['locale']);
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$a[$r['id']] = $r['name'];
|
||||
sql_free_result($rs);
|
||||
fwrite($f, 'labels::addLabels("cache_attrib", "' . str_replace('"', '\\"', serialize($a)) . '");' . "\n");
|
||||
|
||||
$a = array();
|
||||
$rs = sql("SELECT `cache_size`.`id`, IFNULL(`sys_trans_text`.`text`, `cache_size`.`name`) AS `name`
|
||||
FROM `cache_size`
|
||||
LEFT JOIN `sys_trans` ON `cache_size`.`trans_id`=`sys_trans`.`id` AND `cache_size`.`name`=`sys_trans`.`text`
|
||||
LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1'",
|
||||
$opt['template']['locale']);
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$a[$r['id']] = $r['name'];
|
||||
sql_free_result($rs);
|
||||
fwrite($f, 'labels::addLabels("cache_size", "' . str_replace('"', '\\"', serialize($a)) . '");' . "\n");
|
||||
|
||||
$a = array();
|
||||
$rs = sql("SELECT `cache_status`.`id`, IFNULL(`sys_trans_text`.`text`, `cache_status`.`name`) AS `name`
|
||||
FROM `cache_status`
|
||||
LEFT JOIN `sys_trans` ON `cache_status`.`trans_id`=`sys_trans`.`id` AND `cache_status`.`name`=`sys_trans`.`text`
|
||||
LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1'",
|
||||
$opt['template']['locale']);
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$a[$r['id']] = $r['name'];
|
||||
sql_free_result($rs);
|
||||
fwrite($f, 'labels::addLabels("cache_status", "' . str_replace('"', '\\"', serialize($a)) . '");' . "\n");
|
||||
|
||||
$a = array();
|
||||
$rs = sql("SELECT `cache_type`.`id`, IFNULL(`sys_trans_text`.`text`, `cache_type`.`name`) AS `name`
|
||||
FROM `cache_type`
|
||||
LEFT JOIN `sys_trans` ON `cache_type`.`trans_id`=`sys_trans`.`id` AND `cache_type`.`name`=`sys_trans`.`text`
|
||||
LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1'",
|
||||
$opt['template']['locale']);
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$a[$r['id']] = $r['name'];
|
||||
sql_free_result($rs);
|
||||
fwrite($f, 'labels::addLabels("cache_type", "' . str_replace('"', '\\"', serialize($a)) . '");' . "\n");
|
||||
|
||||
$a = array();
|
||||
$rs = sql("SELECT `log_types`.`id`, IFNULL(`sys_trans_text`.`text`, `log_types`.`name`) AS `name`
|
||||
FROM `log_types`
|
||||
LEFT JOIN `sys_trans` ON `log_types`.`trans_id`=`sys_trans`.`id` AND `log_types`.`name`=`sys_trans`.`text`
|
||||
LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1'",
|
||||
$opt['template']['locale']);
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$a[$r['id']] = $r['name'];
|
||||
sql_free_result($rs);
|
||||
fwrite($f, 'labels::addLabels("log_types", "' . str_replace('"', '\\"', serialize($a)) . '");' . "\n");
|
||||
|
||||
$nLastGroup = 1;
|
||||
$a = array();
|
||||
$rs = sql("SELECT `countries_options`.`country`,
|
||||
IF(`countries_options`.`nodeId`='&1', 1, IF(`countries_options`.`nodeId`!=0, 2, 3)) AS `group`,
|
||||
IFNULL(`sys_trans_text`.`text`, `countries`.`name`) AS `name`
|
||||
FROM `countries_options`
|
||||
INNER JOIN `countries` ON `countries_options`.`country`=`countries`.`short`
|
||||
LEFT JOIN `sys_trans` ON `countries`.`trans_id`=`sys_trans`.`id`
|
||||
LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&2'
|
||||
WHERE `countries_options`.`display`=1
|
||||
ORDER BY `group` ASC,
|
||||
IFNULL(`sys_trans_text`.`text`, `countries`.`name`) ASC",
|
||||
$opt['logic']['node']['id'], $opt['template']['locale']);
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
{
|
||||
$r['begin_group'] = ($r['group'] != $nLastGroup);
|
||||
$nLastGroup = $r['group'];
|
||||
|
||||
$a[] = $r;
|
||||
}
|
||||
sql_free_result($rs);
|
||||
fwrite($f, 'labels::addLabels("usercountrieslist", "' . str_replace('"', '\\"', serialize($a)) . '");' . "\n");
|
||||
|
||||
fwrite($f, "?>");
|
||||
fclose($f);
|
||||
}
|
||||
|
||||
static function addLabels($name, $serialized)
|
||||
{
|
||||
self::$aLabels[$name] = unserialize($serialized);
|
||||
}
|
||||
|
||||
static function getLabels($name)
|
||||
{
|
||||
if (isset(self::$aLabels[$name]))
|
||||
return self::$aLabels[$name];
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static function getLabelValue($name, $id)
|
||||
{
|
||||
if (isset(self::$aLabels[$name]))
|
||||
if (isset(self::$aLabels[$name][$id]))
|
||||
return self::$aLabels[$name][$id];
|
||||
else
|
||||
return false;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* check if the mailserver returns an 550 or 553 code
|
||||
***************************************************************************/
|
||||
|
||||
define('CA_OK', 0);
|
||||
define('CA_ERROR_TEMPORARY', 1);
|
||||
define('CA_ERROR_USER_UNKOWN', 2);
|
||||
define('CA_ERROR_CONNECT', 3);
|
||||
define('CA_ERROR_ADDRESS_INVALID', 4);
|
||||
define('CA_ERROR_UNKOWN', 5);
|
||||
|
||||
class mailcheck
|
||||
{
|
||||
var $sHostname = 'somehost.org';
|
||||
var $sFrom = 'postmaster@somehost.org';
|
||||
|
||||
var $nConnectTimeout = 15; // (sec)
|
||||
var $nReadTimeout = 25; // (sec)
|
||||
|
||||
/* check if the mailserver of $sAddress
|
||||
* explicit says that the user does not exist
|
||||
*
|
||||
* CA_OK ... mailserver has been connected and he does not say that the account does not exist
|
||||
* CA_ERROR_TEMPORARY ... mailserver rejected with 4xx code (temporary failure)
|
||||
* CA_ERROR_USER_UNKOWN ... mailserver said that user mailbox does not exist (550 or 553)
|
||||
* CA_ERROR_CONNECT ... mailserver(s) could not be connected
|
||||
* CA_ERROR_ADDRESS_INVALID ... E-Mail format not valid
|
||||
* CA_ERROR_UNKOWN ... any other error
|
||||
*/
|
||||
function checkAddress($sAddress)
|
||||
{
|
||||
if (!is_valid_email_address($sAddress))
|
||||
return CA_ERROR_ADDRESS_INVALID;
|
||||
|
||||
/* get MX records
|
||||
*/
|
||||
$sDomain = substr($sAddress, strpos($sAddress, '@') + 1);
|
||||
if (getmxrr($sDomain, $mx_records, $mx_weight) == false)
|
||||
{
|
||||
$mx_records = array($sDomain);
|
||||
$mx_weight = array(0);
|
||||
}
|
||||
|
||||
// sort MX records
|
||||
$mxs = array();
|
||||
for ($i = 0; $i < count($mx_records); $i++)
|
||||
$mxs[$i] = array('mx' => $mx_records[$i], 'prio' => $mx_weight[$i]);
|
||||
usort($mxs, "mailcheck_cmp");
|
||||
reset($mxs);
|
||||
|
||||
// check address with each MX until one mailserver can be connected
|
||||
for ($i = 0; $i < count($mxs); $i++)
|
||||
{
|
||||
$retval = $this->pCheckAddress($sAddress, $mxs[$i]['mx']);
|
||||
if ($retval != CA_ERROR_CONNECT)
|
||||
return $retval;
|
||||
}
|
||||
|
||||
return CA_ERROR_CONNECT;
|
||||
}
|
||||
|
||||
|
||||
/* check if the specified mailserver
|
||||
* explicit says that the $sAddress does not exist
|
||||
*
|
||||
* CA_OK ... mailserver has been connected and he does not say that the account does not exist
|
||||
* CA_ERROR_TEMPORARY ... mailserver rejected with 4xx code (temporary failure)
|
||||
* CA_ERROR_USER_UNKOWN ... mailserver said that user mailbox does not exist (550 or 553)
|
||||
* CA_ERROR_CONNECT ... mailserver(s) could not be connected
|
||||
* CA_ERROR_ADDRESS_INVALID ... E-Mail format not valid
|
||||
* CA_ERROR_UNKOWN ... any other error
|
||||
*/
|
||||
function pCheckAddress($sAddress, $sMailserver)
|
||||
{
|
||||
if (!is_valid_email_address($sAddress))
|
||||
return CA_ERROR_ADDRESS_INVALID;
|
||||
|
||||
$fp = @fsockopen($sMailserver, 25, $errno, $errstr, $this->nConnectTimeout);
|
||||
if (!$fp)
|
||||
return CA_ERROR_CONNECT;
|
||||
|
||||
$sResp = $this->send_command($fp, "HELO " . $this->sHostname);
|
||||
$sCode = $this->extract_return_code($sResp);
|
||||
if ($sCode != '220')
|
||||
{
|
||||
$this->close($fp);
|
||||
return CA_ERROR_UNKOWN;
|
||||
}
|
||||
|
||||
$sResp = $this->send_command($fp, "MAIL FROM: <" . $this->sFrom . ">");
|
||||
$sCode = $this->extract_return_code($sResp);
|
||||
if ($sCode != '250')
|
||||
{
|
||||
$this->close($fp);
|
||||
return CA_ERROR_UNKOWN;
|
||||
}
|
||||
|
||||
$sResp = $this->send_command($fp, "RCPT TO: <" . $sAddress . ">");
|
||||
$sCode = $this->extract_return_code($sResp);
|
||||
if (strlen($sCode) == 3 && substr($sCode, 0, 1) == '4')
|
||||
{
|
||||
$this->close($fp);
|
||||
return CA_ERROR_TEMPORARY;
|
||||
}
|
||||
else if ($sCode == '553' && $sCode == '550')
|
||||
{
|
||||
$this->close($fp);
|
||||
return CA_ERROR_USER_UNKOWN;
|
||||
}
|
||||
else if ($sCode == '250')
|
||||
{
|
||||
$this->close($fp);
|
||||
return CA_OK;
|
||||
}
|
||||
|
||||
$this->close($fp);
|
||||
return CA_ERROR_UNKOWN;
|
||||
}
|
||||
|
||||
function close($fp)
|
||||
{
|
||||
fwrite($fp, "QUIT\r\n");
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
function extract_return_code($sResp)
|
||||
{
|
||||
$nPos1 = strpos($sResp, ' ');
|
||||
$nPos2 = strpos($sResp, '-');
|
||||
|
||||
if ($nPos1 === false && $nPos2 === false)
|
||||
return $sResp;
|
||||
else if ($nPos1 === false)
|
||||
$nPos = $nPos2;
|
||||
else if ($nPos2 === false)
|
||||
$nPos = $nPos1;
|
||||
else
|
||||
{
|
||||
if ($nPos1 < $nPos2)
|
||||
$nPos = $nPos1;
|
||||
else
|
||||
$nPos = $nPos2;
|
||||
}
|
||||
|
||||
return substr($sResp, 0, $nPos);
|
||||
}
|
||||
|
||||
function send_command($fp, $out)
|
||||
{
|
||||
fwrite($fp, $out . "\r\n");
|
||||
return $this->get_data($fp);
|
||||
}
|
||||
|
||||
function get_data($fp)
|
||||
{
|
||||
$s = "";
|
||||
stream_set_timeout($fp, $this->nReadTimeout);
|
||||
|
||||
for ($i = 0; $i < 2; $i++)
|
||||
$s .= fgets($fp, 1024);
|
||||
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
function mailcheck_cmp($a, $b)
|
||||
{
|
||||
if ($a == $b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (($a['prio']+0) < ($b['prio']+0)) ? -1 : 1;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* get/set has to be commited with save
|
||||
* add/remove etc. is executed instantly
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/logic/rowEditor.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/const.inc.php');
|
||||
|
||||
class picture
|
||||
{
|
||||
var $nPictureId = 0;
|
||||
var $rePicture;
|
||||
var $sFileExtension = '';
|
||||
var $bFilenamesSet = false;
|
||||
|
||||
static function pictureIdFromUUID($uuid)
|
||||
{
|
||||
$pictureid = sql_value("SELECT `id` FROM `pictures` WHERE `uuid`='&1'", 0, $uuid);
|
||||
return $pictureid;
|
||||
}
|
||||
|
||||
static function fromUUID($uuid)
|
||||
{
|
||||
$pictureid = picture::pictureIdFromUUID($uuid);
|
||||
if ($pictureid == 0)
|
||||
return null;
|
||||
|
||||
return new picture($pictureid);
|
||||
}
|
||||
|
||||
function __construct($nNewPictureId=ID_NEW)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$this->rePicture = new rowEditor('pictures');
|
||||
$this->rePicture->addPKInt('id', null, false, RE_INSERT_AUTOINCREMENT);
|
||||
$this->rePicture->addString('uuid', '', false);
|
||||
$this->rePicture->addInt('node', 0, false);
|
||||
$this->rePicture->addDate('date_created', time(), true, RE_INSERT_IGNORE);
|
||||
$this->rePicture->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
|
||||
$this->rePicture->addString('url', '', false);
|
||||
$this->rePicture->addString('title', '', false);
|
||||
$this->rePicture->addDate('last_url_check', 0, true);
|
||||
$this->rePicture->addInt('object_id', null, false);
|
||||
$this->rePicture->addInt('object_type', null, false);
|
||||
$this->rePicture->addString('thumb_url', '', false);
|
||||
$this->rePicture->addDate('thumb_last_generated', 0, false);
|
||||
$this->rePicture->addInt('spoiler', 0, false);
|
||||
$this->rePicture->addInt('local', 0, false);
|
||||
$this->rePicture->addInt('unknown_format', 0, false);
|
||||
$this->rePicture->addInt('display', 1, false);
|
||||
|
||||
$this->nPictureId = $nNewPictureId+0;
|
||||
|
||||
if ($nNewPictureId == ID_NEW)
|
||||
{
|
||||
$this->rePicture->addNew(null);
|
||||
|
||||
$sUUID = mb_strtoupper(sql_value("SELECT UUID()", ''));
|
||||
$this->rePicture->setValue('uuid', $sUUID);
|
||||
$this->rePicture->setValue('node', $opt['logic']['node']['id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->rePicture->load($this->nPictureId);
|
||||
|
||||
$sFilename = $this->getFilename();
|
||||
$fna = mb_split('\\.', $sFilename);
|
||||
$this->sFileExtension = mb_strtolower($fna[count($fna) - 1]);
|
||||
|
||||
$this->bFilenamesSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
function exist()
|
||||
{
|
||||
return $this->rePicture->exist();
|
||||
}
|
||||
|
||||
static function allowedExtension($sFilename)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if (strpos($sFilename, ';') !== false)
|
||||
return false;
|
||||
if (strpos($sFilename, '.') === false)
|
||||
return false;
|
||||
|
||||
$sExtension = mb_strtolower(substr($sFilename, strrpos($sFilename, '.') + 1));
|
||||
|
||||
if (strpos(';' . $opt['logic']['pictures']['extensions'] . ';', ';' . $sExtension . ';') !== false)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function setFilenames($sFilename)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($this->bFilenamesSet == true)
|
||||
return;
|
||||
if (strpos($sFilename, '.') === false)
|
||||
return;
|
||||
$sExtension = mb_strtolower(substr($sFilename, strrpos($sFilename, '.') + 1));
|
||||
|
||||
$sUUID = $this->getUUID();
|
||||
|
||||
$this->sFileExtension = $sExtension;
|
||||
$this->setUrl($opt['logic']['pictures']['url'] . $sUUID . '.' . $sExtension);
|
||||
//$this->setThumbUrl($opt['logic']['pictures']['thumb_url'] . substr($sUUID, 0, 1) . '/' . substr($sUUID, 1, 1) . '/' . $sUUID . '.' . $sExtension);
|
||||
$this->bFilenamesSet = true;
|
||||
}
|
||||
|
||||
function getPictureId()
|
||||
{
|
||||
return $this->nPictureId;
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
// delete record, image and thumb
|
||||
@unlink($this->getFilename());
|
||||
@unlink($this->getThumbFilename());
|
||||
|
||||
sql("DELETE FROM `pictures` WHERE `id`='&1'", $this->nPictureId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getUrl()
|
||||
{
|
||||
return $this->rePicture->getValue('url');
|
||||
}
|
||||
function setUrl($value)
|
||||
{
|
||||
return $this->rePicture->setValue('url', $value);
|
||||
}
|
||||
function getThumbUrl()
|
||||
{
|
||||
return $this->rePicture->getValue('thumb_url');
|
||||
}
|
||||
function setThumbUrl($value)
|
||||
{
|
||||
return $this->rePicture->setValue('thumb_url', $value);
|
||||
}
|
||||
function getTitle()
|
||||
{
|
||||
return $this->rePicture->getValue('title');
|
||||
}
|
||||
function setTitle($value)
|
||||
{
|
||||
if ($value != '')
|
||||
return $this->rePicture->setValue('title', $value);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
function getSpoiler()
|
||||
{
|
||||
return $this->rePicture->getValue('spoiler')!=0;
|
||||
}
|
||||
function setSpoiler($value)
|
||||
{
|
||||
return $this->rePicture->setValue('spoiler', $value ? 1 : 0);
|
||||
}
|
||||
function getLocal()
|
||||
{
|
||||
return $this->rePicture->getValue('local')!=0;
|
||||
}
|
||||
function setLocal($value)
|
||||
{
|
||||
return $this->rePicture->setValue('local', $value ? 1 : 0);
|
||||
}
|
||||
function getDisplay()
|
||||
{
|
||||
return $this->rePicture->getValue('display')!=0;
|
||||
}
|
||||
function setDisplay($value)
|
||||
{
|
||||
return $this->rePicture->setValue('display', $value ? 1 : 0);
|
||||
}
|
||||
function getFilename()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if (mb_substr($opt['logic']['pictures']['dir'], -1, 1) != '/')
|
||||
$opt['logic']['pictures']['dir'] .= '/';
|
||||
|
||||
$uuid = $this->getUUID();
|
||||
$url = $this->getUrl();
|
||||
$fna = mb_split('\\.', $url);
|
||||
$extension = mb_strtolower($fna[count($fna) - 1]);
|
||||
|
||||
return $opt['logic']['pictures']['dir'] . $uuid . '.' . $extension;
|
||||
}
|
||||
function getThumbFilename()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if (mb_substr($opt['logic']['pictures']['thumb_dir'], -1, 1) != '/')
|
||||
$opt['logic']['pictures']['thumb_dir'] .= '/';
|
||||
|
||||
$uuid = $this->getUUID();
|
||||
$url = $this->getUrl();
|
||||
$fna = mb_split('\\.', $url);
|
||||
$extension = mb_strtolower($fna[count($fna) - 1]);
|
||||
|
||||
$dir1 = mb_strtoupper(mb_substr($uuid, 0, 1));
|
||||
$dir2 = mb_strtoupper(mb_substr($uuid, 1, 1));
|
||||
|
||||
return $opt['logic']['pictures']['thumb_dir'] . $dir1 . '/' . $dir2 . '/' . $uuid . '.' . $extension;
|
||||
}
|
||||
function getLogId()
|
||||
{
|
||||
if ($this->getObjectType() == OBJECT_CACHELOG)
|
||||
return $this->getObjectId();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
function getCacheId()
|
||||
{
|
||||
if ($this->getObjectType() == OBJECT_CACHELOG)
|
||||
return sql_value("SELECT `cache_id` FROM `cache_logs` WHERE `id`='&1'", false, $this->getObjectId());
|
||||
else if ($this->getObjectType() == OBJECT_CACHE)
|
||||
return $this->getObjectId();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
function getObjectId()
|
||||
{
|
||||
return $this->rePicture->getValue('object_id');
|
||||
}
|
||||
function setObjectId($value)
|
||||
{
|
||||
return $this->rePicture->setValue('object_id', $value+0);
|
||||
}
|
||||
function getObjectType()
|
||||
{
|
||||
return $this->rePicture->getValue('object_type');
|
||||
}
|
||||
function setObjectType($value)
|
||||
{
|
||||
return $this->rePicture->setValue('object_type', $value+0);
|
||||
}
|
||||
function getUserId()
|
||||
{
|
||||
if ($this->getObjectType() == OBJECT_CACHE)
|
||||
return sql_value("SELECT `caches`.`user_id` FROM `caches` WHERE `caches`.`cache_id`='&1'", false, $this->getObjectId());
|
||||
else if ($this->getObjectType() == OBJECT_CACHELOG)
|
||||
return sql_value("SELECT `cache_logs`.`user_id` FROM `cache_logs` WHERE `cache_logs`.`id`='&1'", false, $this->getObjectId());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function getNode()
|
||||
{
|
||||
return $this->rePicture->getValue('node');
|
||||
}
|
||||
function setNode($value)
|
||||
{
|
||||
return $this->rePicture->setValue('node', $value);
|
||||
}
|
||||
function getUUID()
|
||||
{
|
||||
return $this->rePicture->getValue('uuid');
|
||||
}
|
||||
function getLastModified()
|
||||
{
|
||||
return $this->rePicture->getValue('last_modified');
|
||||
}
|
||||
function getDateCreated()
|
||||
{
|
||||
return $this->rePicture->getValue('date_created');
|
||||
}
|
||||
function getAnyChanged()
|
||||
{
|
||||
return $this->rePicture->getAnyChanged();
|
||||
}
|
||||
|
||||
// return if successfull (with insert)
|
||||
function save()
|
||||
{
|
||||
if ($this->bFilenamesSet == false)
|
||||
return false;
|
||||
|
||||
$bRetVal = $this->rePicture->save();
|
||||
|
||||
if ($bRetVal)
|
||||
sql_slave_exclude();
|
||||
|
||||
return $bRetVal;
|
||||
}
|
||||
|
||||
function allowEdit()
|
||||
{
|
||||
global $login;
|
||||
|
||||
$login->verify();
|
||||
|
||||
if (sql_value("SELECT COUNT(*) FROM `caches` INNER JOIN `cache_status` ON `caches`.`status`=`cache_status`.`id` WHERE (`cache_status`.`allow_user_view`=1 OR `caches`.`user_id`='&1') AND `caches`.`cache_id`='&2'", 0, $login->userid, $this->getCacheId()) == 0)
|
||||
return false;
|
||||
else if ($this->getUserId() == $login->userid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,552 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
class rowEditor
|
||||
{
|
||||
var $sTable;
|
||||
var $sAutoIncrementField = null;
|
||||
var $pk; // (idx:name; type, default, nullable, value, insertfunction)
|
||||
var $fields; // (idx:name; type, default, nullable, value, changed, insertfunction)
|
||||
|
||||
// status var
|
||||
var $bLoaded = false;
|
||||
var $bExist = false;
|
||||
var $bAddNew = false;
|
||||
|
||||
/* primaryKey may be an array
|
||||
*/
|
||||
function __construct($sTable)
|
||||
{
|
||||
$this->pk = array();
|
||||
$this->fields = array();
|
||||
$this->sTable = $sTable;
|
||||
}
|
||||
|
||||
function addPKInt($sField, $nDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->pk[$sField] = array('type' => RE_TYPE_INT,
|
||||
'default' => $nDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $nDefault,
|
||||
'insertfunction' => $nInsertFunction);
|
||||
|
||||
if (($nInsertFunction & RE_INSERT_AUTOINCREMENT) == RE_INSERT_AUTOINCREMENT)
|
||||
$this->sAutoIncrementField = $sField;
|
||||
}
|
||||
|
||||
function addPKFloat($sField, $nDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->pk[$sField] = array('type' => RE_TYPE_FLOAT,
|
||||
'default' => $nDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $nDefault,
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addPKDouble($sField, $nDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->pk[$sField] = array('type' => RE_TYPE_DOUBLE,
|
||||
'default' => $nDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $nDefault,
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addPKString($sField, $sDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->pk[$sField] = array('type' => RE_TYPE_STRING,
|
||||
'default' => $sDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $sDefault,
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addPKBoolean($sField, $bDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->pk[$sField] = array('type' => RE_TYPE_BOOLEAN,
|
||||
'default' => $bDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $bDefault,
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addPKDate($sField, $dDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->pk[$sField] = array('type' => RE_TYPE_DATE,
|
||||
'default' => $dDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $dDefault,
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addInt($sField, $nDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->fields[$sField] = array('type' => RE_TYPE_INT,
|
||||
'default' => $nDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $nDefault,
|
||||
'changed => false',
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addFloat($sField, $nDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->fields[$sField] = array('type' => RE_TYPE_FLOAT,
|
||||
'default' => $nDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $nDefault,
|
||||
'changed => false',
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addDouble($sField, $nDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->fields[$sField] = array('type' => RE_TYPE_DOUBLE,
|
||||
'default' => $nDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $nDefault,
|
||||
'changed => false',
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addString($sField, $sDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->fields[$sField] = array('type' => RE_TYPE_STRING,
|
||||
'default' => $sDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $sDefault,
|
||||
'changed => false',
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addBoolean($sField, $bDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->fields[$sField] = array('type' => RE_TYPE_BOOLEAN,
|
||||
'default' => $bDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $bDefault,
|
||||
'changed => false',
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function addDate($sField, $dDefault, $bNullable, $nInsertFunction=RE_INSERT_NOTHING)
|
||||
{
|
||||
$this->fields[$sField] = array('type' => RE_TYPE_DATE,
|
||||
'default' => $dDefault,
|
||||
'nullable' => $bNullable,
|
||||
'value' => $dDefault,
|
||||
'changed => false',
|
||||
'insertfunction' => $nInsertFunction);
|
||||
}
|
||||
|
||||
function removePK($sField)
|
||||
{
|
||||
unset($this->pk[$sField]);
|
||||
}
|
||||
|
||||
function removeField($sField)
|
||||
{
|
||||
unset($this->fields[$sField]);
|
||||
}
|
||||
|
||||
/* PKValues may be an string, indized or ordered array
|
||||
*/
|
||||
function load($PKValues)
|
||||
{
|
||||
$this->pSetPK($PKValues);
|
||||
|
||||
$this->bLoaded = true;
|
||||
$this->bAddNew = false;
|
||||
$this->bExist = false;
|
||||
|
||||
$rs = sql($this->pBuildSelect());
|
||||
if (!$r = sql_fetch_assoc($rs))
|
||||
{
|
||||
$this->bExist = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// assign values
|
||||
foreach ($this->fields AS $k => $field)
|
||||
{
|
||||
$this->fields[$k]['value'] = $this->pFormatValue($this->fields[$k]['type'], $r[$k]);
|
||||
$this->fields[$k]['changed'] = false;
|
||||
}
|
||||
|
||||
$this->bExist = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function addNew($PKValues)
|
||||
{
|
||||
$this->pSetPK($PKValues);
|
||||
|
||||
$this->bLoaded = true;
|
||||
$this->bExist = false;
|
||||
$this->bAddNew = true;
|
||||
}
|
||||
|
||||
function exist()
|
||||
{
|
||||
return $this->bExist;
|
||||
}
|
||||
|
||||
function pSetPK($PKValues)
|
||||
{
|
||||
$this->pResetValues();
|
||||
|
||||
foreach ($this->pk AS $k => $field)
|
||||
{
|
||||
$this->pk[$k]['value'] = $field['default'];
|
||||
}
|
||||
|
||||
if (is_array($PKValues))
|
||||
{
|
||||
foreach ($PKValues AS $k => $v)
|
||||
{
|
||||
$pkKey = $this->pGetPKKey($k);
|
||||
$this->pk[$pkKey]['value'] = $this->pFormatValue($this->pk[$pkKey]['type'], $v);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$pkKey = $this->pGetPKKey(0);
|
||||
$this->pk[$pkKey]['value'] = $this->pFormatValue($this->pk[$pkKey]['type'], $PKValues);
|
||||
}
|
||||
}
|
||||
|
||||
function pGetPKKey($index)
|
||||
{
|
||||
if (isset($this->pk[$index]))
|
||||
return $index;
|
||||
|
||||
$i = 0;
|
||||
foreach ($this->pk AS $k => $v)
|
||||
{
|
||||
if ($i == $index)
|
||||
return $k;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
function pResetValues()
|
||||
{
|
||||
foreach ($this->fields AS $k => $field)
|
||||
{
|
||||
$this->fields[$k]['value'] = $field['default'];
|
||||
$this->fields[$k]['changed'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
function pFormatValue($type, $value)
|
||||
{
|
||||
if ($value === null)
|
||||
return null;
|
||||
|
||||
if ($type == RE_TYPE_INT)
|
||||
$value = (int)$value+0;
|
||||
else if ($type == RE_TYPE_FLOAT)
|
||||
$value = $value+0;
|
||||
else if ($type == RE_TYPE_DOUBLE)
|
||||
$value = $value+0;
|
||||
else if ($type == RE_TYPE_BOOLEAN)
|
||||
$value = (($value+0) != 0);
|
||||
else if ($type == RE_TYPE_DATE)
|
||||
{
|
||||
if (!is_numeric($value))
|
||||
$value = strtotime($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
function pFormatValueSql($type, $value)
|
||||
{
|
||||
if ($type == RE_TYPE_INT)
|
||||
$value = (int)$value+0;
|
||||
else if ($type == RE_TYPE_FLOAT)
|
||||
$value = $value+0;
|
||||
else if ($type == RE_TYPE_DOUBLE)
|
||||
$value = $value+0;
|
||||
else if ($type == RE_TYPE_BOOLEAN)
|
||||
$value = (($value+0) != 0) ? 1 : 0;
|
||||
else if ($type == RE_TYPE_DATE)
|
||||
{
|
||||
if (!is_numeric($value))
|
||||
$value = strtotime($value);
|
||||
|
||||
$value = strftime(DB_DATE_FORMAT, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
function pBuildSelect()
|
||||
{
|
||||
$fselect = array();
|
||||
$sql = 'SELECT ';
|
||||
foreach ($this->fields AS $k => $field)
|
||||
{
|
||||
$fselect[] = '`' . sql_escape($k) . '`';
|
||||
}
|
||||
$sql .= join(', ', $fselect);
|
||||
|
||||
$sql .= ' FROM `' . sql_escape($this->sTable) . '`';
|
||||
$sql .= ' WHERE ' . $this->pBuildPK();
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function pBuildPK()
|
||||
{
|
||||
$fwhere = array();
|
||||
foreach ($this->pk AS $k => $field)
|
||||
{
|
||||
if ($field['value'] === null)
|
||||
$fwhere[] = 'ISNULL(`' . sql_escape($k) . '`)';
|
||||
else
|
||||
$fwhere[] = '`' . sql_escape($k) . '`=\'' . sql_escape($field['value']) . '\'';
|
||||
}
|
||||
return join(' AND ', $fwhere);
|
||||
}
|
||||
|
||||
function getValue($sField)
|
||||
{
|
||||
if (isset($this->pk[$sField]))
|
||||
return $this->pk[$sField]['value'];
|
||||
|
||||
return $this->fields[$sField]['value'];
|
||||
}
|
||||
|
||||
function getDefault($sField)
|
||||
{
|
||||
return $this->fields[$sField]['default'];
|
||||
}
|
||||
|
||||
function getChanged($sField)
|
||||
{
|
||||
return $this->fields[$sField]['changed'];
|
||||
}
|
||||
|
||||
function getAnyChanged()
|
||||
{
|
||||
foreach ($this->fields AS $field)
|
||||
if ($field['changed'] == true)
|
||||
return true;
|
||||
}
|
||||
|
||||
function setValue($sField, $sValue)
|
||||
{
|
||||
if ($this->bLoaded == false || ($this->bAddNew == false && $this->bExist == false))
|
||||
return false;
|
||||
|
||||
$sFormatedValue = $this->pFormatValue($this->fields[$sField]['type'], $sValue);
|
||||
if ($this->fields[$sField]['value'] != $sFormatedValue)
|
||||
{
|
||||
$this->fields[$sField]['value'] = $sFormatedValue;
|
||||
$this->fields[$sField]['changed'] = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function save()
|
||||
{
|
||||
if ($this->bLoaded == false || ($this->bAddNew == false && $this->bExist == false))
|
||||
return false;
|
||||
|
||||
if ($this->bAddNew == true)
|
||||
{
|
||||
// INSERT
|
||||
$sql = $this->pBuildInsert();
|
||||
|
||||
if ($sql != '')
|
||||
{
|
||||
sql($sql);
|
||||
if (sql_affected_rows() == 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
if ($this->sAutoIncrementField != null)
|
||||
{
|
||||
$nInsertId = sql_insert_id();
|
||||
|
||||
$this->pk[$this->sAutoIncrementField]['value'] = $nInsertId;
|
||||
|
||||
if (isset($this->fields[$this->sAutoIncrementField]))
|
||||
$this->fields[$this->sAutoIncrementField]['value'] = $nInsertId;
|
||||
}
|
||||
|
||||
$pkv = array();
|
||||
foreach ($this->pk AS $k => $v)
|
||||
{
|
||||
$pkv[$k] = $this->pk[$k]['value'];
|
||||
}
|
||||
$this->load($pkv);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// UPDATE
|
||||
$sql = $this->pBuildUpdate();
|
||||
|
||||
if ($sql != '')
|
||||
{
|
||||
$rs = sql($sql);
|
||||
if (sql_affected_rows($rs) == 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
foreach ($this->fields AS $k => $field)
|
||||
{
|
||||
$this->fields[$k]['changed'] = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function reload()
|
||||
{
|
||||
$pkv = array();
|
||||
foreach ($this->pk AS $k => $v)
|
||||
{
|
||||
$pkv[$k] = $this->pk[$k]['value'];
|
||||
}
|
||||
$this->load($pkv);
|
||||
}
|
||||
|
||||
function pBuildInsert()
|
||||
{
|
||||
$sql = 'INSERT IGNORE INTO `' . sql_escape($this->sTable) . '` (';
|
||||
|
||||
$sFields = array();
|
||||
$sValues = array();
|
||||
|
||||
foreach ($this->pk AS $k => $field)
|
||||
{
|
||||
if (isset($this->fields[$k]))
|
||||
continue;
|
||||
|
||||
if ($this->sAutoIncrementField == $k)
|
||||
continue;
|
||||
|
||||
if (($field['insertfunction'] & RE_INSERT_IGNORE) == RE_INSERT_IGNORE)
|
||||
continue;
|
||||
|
||||
$sFields[] = '`' . sql_escape($k) . '`';
|
||||
|
||||
if ((($field['insertfunction'] & RE_INSERT_OVERWRITE) == RE_INSERT_OVERWRITE) || (($field['changed'] == false) && ($field['insertfunction'] != RE_INSERT_NOTHING)))
|
||||
{
|
||||
if (($field['insertfunction'] & RE_INSERT_UUID) == RE_INSERT_UUID)
|
||||
$sValues[] = 'UUID()';
|
||||
else if (($field['insertfunction'] & RE_INSERT_NOW) == RE_INSERT_NOW)
|
||||
$sValues[] = 'NOW()';
|
||||
else
|
||||
$sValues[] = 'NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($field['value'] === null)
|
||||
$sValues[] = 'NULL';
|
||||
else
|
||||
$sValues[] = '\'' . sql_escape($this->pFormatValueSql($field['type'], $field['value'])) . '\'';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->fields AS $k => $field)
|
||||
{
|
||||
if (($field['insertfunction'] & RE_INSERT_IGNORE) == RE_INSERT_IGNORE)
|
||||
continue;
|
||||
|
||||
$sFields[] = '`' . sql_escape($k) . '`';
|
||||
|
||||
if ((($field['insertfunction'] & RE_INSERT_OVERWRITE) == RE_INSERT_OVERWRITE) || (($field['changed'] == false) && ($field['insertfunction'] != RE_INSERT_NOTHING)))
|
||||
{
|
||||
if (($field['insertfunction'] & RE_INSERT_UUID) == RE_INSERT_UUID)
|
||||
$sValues[] = 'UUID()';
|
||||
else if (($field['insertfunction'] & RE_INSERT_NOW) == RE_INSERT_NOW)
|
||||
$sValues[] = 'NOW()';
|
||||
else
|
||||
$sValues[] = 'NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($field['value'] === null)
|
||||
$sValues[] = 'NULL';
|
||||
else
|
||||
$sValues[] = '\'' . sql_escape($this->pFormatValueSql($field['type'], $field['value'])) . '\'';
|
||||
}
|
||||
}
|
||||
$sql .= join(', ', $sFields);
|
||||
$sql .= ') VALUES (';
|
||||
$sql .= join(', ', $sValues);
|
||||
$sql .= ')';
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function pBuildUpdate()
|
||||
{
|
||||
$sql = 'UPDATE IGNORE `' . sql_escape($this->sTable) . '` SET ';
|
||||
|
||||
$sSet = '';
|
||||
foreach ($this->fields AS $k => $field)
|
||||
{
|
||||
if ($field['changed'] == true)
|
||||
{
|
||||
if ($sSet != '') $sSet .= ', ';
|
||||
|
||||
if ($field['value'] === null)
|
||||
$sSet .= '`' . sql_escape($k) . '`=NULL';
|
||||
else
|
||||
$sSet .= '`' . sql_escape($k) . '`=\'' . sql_escape($this->pFormatValueSql($field['type'], $field['value'])) . '\'';
|
||||
}
|
||||
}
|
||||
|
||||
if ($sSet == '')
|
||||
return '';
|
||||
|
||||
$sql .= $sSet;
|
||||
$sql .= ' WHERE ';
|
||||
$sql .= $this->pBuildPK();
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function saveField($field)
|
||||
{
|
||||
if ($this->bLoaded == false || $this->bExist == false || $this->bAddNew == true)
|
||||
return false;
|
||||
|
||||
if ($this->fields[$field]['changed'] == false)
|
||||
return true;
|
||||
|
||||
if ($this->fields[$field]['value'] === null)
|
||||
$sSet = '`' . sql_escape($field) . '`=NULL';
|
||||
else
|
||||
$sSet = '`' . sql_escape($field) . '`=\'' . sql_escape($this->pFormatValueSql($this->fields[$field]['type'], $this->fields[$field]['value'])) . '\'';
|
||||
|
||||
$sql = 'UPDATE `' . sql_escape($this->sTable) . '` SET ' . $sSet;
|
||||
$sql .= ' WHERE ';
|
||||
$sql .= $this->pBuildPK();
|
||||
|
||||
sql($sql);
|
||||
if (sql_affected_rows() == 0)
|
||||
return false;
|
||||
|
||||
$this->fields[$field]['changed'] = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Generate sitemap.xml as specified by http://www.sitemaps.org
|
||||
* And send ping to search engines
|
||||
***************************************************************************/
|
||||
|
||||
class sitemapxml
|
||||
{
|
||||
var $sDefaultChangeFreq = 'monthly';
|
||||
var $nMaxFileSize = 9961472; // max file size, 10MB by specification
|
||||
var $nMaxUrlCount = 50000; // max number of URLs per file, 50000 by specification
|
||||
|
||||
var $sPath = '';
|
||||
var $sDomain = '';
|
||||
var $oIndexFile = false;
|
||||
var $nSitemapIndex = 0;
|
||||
var $oSitemapFile = false;
|
||||
var $nWrittenSize = 0;
|
||||
var $nWrittenCount = 0;
|
||||
|
||||
function open($sPath, $sDomain)
|
||||
{
|
||||
if (substr($sPath, -1, 1) != '/') $sPath .= '/';
|
||||
if (substr($sDomain, -1, 1) != '/') $sDomain .= '/';
|
||||
|
||||
$this->sPath = $sPath;
|
||||
$this->sDomain = $sDomain;
|
||||
|
||||
$this->oIndexFile = fopen($sPath . 'sitemap.xml', 'w');
|
||||
if ($this->oIndexFile === false)
|
||||
return false;
|
||||
|
||||
fwrite($this->oIndexFile, '<?xml version="1.0" encoding="UTF-8"?>' . "\n");
|
||||
fwrite($this->oIndexFile, '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');
|
||||
}
|
||||
|
||||
/* sChaneFreq = {always, hourly, daily, weekly, monthly, yearly, never}
|
||||
* nPriority = {0.0 to 1.0}
|
||||
*/
|
||||
function write($sFile, $dLastMod, $sChangeFreq=false, $nPriority=0.5)
|
||||
{
|
||||
if ($sChangeFreq == false)
|
||||
$sChangeFreq = $this->sDefaultChangeFreq;
|
||||
|
||||
$sXML = '<url>';
|
||||
$sXML .= '<loc>' . xmlentities($this->sDomain . $sFile) . '</loc>';
|
||||
$sXML .= '<lastmod>' . xmlentities(date('c', $dLastMod)) . '</lastmod>';
|
||||
$sXML .= '<changefreq>' . xmlentities($sChangeFreq) . '</changefreq>';
|
||||
$sXML .= '<priority>' . xmlentities($nPriority) . '</priority>';
|
||||
$sXML .= '</url>';
|
||||
|
||||
$this->writeInternal($sXML);
|
||||
}
|
||||
|
||||
function writeInternal($str)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
// close the last file?
|
||||
if (($this->oSitemapFile !== false) && (($this->nWrittenSize + strlen($str) > $this->nMaxFileSize) || ($this->nWrittenCount >= $this->nMaxUrlCount)))
|
||||
{
|
||||
gzwrite($this->oSitemapFile, '</urlset>');
|
||||
gzclose($this->oSitemapFile);
|
||||
$this->oSitemapFile = false;
|
||||
}
|
||||
|
||||
// open new XML file?
|
||||
if ($this->oSitemapFile === false)
|
||||
{
|
||||
$this->nSitemapIndex++;
|
||||
$sFilename = 'sitemap-' . $this->nSitemapIndex . '.xml.gz';
|
||||
$this->oSitemapFile = gzopen($this->sPath . $sFilename, 'wb');
|
||||
|
||||
fwrite($this->oIndexFile, '<sitemap><loc>' . xmlentities($this->sDomain . $sFilename) . '</loc><lastmod>' . xmlentities(date('c')) . '</lastmod></sitemap>');
|
||||
|
||||
gzwrite($this->oSitemapFile, '<?xml version="1.0" encoding="UTF-8"?>' . "\n");
|
||||
gzwrite($this->oSitemapFile, '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');
|
||||
// includes end of xml-tag
|
||||
$this->nWrittenSize = 108;
|
||||
$this->nWrittenCount = 0;
|
||||
}
|
||||
|
||||
// write string to XML
|
||||
gzwrite($this->oSitemapFile, $str);
|
||||
$this->nWrittenSize += strlen($str);
|
||||
$this->nWrittenCount++;
|
||||
}
|
||||
|
||||
function close()
|
||||
{
|
||||
if ($this->oSitemapFile !== false)
|
||||
{
|
||||
gzwrite($this->oSitemapFile, '</urlset>');
|
||||
gzclose($this->oSitemapFile);
|
||||
$this->oSitemapFile = false;
|
||||
}
|
||||
|
||||
if ($this->oIndexFile !== false)
|
||||
{
|
||||
fwrite($this->oIndexFile, '</sitemapindex>');
|
||||
fclose($this->oIndexFile);
|
||||
$this->oIndexFile = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
class smileys
|
||||
{
|
||||
static function getSmileysArray()
|
||||
{
|
||||
return array(
|
||||
array(true, " :) ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-smile.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(false, " :-) ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-smile.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " ;) ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-wink.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(false, " ;-) ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-wink.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " :D ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-laughing.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " 8) ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-cool.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " O:) ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-innocent.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(false, " :-o ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-surprised.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " :o ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-surprised.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " :( ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-frown.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(false, " :-( ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-frown.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " ::| ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-embarassed.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " :,-( ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-cry.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " :-* ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-kiss.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " :P ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-tongue-out.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(false, " :-P ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-tongue-out.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(false, " :-/ ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-undecided.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " :/ ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-undecided.gif" alt="" border="0" width="18px" height="18px" />'),
|
||||
array(true, " XO ", '<img src="resource2/tinymce/plugins/emotions/img/smiley-yell.gif" alt="" border="0" width="18px" height="18px" />')
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/logic/rowEditor.class.php');
|
||||
|
||||
class statpic
|
||||
{
|
||||
var $nUserId = 0;
|
||||
|
||||
var $reUser;
|
||||
|
||||
function __construct($nNewUserId)
|
||||
{
|
||||
$this->reUser = new rowEditor('user');
|
||||
$this->reUser->addPKInt('user_id', null, false, RE_INSERT_AUTOINCREMENT);
|
||||
$this->reUser->addString('statpic_text', '', false);
|
||||
$this->reUser->addString('statpic_logo', 0, false);
|
||||
|
||||
$this->nUserId = $nNewUserId+0;
|
||||
|
||||
$this->reUser->load($this->nUserId);
|
||||
}
|
||||
|
||||
function getStyle()
|
||||
{
|
||||
return $this->reUser->getValue('statpic_logo');
|
||||
}
|
||||
|
||||
function setStyle($value)
|
||||
{
|
||||
return $this->reUser->setValue('statpic_logo', $value);
|
||||
}
|
||||
|
||||
function getText()
|
||||
{
|
||||
return $this->reUser->getValue('statpic_text');
|
||||
}
|
||||
|
||||
function setText($value)
|
||||
{
|
||||
if ($value != '')
|
||||
if (!mb_ereg_match(REGEX_STATPIC_TEXT, $value))
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('statpic_text', $value);
|
||||
}
|
||||
|
||||
function save()
|
||||
{
|
||||
$retval = $this->reUser->save();
|
||||
if ($retval)
|
||||
$this->invalidate();
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
// force regeneration of image on next call of ocstats.php
|
||||
function invalidate()
|
||||
{
|
||||
sql("DELETE FROM `user_statpic` WHERE `user_id`='&1'", $this->nUserId);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,782 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* get/set has to be commited with save
|
||||
* add/remove etc. is executed instantly
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/mail.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/rowEditor.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/statpic.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/countriesList.class.php');
|
||||
require_once($opt['rootpath'] . 'lib2/logic/cracklib.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/translate.class.php');
|
||||
|
||||
class user
|
||||
{
|
||||
var $nUserId = 0;
|
||||
|
||||
var $reUser;
|
||||
var $reUserStat;
|
||||
|
||||
static function fromEMail($email)
|
||||
{
|
||||
$userid = sql_value("SELECT `user_id` FROM `user` WHERE `email`='&1'", 0, $email);
|
||||
if ($userid == 0)
|
||||
return null;
|
||||
|
||||
return new user($userid);
|
||||
}
|
||||
|
||||
static function fromUsername($username)
|
||||
{
|
||||
$userid = sql_value("SELECT `user_id` FROM `user` WHERE `username`='&1'", 0, $username);
|
||||
if ($userid == 0)
|
||||
return null;
|
||||
|
||||
return new user($userid);
|
||||
}
|
||||
|
||||
function __construct($nNewUserId=ID_NEW)
|
||||
{
|
||||
$this->reUser = new rowEditor('user');
|
||||
$this->reUser->addPKInt('user_id', null, false, RE_INSERT_AUTOINCREMENT);
|
||||
$this->reUser->addString('username', '', false);
|
||||
$this->reUser->addString('password', null, true);
|
||||
$this->reUser->addString('email', null, true);
|
||||
$this->reUser->addFloat('latitude', 0, false);
|
||||
$this->reUser->addFloat('longitude', 0, false);
|
||||
$this->reUser->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reUser->addBoolean('is_active_flag', false, false);
|
||||
$this->reUser->addString('last_name', '', false);
|
||||
$this->reUser->addString('first_name', '', false);
|
||||
$this->reUser->addString('country', null, true);
|
||||
$this->reUser->addBoolean('pmr_flag', false, false);
|
||||
$this->reUser->addString('new_pw_code', null, true);
|
||||
$this->reUser->addDate('new_pw_date', null, true);
|
||||
$this->reUser->addDate('date_created', time(), true, RE_INSERT_IGNORE);
|
||||
$this->reUser->addString('new_email_code', null, true);
|
||||
$this->reUser->addDate('new_email_date', null, true);
|
||||
$this->reUser->addString('new_email', null, true);
|
||||
$this->reUser->addString('uuid', '', false, RE_INSERT_OVERWRITE|RE_INSERT_UUID);
|
||||
$this->reUser->addBoolean('permanent_login_flag', false, false);
|
||||
$this->reUser->addInt('watchmail_mode', 1, false);
|
||||
$this->reUser->addInt('watchmail_hour', 0, false);
|
||||
$this->reUser->addDate('watchmail_nextmail', time(), false);
|
||||
$this->reUser->addInt('watchmail_day', 0, false);
|
||||
$this->reUser->addString('activation_code', '', false);
|
||||
$this->reUser->addBoolean('no_htmledit_flag', false, false);
|
||||
$this->reUser->addInt('notify_radius', 0, false);
|
||||
$this->reUser->addInt('admin', 0, false);
|
||||
$this->reUser->addInt('node', 0, false);
|
||||
|
||||
$this->reUserStat = new rowEditor('stat_user');
|
||||
$this->reUserStat->addPKInt('user_id', null, false, RE_INSERT_AUTOINCREMENT);
|
||||
$this->reUserStat->addInt('found', 0, false);
|
||||
$this->reUserStat->addInt('notfound', 0, false);
|
||||
$this->reUserStat->addInt('note', 0, false);
|
||||
$this->reUserStat->addInt('hidden', 0, false);
|
||||
|
||||
$this->nUserId = $nNewUserId+0;
|
||||
|
||||
if ($nNewUserId == ID_NEW)
|
||||
{
|
||||
$this->reUser->addNew(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->reUser->load($this->nUserId);
|
||||
}
|
||||
}
|
||||
|
||||
function exist()
|
||||
{
|
||||
return $this->reUser->exist();
|
||||
}
|
||||
|
||||
static function existUsername($username)
|
||||
{
|
||||
return (sql_value("SELECT COUNT(*) FROM `user` WHERE `username`='&1'", 0, $username) != 0);
|
||||
}
|
||||
|
||||
static function existEMail($email)
|
||||
{
|
||||
return (sql_value("SELECT COUNT(*) FROM `user` WHERE `email`='&1'", 0, $email) != 0);
|
||||
}
|
||||
|
||||
function getUserId()
|
||||
{
|
||||
return $this->nUserId;
|
||||
}
|
||||
|
||||
function getUsername()
|
||||
{
|
||||
return $this->reUser->getValue('username');
|
||||
}
|
||||
function setUsername($value)
|
||||
{
|
||||
if (!mb_ereg_match(REGEX_USERNAME, $value))
|
||||
return false;
|
||||
|
||||
if (is_valid_email_address($value))
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('username', $value);
|
||||
}
|
||||
function getUsernameChanged()
|
||||
{
|
||||
return $this->reUser->getChanged('username');
|
||||
}
|
||||
function getEMail()
|
||||
{
|
||||
return $this->reUser->getValue('email');
|
||||
}
|
||||
function setEMail($value)
|
||||
{
|
||||
if (!is_valid_email_address($value))
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('email', $value);
|
||||
}
|
||||
function getPassword()
|
||||
{
|
||||
return $this->reUser->getValue('password');
|
||||
}
|
||||
function setPassword($value)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if (!mb_ereg_match(REGEX_PASSWORD, $value))
|
||||
return false;
|
||||
|
||||
if (cracklib_checkPW($value, array('open', 'caching', $this->getUsername(), $this->getFirstName(), $this->getLastName())) == false)
|
||||
return false;
|
||||
|
||||
$pwmd5 = md5($value);
|
||||
if ($opt['logic']['password_hash'])
|
||||
$pwmd5 = hash('sha512', $pwmd5);
|
||||
|
||||
return $this->reUser->setValue('password', $pwmd5);
|
||||
}
|
||||
function getFirstName()
|
||||
{
|
||||
return $this->reUser->getValue('first_name');
|
||||
}
|
||||
function setFirstName($value)
|
||||
{
|
||||
if ($value != '')
|
||||
if (!mb_ereg_match(REGEX_FIRST_NAME, $value))
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('first_name', $value);
|
||||
}
|
||||
function getLastName()
|
||||
{
|
||||
return $this->reUser->getValue('last_name');
|
||||
}
|
||||
function setLastName($value)
|
||||
{
|
||||
if ($value != '')
|
||||
if (!mb_ereg_match(REGEX_LAST_NAME, $value))
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('last_name', $value);
|
||||
}
|
||||
function getCountry()
|
||||
{
|
||||
global $opt;
|
||||
return countriesList::getCountryLocaleName($this->reUser->getValue('country'));
|
||||
}
|
||||
function getCountryCode()
|
||||
{
|
||||
return $this->reUser->getValue('country');
|
||||
}
|
||||
function setCountryCode($value)
|
||||
{
|
||||
if ($value !== null && (sql_value("SELECT COUNT(*) FROM countries WHERE short='&1'", 0, $value) == 0))
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('country', $value);
|
||||
}
|
||||
function getLatitude()
|
||||
{
|
||||
return $this->reUser->getValue('latitude');
|
||||
}
|
||||
function setLatitude($value)
|
||||
{
|
||||
if (($value+0) > 90 || ($value+0) < -90)
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('latitude', $value+0);
|
||||
}
|
||||
function getLongitude()
|
||||
{
|
||||
return $this->reUser->getValue('longitude');
|
||||
}
|
||||
function setLongitude($value)
|
||||
{
|
||||
if (($value+0) > 180 || ($value+0) < -180)
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('longitude', $value+0);
|
||||
}
|
||||
function getNotifyRadius()
|
||||
{
|
||||
return $this->reUser->getValue('notify_radius');
|
||||
}
|
||||
function setNotifyRadius($value)
|
||||
{
|
||||
if (($value+0) < 0 || ($value+0) > 150)
|
||||
return false;
|
||||
return $this->reUser->setValue('notify_radius', $value+0);
|
||||
}
|
||||
function getPermanentLogin()
|
||||
{
|
||||
return $this->reUser->getValue('permanent_login_flag');
|
||||
}
|
||||
function setPermanentLogin($value)
|
||||
{
|
||||
return $this->reUser->setValue('permanent_login_flag', $value);
|
||||
}
|
||||
function getNoHTMLEditor()
|
||||
{
|
||||
return $this->reUser->getValue('no_htmledit_flag');
|
||||
}
|
||||
function setNoHTMLEditor($value)
|
||||
{
|
||||
return $this->reUser->setValue('no_htmledit_flag', $value);
|
||||
}
|
||||
function getUsePMR()
|
||||
{
|
||||
return $this->reUser->getValue('pmr_flag');
|
||||
}
|
||||
function setUsePMR($value)
|
||||
{
|
||||
return $this->reUser->setValue('pmr_flag', $value);
|
||||
}
|
||||
function getIsActive()
|
||||
{
|
||||
return $this->reUser->getValue('is_active_flag');
|
||||
}
|
||||
function setIsActive($value)
|
||||
{
|
||||
return $this->reUser->setValue('is_active_flag', $value);
|
||||
}
|
||||
function getActivationCode()
|
||||
{
|
||||
return $this->reUser->getValue('activation_code');
|
||||
}
|
||||
function setActivationCode($value)
|
||||
{
|
||||
return $this->reUser->setValue('activation_code', $value);
|
||||
}
|
||||
function getNewPWCode()
|
||||
{
|
||||
return $this->reUser->getValue('new_pw_code');
|
||||
}
|
||||
function setNewPWCode($value)
|
||||
{
|
||||
return $this->reUser->setValue('new_pw_code', $value);
|
||||
}
|
||||
function getNewPWDate()
|
||||
{
|
||||
return $this->reUser->getValue('new_pw_date');
|
||||
}
|
||||
function setNewPWDate($value)
|
||||
{
|
||||
return $this->reUser->setValue('new_pw_date', $value);
|
||||
}
|
||||
function getNewEMailCode()
|
||||
{
|
||||
return $this->reUser->getValue('new_email_code');
|
||||
}
|
||||
function setNewEMailCode($value)
|
||||
{
|
||||
return $this->reUser->setValue('new_email_code', $value);
|
||||
}
|
||||
function getNewEMailDate()
|
||||
{
|
||||
return $this->reUser->getValue('new_email_date');
|
||||
}
|
||||
function setNewEMailDate($value)
|
||||
{
|
||||
return $this->reUser->setValue('new_email_date', $value);
|
||||
}
|
||||
function getNewEMail()
|
||||
{
|
||||
return $this->reUser->getValue('new_email');
|
||||
}
|
||||
function setNewEMail($value)
|
||||
{
|
||||
if ($value !== null)
|
||||
{
|
||||
if (!is_valid_email_address($value))
|
||||
return false;
|
||||
|
||||
if (user::existEMail($value))
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->reUser->setValue('new_email', $value);
|
||||
}
|
||||
function getWatchmailMode()
|
||||
{
|
||||
return $this->reUser->getValue('watchmail_mode');
|
||||
}
|
||||
function setWatchmailMode($value)
|
||||
{
|
||||
$this->setWatchmailNext('0000-00-00 00:00:00');
|
||||
return $this->reUser->setValue('watchmail_mode', $value);
|
||||
}
|
||||
function getWatchmailHour()
|
||||
{
|
||||
return $this->reUser->getValue('watchmail_hour');
|
||||
}
|
||||
function setWatchmailHour($value)
|
||||
{
|
||||
$this->setWatchmailNext('0000-00-00 00:00:00');
|
||||
return $this->reUser->setValue('watchmail_hour', $value);
|
||||
}
|
||||
function getWatchmailDay()
|
||||
{
|
||||
return $this->reUser->getValue('watchmail_day');
|
||||
}
|
||||
function setWatchmailDay($value)
|
||||
{
|
||||
$this->setWatchmailNext('0000-00-00 00:00:00');
|
||||
return $this->reUser->setValue('watchmail_day', $value);
|
||||
}
|
||||
function getWatchmailNext()
|
||||
{
|
||||
return $this->reUser->getValue('watchmail_nextmail');
|
||||
}
|
||||
function setWatchmailNext()
|
||||
{
|
||||
return $this->reUser->setValue('watchmail_nextmail', $value);
|
||||
}
|
||||
|
||||
function getStatFound()
|
||||
{
|
||||
if ($this->reUserStat->exist())
|
||||
return $this->reUserStat->getValue('found');
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
function getStatNotFound()
|
||||
{
|
||||
if ($this->reUserStat->exist())
|
||||
return $this->reUserStat->getValue('notfound');
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
function getStatNote()
|
||||
{
|
||||
if ($this->reUserStat->exist())
|
||||
return $this->reUserStat->getValue('note');
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
function getStatHidden()
|
||||
{
|
||||
if ($this->reUserStat->exist())
|
||||
return $this->reUserStat->getValue('hidden');
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
function getDateRegistered()
|
||||
{
|
||||
return $this->reUser->getValue('date_created');
|
||||
}
|
||||
function getUUID()
|
||||
{
|
||||
return $this->reUser->getValue('uuid');
|
||||
}
|
||||
function getLastModified()
|
||||
{
|
||||
return $this->reUser->getValue('last_modified');
|
||||
}
|
||||
function getDateCreated()
|
||||
{
|
||||
return $this->reUser->getValue('date_created');
|
||||
}
|
||||
function getAdmin()
|
||||
{
|
||||
return $this->reUser->getValue('admin');
|
||||
}
|
||||
function getNode()
|
||||
{
|
||||
return $this->reUser->getValue('node');
|
||||
}
|
||||
function setNode($value)
|
||||
{
|
||||
return $this->reUser->setValue('node', $value);
|
||||
}
|
||||
|
||||
function getAnyChanged()
|
||||
{
|
||||
return $this->reUser->getAnyChanged();
|
||||
}
|
||||
|
||||
// return if successfull (with insert)
|
||||
function save()
|
||||
{
|
||||
$bNeedStatpicClear = $this->reUser->getChanged('username');
|
||||
|
||||
if ($this->reUser->save())
|
||||
{
|
||||
$this->getStatpic()->invalidate();
|
||||
sql_slave_exclude();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function getStatpic()
|
||||
{
|
||||
return new statpic($this->nUserId);
|
||||
}
|
||||
|
||||
static function createCode()
|
||||
{
|
||||
return mb_strtoupper(mb_substr(md5(uniqid('')), 0, 13));
|
||||
}
|
||||
|
||||
function requestNewPWCode()
|
||||
{
|
||||
global $translate;
|
||||
|
||||
if (!$this->exist())
|
||||
return false;
|
||||
|
||||
$email = $this->getEMail();
|
||||
if ($email === null || $email == '')
|
||||
return false;
|
||||
|
||||
if (!$this->getIsActive())
|
||||
return false;
|
||||
|
||||
$this->setNewPWCode($this->createCode());
|
||||
if (!$this->reUser->saveField('new_pw_code'))
|
||||
return false;
|
||||
|
||||
$this->setNewPWDate(time());
|
||||
if (!$this->reUser->saveField('new_pw_date'))
|
||||
return false;
|
||||
|
||||
// send confirmation
|
||||
$mail = new mail();
|
||||
$mail->name = 'newpw';
|
||||
$mail->to = $email;
|
||||
$mail->subject = $translate->t('New password code', '', basename(__FILE__), __LINE__);
|
||||
$mail->assign('code', $this->getNewPWCode());
|
||||
$mail->send();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function clearNewPWCode()
|
||||
{
|
||||
$this->setNewPWCode(null);
|
||||
if (!$this->reUser->saveField('new_pw_code'))
|
||||
return false;
|
||||
|
||||
$this->setNewPWDate(null);
|
||||
if (!$this->reUser->saveField('new_pw_date'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function requestNewEMail($email)
|
||||
{
|
||||
global $translate;
|
||||
|
||||
if (!$this->exist())
|
||||
return false;
|
||||
|
||||
if (mb_strtolower($this->getEMail()) == mb_strtolower($email))
|
||||
return false;
|
||||
|
||||
if ($this->getEMail() === null || $this->getEMail() == '')
|
||||
return false;
|
||||
|
||||
if (!$this->getIsActive())
|
||||
return false;
|
||||
|
||||
$this->setNewEMailCode($this->createCode());
|
||||
if (!$this->reUser->saveField('new_email_code'))
|
||||
return false;
|
||||
|
||||
$this->setNewEMailDate(time());
|
||||
if (!$this->reUser->saveField('new_email_date'))
|
||||
return false;
|
||||
|
||||
$this->setNewEMail($email);
|
||||
if (!$this->reUser->saveField('new_email'))
|
||||
return false;
|
||||
|
||||
// send confirmation
|
||||
$mail = new mail();
|
||||
$mail->name = 'newemail';
|
||||
$mail->to = $email;
|
||||
$mail->subject = $translate->t('New email code', '', basename(__FILE__), __LINE__);
|
||||
$mail->assign('code', $this->getNewEMailCode());
|
||||
$mail->send();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function clearNewEMailCode()
|
||||
{
|
||||
$this->setNewEMailCode(null);
|
||||
if (!$this->reUser->saveField('new_email_code'))
|
||||
return false;
|
||||
|
||||
$this->setNewEMailDate(null);
|
||||
if (!$this->reUser->saveField('new_email_date'))
|
||||
return false;
|
||||
|
||||
$this->setNewEMail(null);
|
||||
if (!$this->reUser->saveField('new_email'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function remindEMail()
|
||||
{
|
||||
global $translate;
|
||||
|
||||
if (!$this->exist())
|
||||
return false;
|
||||
|
||||
$email = $this->getEMail();
|
||||
if ($email === null || $email == '')
|
||||
return false;
|
||||
|
||||
if (!$this->getIsActive())
|
||||
return false;
|
||||
|
||||
// send confirmation
|
||||
$mail = new mail();
|
||||
$mail->name = 'remindemail';
|
||||
$mail->to = $email;
|
||||
$mail->subject = $translate->t('Reminder to your E-Mail-Address', '', basename(__FILE__), __LINE__);
|
||||
$mail->assign('username', $this->getUsername());
|
||||
$mail->assign('email', $email);
|
||||
$mail->send();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function sendRegistrationCode()
|
||||
{
|
||||
global $translate;
|
||||
|
||||
$countriesList = new countriesList();
|
||||
|
||||
$mail = new mail();
|
||||
$mail->name = 'register';
|
||||
$mail->to = $this->getEMail();
|
||||
$mail->subject = $translate->t('Registration confirmation', '', basename(__FILE__), __LINE__);
|
||||
$mail->assign('username', $this->getUsername());
|
||||
$mail->assign('last_name', $this->getLastName());
|
||||
$mail->assign('first_name', $this->getFirstName());
|
||||
$mail->assign('country', $countriesList->getCountryLocaleName($this->getCountryCode()));
|
||||
$mail->assign('code', $this->getActivationCode());
|
||||
|
||||
if ($mail->send())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function sendEMail($nFromUserId, $sSubject, $sText, $bSendEMailAddress)
|
||||
{
|
||||
global $opt, $translate;
|
||||
|
||||
if ($this->exist() == false)
|
||||
return false;
|
||||
|
||||
if ($this->getIsActive() == false)
|
||||
return false;
|
||||
|
||||
if ($this->getEMail() === null || $this->getEMail() == '')
|
||||
return false;
|
||||
|
||||
if ($sSubject == '')
|
||||
return false;
|
||||
|
||||
if ($sText == '')
|
||||
return false;
|
||||
|
||||
if (mb_strpos($sSubject, "\n") !== false)
|
||||
$sSubject = mb_substr($sSubject, 0, mb_strpos($sSubject, "\n"));
|
||||
$sSubject = mb_trim($sSubject);
|
||||
|
||||
$fromUser = new user($nFromUserId);
|
||||
if ($fromUser->exist() == false)
|
||||
return false;
|
||||
if ($fromUser->getIsActive() == false)
|
||||
return false;
|
||||
if ($fromUser->getEMail() === null || $fromUser->getEMail() == '')
|
||||
return false;
|
||||
|
||||
// ok, we can send ...
|
||||
$mail = new mail();
|
||||
$mail->name = 'usercontactmail';
|
||||
$mail->to = $this->getEMail();
|
||||
|
||||
$mail->from = $opt['mail']['usermail'];
|
||||
|
||||
if ($bSendEMailAddress == true)
|
||||
{
|
||||
$mail->replyTo = $fromUser->getEMail();
|
||||
$mail->returnPath = $fromUser->getEMail();
|
||||
}
|
||||
|
||||
$mail->subject = $translate->t('E-Mail from', '', basename(__FILE__), __LINE__) . ' ' . $fromUser->getUsername() . ': ' . $sSubject;
|
||||
$mail->assign('usersubject', $sSubject);
|
||||
$mail->assign('text', $sText);
|
||||
$mail->assign('username', $this->getUsername());
|
||||
$mail->assign('sendemailaddress', $bSendEMailAddress);
|
||||
$mail->assign('fromusername', $fromUser->getUsername());
|
||||
$mail->assign('fromuserid', $fromUser->getUserId());
|
||||
$mail->assign('fromuseremail', $fromUser->getEMail());
|
||||
|
||||
if ($mail->send())
|
||||
{
|
||||
// send copy to fromUser
|
||||
$mail->assign('copy', true);
|
||||
$mail->to = $fromUser->getEMail();
|
||||
$mail->send();
|
||||
|
||||
// log
|
||||
sql("INSERT INTO `email_user` (`ipaddress`,
|
||||
`from_user_id`,
|
||||
`from_email`,
|
||||
`to_user_id`,
|
||||
`to_email`)
|
||||
VALUES ('&1', '&2', '&3', '&4', '&5')",
|
||||
$_SERVER["REMOTE_ADDR"],
|
||||
$fromUser->getUserId(),
|
||||
$fromUser->getEMail(),
|
||||
$this->getUserId(),
|
||||
$this->getEMail());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function canDisable()
|
||||
{
|
||||
global $login;
|
||||
$login->verify();
|
||||
|
||||
if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER)
|
||||
return false;
|
||||
|
||||
if ($this->getIsActive() != 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function disable()
|
||||
{
|
||||
global $login;
|
||||
|
||||
if ($this->canDisable() == false)
|
||||
return false;
|
||||
|
||||
// write old record to log
|
||||
$backup = array();
|
||||
$backup['username'] = $this->getUsername();
|
||||
$backup['email'] = $this->getEMail();
|
||||
$backup['last_name'] = $this->getLastName();
|
||||
$backup['first_name'] = $this->getFirstName();
|
||||
|
||||
sql("INSERT INTO `logentries` (`module`, `eventid`, `userid`, `objectid1`, `objectid2`, `logtext`, `details`)
|
||||
VALUES ('user', 6, '&1', '&2', '&3', '&4', '&5')",
|
||||
$login->userid, $this->nUserId, 0,
|
||||
'User ' . sql_escape($this->getUsername()) . ' disabled',
|
||||
serialize($backup));
|
||||
|
||||
sql("UPDATE `caches` SET `status`=6 WHERE `user_id`='&1' AND `status` IN (1, 2, 3)", $this->nUserId);
|
||||
sql("UPDATE `user` SET `password`=NULL, `email`=NULL,
|
||||
`is_active_flag`=0,
|
||||
`latitude`=0, `longitude`=0,
|
||||
`last_name`='', `first_name`='',
|
||||
`country`=NULL, `new_pw_code`=NULL,
|
||||
`new_pw_date`=NULL, `new_email`=NULL,
|
||||
`new_email_code`=NULL, `activation_code`='',
|
||||
`notify_radius`=0, `statpic_text`=''
|
||||
WHERE `user_id`='&1'", $this->nUserId);
|
||||
$this->reload();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function canDelete()
|
||||
{
|
||||
global $login;
|
||||
$login->verify();
|
||||
|
||||
if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER)
|
||||
return false;
|
||||
|
||||
if (sql_value("SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'", 0, $this->nUserId) > 0)
|
||||
return false;
|
||||
|
||||
if (sql_value("SELECT COUNT(*) FROM `cache_logs` WHERE `user_id`='&1'", 0, $this->nUserId) > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
global $login;
|
||||
|
||||
if ($this->canDelete() == false)
|
||||
return false;
|
||||
|
||||
// write old record to log
|
||||
$backup = array();
|
||||
$backup['username'] = $this->getUsername();
|
||||
$backup['email'] = $this->getEMail();
|
||||
$backup['last_name'] = $this->getLastName();
|
||||
$backup['first_name'] = $this->getFirstName();
|
||||
|
||||
sql("INSERT INTO `logentries` (`module`, `eventid`, `userid`, `objectid1`, `objectid2`, `logtext`, `details`)
|
||||
VALUES ('user', 7, '&1', '&2', '&3', '&4', '&5')",
|
||||
$login->userid, $this->nUserId, 0,
|
||||
'User ' . sql_escape($this->getUsername()) . ' deleted',
|
||||
serialize($backup));
|
||||
|
||||
sql("DELETE FROM `user` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_adoption` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_ignore` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_rating` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_watches` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `stat_user` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `user_options` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `watches_waiting` WHERE `user_id`='&1'", $this->nUserId);
|
||||
|
||||
$this->reload();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function reload()
|
||||
{
|
||||
$this->reUser->reload();
|
||||
$this->reUserStat->reload();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* set has to be commited with save
|
||||
*
|
||||
***************************************************************************/
|
||||
global $opt;
|
||||
|
||||
require_once($opt['rootpath'] . '../lib/htmlpurifier-4.2.0/library/HTMLPurifier.auto.php');
|
||||
|
||||
class useroptions
|
||||
{
|
||||
|
||||
var $nUserId = 0;
|
||||
var $nOptions;
|
||||
|
||||
function __construct($nUserId=ID_NEW)
|
||||
{
|
||||
$this->nUserId = $nUserId+0;
|
||||
|
||||
if ($nUserId == ID_NEW)
|
||||
{
|
||||
$rs = sqll('SELECT `id`, `name`, `default_value`, `check_regex`, `option_order`, 0 AS `option_visible`, `internal_use`, `default_value` AS `option_value`
|
||||
FROM `profile_options`');
|
||||
}
|
||||
else
|
||||
{
|
||||
$rs = sqll("SELECT `p`.`id`, `p`.`name`, `p`.`default_value`, `p`.`check_regex`, `p`.`option_order`, IFNULL(`u`.`option_visible`, 0) AS `option_visible`, `p`.`internal_use`, IFNULL(`u`.`option_value`, `p`.`default_value`) AS `option_value`
|
||||
FROM `profile_options` AS `p`
|
||||
LEFT JOIN `user_options` AS `u` ON `p`.`id`=`u`.`option_id` AND (`u`.`user_id` IS NULL OR `u`.`user_id`='&1')
|
||||
UNION
|
||||
SELECT `u`.`option_id` AS `id`, `p`.`name`, `p`.`default_value`, `p`.`check_regex`, `p`.`option_order`, `u`.`option_visible`, `p`.`internal_use`, IFNULL(`u`.`option_value`, `p`.`default_value`) AS `option_value`
|
||||
FROM `user_options` AS `u`
|
||||
LEFT JOIN `profile_options` AS `p` ON `p`.`id`=`u`.`option_id`
|
||||
WHERE `u`.`user_id`='&1'",
|
||||
$this->nUserId);
|
||||
}
|
||||
|
||||
while($record = sql_fetch_array($rs))
|
||||
{
|
||||
$this->nOptions[$record['id']] = $record;
|
||||
}
|
||||
|
||||
sql_free_result($rs);
|
||||
}
|
||||
|
||||
function getUserId()
|
||||
{
|
||||
return $this->nUserId;
|
||||
}
|
||||
function getOptName($pId)
|
||||
{
|
||||
return $this->nOptions[$pId]['name'];
|
||||
}
|
||||
function getOptDefault($pId)
|
||||
{
|
||||
return $this->nOptions[$pId]['default_value'];
|
||||
}
|
||||
function getOptRegex($pId)
|
||||
{
|
||||
return $this->nOptions[$pId]['option_regex'];
|
||||
}
|
||||
function getOptOrder($pId)
|
||||
{
|
||||
return $this->nOptions[$pId]['option_order'];
|
||||
}
|
||||
function getOptVisible($pId)
|
||||
{
|
||||
return $this->nOptions[$pId]['option_visible'];
|
||||
}
|
||||
function getOptInternal($pId)
|
||||
{
|
||||
return $this->nOptions[$pId]['internal_use'];
|
||||
}
|
||||
function getOptValue($pId)
|
||||
{
|
||||
if (array_key_exists($pId, $this->nOptions))
|
||||
return $this->nOptions[$pId]['option_value'];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function setOptVisible($pId, $pValue)
|
||||
{
|
||||
$pId += 0;
|
||||
$pValue += 0;
|
||||
|
||||
if ($pValue != 1 || $this->nOptions[$pId]['internal_use'] == 1)
|
||||
{
|
||||
$pValue = 0;
|
||||
}
|
||||
|
||||
$this->nOptions[$pId]['option_visible'] = $pValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
function setOptValue($pId, $pValue)
|
||||
{
|
||||
$pId += 0;
|
||||
if ($this->nOptions[$pId]['check_regex'] == '')
|
||||
{
|
||||
$this->nOptions[$pId]['option_value'] = $pValue;
|
||||
return true;
|
||||
}
|
||||
else if (ereg($this->nOptions[$pId]['check_regex'], $pValue) || strlen($pValue) == 0)
|
||||
{
|
||||
$this->nOptions[$pId]['option_value'] = $pValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// return if successfull (with insert)
|
||||
function save()
|
||||
{
|
||||
foreach($this->nOptions as $record)
|
||||
{
|
||||
sqll("INSERT INTO `user_options` (`user_id`, `option_id`, `option_visible`, `option_value`)
|
||||
VALUES ('&1', '&2', '&3', '&4') ON DUPLICATE KEY UPDATE `option_visible`='&3', `option_value`='&4'",
|
||||
$this->nUserId, $record['id'], $record['option_visible'], $this->tidy_html_description($record['option_value']));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function tidy_html_description($text)
|
||||
{
|
||||
$options = array("input-encoding" => "utf8", "output-encoding" => "utf8", "output-xhtml" => true, "doctype" => "omit", "show-body-only" => true, "char-encoding" => "utf8", "quote-ampersand" => true, "quote-nbsp" => true, "wrap" => 0);
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$cssDefinition = $config->getCSSDefinition();
|
||||
|
||||
$cssDefinition->info['position'] = new
|
||||
HTMLPurifier_AttrDef_Enum(array('absolute', 'fixed', 'relative', 'static', 'inherit'), false);
|
||||
|
||||
$cssDefinition->info['left'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||
new HTMLPurifier_AttrDef_CSS_Length(),
|
||||
new HTMLPurifier_AttrDef_CSS_Percentage()
|
||||
));
|
||||
|
||||
$cssDefinition->info['right'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||
new HTMLPurifier_AttrDef_CSS_Length(),
|
||||
new HTMLPurifier_AttrDef_CSS_Percentage()
|
||||
));
|
||||
|
||||
$cssDefinition->info['top'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||
new HTMLPurifier_AttrDef_CSS_Length(),
|
||||
new HTMLPurifier_AttrDef_CSS_Percentage()
|
||||
));
|
||||
|
||||
$cssDefinition->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||
new HTMLPurifier_AttrDef_CSS_Length(),
|
||||
new HTMLPurifier_AttrDef_CSS_Percentage()
|
||||
));
|
||||
|
||||
$purifier = new HTMLPurifier($config);
|
||||
$clean_html = $purifier->purify($text);
|
||||
return $clean_html;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* This class provides access to the login user data. Informations are
|
||||
* stored in a cookie.
|
||||
*
|
||||
* Methods:
|
||||
* verify() validate the login-session (automatically invoked)
|
||||
* try_login() try to login with the given user/password
|
||||
* logout() logout the user
|
||||
*
|
||||
* Properties:
|
||||
* userid Integer 0 if no login, userid otherwise
|
||||
* username String username or ''
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
define('LOGIN_UNKNOWN_ERROR', -1); // unkown error occured
|
||||
define('LOGIN_OK', 0); // login succeeded
|
||||
define('LOGIN_BADUSERPW', 1); // bad username or password
|
||||
define('LOGIN_TOOMUCHLOGINS', 2); // too many logins in short time
|
||||
define('LOGIN_USERNOTACTIVE', 3); // the useraccount locked
|
||||
define('LOGIN_EMPTY_USERPASSWORD', 4); // given username/password was empty
|
||||
define('LOGIN_LOGOUT_OK', 5); // logout was successfull
|
||||
|
||||
// login times in seconds
|
||||
define('LOGIN_TIME', 60*60);
|
||||
define('LOGIN_TIME_PERMANENT', 90*24*60*60);
|
||||
|
||||
$login = new login();
|
||||
|
||||
class login
|
||||
{
|
||||
var $userid = 0;
|
||||
var $username = '';
|
||||
var $lastlogin = 0;
|
||||
var $permanent = false;
|
||||
var $sessionid = '';
|
||||
var $verified = false;
|
||||
var $admin = 0;
|
||||
|
||||
function login()
|
||||
{
|
||||
global $cookie;
|
||||
|
||||
if ($cookie->is_set('userid') && $cookie->is_set('username'))
|
||||
{
|
||||
$this->userid = $cookie->get('userid')+0;
|
||||
$this->username = $cookie->get('username');
|
||||
$this->permanent = (($cookie->get('permanent')+0) == 1);
|
||||
$this->lastlogin = $cookie->get('lastlogin');
|
||||
$this->sessionid = $cookie->get('sessionid');
|
||||
$this->admin = $cookie->get('admin')+0;
|
||||
$this->verified = false;
|
||||
|
||||
$this->verify();
|
||||
}
|
||||
else
|
||||
$this->pClear();
|
||||
}
|
||||
|
||||
// return true on success
|
||||
function restoreSession($sid)
|
||||
{
|
||||
$min_lastlogin = date('Y-m-d H:i:s', time() - LOGIN_TIME);
|
||||
|
||||
if ($this->checkLoginsCount() == false)
|
||||
{
|
||||
$this->pClear();
|
||||
return false;
|
||||
}
|
||||
|
||||
$rs = sqlf("SELECT `sys_sessions`.`uuid` `sid`, `user`.`user_id`, `sys_sessions`.`last_login`, `user`.`admin`, `user`.`username` FROM &db.`sys_sessions`, &db.`user` WHERE `sys_sessions`.`user_id`=`user`.`user_id` AND `user`.`is_active_flag`=1 AND `sys_sessions`.`uuid`='&1' AND `sys_sessions`.`permanent`=0 AND `sys_sessions`.`last_login`>'&2'", $sid, $min_lastlogin);
|
||||
$r = sql_fetch_assoc($rs);
|
||||
sql_free_result($rs);
|
||||
|
||||
if ($r)
|
||||
{
|
||||
sqlf("UPDATE `sys_sessions` SET `sys_sessions`.`last_login`=NOW() WHERE `sys_sessions`.`uuid`='&1' AND `sys_sessions`.`user_id`='&2'", $r['sid'], $r['user_id']);
|
||||
sqlf("UPDATE `user` SET `user`.`last_login`=NOW() WHERE `user`.`user_id`='&1'", $r['user_id']);
|
||||
|
||||
$this->userid = $r['user_id'];
|
||||
$this->username = $r['username'];
|
||||
$this->permanent = false;
|
||||
$this->lastlogin = $r['last_login'];
|
||||
$this->sessionid = $r['sid'];
|
||||
$this->admin = $r['admin'];
|
||||
$this->verified = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// prevent bruteforce
|
||||
sql("INSERT INTO `sys_logins` (`remote_addr`, `success`) VALUES ('&1', 0)", $_SERVER['REMOTE_ADDR']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pClear()
|
||||
{
|
||||
// set to no valid login
|
||||
$this->userid = 0;
|
||||
$this->username = '';
|
||||
$this->permanent = false;
|
||||
$this->lastlogin = '';
|
||||
$this->sessionid = '';
|
||||
$this->admin = 0;
|
||||
$this->verified = true;
|
||||
|
||||
$this->pStoreCookie();
|
||||
}
|
||||
|
||||
function pStoreCookie()
|
||||
{
|
||||
global $cookie;
|
||||
$cookie->set('userid', $this->userid);
|
||||
$cookie->set('username', $this->username);
|
||||
$cookie->set('permanent', ($this->permanent==true ? 1 : 0));
|
||||
$cookie->set('lastlogin', $this->lastlogin);
|
||||
$cookie->set('sessionid', $this->sessionid);
|
||||
$cookie->set('admin', $this->admin);
|
||||
}
|
||||
|
||||
function verify()
|
||||
{
|
||||
if ($this->verified == true)
|
||||
return;
|
||||
|
||||
if ($this->userid == 0)
|
||||
{
|
||||
$this->pClear();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->checkLoginsCount() == false)
|
||||
{
|
||||
$this->pClear();
|
||||
return;
|
||||
}
|
||||
|
||||
$min_lastlogin = date('Y-m-d H:i:s', time() - LOGIN_TIME);
|
||||
$min_lastlogin_permanent = date('Y-m-d H:i:s', time() - LOGIN_TIME_PERMANENT);
|
||||
|
||||
$rs = sqlf("SELECT `sys_sessions`.`last_login`, `user`.`admin`, `user`.`username` FROM &db.`sys_sessions`, &db.`user` WHERE `sys_sessions`.`user_id`=`user`.`user_id` AND `user`.`is_active_flag`=1 AND `sys_sessions`.`uuid`='&1' AND `sys_sessions`.`user_id`='&2' AND ((`sys_sessions`.`permanent`=1 AND `sys_sessions`.`last_login`>'&3') OR (`sys_sessions`.`permanent`=0 AND `sys_sessions`.`last_login`>'&4'))", $this->sessionid, $this->userid, $min_lastlogin_permanent, $min_lastlogin);
|
||||
if ($rUser = sql_fetch_assoc($rs))
|
||||
{
|
||||
if ((($this->permanent == true) && (strtotime($rUser['last_login']) + LOGIN_TIME/2 < time())) ||
|
||||
(($this->permanent == false) && (strtotime($rUser['last_login']) + LOGIN_TIME_PERMANENT/2 < time())))
|
||||
{
|
||||
sqlf("UPDATE `sys_sessions` SET `sys_sessions`.`last_login`=NOW() WHERE `sys_sessions`.`uuid`='&1' AND `sys_sessions`.`user_id`='&2'", $this->sessionid, $this->userid);
|
||||
$rUser['last_login'] = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
// user.last_login is used for statics, so we keep it up2date
|
||||
sqlf("UPDATE `user` SET `user`.`last_login`=NOW() WHERE `user`.`user_id`='&1'", $this->userid);
|
||||
|
||||
$this->lastlogin = $rUser['last_login'];
|
||||
$this->username = $rUser['username'];
|
||||
$this->admin = $rUser['admin'];
|
||||
$this->verified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// prevent bruteforce
|
||||
sql("INSERT INTO `sys_logins` (`remote_addr`, `success`) VALUES ('&1', 0)", $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$this->pClear();
|
||||
}
|
||||
sql_free_result($rs);
|
||||
|
||||
$this->pStoreCookie();
|
||||
return;
|
||||
}
|
||||
|
||||
function try_login($user, $password, $permanent)
|
||||
{
|
||||
global $opt;
|
||||
|
||||
if ($password == '')
|
||||
return LOGIN_EMPTY_USERPASSWORD;
|
||||
|
||||
$pwmd5 = md5($password);
|
||||
if ($opt['logic']['password_hash'])
|
||||
$pwmd5 = hash('sha512', $pwmd5);
|
||||
|
||||
return $this->try_login_md5($user, $pwmd5, $permanent);
|
||||
}
|
||||
|
||||
function checkLoginsCount()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
// cleanup old entries
|
||||
// (execute only every 50 search calls)
|
||||
if (rand(1, 50) == 1)
|
||||
sqlf("DELETE FROM `sys_logins` WHERE `date_created`<'&1'", date('Y-m-d H:i:s', time() - 3600));
|
||||
|
||||
// check the number of logins in the last hour ...
|
||||
$logins_count = sqlf_value("SELECT COUNT(*) `count` FROM `sys_logins` WHERE `remote_addr`='&1' AND `date_created`>'&2'", 0, $_SERVER['REMOTE_ADDR'], date('Y-m-d H:i:s', time() - 3600));
|
||||
if ($logins_count > $opt['page']['max_logins_per_hour'])
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
function try_login_md5($user, $pwmd5, $permanent)
|
||||
{
|
||||
global $opt;
|
||||
$this->pClear();
|
||||
|
||||
if ($user == '' || $pwmd5 == '')
|
||||
return LOGIN_EMPTY_USERPASSWORD;
|
||||
|
||||
if ($this->checkLoginsCount() == false)
|
||||
return LOGIN_TOOMUCHLOGINS;
|
||||
|
||||
// delete old sessions
|
||||
$min_lastlogin_permanent = date('Y-m-d H:i:s', time() - LOGIN_TIME_PERMANENT);
|
||||
sqlf("DELETE FROM `sys_sessions` WHERE `last_login`<'&1'", $min_lastlogin_permanent);
|
||||
|
||||
// compare $user with email and username, if both matches use email
|
||||
$rsUser = sqlf("SELECT `user_id`, `username`, 2 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` FROM `user` WHERE `username`='&1' AND `password`='&2' UNION
|
||||
SELECT `user_id`, `username`, 1 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` FROM `user` WHERE `email`='&1' AND `password`='&2' ORDER BY `prio` ASC LIMIT 1", $user, $pwmd5);
|
||||
$rUser = sql_fetch_assoc($rsUser);
|
||||
sql_free_result($rsUser);
|
||||
|
||||
if ($permanent == null)
|
||||
$permanent = ($rUser['permanent_login_flag'] == 1);
|
||||
|
||||
if ($rUser)
|
||||
{
|
||||
// ok, there is a valid login
|
||||
if ($rUser['is_active_flag'] != 0)
|
||||
{
|
||||
// begin session
|
||||
$uuid = sqlf_value('SELECT UUID()', '');
|
||||
sqlf("INSERT INTO `sys_sessions` (`uuid`, `user_id`, `permanent`, `last_login`) VALUES ('&1', '&2', '&3', NOW())", $uuid, $rUser['user_id'], ($permanent!=false ? 1 : 0));
|
||||
$this->userid = $rUser['user_id'];
|
||||
$this->username = $rUser['username'];
|
||||
$this->permanent = $permanent;
|
||||
$this->lastlogin = date('Y-m-d H:i:s');
|
||||
$this->sessionid = $uuid;
|
||||
$this->admin = $rUser['admin'];
|
||||
$this->verified = true;
|
||||
|
||||
$retval = LOGIN_OK;
|
||||
}
|
||||
else
|
||||
$retval = LOGIN_USERNOTACTIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// sorry, bad login
|
||||
$retval = LOGIN_BADUSERPW;
|
||||
}
|
||||
|
||||
sqlf("INSERT INTO `sys_logins` (`remote_addr`, `success`) VALUES ('&1', '&2')", $_SERVER['REMOTE_ADDR'], ($rUser===false ? 0 : 1));
|
||||
|
||||
// store to cookie
|
||||
$this->pStoreCookie();
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function getUserCountry()
|
||||
{
|
||||
global $opt, $cookie;
|
||||
|
||||
// language specified in cookie?
|
||||
if ($cookie->is_set('usercountry'))
|
||||
{
|
||||
$sCountry = $cookie->get('usercountry', null);
|
||||
if ($sCountry != null)
|
||||
return $sCountry;
|
||||
}
|
||||
|
||||
// user specified a language?
|
||||
if ($this->userid != 0)
|
||||
{
|
||||
$sCountry = sql_value("SELECT `country` FROM `user` WHERE `user_id`='&1'", null, $this->userid);
|
||||
if ($sCountry != null)
|
||||
return $sCountry;
|
||||
}
|
||||
|
||||
// default country of this language
|
||||
if (isset($opt['locale'][$opt['template']['locale']]['country']))
|
||||
return $opt['locale'][$opt['template']['locale']]['country'];
|
||||
|
||||
// default country of installation (or domain)
|
||||
return $opt['template']['default']['country'];
|
||||
}
|
||||
|
||||
function logout()
|
||||
{
|
||||
if ($this->userid != 0)
|
||||
sqlf("DELETE FROM `sys_sessions` WHERE `uuid`='&1' AND `user_id`='&2'", $this->sessionid, $this->userid);
|
||||
|
||||
$this->pClear();
|
||||
}
|
||||
|
||||
public function hasAdminPriv($privilege = false)
|
||||
{
|
||||
if ($privilege === false)
|
||||
return $this->admin != 0;
|
||||
|
||||
return ($this->admin & $privilege) == $privilege;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
require_once($opt['rootpath'] . 'lib2/smarty/Smarty.class.php');
|
||||
|
||||
class mail extends Smarty
|
||||
{
|
||||
var $name = 'sys_nothing';
|
||||
var $main_template = 'sys_main';
|
||||
var $compile_id = null;
|
||||
|
||||
var $from = '';
|
||||
var $to = '';
|
||||
var $subject = '';
|
||||
|
||||
var $replyTo = null;
|
||||
var $returnPath = null;
|
||||
|
||||
var $headers = array();
|
||||
|
||||
function mail()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$this->template_dir = $opt['rootpath'] . 'templates2/mail/';
|
||||
$this->compile_dir = $opt['rootpath'] . 'cache2/smarty/compiled/';
|
||||
$this->plugins_dir = array('plugins', 'ocplugins');
|
||||
|
||||
// disable caching ...
|
||||
$this->caching = false;
|
||||
|
||||
// register additional functions
|
||||
$this->load_filter('pre', 't');
|
||||
|
||||
// cache control
|
||||
if (($opt['debug'] & DEBUG_TEMPLATES) == DEBUG_TEMPLATES)
|
||||
$this->force_compile = true;
|
||||
|
||||
$this->from = $opt['mail']['from'];
|
||||
}
|
||||
|
||||
function get_compile_id()
|
||||
{
|
||||
global $opt;
|
||||
return 'mail|' . $opt['template']['locale'] . '|' . $this->compile_id;
|
||||
}
|
||||
|
||||
function assign_rs($name, $rs)
|
||||
{
|
||||
$items = array();
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
$items[] = $r;
|
||||
$this->assign($name, $items);
|
||||
}
|
||||
|
||||
function send()
|
||||
{
|
||||
global $tpl, $opt, $login;
|
||||
|
||||
if (!$this->template_exists($this->name . '.tpl'))
|
||||
$tpl->error(ERROR_MAIL_TEMPLATE_NOT_FOUND);
|
||||
$this->assign('template', $this->name);
|
||||
|
||||
$optn['mail']['contact'] = $opt['mail']['contact'];
|
||||
$optn['page']['absolute_url'] = $opt['page']['absolute_url'];
|
||||
$optn['format'] = $opt['locale'][$opt['template']['locale']]['format'];
|
||||
$this->assign('opt', $optn);
|
||||
|
||||
$this->assign('to', $this->to);
|
||||
$this->assign('from', $this->from);
|
||||
$this->assign('subject', $this->subject);
|
||||
|
||||
$llogin['username'] = isset($login) ? $login->username : '';
|
||||
$this->assign('login', $llogin);
|
||||
|
||||
$body = $this->fetch($this->main_template . '.tpl', '', $this->get_compile_id());
|
||||
|
||||
// check if the target domain exists if the domain does not
|
||||
// exist, the mail is sent to the own domain (?!)
|
||||
$domain = mail::getToMailDomain($this->to);
|
||||
if (mail::is_existent_maildomain($domain) == false)
|
||||
return false;
|
||||
|
||||
$aAddHeaders = array();
|
||||
$aAddHeaders[] = 'From: "' . $this->from . '" <' . $this->from . '>';
|
||||
|
||||
if ($this->replyTo !== null)
|
||||
$aAddHeaders[] = 'Reply-To: ' . $this->replyTo;
|
||||
|
||||
if ($this->returnPath !== null)
|
||||
$aAddHeaders[] = 'Return-Path: ' . $this->returnPath;
|
||||
|
||||
$mailheaders = implode("\n", array_merge($aAddHeaders, $this->headers));
|
||||
return mb_send_mail($this->to, $opt['mail']['subject'] . $this->subject, $body, $mailheaders);
|
||||
}
|
||||
|
||||
static function is_existent_maildomain($domain)
|
||||
{
|
||||
$smtp_serverlist = array();
|
||||
$smtp_serverweight = array();
|
||||
|
||||
if (getmxrr($domain, $smtp_serverlist, $smtp_serverweight) != false)
|
||||
if (count($smtp_serverlist)>0)
|
||||
return true;
|
||||
|
||||
// check if A exists
|
||||
$a = dns_get_record($domain, DNS_A);
|
||||
if (count($a) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static function getToMailDomain($mail)
|
||||
{
|
||||
if ($mail == '')
|
||||
return '';
|
||||
|
||||
if (strrpos($mail, '@') === false)
|
||||
$domain = 'localhost';
|
||||
else
|
||||
$domain = substr($mail, strrpos($mail, '@') + 1);
|
||||
|
||||
return $domain;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
define('AUTH_LEVEL_ALL', 0);
|
||||
define('AUTH_LEVEL_ADMIN', '2');
|
||||
|
||||
define('MNU_ROOT', 0);
|
||||
|
||||
global $opt;
|
||||
require_once($opt['rootpath'] . 'lib2/translate.class.php');
|
||||
$menu = new Menu();
|
||||
|
||||
class Menu
|
||||
{
|
||||
var $nSelectedItem = 0;
|
||||
var $sMenuFilename = '';
|
||||
|
||||
function Menu()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$this->sMenuFilename = $opt['rootpath'] . 'cache2/menu-' . $opt['template']['locale'] . '.inc.php';
|
||||
|
||||
if (!file_exists($this->sMenuFilename))
|
||||
$this->CreateCacheFile();
|
||||
|
||||
require_once($this->sMenuFilename);
|
||||
}
|
||||
|
||||
function CreateCacheFile()
|
||||
{
|
||||
global $opt, $translate;
|
||||
|
||||
$f = fopen($this->sMenuFilename, 'w');
|
||||
fwrite($f, "<?php\n");
|
||||
fwrite($f, 'global $menuitem;' . "\n");
|
||||
fwrite($f, "\n");
|
||||
|
||||
$rsDefines = sqlf("SELECT `id`, `id_string` FROM `sys_menu`");
|
||||
while ($rDefine = sql_fetch_assoc($rsDefines))
|
||||
fwrite($f, 'if (!defined(\'' . addslashes($rDefine['id_string']) . '\')) define(\'' . addslashes($rDefine['id_string']) . '\', ' . $rDefine['id'] . ");\n");
|
||||
sql_free_result($rsDefines);
|
||||
fwrite($f, "\n");
|
||||
|
||||
$aMenu = array();
|
||||
$nPos = 0;
|
||||
$rsSubmenu = sqlf("SELECT `id` FROM `sys_menu` WHERE `parent`=0 ORDER BY `parent` ASC, `position` ASC");
|
||||
while ($rSubmenu = sql_fetch_assoc($rsSubmenu))
|
||||
{
|
||||
$aMenu[MNU_ROOT]['subitems'][$nPos] = $rSubmenu['id'];
|
||||
$nPos++;
|
||||
}
|
||||
sql_free_result($rsSubmenu);
|
||||
fwrite($f, "\n");
|
||||
|
||||
$rs = sqlf('SELECT `item`.`id`, `item`.`title`, `item`.`menustring`, `item`.`access`, `item`.`href`, `item`.`visible`, `item`.`parent` AS `parentid`, `item`.`color` AS `color` FROM `sys_menu` AS `item` LEFT JOIN `sys_menu` AS `parentitem` ON `item`.`parent`=`parentitem`.`id`');
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
{
|
||||
$aMenu[$r['id']]['title'] = $translate->t($r['title'], '', basename(__FILE__), __LINE__);
|
||||
$aMenu[$r['id']]['menustring'] = $translate->t($r['menustring'], '', basename(__FILE__), __LINE__);
|
||||
$aMenu[$r['id']]['authlevel'] = ($r['access']==0) ? AUTH_LEVEL_ALL : AUTH_LEVEL_ADMIN;
|
||||
$aMenu[$r['id']]['href'] = $r['href'];
|
||||
$aMenu[$r['id']]['visible'] = ($r['visible'] == 1) ? true : false;
|
||||
$aMenu[$r['id']]['sublevel'] = $this->pGetMenuSublevel($r['id']);
|
||||
|
||||
if ($r['parentid'] != 0)
|
||||
$aMenu[$r['id']]['parent'] = $r['parentid'];
|
||||
if ($r['color'] != null)
|
||||
$aMenu[$r['id']]['color'] = $r['color'];
|
||||
|
||||
$nPos = 0;
|
||||
$rsSubmenu = sqlf("SELECT `id` FROM `sys_menu` WHERE `parent`='&1' ORDER BY `parent` ASC, `position` ASC", $r['id']);
|
||||
while ($rSubmenu = sql_fetch_assoc($rsSubmenu))
|
||||
{
|
||||
$aMenu[$r['id']]['subitems'][$nPos] = $rSubmenu['id'];
|
||||
$nPos++;
|
||||
}
|
||||
sql_free_result($rsSubmenu);
|
||||
}
|
||||
sql_free_result($rs);
|
||||
|
||||
fwrite($f, '$menuitem = unserialize("' . str_replace('"', '\\"', serialize($aMenu)) . '");' . "\n");
|
||||
|
||||
fwrite($f, "?>");
|
||||
fclose($f);
|
||||
}
|
||||
|
||||
function clearCache()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$dir = $opt['rootpath'] . 'cache/';
|
||||
if ($dh = opendir($dir))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (filetype($dir . $file) == 'file')
|
||||
{
|
||||
if (preg_match('/^menu-[a-z]{2,2}.inc.php/', $file))
|
||||
unlink($dir . $file);
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
}
|
||||
|
||||
function pGetMenuSublevel($id)
|
||||
{
|
||||
$parent = sqlf_value("SELECT `parent` FROM `sys_menu` WHERE `id`='&1'", 0, $id);
|
||||
if ($parent != 0)
|
||||
return $this->pGetMenuSublevel($parent) + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function SetSelectItem($item)
|
||||
{
|
||||
$this->nSelectedItem = $item;
|
||||
}
|
||||
|
||||
function GetSelectItem($item)
|
||||
{
|
||||
return $this->nSelectedItem;
|
||||
}
|
||||
|
||||
function GetBreadcrumb()
|
||||
{
|
||||
global $menuitem;
|
||||
|
||||
$retval = array();
|
||||
$retval[] = $menuitem[$this->nSelectedItem];
|
||||
|
||||
$nCurItem = $this->nSelectedItem;
|
||||
|
||||
while ($nCurItem != MNU_ROOT)
|
||||
{
|
||||
if (isset($menuitem[$nCurItem]['parent']))
|
||||
{
|
||||
$nCurItem = $menuitem[$nCurItem]['parent'];
|
||||
$retval[] = $menuitem[$nCurItem];
|
||||
}
|
||||
else
|
||||
$nCurItem = MNU_ROOT;
|
||||
}
|
||||
|
||||
return array_reverse($retval);
|
||||
}
|
||||
|
||||
function GetTopMenu()
|
||||
{
|
||||
global $menuitem, $login;
|
||||
|
||||
$ids = $this->GetSelectedMenuIds();
|
||||
|
||||
$retval = array();
|
||||
foreach ($menuitem[MNU_ROOT]['subitems'] AS $item)
|
||||
{
|
||||
if (($menuitem[$item]['authlevel'] != AUTH_LEVEL_ADMIN || $login->admin != 0) && $menuitem[$item]['visible'] == true)
|
||||
{
|
||||
$thisitem = $menuitem[$item];
|
||||
$thisitem['selected'] = isset($ids[$item]);
|
||||
$retval[] = $thisitem;
|
||||
}
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function GetSubMenu()
|
||||
{
|
||||
global $menuitem, $login;
|
||||
|
||||
$ids = $this->GetSelectedMenuIds();
|
||||
$topmenu = array_pop($ids);
|
||||
if (isset($menuitem[$topmenu]['parent']) && $menuitem[$topmenu]['parent'] != MNU_ROOT)
|
||||
die('internal error Menu::GetSelectedMenuIds');
|
||||
|
||||
$ids[$topmenu] = $topmenu;
|
||||
|
||||
$retval = array();
|
||||
if ($topmenu != MNU_ROOT)
|
||||
{
|
||||
$this->pAppendSubMenu($topmenu, $ids, $retval);
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function pAppendSubMenu($menuid, $ids, &$items)
|
||||
{
|
||||
global $menuitem, $login;
|
||||
|
||||
if (isset($menuitem[$menuid]['subitems']))
|
||||
{
|
||||
foreach ($menuitem[$menuid]['subitems'] AS $item)
|
||||
{
|
||||
if (($menuitem[$item]['authlevel'] != AUTH_LEVEL_ADMIN || $login->admin != 0) && $menuitem[$item]['visible'] == true)
|
||||
{
|
||||
$thisitem = $menuitem[$item];
|
||||
$thisitem['selected'] = isset($ids[$item]);
|
||||
$items[] = $thisitem;
|
||||
|
||||
$this->pAppendSubMenu($item, $ids, $items);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function GetSelectedMenuIds()
|
||||
{
|
||||
global $menuitem;
|
||||
|
||||
$retval = array();
|
||||
$retval[$this->nSelectedItem] = $this->nSelectedItem;
|
||||
|
||||
$nCurItem = $this->nSelectedItem;
|
||||
|
||||
while ($nCurItem != MNU_ROOT)
|
||||
{
|
||||
if (isset($menuitem[$nCurItem]['parent']))
|
||||
{
|
||||
$nCurItem = $menuitem[$nCurItem]['parent'];
|
||||
$retval[$nCurItem] = $nCurItem;
|
||||
}
|
||||
else
|
||||
$nCurItem = MNU_ROOT;
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function getMenuColor()
|
||||
{
|
||||
global $menuitem;
|
||||
|
||||
$nCurItem = $this->nSelectedItem;
|
||||
|
||||
while (!isset($menuitem[$nCurItem]['color']) && $nCurItem != MNU_ROOT)
|
||||
{
|
||||
if (isset($menuitem[$nCurItem]['parent']))
|
||||
{
|
||||
$nCurItem = $menuitem[$nCurItem]['parent'];
|
||||
}
|
||||
else
|
||||
$nCurItem = MNU_ROOT;
|
||||
}
|
||||
if (isset($menuitem[$nCurItem]['color']))
|
||||
return $menuitem[$nCurItem]['color'];
|
||||
else
|
||||
return '';
|
||||
}
|
||||
|
||||
function GetMenuTitle()
|
||||
{
|
||||
global $menuitem;
|
||||
|
||||
if (isset($menuitem[$this->nSelectedItem]))
|
||||
{
|
||||
return isset($menuitem[$this->nSelectedItem]['title']) ? $menuitem[$this->nSelectedItem]['title'] : '';
|
||||
}
|
||||
else
|
||||
return '';
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
***************************************************************************/
|
||||
|
||||
class MenuEditor extends Menu
|
||||
{
|
||||
function GetTopMenu()
|
||||
{
|
||||
global $menuitem, $login;
|
||||
|
||||
$ids = $this->GetSelectedMenuIds();
|
||||
|
||||
$retval = array();
|
||||
foreach ($menuitem[MNU_ROOT]['subitems'] AS $item)
|
||||
{
|
||||
$thisitem = $menuitem[$item];
|
||||
$thisitem['selected'] = isset($ids[$item]);
|
||||
$thisitem['href'] = 'menu.php?id=' . $item;
|
||||
if ($thisitem['menustring'] == '')
|
||||
$thisitem['menustring'] = t('(empty)', '', __FILE__, __LINE__);
|
||||
$retval[] = $thisitem;
|
||||
}
|
||||
|
||||
$thisitem = array();
|
||||
$thisitem['menustring'] = t('New item', '', __FILE__, __LINE__);
|
||||
$thisitem['href'] = 'menu.php?action=add&id=0';
|
||||
$retval[] = $thisitem;
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function GetSubMenu()
|
||||
{
|
||||
global $menuitem, $login;
|
||||
|
||||
$ids = $this->GetSelectedMenuIds();
|
||||
$topmenu = array_pop($ids);
|
||||
if (isset($menuitem[$topmenu]['parent']) && $menuitem[$topmenu]['parent'] != MNU_ROOT)
|
||||
die('internal error MenuEditor::GetSelectedMenuIds');
|
||||
|
||||
$ids[$topmenu] = $topmenu;
|
||||
|
||||
$retval = array();
|
||||
if ($topmenu != MNU_ROOT)
|
||||
{
|
||||
$this->pAppendSubMenu(1, $topmenu, $ids, $retval);
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function pAppendSubMenu($sublevel, $menuid, $ids, &$items)
|
||||
{
|
||||
global $menuitem, $login;
|
||||
|
||||
if (isset($menuitem[$menuid]['subitems']))
|
||||
{
|
||||
foreach ($menuitem[$menuid]['subitems'] AS $item)
|
||||
{
|
||||
$thisitem = $menuitem[$item];
|
||||
$thisitem['selected'] = isset($ids[$item]);
|
||||
$thisitem['href'] = 'menu.php?id=' . $item;
|
||||
if ($thisitem['menustring'] == '')
|
||||
$thisitem['menustring'] = t('(empty)', '', __FILE__, __LINE__);
|
||||
$items[] = $thisitem;
|
||||
|
||||
$this->pAppendSubMenu($sublevel+1, $item, $ids, $items);
|
||||
}
|
||||
}
|
||||
|
||||
$thisitem = array();
|
||||
$thisitem['menustring'] = t('New item', '', __FILE__, __LINE__);
|
||||
$thisitem['href'] = 'menu.php?action=add&id=' . $menuid;
|
||||
$thisitem['sublevel'] = $sublevel;
|
||||
$items[] = $thisitem;
|
||||
}
|
||||
|
||||
function GetSelectedMenuIds()
|
||||
{
|
||||
global $menuitem;
|
||||
|
||||
$retval = array();
|
||||
$retval[$this->nSelectedItem] = $this->nSelectedItem;
|
||||
|
||||
$nCurItem = $this->nSelectedItem;
|
||||
|
||||
while ($nCurItem != MNU_ROOT)
|
||||
{
|
||||
if (isset($menuitem[$nCurItem]['parent']))
|
||||
{
|
||||
$nCurItem = $menuitem[$nCurItem]['parent'];
|
||||
$retval[$nCurItem] = $nCurItem;
|
||||
}
|
||||
else
|
||||
$nCurItem = MNU_ROOT;
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function reorg()
|
||||
{
|
||||
$nPosition = 1;
|
||||
$nLastParent = -1;
|
||||
$rs = sqlf("SELECT `id`, `parent` FROM `sys_menu` ORDER BY `parent` ASC, `position` ASC");
|
||||
while ($r = sql_fetch_assoc($rs))
|
||||
{
|
||||
if ($nLastParent != $r['parent'])
|
||||
{
|
||||
$nPosition = 1;
|
||||
$nLastParent = $r['parent'];
|
||||
}
|
||||
|
||||
sqlf("UPDATE `sys_menu` SET `position`='&1' WHERE `id`='&2'", $nPosition, $r['id']);
|
||||
$nPosition++;
|
||||
}
|
||||
sql_free_result($rs);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* You can find the license in the docs directory
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* This module is included by each site with SOAP-output and contains
|
||||
* functions that are specific to SOAP-output. common.inc.php is included
|
||||
* and will do the setup.
|
||||
*
|
||||
* If you include this script from any subdir, you have to set the
|
||||
* variable $opt['rootpath'], so that it points (relative or absolute)
|
||||
* to the root.
|
||||
***************************************************************************/
|
||||
|
||||
// SOAP Exceptions
|
||||
|
||||
// Unknown webservice error
|
||||
define('WS_ERR_UNKOWN_ID', 500);
|
||||
define('WS_ERR_UNKOWN_STR', 'WS_ERR_UNKOWN');
|
||||
|
||||
// Currently out of service
|
||||
define('WS_ERR_OUTOFSERVICE_ID', 501);
|
||||
define('WS_ERR_OUTOFSERVICE_STR', 'WS_ERR_OUTOFSERVICE');
|
||||
|
||||
// Connection to database failed
|
||||
define('WS_ERR_DATABASE_CONNECT_ID', 502);
|
||||
define('WS_ERR_DATABASE_CONNECT_STR', 'WS_ERR_DATABASE_CONNECT');
|
||||
|
||||
// Invalid operation
|
||||
define('WS_ERR_INVALID_OP_ID', 503);
|
||||
define('WS_ERR_INVALID_OP_STR', 'WS_ERR_INVALID_OP');
|
||||
|
||||
// https required
|
||||
define('WS_ERR_REQUIRE_HTTPS_ID', 504);
|
||||
define('WS_ERR_REQUIRE_HTTPS_STR', 'WS_ERR_REQUIRE_HTTPS');
|
||||
|
||||
// authentication required
|
||||
define('WS_ERR_REQUIRE_AUTH_ID', 505);
|
||||
define('WS_ERR_REQUIRE_AUTH_STR', 'WS_ERR_REQUIRE_AUTH');
|
||||
|
||||
// setup rootpath
|
||||
if (!isset($opt['rootpath'])) $opt['rootpath'] = './';
|
||||
|
||||
// chicken-egg problem ...
|
||||
require($opt['rootpath'] . 'lib2/const.inc.php');
|
||||
|
||||
// do all output in text format
|
||||
$opt['gui'] = GUI_NUSOAP;
|
||||
|
||||
// include the main library
|
||||
require_once($opt['rootpath'] . 'lib2/common.inc.php');
|
||||
require_once($opt['rootpath'] . 'lib2/nusoap/nusoap.php');
|
||||
|
||||
function initSoapRequest($namespace, $nsurl)
|
||||
{
|
||||
global $nuserver, $HTTP_RAW_POST_DATA;
|
||||
|
||||
if(!$HTTP_RAW_POST_DATA)
|
||||
{
|
||||
$HTTP_RAW_POST_DATA = file_get_contents('php://input');
|
||||
}
|
||||
|
||||
$nuserver = new nusoap_server();
|
||||
|
||||
$nuserver->configureWSDL($namespace, $nsurl);
|
||||
$nuserver->wsdl->schemaTargetNamespace = $nsurl;
|
||||
|
||||
/*
|
||||
Define string und integer-arrays
|
||||
*/
|
||||
$nuserver->wsdl->addComplexType(
|
||||
'ArrayOfstring',
|
||||
'complexType',
|
||||
'array',
|
||||
'',
|
||||
'SOAP-ENC:Array',
|
||||
array(),
|
||||
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')),
|
||||
'xsd:string'
|
||||
);
|
||||
|
||||
$nuserver->wsdl->addComplexType(
|
||||
'ArrayOfint',
|
||||
'complexType',
|
||||
'array',
|
||||
'',
|
||||
'SOAP-ENC:Array',
|
||||
array(),
|
||||
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:int[]')),
|
||||
'xsd:int'
|
||||
);
|
||||
}
|
||||
|
||||
function finishSoapRequest()
|
||||
{
|
||||
global $nuserver, $HTTP_RAW_POST_DATA;
|
||||
|
||||
$nuserver->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '');
|
||||
exit;
|
||||
}
|
||||
|
||||
function initSoapFunction()
|
||||
{
|
||||
global $opt, $db;
|
||||
|
||||
// init faults
|
||||
if (($opt['debug'] & DEBUG_OUTOFSERVICE) == DEBUG_OUTOFSERVICE)
|
||||
{
|
||||
return new nusoap_fault(WS_ERR_OUTOFSERVICE_ID, '' , WS_ERR_OUTOFSERVICE_STR);
|
||||
}
|
||||
|
||||
if ($opt['page']['nusoap_require_https'] == true)
|
||||
{
|
||||
if (!isset($_REQUEST['HTTPS']))
|
||||
{
|
||||
return new nusoap_fault(WS_ERR_REQUIRE_HTTPS_ID, '' , WS_ERR_REQUIRE_HTTPS_STR);
|
||||
}
|
||||
}
|
||||
|
||||
if ($db['dblink'] == false)
|
||||
{
|
||||
// try connect
|
||||
sql_connect(null, null, false);
|
||||
if ($db['dblink'] == false)
|
||||
{
|
||||
return new nusoap_fault(WS_ERR_DATABASE_CONNECT_ID, '' , WS_ERR_DATABASE_CONNECT_STR);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,584 @@
|
||||
2003-07-21, version 0.6.5
|
||||
- soap_transport_http: SOAPAction header is quoted again, fixes problem w/ Weblogic Server
|
||||
- applied Jason Levitt patch for proper array serialization, fixes problem w/ Amazon shopping cart services
|
||||
- fixed null value serialization
|
||||
- applied patch from "BZC ToOn'S" - fixes wsdl serialization when no parameters
|
||||
- applied John's patch, implementing compression for the server
|
||||
|
||||
2003-07-22, version 0.6.5
|
||||
- soap_server: fixed bug causing charset encoding not to be passed to the parser
|
||||
- soap_fault: added default encoding to the fault serialization
|
||||
- soap_parser: changed the parser to pre-load the parent's result array when processing scalar values. This increases parsing speed.
|
||||
|
||||
2003-07-23, version 0.6.5
|
||||
- soap_base: fix code that overwrites user-supplied attributes in serialize_val
|
||||
- soap_base: use arrays-of-arrays rather than attempting multi-dimensional in serialize_val
|
||||
- xmlschema: emit import statements and qualify all elements with prefix in serializeSchema (better interop with validation tools)
|
||||
- soapclient: get xml character encoding from HTTP Content-Type header if provided, e.g. text/xml;charset="UTF-8"
|
||||
- soapclient: use headers in call if provided (previously ignored this parameter)
|
||||
- soap_server: in parse_request, if neither getallheaders nor $_SERVER are available, use $HTTP_SERVER_VARS to get SOAPAction and xml encoding
|
||||
|
||||
2003-07-24, version 0.6.5
|
||||
- soap_transport_http: apply patch from Steven Brown "if the server closes connection prematurely, nusoap would spin trying to read data that isn't there"
|
||||
|
||||
2003-07-25, version 0.6.5
|
||||
- wsdl: apply patch from Sven to workaround single schema limitation
|
||||
- wsdl: apply a variant of the patch from Holger to handle empty values for array by serializing an array with 0 elements
|
||||
- xmlschema: remove the redundant default namespace attribute on the schema element; everything in xsd is explicitly specified as being from xsd
|
||||
- soap_transport_http: fix setCredentials and add TODO comments in sendHTTPS about what to change if this setCredentials stays
|
||||
|
||||
2003-07-30, version 0.6.5
|
||||
- nusoap_base: change documentation of soap_defencoding to specify it is the encoding for outgoing messages
|
||||
- nusoap_base: only change &, <, > to entities, not all HTML entities
|
||||
- soap_transport_http: update the Content-Type header in sendRequest, since soap_defencoding could be changed after ctor is called
|
||||
- soap_server: use soap_defencoding instead of charset_encoding
|
||||
- soap_server: read encoding from _SERVER if available
|
||||
- nusoap_base: do entity translation for string parameters with an xsd type specified (thanks David Derr)
|
||||
|
||||
2003-07-31, version 0.6.5
|
||||
- soap_transport_http: add proxy authentication
|
||||
- soap_transport_http: build payload the same way for http and https
|
||||
- wsdl: add proxy authentication
|
||||
- soapclient: add proxy authentication
|
||||
- soapclient: allow proxy information in ctor, so that it can be used for wsdl
|
||||
|
||||
2003-08-01, version 0.6.5
|
||||
- soap_transport_http: close a persistent connection that's at EOF
|
||||
- soap_transport_http: prevent conflicts between setEncoding and usePersistentConnection
|
||||
- soap_transport_http: fix use of $headers instead of $this->incoming_headers in getResponse
|
||||
- soapclient: improve handling of persistent connections
|
||||
- soapclient: force xml_encoding to upper case
|
||||
- soap_server: let the Web server decide whether to close the connection (no Connection: close header)
|
||||
- soap_server: force xml_encoding to upper case
|
||||
|
||||
2003-08-04, version 0.6.5
|
||||
- soap_parser: use XML type information to pick a PHP data type; also decode base64
|
||||
- soap_server: read all HTTP headers when using _SERVER or HTTP_SERVER_VARS
|
||||
- soap_server: add gzip encoding support for outgoing messages
|
||||
- soap_transport_http: deflate is gzcompress/gzuncompress (cf. http://archive.develooper.com/libwww@perl.org/msg04650.html)
|
||||
- soap_transport_http: clean use of persistentConnection so it's always a set boolean
|
||||
- soapclient: add responseData member to access deflated/gunzipped payload
|
||||
|
||||
2003-08-05, version 0.6.5
|
||||
- soap_server: look multiple places when setting debug_flag
|
||||
|
||||
2003-08-07, version 0.6.5
|
||||
- nusoap_base: serialize specified type (e.g. ArrayOfString) even for simple array
|
||||
- wsdl: only specify encodingStyle in the input/output soap bindings when it is not empty (thanks Guillaume)
|
||||
|
||||
2003-08-15, version 0.6.5
|
||||
- soap_parser: fix parsing of elements with no XSD type specified
|
||||
- soap_parser: use PHP string type for XSD long and unsignedLong types
|
||||
|
||||
2003-08-16, version 0.6.5
|
||||
- soap_parser: fix code generating warning (thanks Torsten)
|
||||
|
||||
2003-08-19, version 0.6.5
|
||||
- soap_parser: fix another line of code generating a warning (thanks Torsten)
|
||||
|
||||
2003-08-22, version 0.6.5
|
||||
- soap_server: remove all '--' from debug_str; previous code changed '---' to '- --'
|
||||
- wsdl, soapclient, soap_parser: patch submitted by Mark Spavin as described by
|
||||
the following...
|
||||
> Changes for the multiple/nested imports from the wsdl file. This builds an
|
||||
> array of files not just the last one and also checks for relative paths to
|
||||
> the parent. This will then get the imported files from the remote site
|
||||
> instead of your local disk. Local wsdl files should still work (untested).
|
||||
>
|
||||
> Changes for multiple encoding sytles as previously posted
|
||||
|
||||
2003-08-24, version 0.6.5
|
||||
- wsdl, soapclient: fix some PHP notices from previous update
|
||||
|
||||
2003-08-26, version 0.6.5
|
||||
- wsdl: support multiple SOAP ports
|
||||
- soapclient, soap_server: when no charset is specified, use UTF-8, even though HTTP specifies US-ASCII.
|
||||
- soap_transport_http: do not prepend $host with 'ssl://' for https (is this required for older cURL versions?)
|
||||
|
||||
2003-08-27, version 0.6.5
|
||||
- soap_server: support compressed request messages (thanks John Huong)
|
||||
- soap_parser: deserialize Apache Vector as an array
|
||||
- xmlschema: use $this->typemap in getPHPType (which is not used)
|
||||
- soapclient, wsdl: check for WSDL errors after serializing parameters
|
||||
- nusoap_base: add serialization of Apache Map (when not using WSDL)
|
||||
- wsdl: add serialization of Apache Map (when using WSDL)
|
||||
- wsdl: only change &, <, > to entities, not all HTML entities
|
||||
|
||||
2003-08-28, version 0.6.5
|
||||
- soap_transport_http: disable cURL verification of peer and server (formerly the cURL default)
|
||||
- soap_transport_http: mingle cURL code with straight http, so sendHTTP is no longer needed
|
||||
|
||||
2003-08-29, version 0.6.6
|
||||
- soap_transport_http: add setContentType
|
||||
- soapclient: call setContentType using new getHTTPContentType and getHTTPContentTypeCharset
|
||||
|
||||
2003-09-05, version 0.6.6
|
||||
- wsdl: add some more code to handle null/nil values (but there's still a way to go)
|
||||
|
||||
2003-10-21, version 0.6.6
|
||||
- soap_transport_http: only include port in Host header if it was specified in the URL
|
||||
- soap_transport_http: add some code to use OpenSSL for PHP ssl:// scheme, but comment out since it's not ready
|
||||
- soap_server: use $_SERVER['PHP_SELF'] if $GLOBALS['PHP_SELF'] is not set
|
||||
- wsdl: add WSDL request and response and transport debug to debug
|
||||
- wsdl: handle custom type extending xmlschema namespace (GLUE ... Thanks Matt)
|
||||
- soap_parser: add param to docs
|
||||
- soapclient: add getHTTPBody, getHTTPContentType, getHTTPContentTypeCharset (anticipating MIME subclass)
|
||||
|
||||
2003-10-28, version 0.6.6
|
||||
- nusoap_base: add expandEntities method
|
||||
- wsdl: use expandEntities
|
||||
- soap_fault: use expandEntities
|
||||
- soap_transport_http: Allow credentials to be included in URL, rather than requiring setCredentials
|
||||
- soap_transport_http: Merge HTTP headers that span multiple lines
|
||||
- soap_parser: Properly set errors in ctor
|
||||
- soapclient: Pass headers to parseResponse and parse them in that method
|
||||
|
||||
2003-10-30, version 0.6.6
|
||||
- xmlschema: Add some information for the related type to an element
|
||||
|
||||
2003-12-09, version 0.6.6
|
||||
- nusoap_base: Add some namespace methods previously in xmlschema
|
||||
- xmlschema: Improve parsing of complexType, element and simpleType
|
||||
- xmlschema: Improve serialization
|
||||
- xmlschema: Track imports
|
||||
- xmlschema: Track elementFormDefault and form attributes
|
||||
- wsdl: Support multiple <schema> (note that setting $server->wsdl->schemaTargetNamespace no longer does anything! Use configureWSDL instead.)
|
||||
- wsdl: Use form attribute of element to control namespace specification
|
||||
- wsdl: Support chained imports (A imports B which imports C)
|
||||
- wsdl: Include port in endpoint address when serializing
|
||||
- soap_server: Fix use of style (rpc|document) and use (encoded|literal)
|
||||
- soap_server: Support _SERVER[CONTENT_TYPE] in addition to _SERVER[HTTP_CONTENT_TYPE]
|
||||
- soap_server: Support wsdl with multiple <schema>
|
||||
- soap_client: Remove a var_dump
|
||||
- soap_client: Add style and use parameters to call method to support doc/lit without WSDL
|
||||
- soap_transport_http: Check that $this->fp exists when doing persistent connections
|
||||
|
||||
2003-12-17, version 0.6.6
|
||||
- soap_server: pass namespaces to xmlschema constructor
|
||||
- wsdl: post-process after all imports
|
||||
- wsdl: remove some debug, add some error handling
|
||||
- xmlschema: allow enclosing namespaces to be specified in constructor
|
||||
- xmlschema: improve handling of compositors and simple types
|
||||
|
||||
2004-01-08, version 0.6.6
|
||||
- soap_server: when requested WSDL is in a file, return to client using passthru (thanks Ingo Fischer)
|
||||
- soapclient: have proxy inherit more client state
|
||||
- soapclient: allow timeout and response timeout to be specified in the constructor
|
||||
- wsdl: allow timeout and response timeout to be specified in the constructor
|
||||
- soap_transport_http: allow response timeout to be specified in send and sendHTTPS
|
||||
|
||||
2004-01-28, version 0.6.6
|
||||
- wsdl: add namespace for array and scalar when form is qualified
|
||||
- wsdl: fix a bug in which data type of complexType elements were ignored in serialization
|
||||
- wsdl: enhance handling of URLs with file scheme
|
||||
- wsdl: add addSimpleType
|
||||
- xmlschema: add addSimpleType
|
||||
- xmlschema: always set phpType elements
|
||||
- soapclient: allow a wsdl instance to be specified in constructor
|
||||
- soap_server: allow a wsdl instance to be specified in constructor (not tested!)
|
||||
- soap_server: fix default SOAPAction created in register method
|
||||
- soap_transport_http: accept chunking with LF separators in addition to CRLF.
|
||||
- wsdlcache: added class
|
||||
- nusoapmime: fix comments
|
||||
|
||||
2004-02-23, version 0.6.6
|
||||
- soap_transport_http: don't try to unchunk cURL data, since cURL already does it
|
||||
- soap_transport_http: append CVS revision to version in User-Agent
|
||||
- wsdl: serialize boolean as true|false, not 1|0, to agree with XML Schema
|
||||
- soap_server: always exit() after returning WSDL
|
||||
- soap_server: use the WSDL URL scheme as the default endpoint URL scheme
|
||||
- soap_server: append CVS revision to version in X-SOAP-Server
|
||||
- nusoap_base: add (CVS) revision
|
||||
- wsdlcache: synchronize using a per-WSDL lock file (Thanks Ingo)
|
||||
- wsdlcache: add cache lifetime, after which cache contents are invalidated (Thanks Ingo)
|
||||
|
||||
2004-03-15, version 0.6.6
|
||||
- nusoap_base: add isArraySimpleOrStruct method
|
||||
- soap_server: improve WSDL URL scheme determination
|
||||
- soap_server: only deflate/gzip payloads > 1024 bytes
|
||||
- soap_server: fix parameter order in fault method (always used as faultcode, faultstring)
|
||||
- soap_server: refactor parse_request into multiple functions (for sanity)
|
||||
- soap_server: set the namespace on the Response element to the same as the request
|
||||
- soap_server: name the return value element 'return' by default
|
||||
- soap_server: added and documented data fields, so that service programmers can use them if desired
|
||||
- soap_parser: standardize parsing error message
|
||||
- soap_parser: fix document and responseHeaders so they are the correct XML text (as documented)
|
||||
- soap_transport_http: fix read from persistent connection
|
||||
- soapclient: clean up debugging for persistent connection
|
||||
- wsdl: enforce correct naming of messages parts when an associative array is used for parameters
|
||||
- wsdl: better serialization of null values
|
||||
- wsdl: standardize parsing error message
|
||||
- xmlschema: standardize parsing error message
|
||||
|
||||
2004-03-24, version 0.6.7
|
||||
- soap_transport_http: add digest authentication (based on code by Kevin A. Miller)
|
||||
- xmlschema: improve parsing of import elements
|
||||
- wsdl: do schema imports even if there are no wsdl imports
|
||||
|
||||
2004-04-12, version 0.6.7
|
||||
- wsdl: serialize multiple elements when maxOccurs="unbounded" and value is an array
|
||||
- wsdl: serialize soapval values (used to force an XML type, e.g. when WSDL uses an abstract type)
|
||||
- nusoapmime: do not require nusoap.php (it is now the programmer's responsibility)
|
||||
|
||||
2004-04-21, version 0.6.7
|
||||
- soap_parser: parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
|
||||
- soap_server: do not wrap response in a response element for a document style service
|
||||
|
||||
2004-04-30, version 0.6.7
|
||||
- soap_transport_http: allow digest auth params to be separated by "," as well as ", "
|
||||
- soap_transport_http: re-initialize incoming headers for each response
|
||||
- soap_server: add methodreturnisliteralxml property to allow service function to return XML as a string
|
||||
- soapclient: improve rpc/literal support
|
||||
- soapclient: allow XML string as call params in addition to array
|
||||
- soapclient: support document style and literal encoding when not using WSDL
|
||||
|
||||
2004-05-05, version 0.6.7
|
||||
- wsdl: serialize PHP objects for WSDL XML Schema complexTypes, in addition to associative arrays
|
||||
- wsdl: fix WSDL generation when there is no encodingStyle
|
||||
- soap_transport_http: suppress fsockopen warnings
|
||||
- soap_transport_http: detect socket timeouts when reading (0 bytes returned)
|
||||
- soap_transport_http: read chunked content "in-line" so it works on a persistent connection
|
||||
- nusoap_base: serialize boolean as true|false, not 1|0, to agree with XML Schema
|
||||
- nusoap_base: serialize array of struct differently than array of array
|
||||
|
||||
2004-06-25, version 0.6.8
|
||||
- soap_server: prefer gzip to deflate, since IE does not like our deflate
|
||||
- soap_server: move webDescription to the wsdl class
|
||||
- soap_server: allow class and instance method calls for service (thanks Ingo Fischer and Roland Knall)
|
||||
- wsdl: get webDescription from the soap_server class
|
||||
- wsdl: allow compression from the server
|
||||
- wsdl: fix serialization of soapval without a type
|
||||
- wsdl: propagate debug value from query string to SOAP endpoint in programmatic WSDL generation
|
||||
- nusoap_base: add anyType, anySimpleType for 2001 XML Schema
|
||||
- nusoap_base: provide additional debug functions
|
||||
- soap_transport_http: ignore Content-Length when chunked encoding is used
|
||||
- soap_transport_http: remove ':' from username for Basic authentication (cf. RFC 2617)
|
||||
- soap_transport_http: urldecode username and password taken from URL
|
||||
- soap_transport_http: use raw inflate/deflate for IE/IIS compatibility, rather than having Zlib headers according to HTTP 1.1 spec
|
||||
- soap_transport_http: attempt to handle the case when both the service application and Web server compress the response
|
||||
- soapclient: when creating proxy methods, replace '.' in operation name with '__' in function name
|
||||
- soapclient: initialize requestHeaders in proxy
|
||||
- general: use new debug methods; never access debug_str directly
|
||||
|
||||
2004-09-30, version 0.6.8
|
||||
- soapclient: do not allow getProxy call when WSDL is not used
|
||||
- soapclient: use ISO-8859-1 as the charset if not specified in the Content-Type header
|
||||
- soapclient: when an empty string is specified for the call namespace, do not put the method element in a namespace
|
||||
- soapclient: let soap_transport_http check for SSL support
|
||||
- soapclient: have proxy inherit soap_defencoding from the client from which it is generated
|
||||
- soapclient: do not assume that 'ns1' is an unused namespace prefix; always generate namespace prefixes randomly
|
||||
- soap_parser: compare any encoding in the XML declaration to the charset from the HTTP Content-Type header (thanks Ingo Fischer)
|
||||
- soap_parser: improve parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
|
||||
- soap_server: use ISO-8859-1 as the charset if not specified in the Content-Type header
|
||||
- soap_server: allow suppression of automatic UTF-8 decoding
|
||||
- soap_server: fix a bug when call_user_func_array() is used
|
||||
- soap_transport_http: correct digest authentication through a proxy
|
||||
- wsdl: serialize SOAP-ENC types similarly to XSD types
|
||||
- xmlschema: force unprefixed type into default namespace
|
||||
- xmlschema: fix serialization of definition of simple types
|
||||
|
||||
2004-10-01, version 0.6.8
|
||||
- soap_parser: handle default namespace attributes
|
||||
- soap_server: add default_utf8 field
|
||||
- soap_server: support literal encoding (with RPC style)
|
||||
- soap_transport_http: parse HTTP status and generate error for 300, 302-307, 400, 401-417, 501-505 (thanks for the idea Ghislain)
|
||||
- soap_transport_http: follow HTTP redirection (HTTP status 301 and Location header) (thanks for the idea Ghislain)
|
||||
- xmlschema: allow any attributes to be specified in an element of a complexType, e.g., abstract, default, form, minOccurs, maxOccurs, nillable (thanks Jirka Pech for the original patch)
|
||||
|
||||
2004-10-02, version 0.6.8
|
||||
- soapclient: read/write cookies (thanks Ingo)
|
||||
- soap_server: change faultcode on non-resendable faults to Client
|
||||
- soap_transport_http: read/write cookies (thanks Ingo)
|
||||
|
||||
2004-10-05, version 0.6.8
|
||||
- wsdl: add addElement method
|
||||
- wsdl: support the document style in the register method
|
||||
- xmlschema: parse unnamed simpleTypes, rather than ignoring them
|
||||
- xmlschema: include untyped elements when parsing a complexType
|
||||
- xmlschema: add addElement method
|
||||
|
||||
2004-10-14, version 0.6.8
|
||||
- soapclient: support client certificates
|
||||
- soap_parser: deserialize attributes, prefixing names with "!"
|
||||
- soap_server: notify the client with HTML when WSDL is requested but not supported by service
|
||||
- soap_transport_http: support client certificates
|
||||
- wsdl: support defaults for elements of a complexType
|
||||
- wsdl: serialize elements from complexType extension base
|
||||
- wsdl: serialize data (associative array elements) as attributes according to XML Schema
|
||||
- xmlschema: record extension base if present for a complexType
|
||||
|
||||
2004-12-15, version 0.6.8
|
||||
- nusoap_base: add 2000 XML Schema (rare, but used by Akamai)
|
||||
- soap_parser: avoid deserializing more common attributes that are not data
|
||||
- soap_parser: be lax when HTTP specifies ISO-8859-1 (the default) and XML specifies UTF-8 (the norm)
|
||||
- soap_server: account for the fact that get_class_methods returns methods in all lower case (thanks Steve Haldane)
|
||||
- soap_transport_http: parse digest info that includes '=' in the data (thanks Jinsuk Kim)
|
||||
- wsdl: feably handle some cases for literal serialization of form="unqualified" elements
|
||||
- wsdl: don't serialize the decimal portion of a PHP double when the XML type is long
|
||||
- wsdl: fix serialization of attributes for complexType that is an extension
|
||||
- wsdlcache: enhance diagnostics
|
||||
- xmlschema: handle untyped elements
|
||||
- xmlschema: handle WSDL for SOAP Array that uses the base attribute plus a sequence of element
|
||||
|
||||
2005-01-22, version 0.6.8
|
||||
- wsdl: allow an element in one schema to have a type from another schema
|
||||
|
||||
2005-01-24, version 0.6.8
|
||||
- xmlschema: correctly parse nested complexType definitions
|
||||
|
||||
2005-02-14, version 0.6.8
|
||||
- nusoap_base: fix a bug in which attributes were sometimes not serialized with a value
|
||||
- nusoap_base: improve serialization of null values (thanks Dominique Stender)
|
||||
- soap_parser: parse null values by handling the nil attribute (thanks Dominique Stender)
|
||||
- soap_server: set character encoding for a fault to be the same as for the server (thanks Mark Scott)
|
||||
- soap_server: correctly check for null value returned from method when WSDL is used (without WSDL, cannot distinguish whether NULL or void return is desired)
|
||||
- soapclient: for document style, call should always return an array rooted at the response part (all bets are off when there are multiple parts)
|
||||
- xmlschema: save enumeration values parsed from WSDL
|
||||
|
||||
2005-02-10, version 0.6.9
|
||||
- soapclient: only set SOAP headers when they are specified in call params (so setHeaders still works)
|
||||
|
||||
2005-04-04, version 0.6.9
|
||||
- soap_server: use get_class instead of is_a (thanks Thomas Noel)
|
||||
- soapclient: use get_class instead of is_a (thanks Thomas Noel)
|
||||
- soapclient: add setEndpoint method
|
||||
- soap_transport_http: fix client certificates (thanks Doug Anarino and Eryan Eriobowo)
|
||||
|
||||
2005-04-29, version 0.6.9
|
||||
- nusoap_base: add global variable and methods for setting debug level
|
||||
- nusoap_base: use xsd:anyType instead of xsd:ur-type to serialize arrays with multiple element types (thanks Ingo Fischer)
|
||||
- nusoap_base: expand entities in attributes (thanks Gaetano Giunta)
|
||||
- soapclient: call parent constructor
|
||||
- soapval: call parent constructor
|
||||
- soap_fault: call parent constructor
|
||||
- soap_parser: call parent constructor
|
||||
- soap_server: assume get_class_methods always returns lower case for PHP 4.x only
|
||||
- soap_server: call parent constructor
|
||||
- soap_transport_http: do nothing in setEncoding if gzdeflate is not present (thanks Franck Touanen for pointing this out)
|
||||
- soap_transport_http: fix check for server request for digest authentication (thanks Mark Spavin)
|
||||
- soap_transport_http: call parent constructor
|
||||
- wsdl: fix documentation page popup of one method after another (thanks Owen)
|
||||
- wsdl: call parent constructor
|
||||
- wsdl: expand entities in attributes (thanks Gaetano Giunta)
|
||||
- xmlschema: call parent constructor
|
||||
|
||||
2005-06-03, version 0.6.9
|
||||
- nusoap_base: serialize empty arrays as having elements xsd:anyType[0]
|
||||
- nusoap_base: add encodingStyle parameter to serializeEnvelope
|
||||
- nusoap_base: serialize xsi:type with nil values
|
||||
- nusoap_base: improve debug and comments
|
||||
- soap_parser: correctly parse an empty array to an empty array, not an empty string
|
||||
- soap_parser: improve debug and comments
|
||||
- soap_server: specify encodingStyle for envelope when WSDL is used
|
||||
- soapclient: factor out new getProxyClassCode method
|
||||
- soapclient: specify encodingStyle for envelope
|
||||
- soapclient: improve debug and comments
|
||||
- wsdl: add namespace for Apache SOAP types if a variable of such type is serialized
|
||||
- wsdl: serialize nil value for nillable elements when no value is provided
|
||||
- wsdl: serialize xsi:type with nil values
|
||||
- wsdl: copy attributes as well as elements to an element from its complexType
|
||||
- wsdl: specify encodingStyle for operations
|
||||
- wsdl: improve debug and comments
|
||||
- xmlschema: improve debug and comments
|
||||
|
||||
2005-06-03, version 0.7.0
|
||||
- nusoap_base: improve debug and comments
|
||||
- nusoap_base: fix version, which should have been 0.7.0 since 2005-03-04
|
||||
|
||||
2005-06-06, version 0.7.1
|
||||
- nusoap_base: adjust numeric element names for serialization, instead of forcing them to 'soapVal'
|
||||
- nusoapmime: add type=text/xml to multipart/related (thanks Emmanuel Cordonnier)
|
||||
- soap_fault: fix serialization of detail
|
||||
- soap_server: check required parameters for register method
|
||||
- soap_server: when getallheaders is used, massage header names
|
||||
- soap_server: use SOAPAction to determine operation when doc/lit service does not wrap parameters in an element with the method name (thanks Peter Hrastnik)
|
||||
- soap_transport_http: correctly handle multiple HTTP/1.1 100 responses for https (thanks Jan Slabon)
|
||||
- wsdl: fixed documentation for addComplexType (thanks Csintalan Ádám)
|
||||
- wsdl: serialize array data when maxOccurs = 'unbounded' OR maxOccurs > 1 (thanks Dominique Schreckling)
|
||||
- wsdl: when serializing a string == 'false' as a boolean, set the value to false
|
||||
- wsdl: when serializing a complexType, require the PHP value supplied to be an array
|
||||
|
||||
2005-07-01, version 0.7.1
|
||||
- nusoap_base: Allow SOAP headers to be supplied as an array like parameters
|
||||
- soap_parser: de-serialize simpleContent that accompanies complexContent
|
||||
- soap_server: append debug information when programmatically-defined WSDL is returned
|
||||
- soap_transport_http: Add debug when an outgoing header is set
|
||||
- soapclient: Allow SOAP headers to be supplied as an array like parameters
|
||||
- xmlschema: serialize attributes more generally, rather than assuming they are for SOAP 1.1 Array
|
||||
- wsdl: when serializing, look up types by namespace, not prefix (simple programmatic doc/lit WSDL now seems to work)
|
||||
- wsdl: process namespace declarations first when parsing an element
|
||||
|
||||
2005-07-27, version 0.7.1
|
||||
- nusoap_base: do not override supplied element name with class name when serializing an object in serialize_val
|
||||
- nusoap_base: remove http://soapinterop.org/xsd (si) from namespaces array
|
||||
- nusoapmime: add nusoapservermime class to implement MIME attachments on the server
|
||||
- soap_fault: improve documentation
|
||||
- soap_server: improve documentation
|
||||
- soap_server: make consistent use of _SERVER and HTTP_SERVER_VARS
|
||||
- soap_server: make all incoming HTTP header keys lower case
|
||||
- soap_server: add hook functions to support subclassing for MIME attachments
|
||||
- soap_transport_http: remove an unnecessary global statement
|
||||
- soapclient: when creating a proxy, make $params within each function an associative array
|
||||
- soapval: improve documentation
|
||||
- wsdl: when serializing complexType elements, used typed serialization if there is either a type or a reference for the element
|
||||
- wsdl: allow PHP objects to be serialized as SOAP structs in serializeType
|
||||
- wsdl: for WSDL and XML Schema imports, don't forget to use the TCP port number (thanks Luca GIOPPO)
|
||||
- wsdl: make consistent use of _SERVER and HTTP_SERVER_VARS
|
||||
- xmlschema: improve documentation
|
||||
|
||||
2005-07-31, version 0.7.2
|
||||
- nusoap_base: correctly serialize attributes in serialize_val (thanks Hidran Arias)
|
||||
- soap_parser: when resolving references, do not assume that buildVal returns an array (thanks Akshell)
|
||||
- soap_parser: removed decode_entities, which does not work (thanks Martin Sarsale)
|
||||
- soap_server: fix a bug parsing headers from _SERVER and HTTP_SERVER_VARS (thanks Bert Catsburg)
|
||||
- soap_server: parse all "headers" from HTTP_SERVER_VARS (not just HTTP_*)
|
||||
- soap_server: use PHP_SELF instead of SCRIPT_NAME for WSDL endpoint
|
||||
- soap_server: when generating a fault while debug_flag is true, put debug into faultdetail
|
||||
- wsdl: add enumeration parameter to addSimpleType
|
||||
- xmlschema: add enumeration parameter to addSimpleType
|
||||
|
||||
2006-02-02, version 0.7.2
|
||||
- soapclient: initialize paramArrayStr to improve proxy generation
|
||||
- soap_parser: handle PHP5 soapclient's incorrect transmission of WSDL-described SOAP encoded arrays.
|
||||
- soap_server: don't assume _SERVER['HTTPS'] is set; try HTTP_SERVER_VARS['HTTPS'] if it is not
|
||||
- soap_server: "flatten out" the parameter array to call_user_func_array (thanks André Mamitzsch)
|
||||
- soap_server: make thrown exceptions conform to specs
|
||||
- wsdl: use serialize_val to serialize an array when the XSD type is soapenc:Array (JBoss/Axis does this)
|
||||
- wsdl: change formatting of serialized XML for the WSDL
|
||||
- xmlschema: change formatting of namespaces when serializing XML for the schema
|
||||
|
||||
2006-04-07, version 0.7.2
|
||||
- soap_server: if methodparams is not an array, call call_user_func_array with an empty array (thanks Eric Grossi)
|
||||
- wsdl: distinguish parts with element specified from those with type specified by suffixing element names with ^
|
||||
- wsdl: do a case-insensitive match on schema URI when looking for type
|
||||
- xmlschema: only get element (not type) when name has ^ suffix
|
||||
|
||||
2006-05-16, version 0.7.2
|
||||
- soapclient: add getHeader to get parsed SOAP Header
|
||||
- soap_parser: check status when receiving Header or Body element
|
||||
- soap_parser: add soapheader
|
||||
- soap_server: add requestHeader with parsed SOAP Header
|
||||
|
||||
2006-06-15, version 0.7.2
|
||||
- wsdl: fix bug in addComplexType (thanks Maarten Meijer)
|
||||
- soap_transport_http: change cURL message
|
||||
|
||||
2007-03-19, version 0.7.2
|
||||
- soapclient: declare as nusoapclient, then also subclass soapclient if SOAP extension not loaded
|
||||
- soapclientmime: declare as nusoapclientmime, then also subclass soapclientmime if SOAP extension not loaded
|
||||
|
||||
2007-03-28, version 0.7.2
|
||||
- nusoap_base: fix serialization of a soapval when its value is a soapval
|
||||
- soapval: fix serialization of a soapval when its value is a soapval
|
||||
- soapval: add __toString (cf. http://article.gmane.org/gmane.comp.php.nusoap.general/2776)
|
||||
- nusoapclient: use lazy retrieval of WSDL instead of always getting it in the constructor
|
||||
- nusoapclient: fix getProxy that was broken in last revision
|
||||
- wsdl: add ability to set authorization credentials and retrieve WSDL outside of constructor
|
||||
|
||||
2007-04-05, version 0.7.2
|
||||
- nusoapclientmime: don't rely exclusively on Content-Disposition to distinguish the root part from attachment; also check Content-Type (thanks Ben Bosman)
|
||||
- nusoapclientmime: obey RFC 2045 Section 5.1 (thanks Chris Butler)
|
||||
- nusoapservermime: don't rely exclusively on Content-Disposition to distinguish the root part from attachment; also check Content-Type (thanks Ben Bosman)
|
||||
- nusoapservermime: obey RFC 2045 Section 5.1 (thanks Chris Butler)
|
||||
- nusoap_base: remove extra whitespace from some XML elements
|
||||
- nusoap_base: allow SOAP headers to be specified as an associative array (thanks Unique)
|
||||
- nusoap_base: implement __toString
|
||||
- nusoap_base: improve doc accuracy and consistency (thanks Martin K?gler)
|
||||
- iso8601_to_timestamp: avoid problem with negative hours after calculation, etc. (thanks Guntram Trebs)
|
||||
- nusoapclient: support user-settable cURL options (thanks Ciprian Popovici)
|
||||
- nusoapclient: call SOAP 1.2 binding operations if no SOAP 1.1 present (there is no reason to believe this will always work!)
|
||||
- nusoapclient: improve doc accuracy and consistency (thanks Martin K?gler)
|
||||
- soap_server: don't try to use eval to call function when any parameter is an object
|
||||
- soap_server: don't print return value within debug string; returned objects would need __toString in PHP 5.2
|
||||
- soap_server: use URL scheme for WSDL access as the scheme in SOAPAction
|
||||
- soap_server: strip port number from server name (some FastCGI implementations include port in server name)
|
||||
- soap_transport_http: support user-settable cURL options (thanks Ciprian Popovici)
|
||||
- soap_transport_http: use cURL for NTLM authentication
|
||||
- soap_transport_http: make digest authentication work for GET as well as POST
|
||||
- soap_transport_http: improve doc accuracy and consistency (thanks Martin K?gler)
|
||||
- soapval: remove __toString
|
||||
- wsdl: set operation style if necessary, but do not override one already provided (thanks Raffaele Capobianco)
|
||||
- wsdl: check SOAP 1.2 binding operations if no SOAP 1.1 present
|
||||
- wsdl: improve doc accuracy and consistency (thanks Martin K?gler)
|
||||
- xmlschema: fix simpleType serialization
|
||||
- xmlschema: improve doc accuracy and consistency (thanks Martin K?gler)
|
||||
|
||||
2007-04-09, version 0.7.2
|
||||
- nusoapclient: set decode_utf8 when creating a proxy (thanks Dmitri Dmitrienko)
|
||||
- nusoapclient: rename class to nusoap_client
|
||||
- soap_fault: also provide a class named nusoap_fault
|
||||
- soap_parser: also provide a class named nusoap_parser
|
||||
- soap_server: also provide a class named nusoap_server
|
||||
- soap_transport_http: skip HTTP responses 301 and 401 when using cURL
|
||||
- soap_transport_http: don't force HTTP Connection header when using cURL
|
||||
- soap_transport_http: don't set HTTP Host and Content-Length headers when using cURL
|
||||
- soap_transport_http: support CURLOPT_SSLCERTPASSWD (thanks David Blanco)
|
||||
- wsdl: support user-settable cURL options (thanks Ciprian Popovici)
|
||||
- wsdl: serialize parameters for non-SOAP 1.1 binding operations (there is no reason to believe this will always work!)
|
||||
- xmlschema: also provide a class named nusoap_xmlschema
|
||||
- nusoapclientmime: rename class to nusoap_client_mime
|
||||
- nusoapservermime: rename class to nusoap_server_mime
|
||||
|
||||
2007-04-11, version 0.7.2
|
||||
- nusoap_client: enable cURL usage to be forced (thanks Giunta Gaetano)
|
||||
- soap_transport_http: enable cURL proxy usage (thanks Giunta Gaetano)
|
||||
- soap_transport_http: enable cURL usage to be forced (thanks Giunta Gaetano)
|
||||
- soap_transport_http: use cURL's HTTP authentication options for basic, digest
|
||||
- wsdl: enable cURL usage to be forced (thanks Giunta Gaetano)
|
||||
|
||||
2007-04-12, version 0.7.2
|
||||
- nusoap_client: add debug
|
||||
- nusoap_xmlschema: don't add elements of complexTypes to elements array (thanks Heiko Hund)
|
||||
- soap_transport_http: set cURL connection timeout if supported
|
||||
- soap_transport_http: add debug when setting cURL option
|
||||
- soap_transport_http: fix digest authentication broken in previous revision
|
||||
- wsdl: add debug
|
||||
- wsdlcache: address some issues with non-existing cache-files and PHP Warnings which came in such cases (thanks Ingo Fischer)
|
||||
- wsdlcache: change class name to nusoap_wsdlcache
|
||||
|
||||
2007-04-13, version 0.7.2
|
||||
- wsdl: wrap parameters if unwrapped values are supplied and WSDL specifies Microsoft-style wrapping
|
||||
|
||||
2007-04-16, version 0.7.2
|
||||
- nusoap_base: avoid warning in getDebugAsXMLComment
|
||||
- nusoap_client: small debug change
|
||||
- nusoap_client_mime: set responseData when the root part is found
|
||||
|
||||
2007-04-17, version 0.7.2
|
||||
- soap_transport_http: improve detection of undefined cURL options (thanks Ingo Fischer)
|
||||
|
||||
2007-05-28, version 0.7.2
|
||||
- soap_transport_http: support digest authentication opaque feature (cf. RFC 2617) (thanks Daniel Lacroix)
|
||||
- soap_transport_http: check safe_mode and open_basedir before setting CURLOPT_FOLLOWLOCATION
|
||||
- soap_transport_http: skip "HTTP/1.0 200 Connection established" header when cURL returns it (thanks Raimund Jacob)
|
||||
- nusoap_client: improve handling when getProxy is called and WSDL is not being used
|
||||
- nusoap_base: add comments about which specifications are used/implemented by NuSOAP
|
||||
- nusoap_xmlschema: create names for unnamed types that are unique by scope within XML Schema
|
||||
|
||||
2007-06-11, version 0.7.2
|
||||
- wsdl: wrap return value if unwrapped value is supplied and WSDL specifies Microsoft-style wrapping
|
||||
|
||||
2007-06-22, version 0.7.2
|
||||
- nusoap_xmlschema: fix serialization of simpleType restriction (thanks Rizwan Tejpar)
|
||||
|
||||
2007-07-30, version 0.7.2
|
||||
- nusoap_server: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
|
||||
- nusoap_client: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
|
||||
|
||||
2007-10-21, version 0.7.2
|
||||
- nusoap_server: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
|
||||
- nusoap_client: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
|
||||
|
||||
2007-10-26, version 0.7.2
|
||||
- nusoap_server: Fix munging of _SERVER variables that start with HTTP_ (thanks Thomas Wieczorek)
|
||||
|
||||
2007-10-30, version 0.7.2
|
||||
- nusoap_xmlschema: Serialize values for elementFormDefault, attributeFormDefault
|
||||
- wsdl: Improve consistency between doc/lit schema auto-wrapping and client's parsed schema
|
||||
- nusoap_server: Correct bug that placed encodingType in Envelope for doc/lit
|
||||
- nusoap_server: Specify elementFormDefault for schema within doc/lit wsdl
|
||||
|
||||
2007-10-31, version 0.7.2
|
||||
- wsdl: Fix typo in parametersMatchWrapped (thanks Sam Stepanyan)
|
||||
- soap_transport_http: Fix three typos in setProxy (thanks Sam Stepanyan)
|
||||
- nusoap_xmlschema: Fix typo in serializeTypeDef (thanks Sam Stepanyan)
|
||||
@@ -0,0 +1,984 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
$Id: class.nusoap_base.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
|
||||
NuSOAP - Web Services Toolkit for PHP
|
||||
|
||||
Copyright (c) 2002 NuSphere Corporation
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
The NuSOAP project home is:
|
||||
http://sourceforge.net/projects/nusoap/
|
||||
|
||||
The primary support for NuSOAP is the mailing list:
|
||||
nusoap-general@lists.sourceforge.net
|
||||
|
||||
If you have any questions or comments, please email:
|
||||
|
||||
Dietrich Ayala
|
||||
dietrich@ganx4.com
|
||||
http://dietrich.ganx4.com/nusoap
|
||||
|
||||
NuSphere Corporation
|
||||
http://www.nusphere.com
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some of the standards implmented in whole or part by NuSOAP:
|
||||
*
|
||||
* SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
|
||||
* WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
|
||||
* SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
|
||||
* XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
|
||||
* Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
|
||||
* XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
|
||||
* RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
|
||||
* RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
|
||||
* RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
|
||||
*/
|
||||
|
||||
/* load classes
|
||||
|
||||
// necessary classes
|
||||
require_once('class.soapclient.php');
|
||||
require_once('class.soap_val.php');
|
||||
require_once('class.soap_parser.php');
|
||||
require_once('class.soap_fault.php');
|
||||
|
||||
// transport classes
|
||||
require_once('class.soap_transport_http.php');
|
||||
|
||||
// optional add-on classes
|
||||
require_once('class.xmlschema.php');
|
||||
require_once('class.wsdl.php');
|
||||
|
||||
// server class
|
||||
require_once('class.soap_server.php');*/
|
||||
|
||||
// class variable emulation
|
||||
// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
|
||||
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
|
||||
|
||||
/**
|
||||
*
|
||||
* nusoap_base
|
||||
*
|
||||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||||
* @author Scott Nichol <snichol@users.sourceforge.net>
|
||||
* @version $Id: class.nusoap_base.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_base {
|
||||
/**
|
||||
* Identification for HTTP headers.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $title = 'NuSOAP';
|
||||
/**
|
||||
* Version for HTTP headers.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $version = '0.7.3';
|
||||
/**
|
||||
* CVS revision for HTTP headers.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $revision = '$Revision: 1.1 $';
|
||||
/**
|
||||
* Current error string (manipulated by getError/setError)
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $error_str = '';
|
||||
/**
|
||||
* Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $debug_str = '';
|
||||
/**
|
||||
* toggles automatic encoding of special characters as entities
|
||||
* (should always be true, I think)
|
||||
*
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $charencoding = true;
|
||||
/**
|
||||
* the debug level for this instance
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $debugLevel;
|
||||
|
||||
/**
|
||||
* set schema version
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
|
||||
|
||||
/**
|
||||
* charset encoding for outgoing messages
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $soap_defencoding = 'ISO-8859-1';
|
||||
//var $soap_defencoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* namespaces in an array of prefix => uri
|
||||
*
|
||||
* this is "seeded" by a set of constants, but it may be altered by code
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $namespaces = array(
|
||||
'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
||||
'xsd' => 'http://www.w3.org/2001/XMLSchema',
|
||||
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
|
||||
);
|
||||
|
||||
/**
|
||||
* namespaces used in the current context, e.g. during serialization
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $usedNamespaces = array();
|
||||
|
||||
/**
|
||||
* XML Schema types in an array of uri => (array of xml type => php type)
|
||||
* is this legacy yet?
|
||||
* no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $typemap = array(
|
||||
'http://www.w3.org/2001/XMLSchema' => array(
|
||||
'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
|
||||
'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
|
||||
'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
|
||||
// abstract "any" types
|
||||
'anyType'=>'string','anySimpleType'=>'string',
|
||||
// derived datatypes
|
||||
'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
|
||||
'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
|
||||
'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
|
||||
'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
|
||||
'http://www.w3.org/2000/10/XMLSchema' => array(
|
||||
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
|
||||
'float'=>'double','dateTime'=>'string',
|
||||
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
|
||||
'http://www.w3.org/1999/XMLSchema' => array(
|
||||
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
|
||||
'float'=>'double','dateTime'=>'string',
|
||||
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
|
||||
'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
|
||||
'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
|
||||
'http://xml.apache.org/xml-soap' => array('Map')
|
||||
);
|
||||
|
||||
/**
|
||||
* XML entities to convert
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
* @deprecated
|
||||
* @see expandEntities
|
||||
*/
|
||||
var $xmlEntities = array('quot' => '"','amp' => '&',
|
||||
'lt' => '<','gt' => '>','apos' => "'");
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function nusoap_base() {
|
||||
$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the global debug level, which applies to future instances
|
||||
*
|
||||
* @return integer Debug level 0-9, where 0 turns off
|
||||
* @access public
|
||||
*/
|
||||
function getGlobalDebugLevel() {
|
||||
return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the global debug level, which applies to future instances
|
||||
*
|
||||
* @param int $level Debug level 0-9, where 0 turns off
|
||||
* @access public
|
||||
*/
|
||||
function setGlobalDebugLevel($level) {
|
||||
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the debug level for this instance
|
||||
*
|
||||
* @return int Debug level 0-9, where 0 turns off
|
||||
* @access public
|
||||
*/
|
||||
function getDebugLevel() {
|
||||
return $this->debugLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the debug level for this instance
|
||||
*
|
||||
* @param int $level Debug level 0-9, where 0 turns off
|
||||
* @access public
|
||||
*/
|
||||
function setDebugLevel($level) {
|
||||
$this->debugLevel = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds debug data to the instance debug string with formatting
|
||||
*
|
||||
* @param string $string debug data
|
||||
* @access private
|
||||
*/
|
||||
function debug($string){
|
||||
if ($this->debugLevel > 0) {
|
||||
$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* adds debug data to the instance debug string without formatting
|
||||
*
|
||||
* @param string $string debug data
|
||||
* @access public
|
||||
*/
|
||||
function appendDebug($string){
|
||||
if ($this->debugLevel > 0) {
|
||||
// it would be nice to use a memory stream here to use
|
||||
// memory more efficiently
|
||||
$this->debug_str .= $string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clears the current debug data for this instance
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function clearDebug() {
|
||||
// it would be nice to use a memory stream here to use
|
||||
// memory more efficiently
|
||||
$this->debug_str = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the current debug data for this instance
|
||||
*
|
||||
* @return debug data
|
||||
* @access public
|
||||
*/
|
||||
function &getDebug() {
|
||||
// it would be nice to use a memory stream here to use
|
||||
// memory more efficiently
|
||||
return $this->debug_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the current debug data for this instance as an XML comment
|
||||
* this may change the contents of the debug data
|
||||
*
|
||||
* @return debug data as an XML comment
|
||||
* @access public
|
||||
*/
|
||||
function &getDebugAsXMLComment() {
|
||||
// it would be nice to use a memory stream here to use
|
||||
// memory more efficiently
|
||||
while (strpos($this->debug_str, '--')) {
|
||||
$this->debug_str = str_replace('--', '- -', $this->debug_str);
|
||||
}
|
||||
$ret = "<!--\n" . $this->debug_str . "\n-->";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* expands entities, e.g. changes '<' to '<'.
|
||||
*
|
||||
* @param string $val The string in which to expand entities.
|
||||
* @access private
|
||||
*/
|
||||
function expandEntities($val) {
|
||||
if ($this->charencoding) {
|
||||
$val = str_replace('&', '&', $val);
|
||||
$val = str_replace("'", ''', $val);
|
||||
$val = str_replace('"', '"', $val);
|
||||
$val = str_replace('<', '<', $val);
|
||||
$val = str_replace('>', '>', $val);
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns error string if present
|
||||
*
|
||||
* @return mixed error string or false
|
||||
* @access public
|
||||
*/
|
||||
function getError(){
|
||||
if($this->error_str != ''){
|
||||
return $this->error_str;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets error string
|
||||
*
|
||||
* @return boolean $string error string
|
||||
* @access private
|
||||
*/
|
||||
function setError($str){
|
||||
$this->error_str = $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* detect if array is a simple array or a struct (associative array)
|
||||
*
|
||||
* @param mixed $val The PHP array
|
||||
* @return string (arraySimple|arrayStruct)
|
||||
* @access private
|
||||
*/
|
||||
function isArraySimpleOrStruct($val) {
|
||||
$keyList = array_keys($val);
|
||||
foreach ($keyList as $keyListValue) {
|
||||
if (!is_int($keyListValue)) {
|
||||
return 'arrayStruct';
|
||||
}
|
||||
}
|
||||
return 'arraySimple';
|
||||
}
|
||||
|
||||
/**
|
||||
* serializes PHP values in accordance w/ section 5. Type information is
|
||||
* not serialized if $use == 'literal'.
|
||||
*
|
||||
* @param mixed $val The value to serialize
|
||||
* @param string $name The name (local part) of the XML element
|
||||
* @param string $type The XML schema type (local part) for the element
|
||||
* @param string $name_ns The namespace for the name of the XML element
|
||||
* @param string $type_ns The namespace for the type of the element
|
||||
* @param array $attributes The attributes to serialize as name=>value pairs
|
||||
* @param string $use The WSDL "use" (encoded|literal)
|
||||
* @param boolean $soapval Whether this is called from soapval.
|
||||
* @return string The serialized element, possibly with child elements
|
||||
* @access public
|
||||
*/
|
||||
function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
|
||||
$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
|
||||
$this->appendDebug('value=' . $this->varDump($val));
|
||||
$this->appendDebug('attributes=' . $this->varDump($attributes));
|
||||
|
||||
if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
|
||||
$this->debug("serialize_val: serialize soapval");
|
||||
$xml = $val->serialize($use);
|
||||
$this->appendDebug($val->getDebug());
|
||||
$val->clearDebug();
|
||||
$this->debug("serialize_val of soapval returning $xml");
|
||||
return $xml;
|
||||
}
|
||||
// force valid name if necessary
|
||||
if (is_numeric($name)) {
|
||||
$name = '__numeric_' . $name;
|
||||
} elseif (! $name) {
|
||||
$name = 'noname';
|
||||
}
|
||||
// if name has ns, add ns prefix to name
|
||||
$xmlns = '';
|
||||
if($name_ns){
|
||||
$prefix = 'nu'.rand(1000,9999);
|
||||
$name = $prefix.':'.$name;
|
||||
$xmlns .= " xmlns:$prefix=\"$name_ns\"";
|
||||
}
|
||||
// if type is prefixed, create type prefix
|
||||
if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
|
||||
// need to fix this. shouldn't default to xsd if no ns specified
|
||||
// w/o checking against typemap
|
||||
$type_prefix = 'xsd';
|
||||
} elseif($type_ns){
|
||||
$type_prefix = 'ns'.rand(1000,9999);
|
||||
$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
|
||||
}
|
||||
// serialize attributes if present
|
||||
$atts = '';
|
||||
if($attributes){
|
||||
foreach($attributes as $k => $v){
|
||||
$atts .= " $k=\"".$this->expandEntities($v).'"';
|
||||
}
|
||||
}
|
||||
// serialize null value
|
||||
if (is_null($val)) {
|
||||
$this->debug("serialize_val: serialize null");
|
||||
if ($use == 'literal') {
|
||||
// TODO: depends on minOccurs
|
||||
$xml = "<$name$xmlns$atts/>";
|
||||
$this->debug("serialize_val returning $xml");
|
||||
return $xml;
|
||||
} else {
|
||||
if (isset($type) && isset($type_prefix)) {
|
||||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||||
} else {
|
||||
$type_str = '';
|
||||
}
|
||||
$xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
|
||||
$this->debug("serialize_val returning $xml");
|
||||
return $xml;
|
||||
}
|
||||
}
|
||||
// serialize if an xsd built-in primitive type
|
||||
if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
|
||||
$this->debug("serialize_val: serialize xsd built-in primitive type");
|
||||
if (is_bool($val)) {
|
||||
if ($type == 'boolean') {
|
||||
$val = $val ? 'true' : 'false';
|
||||
} elseif (! $val) {
|
||||
$val = 0;
|
||||
}
|
||||
} else if (is_string($val)) {
|
||||
$val = $this->expandEntities($val);
|
||||
}
|
||||
if ($use == 'literal') {
|
||||
$xml = "<$name$xmlns$atts>$val</$name>";
|
||||
$this->debug("serialize_val returning $xml");
|
||||
return $xml;
|
||||
} else {
|
||||
$xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
|
||||
$this->debug("serialize_val returning $xml");
|
||||
return $xml;
|
||||
}
|
||||
}
|
||||
// detect type and serialize
|
||||
$xml = '';
|
||||
switch(true) {
|
||||
case (is_bool($val) || $type == 'boolean'):
|
||||
$this->debug("serialize_val: serialize boolean");
|
||||
if ($type == 'boolean') {
|
||||
$val = $val ? 'true' : 'false';
|
||||
} elseif (! $val) {
|
||||
$val = 0;
|
||||
}
|
||||
if ($use == 'literal') {
|
||||
$xml .= "<$name$xmlns$atts>$val</$name>";
|
||||
} else {
|
||||
$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
|
||||
}
|
||||
break;
|
||||
case (is_int($val) || is_long($val) || $type == 'int'):
|
||||
$this->debug("serialize_val: serialize int");
|
||||
if ($use == 'literal') {
|
||||
$xml .= "<$name$xmlns$atts>$val</$name>";
|
||||
} else {
|
||||
$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
|
||||
}
|
||||
break;
|
||||
case (is_float($val)|| is_double($val) || $type == 'float'):
|
||||
$this->debug("serialize_val: serialize float");
|
||||
if ($use == 'literal') {
|
||||
$xml .= "<$name$xmlns$atts>$val</$name>";
|
||||
} else {
|
||||
$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
|
||||
}
|
||||
break;
|
||||
case (is_string($val) || $type == 'string'):
|
||||
$this->debug("serialize_val: serialize string");
|
||||
$val = $this->expandEntities($val);
|
||||
if ($use == 'literal') {
|
||||
$xml .= "<$name$xmlns$atts>$val</$name>";
|
||||
} else {
|
||||
$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
|
||||
}
|
||||
break;
|
||||
case is_object($val):
|
||||
$this->debug("serialize_val: serialize object");
|
||||
if (get_class($val) == 'soapval') {
|
||||
$this->debug("serialize_val: serialize soapval object");
|
||||
$pXml = $val->serialize($use);
|
||||
$this->appendDebug($val->getDebug());
|
||||
$val->clearDebug();
|
||||
} else {
|
||||
if (! $name) {
|
||||
$name = get_class($val);
|
||||
$this->debug("In serialize_val, used class name $name as element name");
|
||||
} else {
|
||||
$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
|
||||
}
|
||||
foreach(get_object_vars($val) as $k => $v){
|
||||
$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
|
||||
}
|
||||
}
|
||||
if(isset($type) && isset($type_prefix)){
|
||||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||||
} else {
|
||||
$type_str = '';
|
||||
}
|
||||
if ($use == 'literal') {
|
||||
$xml .= "<$name$xmlns$atts>$pXml</$name>";
|
||||
} else {
|
||||
$xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case (is_array($val) || $type):
|
||||
// detect if struct or array
|
||||
$valueType = $this->isArraySimpleOrStruct($val);
|
||||
if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
|
||||
$this->debug("serialize_val: serialize array");
|
||||
$i = 0;
|
||||
if(is_array($val) && count($val)> 0){
|
||||
foreach($val as $v){
|
||||
if(is_object($v) && get_class($v) == 'soapval'){
|
||||
$tt_ns = $v->type_ns;
|
||||
$tt = $v->type;
|
||||
} elseif (is_array($v)) {
|
||||
$tt = $this->isArraySimpleOrStruct($v);
|
||||
} else {
|
||||
$tt = gettype($v);
|
||||
}
|
||||
$array_types[$tt] = 1;
|
||||
// TODO: for literal, the name should be $name
|
||||
$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
|
||||
++$i;
|
||||
}
|
||||
if(count($array_types) > 1){
|
||||
$array_typename = 'xsd:anyType';
|
||||
} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
|
||||
if ($tt == 'integer') {
|
||||
$tt = 'int';
|
||||
}
|
||||
$array_typename = 'xsd:'.$tt;
|
||||
} elseif(isset($tt) && $tt == 'arraySimple'){
|
||||
$array_typename = 'SOAP-ENC:Array';
|
||||
} elseif(isset($tt) && $tt == 'arrayStruct'){
|
||||
$array_typename = 'unnamed_struct_use_soapval';
|
||||
} else {
|
||||
// if type is prefixed, create type prefix
|
||||
if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
|
||||
$array_typename = 'xsd:' . $tt;
|
||||
} elseif ($tt_ns) {
|
||||
$tt_prefix = 'ns' . rand(1000, 9999);
|
||||
$array_typename = "$tt_prefix:$tt";
|
||||
$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
|
||||
} else {
|
||||
$array_typename = $tt;
|
||||
}
|
||||
}
|
||||
$array_type = $i;
|
||||
if ($use == 'literal') {
|
||||
$type_str = '';
|
||||
} else if (isset($type) && isset($type_prefix)) {
|
||||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||||
} else {
|
||||
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
|
||||
}
|
||||
// empty array
|
||||
} else {
|
||||
if ($use == 'literal') {
|
||||
$type_str = '';
|
||||
} else if (isset($type) && isset($type_prefix)) {
|
||||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||||
} else {
|
||||
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
|
||||
}
|
||||
}
|
||||
// TODO: for array in literal, there is no wrapper here
|
||||
$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
|
||||
} else {
|
||||
// got a struct
|
||||
$this->debug("serialize_val: serialize struct");
|
||||
if(isset($type) && isset($type_prefix)){
|
||||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||||
} else {
|
||||
$type_str = '';
|
||||
}
|
||||
if ($use == 'literal') {
|
||||
$xml .= "<$name$xmlns$atts>";
|
||||
} else {
|
||||
$xml .= "<$name$xmlns$type_str$atts>";
|
||||
}
|
||||
foreach($val as $k => $v){
|
||||
// Apache Map
|
||||
if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
|
||||
$xml .= '<item>';
|
||||
$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
|
||||
$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
|
||||
$xml .= '</item>';
|
||||
} else {
|
||||
$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
|
||||
}
|
||||
}
|
||||
$xml .= "</$name>";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->debug("serialize_val: serialize unknown");
|
||||
$xml .= 'not detected, got '.gettype($val).' for '.$val;
|
||||
break;
|
||||
}
|
||||
$this->debug("serialize_val returning $xml");
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* serializes a message
|
||||
*
|
||||
* @param string $body the XML of the SOAP body
|
||||
* @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
|
||||
* @param array $namespaces optional the namespaces used in generating the body and headers
|
||||
* @param string $style optional (rpc|document)
|
||||
* @param string $use optional (encoded|literal)
|
||||
* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
|
||||
* @return string the message
|
||||
* @access public
|
||||
*/
|
||||
function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
|
||||
// TODO: add an option to automatically run utf8_encode on $body and $headers
|
||||
// if $this->soap_defencoding is UTF-8. Not doing this automatically allows
|
||||
// one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
|
||||
|
||||
$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
|
||||
$this->debug("headers:");
|
||||
$this->appendDebug($this->varDump($headers));
|
||||
$this->debug("namespaces:");
|
||||
$this->appendDebug($this->varDump($namespaces));
|
||||
|
||||
// serialize namespaces
|
||||
$ns_string = '';
|
||||
foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
|
||||
$ns_string .= " xmlns:$k=\"$v\"";
|
||||
}
|
||||
if($encodingStyle) {
|
||||
$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
|
||||
}
|
||||
|
||||
// serialize headers
|
||||
if($headers){
|
||||
if (is_array($headers)) {
|
||||
$xml = '';
|
||||
foreach ($headers as $k => $v) {
|
||||
if (is_object($v) && get_class($v) == 'soapval') {
|
||||
$xml .= $this->serialize_val($v, false, false, false, false, false, $use);
|
||||
} else {
|
||||
$xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
|
||||
}
|
||||
}
|
||||
$headers = $xml;
|
||||
$this->debug("In serializeEnvelope, serialized array of headers to $headers");
|
||||
}
|
||||
$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
|
||||
}
|
||||
// serialize envelope
|
||||
return
|
||||
'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
|
||||
'<SOAP-ENV:Envelope'.$ns_string.">".
|
||||
$headers.
|
||||
"<SOAP-ENV:Body>".
|
||||
$body.
|
||||
"</SOAP-ENV:Body>".
|
||||
"</SOAP-ENV:Envelope>";
|
||||
}
|
||||
|
||||
/**
|
||||
* formats a string to be inserted into an HTML stream
|
||||
*
|
||||
* @param string $str The string to format
|
||||
* @return string The formatted string
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function formatDump($str){
|
||||
$str = htmlspecialchars($str);
|
||||
return nl2br($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* contracts (changes namespace to prefix) a qualified name
|
||||
*
|
||||
* @param string $qname qname
|
||||
* @return string contracted qname
|
||||
* @access private
|
||||
*/
|
||||
function contractQname($qname){
|
||||
// get element namespace
|
||||
//$this->xdebug("Contract $qname");
|
||||
if (strrpos($qname, ':')) {
|
||||
// get unqualified name
|
||||
$name = substr($qname, strrpos($qname, ':') + 1);
|
||||
// get ns
|
||||
$ns = substr($qname, 0, strrpos($qname, ':'));
|
||||
$p = $this->getPrefixFromNamespace($ns);
|
||||
if ($p) {
|
||||
return $p . ':' . $name;
|
||||
}
|
||||
return $qname;
|
||||
} else {
|
||||
return $qname;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* expands (changes prefix to namespace) a qualified name
|
||||
*
|
||||
* @param string $qname qname
|
||||
* @return string expanded qname
|
||||
* @access private
|
||||
*/
|
||||
function expandQname($qname){
|
||||
// get element prefix
|
||||
if(strpos($qname,':') && !ereg('^http://',$qname)){
|
||||
// get unqualified name
|
||||
$name = substr(strstr($qname,':'),1);
|
||||
// get ns prefix
|
||||
$prefix = substr($qname,0,strpos($qname,':'));
|
||||
if(isset($this->namespaces[$prefix])){
|
||||
return $this->namespaces[$prefix].':'.$name;
|
||||
} else {
|
||||
return $qname;
|
||||
}
|
||||
} else {
|
||||
return $qname;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the local part of a prefixed string
|
||||
* returns the original string, if not prefixed
|
||||
*
|
||||
* @param string $str The prefixed string
|
||||
* @return string The local part
|
||||
* @access public
|
||||
*/
|
||||
function getLocalPart($str){
|
||||
if($sstr = strrchr($str,':')){
|
||||
// get unqualified name
|
||||
return substr( $sstr, 1 );
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the prefix part of a prefixed string
|
||||
* returns false, if not prefixed
|
||||
*
|
||||
* @param string $str The prefixed string
|
||||
* @return mixed The prefix or false if there is no prefix
|
||||
* @access public
|
||||
*/
|
||||
function getPrefix($str){
|
||||
if($pos = strrpos($str,':')){
|
||||
// get prefix
|
||||
return substr($str,0,$pos);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* pass it a prefix, it returns a namespace
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @return mixed The namespace, false if no namespace has the specified prefix
|
||||
* @access public
|
||||
*/
|
||||
function getNamespaceFromPrefix($prefix){
|
||||
if (isset($this->namespaces[$prefix])) {
|
||||
return $this->namespaces[$prefix];
|
||||
}
|
||||
//$this->setError("No namespace registered for prefix '$prefix'");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the prefix for a given namespace (or prefix)
|
||||
* or false if no prefixes registered for the given namespace
|
||||
*
|
||||
* @param string $ns The namespace
|
||||
* @return mixed The prefix, false if the namespace has no prefixes
|
||||
* @access public
|
||||
*/
|
||||
function getPrefixFromNamespace($ns) {
|
||||
foreach ($this->namespaces as $p => $n) {
|
||||
if ($ns == $n || $ns == $p) {
|
||||
$this->usedNamespaces[$p] = $n;
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the time in ODBC canonical form with microseconds
|
||||
*
|
||||
* @return string The time in ODBC canonical form with microseconds
|
||||
* @access public
|
||||
*/
|
||||
function getmicrotime() {
|
||||
if (function_exists('gettimeofday')) {
|
||||
$tod = gettimeofday();
|
||||
$sec = $tod['sec'];
|
||||
$usec = $tod['usec'];
|
||||
} else {
|
||||
$sec = time();
|
||||
$usec = 0;
|
||||
}
|
||||
return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with the output of var_dump
|
||||
*
|
||||
* @param mixed $data The variable to var_dump
|
||||
* @return string The output of var_dump
|
||||
* @access public
|
||||
*/
|
||||
function varDump($data) {
|
||||
ob_start();
|
||||
var_dump($data);
|
||||
$ret_val = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* represents the object as a string
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function __toString() {
|
||||
return $this->varDump($this);
|
||||
}
|
||||
}
|
||||
|
||||
// XML Schema Datatype Helper Functions
|
||||
|
||||
//xsd:dateTime helpers
|
||||
|
||||
/**
|
||||
* convert unix timestamp to ISO 8601 compliant date string
|
||||
*
|
||||
* @param string $timestamp Unix time stamp
|
||||
* @param boolean $utc Whether the time stamp is UTC or local
|
||||
* @access public
|
||||
*/
|
||||
function timestamp_to_iso8601($timestamp,$utc=true){
|
||||
$datestr = date('Y-m-d\TH:i:sO',$timestamp);
|
||||
if($utc){
|
||||
$eregStr =
|
||||
'([0-9]{4})-'. // centuries & years CCYY-
|
||||
'([0-9]{2})-'. // months MM-
|
||||
'([0-9]{2})'. // days DD
|
||||
'T'. // separator T
|
||||
'([0-9]{2}):'. // hours hh:
|
||||
'([0-9]{2}):'. // minutes mm:
|
||||
'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
|
||||
'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
|
||||
|
||||
if(ereg($eregStr,$datestr,$regs)){
|
||||
return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return $datestr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* convert ISO 8601 compliant date string to unix timestamp
|
||||
*
|
||||
* @param string $datestr ISO 8601 compliant date string
|
||||
* @access public
|
||||
*/
|
||||
function iso8601_to_timestamp($datestr){
|
||||
$eregStr =
|
||||
'([0-9]{4})-'. // centuries & years CCYY-
|
||||
'([0-9]{2})-'. // months MM-
|
||||
'([0-9]{2})'. // days DD
|
||||
'T'. // separator T
|
||||
'([0-9]{2}):'. // hours hh:
|
||||
'([0-9]{2}):'. // minutes mm:
|
||||
'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
|
||||
'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
|
||||
if(ereg($eregStr,$datestr,$regs)){
|
||||
// not utc
|
||||
if($regs[8] != 'Z'){
|
||||
$op = substr($regs[8],0,1);
|
||||
$h = substr($regs[8],1,2);
|
||||
$m = substr($regs[8],strlen($regs[8])-2,2);
|
||||
if($op == '-'){
|
||||
$regs[4] = $regs[4] + $h;
|
||||
$regs[5] = $regs[5] + $m;
|
||||
} elseif($op == '+'){
|
||||
$regs[4] = $regs[4] - $h;
|
||||
$regs[5] = $regs[5] - $m;
|
||||
}
|
||||
}
|
||||
return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
|
||||
// return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sleeps some number of microseconds
|
||||
*
|
||||
* @param string $usec the number of microseconds to sleep
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function usleepWindows($usec)
|
||||
{
|
||||
$start = gettimeofday();
|
||||
|
||||
do
|
||||
{
|
||||
$stop = gettimeofday();
|
||||
$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
|
||||
+ $stop['usec'] - $start['usec'];
|
||||
}
|
||||
while ($timePassed < $usec);
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Contains information for a SOAP fault.
|
||||
* Mainly used for returning faults from deployed functions
|
||||
* in a server instance.
|
||||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||||
* @version $Id: class.soap_fault.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_fault extends nusoap_base {
|
||||
/**
|
||||
* The fault code (client|server)
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $faultcode;
|
||||
/**
|
||||
* The fault actor
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $faultactor;
|
||||
/**
|
||||
* The fault string, a description of the fault
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $faultstring;
|
||||
/**
|
||||
* The fault detail, typically a string or array of string
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $faultdetail;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $faultcode (SOAP-ENV:Client | SOAP-ENV:Server)
|
||||
* @param string $faultactor only used when msg routed between multiple actors
|
||||
* @param string $faultstring human readable error message
|
||||
* @param mixed $faultdetail detail, typically a string or array of string
|
||||
*/
|
||||
function nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
|
||||
parent::nusoap_base();
|
||||
$this->faultcode = $faultcode;
|
||||
$this->faultactor = $faultactor;
|
||||
$this->faultstring = $faultstring;
|
||||
$this->faultdetail = $faultdetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* serialize a fault
|
||||
*
|
||||
* @return string The serialization of the fault instance.
|
||||
* @access public
|
||||
*/
|
||||
function serialize(){
|
||||
$ns_string = '';
|
||||
foreach($this->namespaces as $k => $v){
|
||||
$ns_string .= "\n xmlns:$k=\"$v\"";
|
||||
}
|
||||
$return_msg =
|
||||
'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
|
||||
'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
|
||||
'<SOAP-ENV:Body>'.
|
||||
'<SOAP-ENV:Fault>'.
|
||||
$this->serialize_val($this->faultcode, 'faultcode').
|
||||
$this->serialize_val($this->faultactor, 'faultactor').
|
||||
$this->serialize_val($this->faultstring, 'faultstring').
|
||||
$this->serialize_val($this->faultdetail, 'detail').
|
||||
'</SOAP-ENV:Fault>'.
|
||||
'</SOAP-ENV:Body>'.
|
||||
'</SOAP-ENV:Envelope>';
|
||||
return $return_msg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backward compatibility
|
||||
*/
|
||||
class soap_fault extends nusoap_fault {
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,639 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* nusoap_parser class parses SOAP XML messages into native PHP values
|
||||
*
|
||||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||||
* @author Scott Nichol <snichol@users.sourceforge.net>
|
||||
* @version $Id: class.soap_parser.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_parser extends nusoap_base {
|
||||
|
||||
var $xml = '';
|
||||
var $xml_encoding = '';
|
||||
var $method = '';
|
||||
var $root_struct = '';
|
||||
var $root_struct_name = '';
|
||||
var $root_struct_namespace = '';
|
||||
var $root_header = '';
|
||||
var $document = ''; // incoming SOAP body (text)
|
||||
// determines where in the message we are (envelope,header,body,method)
|
||||
var $status = '';
|
||||
var $position = 0;
|
||||
var $depth = 0;
|
||||
var $default_namespace = '';
|
||||
var $namespaces = array();
|
||||
var $message = array();
|
||||
var $parent = '';
|
||||
var $fault = false;
|
||||
var $fault_code = '';
|
||||
var $fault_str = '';
|
||||
var $fault_detail = '';
|
||||
var $depth_array = array();
|
||||
var $debug_flag = true;
|
||||
var $soapresponse = NULL; // parsed SOAP Body
|
||||
var $soapheader = NULL; // parsed SOAP Header
|
||||
var $responseHeaders = ''; // incoming SOAP headers (text)
|
||||
var $body_position = 0;
|
||||
// for multiref parsing:
|
||||
// array of id => pos
|
||||
var $ids = array();
|
||||
// array of id => hrefs => pos
|
||||
var $multirefs = array();
|
||||
// toggle for auto-decoding element content
|
||||
var $decode_utf8 = true;
|
||||
|
||||
/**
|
||||
* constructor that actually does the parsing
|
||||
*
|
||||
* @param string $xml SOAP message
|
||||
* @param string $encoding character encoding scheme of message
|
||||
* @param string $method method for which XML is parsed (unused?)
|
||||
* @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
|
||||
* @access public
|
||||
*/
|
||||
function nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
|
||||
parent::nusoap_base();
|
||||
$this->xml = $xml;
|
||||
$this->xml_encoding = $encoding;
|
||||
$this->method = $method;
|
||||
$this->decode_utf8 = $decode_utf8;
|
||||
|
||||
// Check whether content has been read.
|
||||
if(!empty($xml)){
|
||||
// Check XML encoding
|
||||
$pos_xml = strpos($xml, '<?xml');
|
||||
if ($pos_xml !== FALSE) {
|
||||
$xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
|
||||
if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
|
||||
$xml_encoding = $res[1];
|
||||
if (strtoupper($xml_encoding) != $encoding) {
|
||||
$err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
|
||||
$this->debug($err);
|
||||
if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
|
||||
$this->setError($err);
|
||||
return;
|
||||
}
|
||||
// when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
|
||||
} else {
|
||||
$this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
|
||||
}
|
||||
} else {
|
||||
$this->debug('No encoding specified in XML declaration');
|
||||
}
|
||||
} else {
|
||||
$this->debug('No XML declaration');
|
||||
}
|
||||
$this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
|
||||
// Create an XML parser - why not xml_parser_create_ns?
|
||||
$this->parser = xml_parser_create($this->xml_encoding);
|
||||
// Set the options for parsing the XML data.
|
||||
//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
|
||||
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
|
||||
xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
|
||||
// Set the object for the parser.
|
||||
xml_set_object($this->parser, $this);
|
||||
// Set the element handlers for the parser.
|
||||
xml_set_element_handler($this->parser, 'start_element','end_element');
|
||||
xml_set_character_data_handler($this->parser,'character_data');
|
||||
|
||||
// Parse the XML file.
|
||||
if(!xml_parse($this->parser,$xml,true)){
|
||||
// Display an error message.
|
||||
$err = sprintf('XML error parsing SOAP payload on line %d: %s',
|
||||
xml_get_current_line_number($this->parser),
|
||||
xml_error_string(xml_get_error_code($this->parser)));
|
||||
$this->debug($err);
|
||||
$this->debug("XML payload:\n" . $xml);
|
||||
$this->setError($err);
|
||||
} else {
|
||||
$this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
|
||||
// get final value
|
||||
$this->soapresponse = $this->message[$this->root_struct]['result'];
|
||||
// get header value
|
||||
if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
|
||||
$this->soapheader = $this->message[$this->root_header]['result'];
|
||||
}
|
||||
// resolve hrefs/ids
|
||||
if(sizeof($this->multirefs) > 0){
|
||||
foreach($this->multirefs as $id => $hrefs){
|
||||
$this->debug('resolving multirefs for id: '.$id);
|
||||
$idVal = $this->buildVal($this->ids[$id]);
|
||||
if (is_array($idVal) && isset($idVal['!id'])) {
|
||||
unset($idVal['!id']);
|
||||
}
|
||||
foreach($hrefs as $refPos => $ref){
|
||||
$this->debug('resolving href at pos '.$refPos);
|
||||
$this->multirefs[$id][$refPos] = $idVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xml_parser_free($this->parser);
|
||||
} else {
|
||||
$this->debug('xml was empty, didn\'t parse!');
|
||||
$this->setError('xml was empty, didn\'t parse!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* start-element handler
|
||||
*
|
||||
* @param resource $parser XML parser object
|
||||
* @param string $name element name
|
||||
* @param array $attrs associative array of attributes
|
||||
* @access private
|
||||
*/
|
||||
function start_element($parser, $name, $attrs) {
|
||||
// position in a total number of elements, starting from 0
|
||||
// update class level pos
|
||||
$pos = $this->position++;
|
||||
// and set mine
|
||||
$this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
|
||||
// depth = how many levels removed from root?
|
||||
// set mine as current global depth and increment global depth value
|
||||
$this->message[$pos]['depth'] = $this->depth++;
|
||||
|
||||
// else add self as child to whoever the current parent is
|
||||
if($pos != 0){
|
||||
$this->message[$this->parent]['children'] .= '|'.$pos;
|
||||
}
|
||||
// set my parent
|
||||
$this->message[$pos]['parent'] = $this->parent;
|
||||
// set self as current parent
|
||||
$this->parent = $pos;
|
||||
// set self as current value for this depth
|
||||
$this->depth_array[$this->depth] = $pos;
|
||||
// get element prefix
|
||||
if(strpos($name,':')){
|
||||
// get ns prefix
|
||||
$prefix = substr($name,0,strpos($name,':'));
|
||||
// get unqualified name
|
||||
$name = substr(strstr($name,':'),1);
|
||||
}
|
||||
// set status
|
||||
if($name == 'Envelope'){
|
||||
$this->status = 'envelope';
|
||||
} elseif($name == 'Header' && $this->status = 'envelope'){
|
||||
$this->root_header = $pos;
|
||||
$this->status = 'header';
|
||||
} elseif($name == 'Body' && $this->status = 'envelope'){
|
||||
$this->status = 'body';
|
||||
$this->body_position = $pos;
|
||||
// set method
|
||||
} elseif($this->status == 'body' && $pos == ($this->body_position+1)){
|
||||
$this->status = 'method';
|
||||
$this->root_struct_name = $name;
|
||||
$this->root_struct = $pos;
|
||||
$this->message[$pos]['type'] = 'struct';
|
||||
$this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
|
||||
}
|
||||
// set my status
|
||||
$this->message[$pos]['status'] = $this->status;
|
||||
// set name
|
||||
$this->message[$pos]['name'] = htmlspecialchars($name);
|
||||
// set attrs
|
||||
$this->message[$pos]['attrs'] = $attrs;
|
||||
|
||||
// loop through atts, logging ns and type declarations
|
||||
$attstr = '';
|
||||
foreach($attrs as $key => $value){
|
||||
$key_prefix = $this->getPrefix($key);
|
||||
$key_localpart = $this->getLocalPart($key);
|
||||
// if ns declarations, add to class level array of valid namespaces
|
||||
if($key_prefix == 'xmlns'){
|
||||
if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){
|
||||
$this->XMLSchemaVersion = $value;
|
||||
$this->namespaces['xsd'] = $this->XMLSchemaVersion;
|
||||
$this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
|
||||
}
|
||||
$this->namespaces[$key_localpart] = $value;
|
||||
// set method namespace
|
||||
if($name == $this->root_struct_name){
|
||||
$this->methodNamespace = $value;
|
||||
}
|
||||
// if it's a type declaration, set type
|
||||
} elseif($key_localpart == 'type'){
|
||||
if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
|
||||
// do nothing: already processed arrayType
|
||||
} else {
|
||||
$value_prefix = $this->getPrefix($value);
|
||||
$value_localpart = $this->getLocalPart($value);
|
||||
$this->message[$pos]['type'] = $value_localpart;
|
||||
$this->message[$pos]['typePrefix'] = $value_prefix;
|
||||
if(isset($this->namespaces[$value_prefix])){
|
||||
$this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
|
||||
} else if(isset($attrs['xmlns:'.$value_prefix])) {
|
||||
$this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
|
||||
}
|
||||
// should do something here with the namespace of specified type?
|
||||
}
|
||||
} elseif($key_localpart == 'arrayType'){
|
||||
$this->message[$pos]['type'] = 'array';
|
||||
/* do arrayType ereg here
|
||||
[1] arrayTypeValue ::= atype asize
|
||||
[2] atype ::= QName rank*
|
||||
[3] rank ::= '[' (',')* ']'
|
||||
[4] asize ::= '[' length~ ']'
|
||||
[5] length ::= nextDimension* Digit+
|
||||
[6] nextDimension ::= Digit+ ','
|
||||
*/
|
||||
$expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]';
|
||||
if(ereg($expr,$value,$regs)){
|
||||
$this->message[$pos]['typePrefix'] = $regs[1];
|
||||
$this->message[$pos]['arrayTypePrefix'] = $regs[1];
|
||||
if (isset($this->namespaces[$regs[1]])) {
|
||||
$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
|
||||
} else if (isset($attrs['xmlns:'.$regs[1]])) {
|
||||
$this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
|
||||
}
|
||||
$this->message[$pos]['arrayType'] = $regs[2];
|
||||
$this->message[$pos]['arraySize'] = $regs[3];
|
||||
$this->message[$pos]['arrayCols'] = $regs[4];
|
||||
}
|
||||
// specifies nil value (or not)
|
||||
} elseif ($key_localpart == 'nil'){
|
||||
$this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
|
||||
// some other attribute
|
||||
} elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
|
||||
$this->message[$pos]['xattrs']['!' . $key] = $value;
|
||||
}
|
||||
|
||||
if ($key == 'xmlns') {
|
||||
$this->default_namespace = $value;
|
||||
}
|
||||
// log id
|
||||
if($key == 'id'){
|
||||
$this->ids[$value] = $pos;
|
||||
}
|
||||
// root
|
||||
if($key_localpart == 'root' && $value == 1){
|
||||
$this->status = 'method';
|
||||
$this->root_struct_name = $name;
|
||||
$this->root_struct = $pos;
|
||||
$this->debug("found root struct $this->root_struct_name, pos $pos");
|
||||
}
|
||||
// for doclit
|
||||
$attstr .= " $key=\"$value\"";
|
||||
}
|
||||
// get namespace - must be done after namespace atts are processed
|
||||
if(isset($prefix)){
|
||||
$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
|
||||
$this->default_namespace = $this->namespaces[$prefix];
|
||||
} else {
|
||||
$this->message[$pos]['namespace'] = $this->default_namespace;
|
||||
}
|
||||
if($this->status == 'header'){
|
||||
if ($this->root_header != $pos) {
|
||||
$this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
|
||||
}
|
||||
} elseif($this->root_struct_name != ''){
|
||||
$this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* end-element handler
|
||||
*
|
||||
* @param resource $parser XML parser object
|
||||
* @param string $name element name
|
||||
* @access private
|
||||
*/
|
||||
function end_element($parser, $name) {
|
||||
// position of current element is equal to the last value left in depth_array for my depth
|
||||
$pos = $this->depth_array[$this->depth--];
|
||||
|
||||
// get element prefix
|
||||
if(strpos($name,':')){
|
||||
// get ns prefix
|
||||
$prefix = substr($name,0,strpos($name,':'));
|
||||
// get unqualified name
|
||||
$name = substr(strstr($name,':'),1);
|
||||
}
|
||||
|
||||
// build to native type
|
||||
if(isset($this->body_position) && $pos > $this->body_position){
|
||||
// deal w/ multirefs
|
||||
if(isset($this->message[$pos]['attrs']['href'])){
|
||||
// get id
|
||||
$id = substr($this->message[$pos]['attrs']['href'],1);
|
||||
// add placeholder to href array
|
||||
$this->multirefs[$id][$pos] = 'placeholder';
|
||||
// add set a reference to it as the result value
|
||||
$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
|
||||
// build complexType values
|
||||
} elseif($this->message[$pos]['children'] != ''){
|
||||
// if result has already been generated (struct/array)
|
||||
if(!isset($this->message[$pos]['result'])){
|
||||
$this->message[$pos]['result'] = $this->buildVal($pos);
|
||||
}
|
||||
// build complexType values of attributes and possibly simpleContent
|
||||
} elseif (isset($this->message[$pos]['xattrs'])) {
|
||||
if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
|
||||
$this->message[$pos]['xattrs']['!'] = null;
|
||||
} elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
|
||||
if (isset($this->message[$pos]['type'])) {
|
||||
$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
|
||||
} else {
|
||||
$parent = $this->message[$pos]['parent'];
|
||||
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
|
||||
$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
|
||||
} else {
|
||||
$this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
|
||||
// set value of simpleType (or nil complexType)
|
||||
} else {
|
||||
//$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
|
||||
if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
|
||||
$this->message[$pos]['xattrs']['!'] = null;
|
||||
} elseif (isset($this->message[$pos]['type'])) {
|
||||
$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
|
||||
} else {
|
||||
$parent = $this->message[$pos]['parent'];
|
||||
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
|
||||
$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
|
||||
} else {
|
||||
$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
|
||||
}
|
||||
}
|
||||
|
||||
/* add value to parent's result, if parent is struct/array
|
||||
$parent = $this->message[$pos]['parent'];
|
||||
if($this->message[$parent]['type'] != 'map'){
|
||||
if(strtolower($this->message[$parent]['type']) == 'array'){
|
||||
$this->message[$parent]['result'][] = $this->message[$pos]['result'];
|
||||
} else {
|
||||
$this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// for doclit
|
||||
if($this->status == 'header'){
|
||||
if ($this->root_header != $pos) {
|
||||
$this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
|
||||
}
|
||||
} elseif($pos >= $this->root_struct){
|
||||
$this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
|
||||
}
|
||||
// switch status
|
||||
if($pos == $this->root_struct){
|
||||
$this->status = 'body';
|
||||
$this->root_struct_namespace = $this->message[$pos]['namespace'];
|
||||
} elseif($name == 'Body'){
|
||||
$this->status = 'envelope';
|
||||
} elseif($name == 'Header'){
|
||||
$this->status = 'envelope';
|
||||
} elseif($name == 'Envelope'){
|
||||
//
|
||||
}
|
||||
// set parent back to my parent
|
||||
$this->parent = $this->message[$pos]['parent'];
|
||||
}
|
||||
|
||||
/**
|
||||
* element content handler
|
||||
*
|
||||
* @param resource $parser XML parser object
|
||||
* @param string $data element content
|
||||
* @access private
|
||||
*/
|
||||
function character_data($parser, $data){
|
||||
$pos = $this->depth_array[$this->depth];
|
||||
if ($this->xml_encoding=='UTF-8'){
|
||||
// TODO: add an option to disable this for folks who want
|
||||
// raw UTF-8 that, e.g., might not map to iso-8859-1
|
||||
// TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
|
||||
if($this->decode_utf8){
|
||||
$data = utf8_decode($data);
|
||||
}
|
||||
}
|
||||
$this->message[$pos]['cdata'] .= $data;
|
||||
// for doclit
|
||||
if($this->status == 'header'){
|
||||
$this->responseHeaders .= $data;
|
||||
} else {
|
||||
$this->document .= $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the parsed message (SOAP Body)
|
||||
*
|
||||
* @return mixed
|
||||
* @access public
|
||||
* @deprecated use get_soapbody instead
|
||||
*/
|
||||
function get_response(){
|
||||
return $this->soapresponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the parsed SOAP Body (NULL if there was none)
|
||||
*
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function get_soapbody(){
|
||||
return $this->soapresponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the parsed SOAP Header (NULL if there was none)
|
||||
*
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function get_soapheader(){
|
||||
return $this->soapheader;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the unparsed SOAP Header
|
||||
*
|
||||
* @return string XML or empty if no Header
|
||||
* @access public
|
||||
*/
|
||||
function getHeaders(){
|
||||
return $this->responseHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes simple types into PHP variables
|
||||
*
|
||||
* @param string $value value to decode
|
||||
* @param string $type XML type to decode
|
||||
* @param string $typens XML type namespace to decode
|
||||
* @return mixed PHP value
|
||||
* @access private
|
||||
*/
|
||||
function decodeSimple($value, $type, $typens) {
|
||||
// TODO: use the namespace!
|
||||
if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
|
||||
return (string) $value;
|
||||
}
|
||||
if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
|
||||
return (int) $value;
|
||||
}
|
||||
if ($type == 'float' || $type == 'double' || $type == 'decimal') {
|
||||
return (double) $value;
|
||||
}
|
||||
if ($type == 'boolean') {
|
||||
if (strtolower($value) == 'false' || strtolower($value) == 'f') {
|
||||
return false;
|
||||
}
|
||||
return (boolean) $value;
|
||||
}
|
||||
if ($type == 'base64' || $type == 'base64Binary') {
|
||||
$this->debug('Decode base64 value');
|
||||
return base64_decode($value);
|
||||
}
|
||||
// obscure numeric types
|
||||
if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
|
||||
|| $type == 'nonNegativeInteger' || $type == 'positiveInteger'
|
||||
|| $type == 'unsignedInt'
|
||||
|| $type == 'unsignedShort' || $type == 'unsignedByte') {
|
||||
return (int) $value;
|
||||
}
|
||||
// bogus: parser treats array with no elements as a simple type
|
||||
if ($type == 'array') {
|
||||
return array();
|
||||
}
|
||||
// everything else
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* builds response structures for compound values (arrays/structs)
|
||||
* and scalars
|
||||
*
|
||||
* @param integer $pos position in node tree
|
||||
* @return mixed PHP value
|
||||
* @access private
|
||||
*/
|
||||
function buildVal($pos){
|
||||
if(!isset($this->message[$pos]['type'])){
|
||||
$this->message[$pos]['type'] = '';
|
||||
}
|
||||
$this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
|
||||
// if there are children...
|
||||
if($this->message[$pos]['children'] != ''){
|
||||
$this->debug('in buildVal, there are children');
|
||||
$children = explode('|',$this->message[$pos]['children']);
|
||||
array_shift($children); // knock off empty
|
||||
// md array
|
||||
if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
|
||||
$r=0; // rowcount
|
||||
$c=0; // colcount
|
||||
foreach($children as $child_pos){
|
||||
$this->debug("in buildVal, got an MD array element: $r, $c");
|
||||
$params[$r][] = $this->message[$child_pos]['result'];
|
||||
$c++;
|
||||
if($c == $this->message[$pos]['arrayCols']){
|
||||
$c = 0;
|
||||
$r++;
|
||||
}
|
||||
}
|
||||
// array
|
||||
} elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
|
||||
$this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
|
||||
foreach($children as $child_pos){
|
||||
$params[] = &$this->message[$child_pos]['result'];
|
||||
}
|
||||
// apache Map type: java hashtable
|
||||
} elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
|
||||
$this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
|
||||
foreach($children as $child_pos){
|
||||
$kv = explode("|",$this->message[$child_pos]['children']);
|
||||
$params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
|
||||
}
|
||||
// generic compound type
|
||||
//} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
|
||||
} else {
|
||||
// Apache Vector type: treat as an array
|
||||
$this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
|
||||
if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
|
||||
$notstruct = 1;
|
||||
} else {
|
||||
$notstruct = 0;
|
||||
}
|
||||
//
|
||||
foreach($children as $child_pos){
|
||||
if($notstruct){
|
||||
$params[] = &$this->message[$child_pos]['result'];
|
||||
} else {
|
||||
if (isset($params[$this->message[$child_pos]['name']])) {
|
||||
// de-serialize repeated element name into an array
|
||||
if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
|
||||
$params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
|
||||
}
|
||||
$params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
|
||||
} else {
|
||||
$params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->message[$pos]['xattrs'])) {
|
||||
$this->debug('in buildVal, handling attributes');
|
||||
foreach ($this->message[$pos]['xattrs'] as $n => $v) {
|
||||
$params[$n] = $v;
|
||||
}
|
||||
}
|
||||
// handle simpleContent
|
||||
if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
|
||||
$this->debug('in buildVal, handling simpleContent');
|
||||
if (isset($this->message[$pos]['type'])) {
|
||||
$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
|
||||
} else {
|
||||
$parent = $this->message[$pos]['parent'];
|
||||
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
|
||||
$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
|
||||
} else {
|
||||
$params['!'] = $this->message[$pos]['cdata'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$ret = is_array($params) ? $params : array();
|
||||
$this->debug('in buildVal, return:');
|
||||
$this->appendDebug($this->varDump($ret));
|
||||
return $ret;
|
||||
} else {
|
||||
$this->debug('in buildVal, no children, building scalar');
|
||||
$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
|
||||
if (isset($this->message[$pos]['type'])) {
|
||||
$ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
|
||||
$this->debug("in buildVal, return: $ret");
|
||||
return $ret;
|
||||
}
|
||||
$parent = $this->message[$pos]['parent'];
|
||||
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
|
||||
$ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
|
||||
$this->debug("in buildVal, return: $ret");
|
||||
return $ret;
|
||||
}
|
||||
$ret = $this->message[$pos]['cdata'];
|
||||
$this->debug("in buildVal, return: $ret");
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backward compatibility
|
||||
*/
|
||||
class soap_parser extends nusoap_parser {
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* For creating serializable abstractions of native PHP types. This class
|
||||
* allows element name/namespace, XSD type, and XML attributes to be
|
||||
* associated with a value. This is extremely useful when WSDL is not
|
||||
* used, but is also useful when WSDL is used with polymorphic types, including
|
||||
* xsd:anyType and user-defined types.
|
||||
*
|
||||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||||
* @version $Id: class.soap_val.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class soapval extends nusoap_base {
|
||||
/**
|
||||
* The XML element name
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $name;
|
||||
/**
|
||||
* The XML type name (string or false)
|
||||
*
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $type;
|
||||
/**
|
||||
* The PHP value
|
||||
*
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $value;
|
||||
/**
|
||||
* The XML element namespace (string or false)
|
||||
*
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $element_ns;
|
||||
/**
|
||||
* The XML type namespace (string or false)
|
||||
*
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $type_ns;
|
||||
/**
|
||||
* The XML element attributes (array or false)
|
||||
*
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $attributes;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $name optional name
|
||||
* @param mixed $type optional type name
|
||||
* @param mixed $value optional value
|
||||
* @param mixed $element_ns optional namespace of value
|
||||
* @param mixed $type_ns optional namespace of type
|
||||
* @param mixed $attributes associative array of attributes to add to element serialization
|
||||
* @access public
|
||||
*/
|
||||
function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
|
||||
parent::nusoap_base();
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->value = $value;
|
||||
$this->element_ns = $element_ns;
|
||||
$this->type_ns = $type_ns;
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* return serialized value
|
||||
*
|
||||
* @param string $use The WSDL use value (encoded|literal)
|
||||
* @return string XML data
|
||||
* @access public
|
||||
*/
|
||||
function serialize($use='encoded') {
|
||||
return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a soapval object into a PHP native type
|
||||
*
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function decode(){
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,977 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* [nu]soapclient higher level class for easy usage.
|
||||
*
|
||||
* usage:
|
||||
*
|
||||
* // instantiate client with server info
|
||||
* $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
|
||||
*
|
||||
* // call method, get results
|
||||
* echo $soapclient->call( string methodname [ ,array parameters] );
|
||||
*
|
||||
* // bye bye client
|
||||
* unset($soapclient);
|
||||
*
|
||||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||||
* @author Scott Nichol <snichol@users.sourceforge.net>
|
||||
* @version $Id: class.soapclient.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_client extends nusoap_base {
|
||||
|
||||
var $username = ''; // Username for HTTP authentication
|
||||
var $password = ''; // Password for HTTP authentication
|
||||
var $authtype = ''; // Type of HTTP authentication
|
||||
var $certRequest = array(); // Certificate for HTTP SSL authentication
|
||||
var $requestHeaders = false; // SOAP headers in request (text)
|
||||
var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
|
||||
var $responseHeader = NULL; // SOAP Header from response (parsed)
|
||||
var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
|
||||
var $endpoint;
|
||||
var $forceEndpoint = ''; // overrides WSDL endpoint
|
||||
var $proxyhost = '';
|
||||
var $proxyport = '';
|
||||
var $proxyusername = '';
|
||||
var $proxypassword = '';
|
||||
var $xml_encoding = ''; // character set encoding of incoming (response) messages
|
||||
var $http_encoding = false;
|
||||
var $timeout = 0; // HTTP connection timeout
|
||||
var $response_timeout = 30; // HTTP response timeout
|
||||
var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error
|
||||
var $persistentConnection = false;
|
||||
var $defaultRpcParams = false; // This is no longer used
|
||||
var $request = ''; // HTTP request
|
||||
var $response = ''; // HTTP response
|
||||
var $responseData = ''; // SOAP payload of response
|
||||
var $cookies = array(); // Cookies from response or for request
|
||||
var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
|
||||
var $operations = array(); // WSDL operations, empty for WSDL initialization error
|
||||
var $curl_options = array(); // User-specified cURL options
|
||||
var $bindingType = ''; // WSDL operation binding type
|
||||
var $use_curl = false; // whether to always try to use cURL
|
||||
|
||||
/*
|
||||
* fault related variables
|
||||
*/
|
||||
/**
|
||||
* @var fault
|
||||
* @access public
|
||||
*/
|
||||
var $fault;
|
||||
/**
|
||||
* @var faultcode
|
||||
* @access public
|
||||
*/
|
||||
var $faultcode;
|
||||
/**
|
||||
* @var faultstring
|
||||
* @access public
|
||||
*/
|
||||
var $faultstring;
|
||||
/**
|
||||
* @var faultdetail
|
||||
* @access public
|
||||
*/
|
||||
var $faultdetail;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
|
||||
* @param bool $wsdl optional, set to true if using WSDL
|
||||
* @param int $portName optional portName in WSDL document
|
||||
* @param string $proxyhost
|
||||
* @param string $proxyport
|
||||
* @param string $proxyusername
|
||||
* @param string $proxypassword
|
||||
* @param integer $timeout set the connection timeout
|
||||
* @param integer $response_timeout set the response timeout
|
||||
* @access public
|
||||
*/
|
||||
function nusoap_client($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
|
||||
parent::nusoap_base();
|
||||
$this->endpoint = $endpoint;
|
||||
$this->proxyhost = $proxyhost;
|
||||
$this->proxyport = $proxyport;
|
||||
$this->proxyusername = $proxyusername;
|
||||
$this->proxypassword = $proxypassword;
|
||||
$this->timeout = $timeout;
|
||||
$this->response_timeout = $response_timeout;
|
||||
|
||||
$this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
|
||||
$this->appendDebug('endpoint=' . $this->varDump($endpoint));
|
||||
|
||||
// make values
|
||||
if($wsdl){
|
||||
if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
|
||||
$this->wsdl = $endpoint;
|
||||
$this->endpoint = $this->wsdl->wsdl;
|
||||
$this->wsdlFile = $this->endpoint;
|
||||
$this->debug('existing wsdl instance created from ' . $this->endpoint);
|
||||
$this->checkWSDL();
|
||||
} else {
|
||||
$this->wsdlFile = $this->endpoint;
|
||||
$this->wsdl = null;
|
||||
$this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
|
||||
}
|
||||
$this->endpointType = 'wsdl';
|
||||
} else {
|
||||
$this->debug("instantiate SOAP with endpoint at $endpoint");
|
||||
$this->endpointType = 'soap';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calls method, returns PHP native type
|
||||
*
|
||||
* @param string $operation SOAP server URL or path
|
||||
* @param mixed $params An array, associative or simple, of the parameters
|
||||
* for the method call, or a string that is the XML
|
||||
* for the call. For rpc style, this call will
|
||||
* wrap the XML in a tag named after the method, as
|
||||
* well as the SOAP Envelope and Body. For document
|
||||
* style, this will only wrap with the Envelope and Body.
|
||||
* IMPORTANT: when using an array with document style,
|
||||
* in which case there
|
||||
* is really one parameter, the root of the fragment
|
||||
* used in the call, which encloses what programmers
|
||||
* normally think of parameters. A parameter array
|
||||
* *must* include the wrapper.
|
||||
* @param string $namespace optional method namespace (WSDL can override)
|
||||
* @param string $soapAction optional SOAPAction value (WSDL can override)
|
||||
* @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
|
||||
* @param boolean $rpcParams optional (no longer used)
|
||||
* @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
|
||||
* @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override)
|
||||
* @return mixed response from SOAP call
|
||||
* @access public
|
||||
*/
|
||||
function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
|
||||
$this->operation = $operation;
|
||||
$this->fault = false;
|
||||
$this->setError('');
|
||||
$this->request = '';
|
||||
$this->response = '';
|
||||
$this->responseData = '';
|
||||
$this->faultstring = '';
|
||||
$this->faultcode = '';
|
||||
$this->opData = array();
|
||||
|
||||
$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
|
||||
$this->appendDebug('params=' . $this->varDump($params));
|
||||
$this->appendDebug('headers=' . $this->varDump($headers));
|
||||
if ($headers) {
|
||||
$this->requestHeaders = $headers;
|
||||
}
|
||||
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
|
||||
$this->loadWSDL();
|
||||
if ($this->getError())
|
||||
return false;
|
||||
}
|
||||
// serialize parameters
|
||||
if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
|
||||
// use WSDL for operation
|
||||
$this->opData = $opData;
|
||||
$this->debug("found operation");
|
||||
$this->appendDebug('opData=' . $this->varDump($opData));
|
||||
if (isset($opData['soapAction'])) {
|
||||
$soapAction = $opData['soapAction'];
|
||||
}
|
||||
if (! $this->forceEndpoint) {
|
||||
$this->endpoint = $opData['endpoint'];
|
||||
} else {
|
||||
$this->endpoint = $this->forceEndpoint;
|
||||
}
|
||||
$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
|
||||
$style = $opData['style'];
|
||||
$use = $opData['input']['use'];
|
||||
// add ns to ns array
|
||||
if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
|
||||
$nsPrefix = 'ns' . rand(1000, 9999);
|
||||
$this->wsdl->namespaces[$nsPrefix] = $namespace;
|
||||
}
|
||||
$nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
|
||||
// serialize payload
|
||||
if (is_string($params)) {
|
||||
$this->debug("serializing param string for WSDL operation $operation");
|
||||
$payload = $params;
|
||||
} elseif (is_array($params)) {
|
||||
$this->debug("serializing param array for WSDL operation $operation");
|
||||
$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
|
||||
} else {
|
||||
$this->debug('params must be array or string');
|
||||
$this->setError('params must be array or string');
|
||||
return false;
|
||||
}
|
||||
$usedNamespaces = $this->wsdl->usedNamespaces;
|
||||
if (isset($opData['input']['encodingStyle'])) {
|
||||
$encodingStyle = $opData['input']['encodingStyle'];
|
||||
} else {
|
||||
$encodingStyle = '';
|
||||
}
|
||||
$this->appendDebug($this->wsdl->getDebug());
|
||||
$this->wsdl->clearDebug();
|
||||
if ($errstr = $this->wsdl->getError()) {
|
||||
$this->debug('got wsdl error: '.$errstr);
|
||||
$this->setError('wsdl error: '.$errstr);
|
||||
return false;
|
||||
}
|
||||
} elseif($this->endpointType == 'wsdl') {
|
||||
// operation not in WSDL
|
||||
$this->appendDebug($this->wsdl->getDebug());
|
||||
$this->wsdl->clearDebug();
|
||||
$this->setError( 'operation '.$operation.' not present.');
|
||||
$this->debug("operation '$operation' not present.");
|
||||
return false;
|
||||
} else {
|
||||
// no WSDL
|
||||
//$this->namespaces['ns1'] = $namespace;
|
||||
$nsPrefix = 'ns' . rand(1000, 9999);
|
||||
// serialize
|
||||
$payload = '';
|
||||
if (is_string($params)) {
|
||||
$this->debug("serializing param string for operation $operation");
|
||||
$payload = $params;
|
||||
} elseif (is_array($params)) {
|
||||
$this->debug("serializing param array for operation $operation");
|
||||
foreach($params as $k => $v){
|
||||
$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
|
||||
}
|
||||
} else {
|
||||
$this->debug('params must be array or string');
|
||||
$this->setError('params must be array or string');
|
||||
return false;
|
||||
}
|
||||
$usedNamespaces = array();
|
||||
if ($use == 'encoded') {
|
||||
$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
|
||||
} else {
|
||||
$encodingStyle = '';
|
||||
}
|
||||
}
|
||||
// wrap RPC calls with method element
|
||||
if ($style == 'rpc') {
|
||||
if ($use == 'literal') {
|
||||
$this->debug("wrapping RPC request with literal method element");
|
||||
if ($namespace) {
|
||||
// http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
|
||||
$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
|
||||
$payload .
|
||||
"</$nsPrefix:$operation>";
|
||||
} else {
|
||||
$payload = "<$operation>" . $payload . "</$operation>";
|
||||
}
|
||||
} else {
|
||||
$this->debug("wrapping RPC request with encoded method element");
|
||||
if ($namespace) {
|
||||
$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
|
||||
$payload .
|
||||
"</$nsPrefix:$operation>";
|
||||
} else {
|
||||
$payload = "<$operation>" .
|
||||
$payload .
|
||||
"</$operation>";
|
||||
}
|
||||
}
|
||||
}
|
||||
// serialize envelope
|
||||
$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
|
||||
$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
|
||||
$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
|
||||
// send
|
||||
$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
|
||||
if($errstr = $this->getError()){
|
||||
$this->debug('Error: '.$errstr);
|
||||
return false;
|
||||
} else {
|
||||
$this->return = $return;
|
||||
$this->debug('sent message successfully and got a(n) '.gettype($return));
|
||||
$this->appendDebug('return=' . $this->varDump($return));
|
||||
|
||||
// fault?
|
||||
if(is_array($return) && isset($return['faultcode'])){
|
||||
$this->debug('got fault');
|
||||
$this->setError($return['faultcode'].': '.$return['faultstring']);
|
||||
$this->fault = true;
|
||||
foreach($return as $k => $v){
|
||||
$this->$k = $v;
|
||||
$this->debug("$k = $v<br>");
|
||||
}
|
||||
return $return;
|
||||
} elseif ($style == 'document') {
|
||||
// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
|
||||
// we are only going to return the first part here...sorry about that
|
||||
return $return;
|
||||
} else {
|
||||
// array of return values
|
||||
if(is_array($return)){
|
||||
// multiple 'out' parameters, which we return wrapped up
|
||||
// in the array
|
||||
if(sizeof($return) > 1){
|
||||
return $return;
|
||||
}
|
||||
// single 'out' parameter (normally the return value)
|
||||
$return = array_shift($return);
|
||||
$this->debug('return shifted value: ');
|
||||
$this->appendDebug($this->varDump($return));
|
||||
return $return;
|
||||
// nothing returned (ie, echoVoid)
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check WSDL passed as an instance or pulled from an endpoint
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function checkWSDL() {
|
||||
$this->appendDebug($this->wsdl->getDebug());
|
||||
$this->wsdl->clearDebug();
|
||||
$this->debug('checkWSDL');
|
||||
// catch errors
|
||||
if ($errstr = $this->wsdl->getError()) {
|
||||
$this->debug('got wsdl error: '.$errstr);
|
||||
$this->setError('wsdl error: '.$errstr);
|
||||
} elseif ($this->operations = $this->wsdl->getOperations('soap')) {
|
||||
$this->bindingType = 'soap';
|
||||
$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
|
||||
} elseif ($this->operations = $this->wsdl->getOperations('soap12')) {
|
||||
$this->bindingType = 'soap12';
|
||||
$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
|
||||
$this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
|
||||
} else {
|
||||
$this->debug('getOperations returned false');
|
||||
$this->setError('no operations defined in the WSDL document!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* instantiate wsdl object and parse wsdl file
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function loadWSDL() {
|
||||
$this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
|
||||
$this->wsdl =& new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
|
||||
$this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
|
||||
$this->wsdl->fetchWSDL($this->wsdlFile);
|
||||
$this->checkWSDL();
|
||||
}
|
||||
|
||||
/**
|
||||
* get available data pertaining to an operation
|
||||
*
|
||||
* @param string $operation operation name
|
||||
* @return array array of data pertaining to the operation
|
||||
* @access public
|
||||
*/
|
||||
function getOperationData($operation){
|
||||
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
|
||||
$this->loadWSDL();
|
||||
if ($this->getError())
|
||||
return false;
|
||||
}
|
||||
if(isset($this->operations[$operation])){
|
||||
return $this->operations[$operation];
|
||||
}
|
||||
$this->debug("No data for operation: $operation");
|
||||
}
|
||||
|
||||
/**
|
||||
* send the SOAP message
|
||||
*
|
||||
* Note: if the operation has multiple return values
|
||||
* the return value of this method will be an array
|
||||
* of those values.
|
||||
*
|
||||
* @param string $msg a SOAPx4 soapmsg object
|
||||
* @param string $soapaction SOAPAction value
|
||||
* @param integer $timeout set connection timeout in seconds
|
||||
* @param integer $response_timeout set response timeout in seconds
|
||||
* @return mixed native PHP types.
|
||||
* @access private
|
||||
*/
|
||||
function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
|
||||
$this->checkCookies();
|
||||
// detect transport
|
||||
switch(true){
|
||||
// http(s)
|
||||
case ereg('^http',$this->endpoint):
|
||||
$this->debug('transporting via HTTP');
|
||||
if($this->persistentConnection == true && is_object($this->persistentConnection)){
|
||||
$http =& $this->persistentConnection;
|
||||
} else {
|
||||
$http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
|
||||
if ($this->persistentConnection) {
|
||||
$http->usePersistentConnection();
|
||||
}
|
||||
}
|
||||
$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
|
||||
$http->setSOAPAction($soapaction);
|
||||
if($this->proxyhost && $this->proxyport){
|
||||
$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
|
||||
}
|
||||
if($this->authtype != '') {
|
||||
$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
|
||||
}
|
||||
if($this->http_encoding != ''){
|
||||
$http->setEncoding($this->http_encoding);
|
||||
}
|
||||
$this->debug('sending message, length='.strlen($msg));
|
||||
if(ereg('^http:',$this->endpoint)){
|
||||
//if(strpos($this->endpoint,'http:')){
|
||||
$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
|
||||
} elseif(ereg('^https',$this->endpoint)){
|
||||
//} elseif(strpos($this->endpoint,'https:')){
|
||||
//if(phpversion() == '4.3.0-dev'){
|
||||
//$response = $http->send($msg,$timeout,$response_timeout);
|
||||
//$this->request = $http->outgoing_payload;
|
||||
//$this->response = $http->incoming_payload;
|
||||
//} else
|
||||
$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
|
||||
} else {
|
||||
$this->setError('no http/s in endpoint url');
|
||||
}
|
||||
$this->request = $http->outgoing_payload;
|
||||
$this->response = $http->incoming_payload;
|
||||
$this->appendDebug($http->getDebug());
|
||||
$this->UpdateCookies($http->incoming_cookies);
|
||||
|
||||
// save transport object if using persistent connections
|
||||
if ($this->persistentConnection) {
|
||||
$http->clearDebug();
|
||||
if (!is_object($this->persistentConnection)) {
|
||||
$this->persistentConnection = $http;
|
||||
}
|
||||
}
|
||||
|
||||
if($err = $http->getError()){
|
||||
$this->setError('HTTP Error: '.$err);
|
||||
return false;
|
||||
} elseif($this->getError()){
|
||||
return false;
|
||||
} else {
|
||||
$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
|
||||
return $this->parseResponse($http->incoming_headers, $this->responseData);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->setError('no transport found, or selected transport is not yet supported!');
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* processes SOAP message returned from server
|
||||
*
|
||||
* @param array $headers The HTTP headers
|
||||
* @param string $data unprocessed response data from server
|
||||
* @return mixed value of the message, decoded into a PHP type
|
||||
* @access private
|
||||
*/
|
||||
function parseResponse($headers, $data) {
|
||||
$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
|
||||
$this->appendDebug($this->varDump($headers));
|
||||
if (!strstr($headers['content-type'], 'text/xml')) {
|
||||
$this->setError('Response not of type text/xml: ' . $headers['content-type']);
|
||||
return false;
|
||||
}
|
||||
if (strpos($headers['content-type'], '=')) {
|
||||
$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
|
||||
$this->debug('Got response encoding: ' . $enc);
|
||||
if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
|
||||
$this->xml_encoding = strtoupper($enc);
|
||||
} else {
|
||||
$this->xml_encoding = 'US-ASCII';
|
||||
}
|
||||
} else {
|
||||
// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
|
||||
$this->xml_encoding = 'ISO-8859-1';
|
||||
}
|
||||
$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
|
||||
$parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
|
||||
// add parser debug data to our debug
|
||||
$this->appendDebug($parser->getDebug());
|
||||
// if parse errors
|
||||
if($errstr = $parser->getError()){
|
||||
$this->setError( $errstr);
|
||||
// destroy the parser object
|
||||
unset($parser);
|
||||
return false;
|
||||
} else {
|
||||
// get SOAP headers
|
||||
$this->responseHeaders = $parser->getHeaders();
|
||||
// get SOAP headers
|
||||
$this->responseHeader = $parser->get_soapheader();
|
||||
// get decoded message
|
||||
$return = $parser->get_soapbody();
|
||||
// add document for doclit support
|
||||
$this->document = $parser->document;
|
||||
// destroy the parser object
|
||||
unset($parser);
|
||||
// return decode message
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets user-specified cURL options
|
||||
*
|
||||
* @param mixed $option The cURL option (always integer?)
|
||||
* @param mixed $value The cURL option value
|
||||
* @access public
|
||||
*/
|
||||
function setCurlOption($option, $value) {
|
||||
$this->debug("setCurlOption option=$option, value=");
|
||||
$this->appendDebug($this->varDump($value));
|
||||
$this->curl_options[$option] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the SOAP endpoint, which can override WSDL
|
||||
*
|
||||
* @param string $endpoint The endpoint URL to use, or empty string or false to prevent override
|
||||
* @access public
|
||||
*/
|
||||
function setEndpoint($endpoint) {
|
||||
$this->debug("setEndpoint(\"$endpoint\")");
|
||||
$this->forceEndpoint = $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the SOAP headers
|
||||
*
|
||||
* @param mixed $headers String of XML with SOAP header content, or array of soapval objects for SOAP headers
|
||||
* @access public
|
||||
*/
|
||||
function setHeaders($headers){
|
||||
$this->debug("setHeaders headers=");
|
||||
$this->appendDebug($this->varDump($headers));
|
||||
$this->requestHeaders = $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the SOAP response headers (namespace resolution incomplete)
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getHeaders(){
|
||||
return $this->responseHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the SOAP response Header (parsed)
|
||||
*
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function getHeader(){
|
||||
return $this->responseHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* set proxy info here
|
||||
*
|
||||
* @param string $proxyhost
|
||||
* @param string $proxyport
|
||||
* @param string $proxyusername
|
||||
* @param string $proxypassword
|
||||
* @access public
|
||||
*/
|
||||
function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
|
||||
$this->proxyhost = $proxyhost;
|
||||
$this->proxyport = $proxyport;
|
||||
$this->proxyusername = $proxyusername;
|
||||
$this->proxypassword = $proxypassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* if authenticating, set user credentials here
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $authtype (basic|digest|certificate|ntlm)
|
||||
* @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
|
||||
* @access public
|
||||
*/
|
||||
function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
|
||||
$this->debug("setCredentials username=$username authtype=$authtype certRequest=");
|
||||
$this->appendDebug($this->varDump($certRequest));
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->authtype = $authtype;
|
||||
$this->certRequest = $certRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* use HTTP encoding
|
||||
*
|
||||
* @param string $enc HTTP encoding
|
||||
* @access public
|
||||
*/
|
||||
function setHTTPEncoding($enc='gzip, deflate'){
|
||||
$this->debug("setHTTPEncoding(\"$enc\")");
|
||||
$this->http_encoding = $enc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to try to use cURL connections if possible
|
||||
*
|
||||
* @param boolean $use Whether to try to use cURL
|
||||
* @access public
|
||||
*/
|
||||
function setUseCURL($use) {
|
||||
$this->debug("setUseCURL($use)");
|
||||
$this->use_curl = $use;
|
||||
}
|
||||
|
||||
/**
|
||||
* use HTTP persistent connections if possible
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function useHTTPPersistentConnection(){
|
||||
$this->debug("useHTTPPersistentConnection");
|
||||
$this->persistentConnection = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the default RPC parameter setting.
|
||||
* If true, default is that call params are like RPC even for document style.
|
||||
* Each call() can override this value.
|
||||
*
|
||||
* This is no longer used.
|
||||
*
|
||||
* @return boolean
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function getDefaultRpcParams() {
|
||||
return $this->defaultRpcParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the default RPC parameter setting.
|
||||
* If true, default is that call params are like RPC even for document style
|
||||
* Each call() can override this value.
|
||||
*
|
||||
* This is no longer used.
|
||||
*
|
||||
* @param boolean $rpcParams
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function setDefaultRpcParams($rpcParams) {
|
||||
$this->defaultRpcParams = $rpcParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* dynamically creates an instance of a proxy class,
|
||||
* allowing user to directly call methods from wsdl
|
||||
*
|
||||
* @return object soap_proxy object
|
||||
* @access public
|
||||
*/
|
||||
function getProxy() {
|
||||
$r = rand();
|
||||
$evalStr = $this->_getProxyClassCode($r);
|
||||
//$this->debug("proxy class: $evalStr");
|
||||
if ($this->getError()) {
|
||||
$this->debug("Error from _getProxyClassCode, so return NULL");
|
||||
return null;
|
||||
}
|
||||
// eval the class
|
||||
eval($evalStr);
|
||||
// instantiate proxy object
|
||||
eval("\$proxy = new nusoap_proxy_$r('');");
|
||||
// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
|
||||
$proxy->endpointType = 'wsdl';
|
||||
$proxy->wsdlFile = $this->wsdlFile;
|
||||
$proxy->wsdl = $this->wsdl;
|
||||
$proxy->operations = $this->operations;
|
||||
$proxy->defaultRpcParams = $this->defaultRpcParams;
|
||||
// transfer other state
|
||||
$proxy->soap_defencoding = $this->soap_defencoding;
|
||||
$proxy->username = $this->username;
|
||||
$proxy->password = $this->password;
|
||||
$proxy->authtype = $this->authtype;
|
||||
$proxy->certRequest = $this->certRequest;
|
||||
$proxy->requestHeaders = $this->requestHeaders;
|
||||
$proxy->endpoint = $this->endpoint;
|
||||
$proxy->forceEndpoint = $this->forceEndpoint;
|
||||
$proxy->proxyhost = $this->proxyhost;
|
||||
$proxy->proxyport = $this->proxyport;
|
||||
$proxy->proxyusername = $this->proxyusername;
|
||||
$proxy->proxypassword = $this->proxypassword;
|
||||
$proxy->http_encoding = $this->http_encoding;
|
||||
$proxy->timeout = $this->timeout;
|
||||
$proxy->response_timeout = $this->response_timeout;
|
||||
$proxy->persistentConnection = &$this->persistentConnection;
|
||||
$proxy->decode_utf8 = $this->decode_utf8;
|
||||
$proxy->curl_options = $this->curl_options;
|
||||
$proxy->bindingType = $this->bindingType;
|
||||
$proxy->use_curl = $this->use_curl;
|
||||
return $proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* dynamically creates proxy class code
|
||||
*
|
||||
* @return string PHP/NuSOAP code for the proxy class
|
||||
* @access private
|
||||
*/
|
||||
function _getProxyClassCode($r) {
|
||||
$this->debug("in getProxy endpointType=$this->endpointType");
|
||||
$this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
|
||||
if ($this->endpointType != 'wsdl') {
|
||||
$evalStr = 'A proxy can only be created for a WSDL client';
|
||||
$this->setError($evalStr);
|
||||
$evalStr = "echo \"$evalStr\";";
|
||||
return $evalStr;
|
||||
}
|
||||
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
|
||||
$this->loadWSDL();
|
||||
if ($this->getError()) {
|
||||
return "echo \"" . $this->getError() . "\";";
|
||||
}
|
||||
}
|
||||
$evalStr = '';
|
||||
foreach ($this->operations as $operation => $opData) {
|
||||
if ($operation != '') {
|
||||
// create param string and param comment string
|
||||
if (sizeof($opData['input']['parts']) > 0) {
|
||||
$paramStr = '';
|
||||
$paramArrayStr = '';
|
||||
$paramCommentStr = '';
|
||||
foreach ($opData['input']['parts'] as $name => $type) {
|
||||
$paramStr .= "\$$name, ";
|
||||
$paramArrayStr .= "'$name' => \$$name, ";
|
||||
$paramCommentStr .= "$type \$$name, ";
|
||||
}
|
||||
$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
|
||||
$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
|
||||
$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
|
||||
} else {
|
||||
$paramStr = '';
|
||||
$paramArrayStr = '';
|
||||
$paramCommentStr = 'void';
|
||||
}
|
||||
$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
|
||||
$evalStr .= "// $paramCommentStr
|
||||
function " . str_replace('.', '__', $operation) . "($paramStr) {
|
||||
\$params = array($paramArrayStr);
|
||||
return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
|
||||
}
|
||||
";
|
||||
unset($paramStr);
|
||||
unset($paramCommentStr);
|
||||
}
|
||||
}
|
||||
$evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
|
||||
'.$evalStr.'
|
||||
}';
|
||||
return $evalStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* dynamically creates proxy class code
|
||||
*
|
||||
* @return string PHP/NuSOAP code for the proxy class
|
||||
* @access public
|
||||
*/
|
||||
function getProxyClassCode() {
|
||||
$r = rand();
|
||||
return $this->_getProxyClassCode($r);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP body for the current request.
|
||||
*
|
||||
* @param string $soapmsg The SOAP payload
|
||||
* @return string The HTTP body, which includes the SOAP payload
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPBody($soapmsg) {
|
||||
return $soapmsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP content type for the current request.
|
||||
*
|
||||
* Note: getHTTPBody must be called before this.
|
||||
*
|
||||
* @return string the HTTP content type for the current request.
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPContentType() {
|
||||
return 'text/xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP content type charset for the current request.
|
||||
* returns false for non-text content types.
|
||||
*
|
||||
* Note: getHTTPBody must be called before this.
|
||||
*
|
||||
* @return string the HTTP content type charset for the current request.
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPContentTypeCharset() {
|
||||
return $this->soap_defencoding;
|
||||
}
|
||||
|
||||
/*
|
||||
* whether or not parser should decode utf8 element content
|
||||
*
|
||||
* @return always returns true
|
||||
* @access public
|
||||
*/
|
||||
function decodeUTF8($bool){
|
||||
$this->decode_utf8 = $bool;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a new Cookie into $this->cookies array
|
||||
*
|
||||
* @param string $name Cookie Name
|
||||
* @param string $value Cookie Value
|
||||
* @return boolean if cookie-set was successful returns true, else false
|
||||
* @access public
|
||||
*/
|
||||
function setCookie($name, $value) {
|
||||
if (strlen($name) == 0) {
|
||||
return false;
|
||||
}
|
||||
$this->cookies[] = array('name' => $name, 'value' => $value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets all Cookies
|
||||
*
|
||||
* @return array with all internal cookies
|
||||
* @access public
|
||||
*/
|
||||
function getCookies() {
|
||||
return $this->cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks all Cookies and delete those which are expired
|
||||
*
|
||||
* @return boolean always return true
|
||||
* @access private
|
||||
*/
|
||||
function checkCookies() {
|
||||
if (sizeof($this->cookies) == 0) {
|
||||
return true;
|
||||
}
|
||||
$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
|
||||
$curr_cookies = $this->cookies;
|
||||
$this->cookies = array();
|
||||
foreach ($curr_cookies as $cookie) {
|
||||
if (! is_array($cookie)) {
|
||||
$this->debug('Remove cookie that is not an array');
|
||||
continue;
|
||||
}
|
||||
if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
|
||||
if (strtotime($cookie['expires']) > time()) {
|
||||
$this->cookies[] = $cookie;
|
||||
} else {
|
||||
$this->debug('Remove expired cookie ' . $cookie['name']);
|
||||
}
|
||||
} else {
|
||||
$this->cookies[] = $cookie;
|
||||
}
|
||||
}
|
||||
$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* updates the current cookies with a new set
|
||||
*
|
||||
* @param array $cookies new cookies with which to update current ones
|
||||
* @return boolean always return true
|
||||
* @access private
|
||||
*/
|
||||
function UpdateCookies($cookies) {
|
||||
if (sizeof($this->cookies) == 0) {
|
||||
// no existing cookies: take whatever is new
|
||||
if (sizeof($cookies) > 0) {
|
||||
$this->debug('Setting new cookie(s)');
|
||||
$this->cookies = $cookies;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (sizeof($cookies) == 0) {
|
||||
// no new cookies: keep what we've got
|
||||
return true;
|
||||
}
|
||||
// merge
|
||||
foreach ($cookies as $newCookie) {
|
||||
if (!is_array($newCookie)) {
|
||||
continue;
|
||||
}
|
||||
if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
|
||||
continue;
|
||||
}
|
||||
$newName = $newCookie['name'];
|
||||
|
||||
$found = false;
|
||||
for ($i = 0; $i < count($this->cookies); $i++) {
|
||||
$cookie = $this->cookies[$i];
|
||||
if (!is_array($cookie)) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($cookie['name'])) {
|
||||
continue;
|
||||
}
|
||||
if ($newName != $cookie['name']) {
|
||||
continue;
|
||||
}
|
||||
$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
|
||||
$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
|
||||
if ($newDomain != $domain) {
|
||||
continue;
|
||||
}
|
||||
$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
|
||||
$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
|
||||
if ($newPath != $path) {
|
||||
continue;
|
||||
}
|
||||
$this->cookies[$i] = $newCookie;
|
||||
$found = true;
|
||||
$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
|
||||
break;
|
||||
}
|
||||
if (! $found) {
|
||||
$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
|
||||
$this->cookies[] = $newCookie;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!extension_loaded('soap')) {
|
||||
/**
|
||||
* For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
|
||||
*/
|
||||
class soapclient extends nusoap_client {
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/*
|
||||
The NuSOAP project home is:
|
||||
http://sourceforge.net/projects/nusoap/
|
||||
|
||||
The primary support for NuSOAP is the mailing list:
|
||||
nusoap-general@lists.sourceforge.net
|
||||
*/
|
||||
|
||||
/**
|
||||
* caches instances of the wsdl class
|
||||
*
|
||||
* @author Scott Nichol <snichol@users.sourceforge.net>
|
||||
* @author Ingo Fischer <ingo@apollon.de>
|
||||
* @version $Id: class.wsdlcache.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_wsdlcache {
|
||||
/**
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $fplock;
|
||||
/**
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $cache_lifetime;
|
||||
/**
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cache_dir;
|
||||
/**
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $debug_str = '';
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $cache_dir directory for cache-files
|
||||
* @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited
|
||||
* @access public
|
||||
*/
|
||||
function nusoap_wsdlcache($cache_dir='.', $cache_lifetime=0) {
|
||||
$this->fplock = array();
|
||||
$this->cache_dir = $cache_dir != '' ? $cache_dir : '.';
|
||||
$this->cache_lifetime = $cache_lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the filename used to cache a wsdl instance
|
||||
*
|
||||
* @param string $wsdl The URL of the wsdl instance
|
||||
* @return string The filename used to cache the instance
|
||||
* @access private
|
||||
*/
|
||||
function createFilename($wsdl) {
|
||||
return $this->cache_dir.'/wsdlcache-' . md5($wsdl);
|
||||
}
|
||||
|
||||
/**
|
||||
* adds debug data to the class level debug string
|
||||
*
|
||||
* @param string $string debug data
|
||||
* @access private
|
||||
*/
|
||||
function debug($string){
|
||||
$this->debug_str .= get_class($this).": $string\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a wsdl instance from the cache
|
||||
*
|
||||
* @param string $wsdl The URL of the wsdl instance
|
||||
* @return object wsdl The cached wsdl instance, null if the instance is not in the cache
|
||||
* @access public
|
||||
*/
|
||||
function get($wsdl) {
|
||||
$filename = $this->createFilename($wsdl);
|
||||
if ($this->obtainMutex($filename, "r")) {
|
||||
// check for expired WSDL that must be removed from the cache
|
||||
if ($this->cache_lifetime > 0) {
|
||||
if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) {
|
||||
unlink($filename);
|
||||
$this->debug("Expired $wsdl ($filename) from cache");
|
||||
$this->releaseMutex($filename);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// see what there is to return
|
||||
if (!file_exists($filename)) {
|
||||
$this->debug("$wsdl ($filename) not in cache (1)");
|
||||
$this->releaseMutex($filename);
|
||||
return null;
|
||||
}
|
||||
$fp = @fopen($filename, "r");
|
||||
if ($fp) {
|
||||
$s = implode("", @file($filename));
|
||||
fclose($fp);
|
||||
$this->debug("Got $wsdl ($filename) from cache");
|
||||
} else {
|
||||
$s = null;
|
||||
$this->debug("$wsdl ($filename) not in cache (2)");
|
||||
}
|
||||
$this->releaseMutex($filename);
|
||||
return (!is_null($s)) ? unserialize($s) : null;
|
||||
} else {
|
||||
$this->debug("Unable to obtain mutex for $filename in get");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* obtains the local mutex
|
||||
*
|
||||
* @param string $filename The Filename of the Cache to lock
|
||||
* @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode
|
||||
* @return boolean Lock successfully obtained ?!
|
||||
* @access private
|
||||
*/
|
||||
function obtainMutex($filename, $mode) {
|
||||
if (isset($this->fplock[md5($filename)])) {
|
||||
$this->debug("Lock for $filename already exists");
|
||||
return false;
|
||||
}
|
||||
$this->fplock[md5($filename)] = fopen($filename.".lock", "w");
|
||||
if ($mode == "r") {
|
||||
return flock($this->fplock[md5($filename)], LOCK_SH);
|
||||
} else {
|
||||
return flock($this->fplock[md5($filename)], LOCK_EX);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a wsdl instance to the cache
|
||||
*
|
||||
* @param object wsdl $wsdl_instance The wsdl instance to add
|
||||
* @return boolean WSDL successfully cached
|
||||
* @access public
|
||||
*/
|
||||
function put($wsdl_instance) {
|
||||
$filename = $this->createFilename($wsdl_instance->wsdl);
|
||||
$s = serialize($wsdl_instance);
|
||||
if ($this->obtainMutex($filename, "w")) {
|
||||
$fp = fopen($filename, "w");
|
||||
if (! $fp) {
|
||||
$this->debug("Cannot write $wsdl_instance->wsdl ($filename) in cache");
|
||||
$this->releaseMutex($filename);
|
||||
return false;
|
||||
}
|
||||
fputs($fp, $s);
|
||||
fclose($fp);
|
||||
$this->debug("Put $wsdl_instance->wsdl ($filename) in cache");
|
||||
$this->releaseMutex($filename);
|
||||
return true;
|
||||
} else {
|
||||
$this->debug("Unable to obtain mutex for $filename in put");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* releases the local mutex
|
||||
*
|
||||
* @param string $filename The Filename of the Cache to lock
|
||||
* @return boolean Lock successfully released
|
||||
* @access private
|
||||
*/
|
||||
function releaseMutex($filename) {
|
||||
$ret = flock($this->fplock[md5($filename)], LOCK_UN);
|
||||
fclose($this->fplock[md5($filename)]);
|
||||
unset($this->fplock[md5($filename)]);
|
||||
if (! $ret) {
|
||||
$this->debug("Not able to release lock for $filename");
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a wsdl instance from the cache
|
||||
*
|
||||
* @param string $wsdl The URL of the wsdl instance
|
||||
* @return boolean Whether there was an instance to remove
|
||||
* @access public
|
||||
*/
|
||||
function remove($wsdl) {
|
||||
$filename = $this->createFilename($wsdl);
|
||||
if (!file_exists($filename)) {
|
||||
$this->debug("$wsdl ($filename) not in cache to be removed");
|
||||
return false;
|
||||
}
|
||||
// ignore errors obtaining mutex
|
||||
$this->obtainMutex($filename, "w");
|
||||
$ret = unlink($filename);
|
||||
$this->debug("Removed ($ret) $wsdl ($filename) from cache");
|
||||
$this->releaseMutex($filename);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For backward compatibility
|
||||
*/
|
||||
class wsdlcache extends nusoap_wsdlcache {
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,938 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* parses an XML Schema, allows access to it's data, other utility methods.
|
||||
* imperfect, no validation... yet, but quite functional.
|
||||
*
|
||||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||||
* @author Scott Nichol <snichol@users.sourceforge.net>
|
||||
* @version $Id: class.xmlschema.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_xmlschema extends nusoap_base {
|
||||
|
||||
// files
|
||||
var $schema = '';
|
||||
var $xml = '';
|
||||
// namespaces
|
||||
var $enclosingNamespaces;
|
||||
// schema info
|
||||
var $schemaInfo = array();
|
||||
var $schemaTargetNamespace = '';
|
||||
// types, elements, attributes defined by the schema
|
||||
var $attributes = array();
|
||||
var $complexTypes = array();
|
||||
var $complexTypeStack = array();
|
||||
var $currentComplexType = null;
|
||||
var $elements = array();
|
||||
var $elementStack = array();
|
||||
var $currentElement = null;
|
||||
var $simpleTypes = array();
|
||||
var $simpleTypeStack = array();
|
||||
var $currentSimpleType = null;
|
||||
// imports
|
||||
var $imports = array();
|
||||
// parser vars
|
||||
var $parser;
|
||||
var $position = 0;
|
||||
var $depth = 0;
|
||||
var $depth_array = array();
|
||||
var $message = array();
|
||||
var $defaultNamespace = array();
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $schema schema document URI
|
||||
* @param string $xml xml document URI
|
||||
* @param string $namespaces namespaces defined in enclosing XML
|
||||
* @access public
|
||||
*/
|
||||
function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
|
||||
parent::nusoap_base();
|
||||
$this->debug('nusoap_xmlschema class instantiated, inside constructor');
|
||||
// files
|
||||
$this->schema = $schema;
|
||||
$this->xml = $xml;
|
||||
|
||||
// namespaces
|
||||
$this->enclosingNamespaces = $namespaces;
|
||||
$this->namespaces = array_merge($this->namespaces, $namespaces);
|
||||
|
||||
// parse schema file
|
||||
if($schema != ''){
|
||||
$this->debug('initial schema file: '.$schema);
|
||||
$this->parseFile($schema, 'schema');
|
||||
}
|
||||
|
||||
// parse xml file
|
||||
if($xml != ''){
|
||||
$this->debug('initial xml file: '.$xml);
|
||||
$this->parseFile($xml, 'xml');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* parse an XML file
|
||||
*
|
||||
* @param string $xml path/URL to XML file
|
||||
* @param string $type (schema | xml)
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function parseFile($xml,$type){
|
||||
// parse xml file
|
||||
if($xml != ""){
|
||||
$xmlStr = @join("",@file($xml));
|
||||
if($xmlStr == ""){
|
||||
$msg = 'Error reading XML from '.$xml;
|
||||
$this->setError($msg);
|
||||
$this->debug($msg);
|
||||
return false;
|
||||
} else {
|
||||
$this->debug("parsing $xml");
|
||||
$this->parseString($xmlStr,$type);
|
||||
$this->debug("done parsing $xml");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse an XML string
|
||||
*
|
||||
* @param string $xml path or URL
|
||||
* @param string $type (schema|xml)
|
||||
* @access private
|
||||
*/
|
||||
function parseString($xml,$type){
|
||||
// parse xml string
|
||||
if($xml != ""){
|
||||
|
||||
// Create an XML parser.
|
||||
$this->parser = xml_parser_create();
|
||||
// Set the options for parsing the XML data.
|
||||
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
|
||||
|
||||
// Set the object for the parser.
|
||||
xml_set_object($this->parser, $this);
|
||||
|
||||
// Set the element handlers for the parser.
|
||||
if($type == "schema"){
|
||||
xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
|
||||
xml_set_character_data_handler($this->parser,'schemaCharacterData');
|
||||
} elseif($type == "xml"){
|
||||
xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
|
||||
xml_set_character_data_handler($this->parser,'xmlCharacterData');
|
||||
}
|
||||
|
||||
// Parse the XML file.
|
||||
if(!xml_parse($this->parser,$xml,true)){
|
||||
// Display an error message.
|
||||
$errstr = sprintf('XML error parsing XML schema on line %d: %s',
|
||||
xml_get_current_line_number($this->parser),
|
||||
xml_error_string(xml_get_error_code($this->parser))
|
||||
);
|
||||
$this->debug($errstr);
|
||||
$this->debug("XML payload:\n" . $xml);
|
||||
$this->setError($errstr);
|
||||
}
|
||||
|
||||
xml_parser_free($this->parser);
|
||||
} else{
|
||||
$this->debug('no xml passed to parseString()!!');
|
||||
$this->setError('no xml passed to parseString()!!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a type name for an unnamed type
|
||||
*
|
||||
* @param string Element name
|
||||
* @return string A type name for an unnamed type
|
||||
* @access private
|
||||
*/
|
||||
function CreateTypeName($ename) {
|
||||
$scope = '';
|
||||
for ($i = 0; $i < count($this->complexTypeStack); $i++) {
|
||||
$scope .= $this->complexTypeStack[$i] . '_';
|
||||
}
|
||||
return $scope . $ename . '_ContainedType';
|
||||
}
|
||||
|
||||
/**
|
||||
* start-element handler
|
||||
*
|
||||
* @param string $parser XML parser object
|
||||
* @param string $name element name
|
||||
* @param string $attrs associative array of attributes
|
||||
* @access private
|
||||
*/
|
||||
function schemaStartElement($parser, $name, $attrs) {
|
||||
|
||||
// position in the total number of elements, starting from 0
|
||||
$pos = $this->position++;
|
||||
$depth = $this->depth++;
|
||||
// set self as current value for this depth
|
||||
$this->depth_array[$depth] = $pos;
|
||||
$this->message[$pos] = array('cdata' => '');
|
||||
if ($depth > 0) {
|
||||
$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
|
||||
} else {
|
||||
$this->defaultNamespace[$pos] = false;
|
||||
}
|
||||
|
||||
// get element prefix
|
||||
if($prefix = $this->getPrefix($name)){
|
||||
// get unqualified name
|
||||
$name = $this->getLocalPart($name);
|
||||
} else {
|
||||
$prefix = '';
|
||||
}
|
||||
|
||||
// loop thru attributes, expanding, and registering namespace declarations
|
||||
if(count($attrs) > 0){
|
||||
foreach($attrs as $k => $v){
|
||||
// if ns declarations, add to class level array of valid namespaces
|
||||
if(ereg("^xmlns",$k)){
|
||||
//$this->xdebug("$k: $v");
|
||||
//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
|
||||
if($ns_prefix = substr(strrchr($k,':'),1)){
|
||||
//$this->xdebug("Add namespace[$ns_prefix] = $v");
|
||||
$this->namespaces[$ns_prefix] = $v;
|
||||
} else {
|
||||
$this->defaultNamespace[$pos] = $v;
|
||||
if (! $this->getPrefixFromNamespace($v)) {
|
||||
$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
|
||||
}
|
||||
}
|
||||
if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
|
||||
$this->XMLSchemaVersion = $v;
|
||||
$this->namespaces['xsi'] = $v.'-instance';
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($attrs as $k => $v){
|
||||
// expand each attribute
|
||||
$k = strpos($k,':') ? $this->expandQname($k) : $k;
|
||||
$v = strpos($v,':') ? $this->expandQname($v) : $v;
|
||||
$eAttrs[$k] = $v;
|
||||
}
|
||||
$attrs = $eAttrs;
|
||||
} else {
|
||||
$attrs = array();
|
||||
}
|
||||
// find status, register data
|
||||
switch($name){
|
||||
case 'all': // (optional) compositor content for a complexType
|
||||
case 'choice':
|
||||
case 'group':
|
||||
case 'sequence':
|
||||
//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
|
||||
$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
|
||||
//if($name == 'all' || $name == 'sequence'){
|
||||
// $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
|
||||
//}
|
||||
break;
|
||||
case 'attribute': // complexType attribute
|
||||
//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
|
||||
$this->xdebug("parsing attribute:");
|
||||
$this->appendDebug($this->varDump($attrs));
|
||||
if (!isset($attrs['form'])) {
|
||||
$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
|
||||
}
|
||||
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
|
||||
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
|
||||
if (!strpos($v, ':')) {
|
||||
// no namespace in arrayType attribute value...
|
||||
if ($this->defaultNamespace[$pos]) {
|
||||
// ...so use the default
|
||||
$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isset($attrs['name'])){
|
||||
$this->attributes[$attrs['name']] = $attrs;
|
||||
$aname = $attrs['name'];
|
||||
} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
|
||||
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
|
||||
$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
|
||||
} else {
|
||||
$aname = '';
|
||||
}
|
||||
} elseif(isset($attrs['ref'])){
|
||||
$aname = $attrs['ref'];
|
||||
$this->attributes[$attrs['ref']] = $attrs;
|
||||
}
|
||||
|
||||
if($this->currentComplexType){ // This should *always* be
|
||||
$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
|
||||
}
|
||||
// arrayType attribute
|
||||
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
|
||||
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
|
||||
$prefix = $this->getPrefix($aname);
|
||||
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
|
||||
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
|
||||
} else {
|
||||
$v = '';
|
||||
}
|
||||
if(strpos($v,'[,]')){
|
||||
$this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
|
||||
}
|
||||
$v = substr($v,0,strpos($v,'[')); // clip the []
|
||||
if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
|
||||
$v = $this->XMLSchemaVersion.':'.$v;
|
||||
}
|
||||
$this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
|
||||
}
|
||||
break;
|
||||
case 'complexContent': // (optional) content for a complexType
|
||||
break;
|
||||
case 'complexType':
|
||||
array_push($this->complexTypeStack, $this->currentComplexType);
|
||||
if(isset($attrs['name'])){
|
||||
// TODO: what is the scope of named complexTypes that appear
|
||||
// nested within other c complexTypes?
|
||||
$this->xdebug('processing named complexType '.$attrs['name']);
|
||||
//$this->currentElement = false;
|
||||
$this->currentComplexType = $attrs['name'];
|
||||
$this->complexTypes[$this->currentComplexType] = $attrs;
|
||||
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
|
||||
// This is for constructs like
|
||||
// <complexType name="ListOfString" base="soap:Array">
|
||||
// <sequence>
|
||||
// <element name="string" type="xsd:string"
|
||||
// minOccurs="0" maxOccurs="unbounded" />
|
||||
// </sequence>
|
||||
// </complexType>
|
||||
if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
|
||||
$this->xdebug('complexType is unusual array');
|
||||
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
|
||||
} else {
|
||||
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
|
||||
}
|
||||
} else {
|
||||
$name = $this->CreateTypeName($this->currentElement);
|
||||
$this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
|
||||
$this->currentComplexType = $name;
|
||||
//$this->currentElement = false;
|
||||
$this->complexTypes[$this->currentComplexType] = $attrs;
|
||||
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
|
||||
// This is for constructs like
|
||||
// <complexType name="ListOfString" base="soap:Array">
|
||||
// <sequence>
|
||||
// <element name="string" type="xsd:string"
|
||||
// minOccurs="0" maxOccurs="unbounded" />
|
||||
// </sequence>
|
||||
// </complexType>
|
||||
if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
|
||||
$this->xdebug('complexType is unusual array');
|
||||
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
|
||||
} else {
|
||||
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'element':
|
||||
array_push($this->elementStack, $this->currentElement);
|
||||
if (!isset($attrs['form'])) {
|
||||
$attrs['form'] = $this->schemaInfo['elementFormDefault'];
|
||||
}
|
||||
if(isset($attrs['type'])){
|
||||
$this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
|
||||
if (! $this->getPrefix($attrs['type'])) {
|
||||
if ($this->defaultNamespace[$pos]) {
|
||||
$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
|
||||
$this->xdebug('used default namespace to make type ' . $attrs['type']);
|
||||
}
|
||||
}
|
||||
// This is for constructs like
|
||||
// <complexType name="ListOfString" base="soap:Array">
|
||||
// <sequence>
|
||||
// <element name="string" type="xsd:string"
|
||||
// minOccurs="0" maxOccurs="unbounded" />
|
||||
// </sequence>
|
||||
// </complexType>
|
||||
if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
|
||||
$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
|
||||
$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
|
||||
}
|
||||
$this->currentElement = $attrs['name'];
|
||||
$ename = $attrs['name'];
|
||||
} elseif(isset($attrs['ref'])){
|
||||
$this->xdebug("processing element as ref to ".$attrs['ref']);
|
||||
$this->currentElement = "ref to ".$attrs['ref'];
|
||||
$ename = $this->getLocalPart($attrs['ref']);
|
||||
} else {
|
||||
$type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
|
||||
$this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
|
||||
$this->currentElement = $attrs['name'];
|
||||
$attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
|
||||
$ename = $attrs['name'];
|
||||
}
|
||||
if (isset($ename) && $this->currentComplexType) {
|
||||
$this->xdebug("add element $ename to complexType $this->currentComplexType");
|
||||
$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
|
||||
} elseif (!isset($attrs['ref'])) {
|
||||
$this->xdebug("add element $ename to elements array");
|
||||
$this->elements[ $attrs['name'] ] = $attrs;
|
||||
$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
|
||||
}
|
||||
break;
|
||||
case 'enumeration': // restriction value list member
|
||||
$this->xdebug('enumeration ' . $attrs['value']);
|
||||
if ($this->currentSimpleType) {
|
||||
$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
|
||||
} elseif ($this->currentComplexType) {
|
||||
$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
|
||||
}
|
||||
break;
|
||||
case 'extension': // simpleContent or complexContent type extension
|
||||
$this->xdebug('extension ' . $attrs['base']);
|
||||
if ($this->currentComplexType) {
|
||||
$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
|
||||
}
|
||||
break;
|
||||
case 'import':
|
||||
if (isset($attrs['schemaLocation'])) {
|
||||
//$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
|
||||
$this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
|
||||
} else {
|
||||
//$this->xdebug('import namespace ' . $attrs['namespace']);
|
||||
$this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
|
||||
if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
|
||||
$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'list': // simpleType value list
|
||||
break;
|
||||
case 'restriction': // simpleType, simpleContent or complexContent value restriction
|
||||
$this->xdebug('restriction ' . $attrs['base']);
|
||||
if($this->currentSimpleType){
|
||||
$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
|
||||
} elseif($this->currentComplexType){
|
||||
$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
|
||||
if(strstr($attrs['base'],':') == ':Array'){
|
||||
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'schema':
|
||||
$this->schemaInfo = $attrs;
|
||||
$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
|
||||
if (isset($attrs['targetNamespace'])) {
|
||||
$this->schemaTargetNamespace = $attrs['targetNamespace'];
|
||||
}
|
||||
if (!isset($attrs['elementFormDefault'])) {
|
||||
$this->schemaInfo['elementFormDefault'] = 'unqualified';
|
||||
}
|
||||
if (!isset($attrs['attributeFormDefault'])) {
|
||||
$this->schemaInfo['attributeFormDefault'] = 'unqualified';
|
||||
}
|
||||
break;
|
||||
case 'simpleContent': // (optional) content for a complexType
|
||||
break;
|
||||
case 'simpleType':
|
||||
array_push($this->simpleTypeStack, $this->currentSimpleType);
|
||||
if(isset($attrs['name'])){
|
||||
$this->xdebug("processing simpleType for name " . $attrs['name']);
|
||||
$this->currentSimpleType = $attrs['name'];
|
||||
$this->simpleTypes[ $attrs['name'] ] = $attrs;
|
||||
$this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
|
||||
$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
|
||||
} else {
|
||||
$name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
|
||||
$this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
|
||||
$this->currentSimpleType = $name;
|
||||
//$this->currentElement = false;
|
||||
$this->simpleTypes[$this->currentSimpleType] = $attrs;
|
||||
$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
|
||||
}
|
||||
break;
|
||||
case 'union': // simpleType type list
|
||||
break;
|
||||
default:
|
||||
//$this->xdebug("do not have anything to do for element $name");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* end-element handler
|
||||
*
|
||||
* @param string $parser XML parser object
|
||||
* @param string $name element name
|
||||
* @access private
|
||||
*/
|
||||
function schemaEndElement($parser, $name) {
|
||||
// bring depth down a notch
|
||||
$this->depth--;
|
||||
// position of current element is equal to the last value left in depth_array for my depth
|
||||
if(isset($this->depth_array[$this->depth])){
|
||||
$pos = $this->depth_array[$this->depth];
|
||||
}
|
||||
// get element prefix
|
||||
if ($prefix = $this->getPrefix($name)){
|
||||
// get unqualified name
|
||||
$name = $this->getLocalPart($name);
|
||||
} else {
|
||||
$prefix = '';
|
||||
}
|
||||
// move on...
|
||||
if($name == 'complexType'){
|
||||
$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
|
||||
$this->currentComplexType = array_pop($this->complexTypeStack);
|
||||
//$this->currentElement = false;
|
||||
}
|
||||
if($name == 'element'){
|
||||
$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
|
||||
$this->currentElement = array_pop($this->elementStack);
|
||||
}
|
||||
if($name == 'simpleType'){
|
||||
$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
|
||||
$this->currentSimpleType = array_pop($this->simpleTypeStack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* element content handler
|
||||
*
|
||||
* @param string $parser XML parser object
|
||||
* @param string $data element content
|
||||
* @access private
|
||||
*/
|
||||
function schemaCharacterData($parser, $data){
|
||||
$pos = $this->depth_array[$this->depth - 1];
|
||||
$this->message[$pos]['cdata'] .= $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* serialize the schema
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function serializeSchema(){
|
||||
|
||||
$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
|
||||
$xml = '';
|
||||
// imports
|
||||
if (sizeof($this->imports) > 0) {
|
||||
foreach($this->imports as $ns => $list) {
|
||||
foreach ($list as $ii) {
|
||||
if ($ii['location'] != '') {
|
||||
$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
|
||||
} else {
|
||||
$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// complex types
|
||||
foreach($this->complexTypes as $typeName => $attrs){
|
||||
$contentStr = '';
|
||||
// serialize child elements
|
||||
if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
|
||||
foreach($attrs['elements'] as $element => $eParts){
|
||||
if(isset($eParts['ref'])){
|
||||
$contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
|
||||
} else {
|
||||
$contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
|
||||
foreach ($eParts as $aName => $aValue) {
|
||||
// handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
|
||||
if ($aName != 'name' && $aName != 'type') {
|
||||
$contentStr .= " $aName=\"$aValue\"";
|
||||
}
|
||||
}
|
||||
$contentStr .= "/>\n";
|
||||
}
|
||||
}
|
||||
// compositor wraps elements
|
||||
if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
|
||||
$contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
|
||||
}
|
||||
}
|
||||
// attributes
|
||||
if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
|
||||
foreach($attrs['attrs'] as $attr => $aParts){
|
||||
$contentStr .= " <$schemaPrefix:attribute";
|
||||
foreach ($aParts as $a => $v) {
|
||||
if ($a == 'ref' || $a == 'type') {
|
||||
$contentStr .= " $a=\"".$this->contractQName($v).'"';
|
||||
} elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
|
||||
$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
|
||||
$contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
|
||||
} else {
|
||||
$contentStr .= " $a=\"$v\"";
|
||||
}
|
||||
}
|
||||
$contentStr .= "/>\n";
|
||||
}
|
||||
}
|
||||
// if restriction
|
||||
if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
|
||||
$contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
|
||||
// complex or simple content
|
||||
if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
|
||||
$contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
|
||||
}
|
||||
}
|
||||
// finalize complex type
|
||||
if($contentStr != ''){
|
||||
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
|
||||
} else {
|
||||
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
|
||||
}
|
||||
$xml .= $contentStr;
|
||||
}
|
||||
// simple types
|
||||
if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
|
||||
foreach($this->simpleTypes as $typeName => $eParts){
|
||||
$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
|
||||
if (isset($eParts['enumeration'])) {
|
||||
foreach ($eParts['enumeration'] as $e) {
|
||||
$xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
|
||||
}
|
||||
}
|
||||
$xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
|
||||
}
|
||||
}
|
||||
// elements
|
||||
if(isset($this->elements) && count($this->elements) > 0){
|
||||
foreach($this->elements as $element => $eParts){
|
||||
$xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
|
||||
}
|
||||
}
|
||||
// attributes
|
||||
if(isset($this->attributes) && count($this->attributes) > 0){
|
||||
foreach($this->attributes as $attr => $aParts){
|
||||
$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
|
||||
}
|
||||
}
|
||||
// finish 'er up
|
||||
$attr = '';
|
||||
foreach ($this->schemaInfo as $k => $v) {
|
||||
if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
|
||||
$attr .= " $k=\"$v\"";
|
||||
}
|
||||
}
|
||||
$el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
|
||||
foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
|
||||
$el .= " xmlns:$nsp=\"$ns\"";
|
||||
}
|
||||
$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds debug data to the clas level debug string
|
||||
*
|
||||
* @param string $string debug data
|
||||
* @access private
|
||||
*/
|
||||
function xdebug($string){
|
||||
$this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the PHP type of a user defined type in the schema
|
||||
* PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
|
||||
* returns false if no type exists, or not w/ the given namespace
|
||||
* else returns a string that is either a native php type, or 'struct'
|
||||
*
|
||||
* @param string $type name of defined type
|
||||
* @param string $ns namespace of type
|
||||
* @return mixed
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function getPHPType($type,$ns){
|
||||
if(isset($this->typemap[$ns][$type])){
|
||||
//print "found type '$type' and ns $ns in typemap<br>";
|
||||
return $this->typemap[$ns][$type];
|
||||
} elseif(isset($this->complexTypes[$type])){
|
||||
//print "getting type '$type' and ns $ns from complexTypes array<br>";
|
||||
return $this->complexTypes[$type]['phpType'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an associative array of information about a given type
|
||||
* returns false if no type exists by the given name
|
||||
*
|
||||
* For a complexType typeDef = array(
|
||||
* 'restrictionBase' => '',
|
||||
* 'phpType' => '',
|
||||
* 'compositor' => '(sequence|all)',
|
||||
* 'elements' => array(), // refs to elements array
|
||||
* 'attrs' => array() // refs to attributes array
|
||||
* ... and so on (see addComplexType)
|
||||
* )
|
||||
*
|
||||
* For simpleType or element, the array has different keys.
|
||||
*
|
||||
* @param string $type
|
||||
* @return mixed
|
||||
* @access public
|
||||
* @see addComplexType
|
||||
* @see addSimpleType
|
||||
* @see addElement
|
||||
*/
|
||||
function getTypeDef($type){
|
||||
//$this->debug("in getTypeDef for type $type");
|
||||
if (substr($type, -1) == '^') {
|
||||
$is_element = 1;
|
||||
$type = substr($type, 0, -1);
|
||||
} else {
|
||||
$is_element = 0;
|
||||
}
|
||||
|
||||
if((! $is_element) && isset($this->complexTypes[$type])){
|
||||
$this->xdebug("in getTypeDef, found complexType $type");
|
||||
return $this->complexTypes[$type];
|
||||
} elseif((! $is_element) && isset($this->simpleTypes[$type])){
|
||||
$this->xdebug("in getTypeDef, found simpleType $type");
|
||||
if (!isset($this->simpleTypes[$type]['phpType'])) {
|
||||
// get info for type to tack onto the simple type
|
||||
// TODO: can this ever really apply (i.e. what is a simpleType really?)
|
||||
$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
|
||||
$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
|
||||
$etype = $this->getTypeDef($uqType);
|
||||
if ($etype) {
|
||||
$this->xdebug("in getTypeDef, found type for simpleType $type:");
|
||||
$this->xdebug($this->varDump($etype));
|
||||
if (isset($etype['phpType'])) {
|
||||
$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
|
||||
}
|
||||
if (isset($etype['elements'])) {
|
||||
$this->simpleTypes[$type]['elements'] = $etype['elements'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->simpleTypes[$type];
|
||||
} elseif(isset($this->elements[$type])){
|
||||
$this->xdebug("in getTypeDef, found element $type");
|
||||
if (!isset($this->elements[$type]['phpType'])) {
|
||||
// get info for type to tack onto the element
|
||||
$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
|
||||
$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
|
||||
$etype = $this->getTypeDef($uqType);
|
||||
if ($etype) {
|
||||
$this->xdebug("in getTypeDef, found type for element $type:");
|
||||
$this->xdebug($this->varDump($etype));
|
||||
if (isset($etype['phpType'])) {
|
||||
$this->elements[$type]['phpType'] = $etype['phpType'];
|
||||
}
|
||||
if (isset($etype['elements'])) {
|
||||
$this->elements[$type]['elements'] = $etype['elements'];
|
||||
}
|
||||
} elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
|
||||
$this->xdebug("in getTypeDef, element $type is an XSD type");
|
||||
$this->elements[$type]['phpType'] = 'scalar';
|
||||
}
|
||||
}
|
||||
return $this->elements[$type];
|
||||
} elseif(isset($this->attributes[$type])){
|
||||
$this->xdebug("in getTypeDef, found attribute $type");
|
||||
return $this->attributes[$type];
|
||||
} elseif (ereg('_ContainedType$', $type)) {
|
||||
$this->xdebug("in getTypeDef, have an untyped element $type");
|
||||
$typeDef['typeClass'] = 'simpleType';
|
||||
$typeDef['phpType'] = 'scalar';
|
||||
$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
|
||||
return $typeDef;
|
||||
}
|
||||
$this->xdebug("in getTypeDef, did not find $type");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a sample serialization of a given type, or false if no type by the given name
|
||||
*
|
||||
* @param string $type name of type
|
||||
* @return mixed
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function serializeTypeDef($type){
|
||||
//print "in sTD() for type $type<br>";
|
||||
if($typeDef = $this->getTypeDef($type)){
|
||||
$str .= '<'.$type;
|
||||
if(is_array($typeDef['attrs'])){
|
||||
foreach($typeDef['attrs'] as $attName => $data){
|
||||
$str .= " $attName=\"{type = ".$data['type']."}\"";
|
||||
}
|
||||
}
|
||||
$str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
|
||||
if(count($typeDef['elements']) > 0){
|
||||
$str .= ">";
|
||||
foreach($typeDef['elements'] as $element => $eData){
|
||||
$str .= $this->serializeTypeDef($element);
|
||||
}
|
||||
$str .= "</$type>";
|
||||
} elseif($typeDef['typeClass'] == 'element') {
|
||||
$str .= "></$type>";
|
||||
} else {
|
||||
$str .= "/>";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns HTML form elements that allow a user
|
||||
* to enter values for creating an instance of the given type.
|
||||
*
|
||||
* @param string $name name for type instance
|
||||
* @param string $type name of type
|
||||
* @return string
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function typeToForm($name,$type){
|
||||
// get typedef
|
||||
if($typeDef = $this->getTypeDef($type)){
|
||||
// if struct
|
||||
if($typeDef['phpType'] == 'struct'){
|
||||
$buffer .= '<table>';
|
||||
foreach($typeDef['elements'] as $child => $childDef){
|
||||
$buffer .= "
|
||||
<tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
|
||||
<td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
|
||||
}
|
||||
$buffer .= '</table>';
|
||||
// if array
|
||||
} elseif($typeDef['phpType'] == 'array'){
|
||||
$buffer .= '<table>';
|
||||
for($i=0;$i < 3; $i++){
|
||||
$buffer .= "
|
||||
<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
|
||||
<td><input type='text' name='parameters[".$name."][]'></td></tr>";
|
||||
}
|
||||
$buffer .= '</table>';
|
||||
// if scalar
|
||||
} else {
|
||||
$buffer .= "<input type='text' name='parameters[$name]'>";
|
||||
}
|
||||
} else {
|
||||
$buffer .= "<input type='text' name='parameters[$name]'>";
|
||||
}
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a complex type to the schema
|
||||
*
|
||||
* example: array
|
||||
*
|
||||
* addType(
|
||||
* 'ArrayOfstring',
|
||||
* 'complexType',
|
||||
* 'array',
|
||||
* '',
|
||||
* 'SOAP-ENC:Array',
|
||||
* array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
|
||||
* 'xsd:string'
|
||||
* );
|
||||
*
|
||||
* example: PHP associative array ( SOAP Struct )
|
||||
*
|
||||
* addType(
|
||||
* 'SOAPStruct',
|
||||
* 'complexType',
|
||||
* 'struct',
|
||||
* 'all',
|
||||
* array('myVar'=> array('name'=>'myVar','type'=>'string')
|
||||
* );
|
||||
*
|
||||
* @param name
|
||||
* @param typeClass (complexType|simpleType|attribute)
|
||||
* @param phpType: currently supported are array and struct (php assoc array)
|
||||
* @param compositor (all|sequence|choice)
|
||||
* @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
|
||||
* @param elements = array ( name = array(name=>'',type=>'') )
|
||||
* @param attrs = array(
|
||||
* array(
|
||||
* 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
|
||||
* "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
|
||||
* )
|
||||
* )
|
||||
* @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
|
||||
* @access public
|
||||
* @see getTypeDef
|
||||
*/
|
||||
function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
|
||||
$this->complexTypes[$name] = array(
|
||||
'name' => $name,
|
||||
'typeClass' => $typeClass,
|
||||
'phpType' => $phpType,
|
||||
'compositor'=> $compositor,
|
||||
'restrictionBase' => $restrictionBase,
|
||||
'elements' => $elements,
|
||||
'attrs' => $attrs,
|
||||
'arrayType' => $arrayType
|
||||
);
|
||||
|
||||
$this->xdebug("addComplexType $name:");
|
||||
$this->appendDebug($this->varDump($this->complexTypes[$name]));
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a simple type to the schema
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
|
||||
* @param string $typeClass (should always be simpleType)
|
||||
* @param string $phpType (should always be scalar)
|
||||
* @param array $enumeration array of values
|
||||
* @access public
|
||||
* @see nusoap_xmlschema
|
||||
* @see getTypeDef
|
||||
*/
|
||||
function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
|
||||
$this->simpleTypes[$name] = array(
|
||||
'name' => $name,
|
||||
'typeClass' => $typeClass,
|
||||
'phpType' => $phpType,
|
||||
'type' => $restrictionBase,
|
||||
'enumeration' => $enumeration
|
||||
);
|
||||
|
||||
$this->xdebug("addSimpleType $name:");
|
||||
$this->appendDebug($this->varDump($this->simpleTypes[$name]));
|
||||
}
|
||||
|
||||
/**
|
||||
* adds an element to the schema
|
||||
*
|
||||
* @param array $attrs attributes that must include name and type
|
||||
* @see nusoap_xmlschema
|
||||
* @access public
|
||||
*/
|
||||
function addElement($attrs) {
|
||||
if (! $this->getPrefix($attrs['type'])) {
|
||||
$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
|
||||
}
|
||||
$this->elements[ $attrs['name'] ] = $attrs;
|
||||
$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
|
||||
|
||||
$this->xdebug("addElement " . $attrs['name']);
|
||||
$this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backward compatibility
|
||||
*/
|
||||
class XMLSchema extends nusoap_xmlschema {
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,501 @@
|
||||
<?php
|
||||
/*
|
||||
$Id: nusoapmime.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
|
||||
NuSOAP - Web Services Toolkit for PHP
|
||||
|
||||
Copyright (c) 2002 NuSphere Corporation
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
The NuSOAP project home is:
|
||||
http://sourceforge.net/projects/nusoap/
|
||||
|
||||
The primary support for NuSOAP is the mailing list:
|
||||
nusoap-general@lists.sourceforge.net
|
||||
|
||||
If you have any questions or comments, please email:
|
||||
|
||||
Dietrich Ayala
|
||||
dietrich@ganx4.com
|
||||
http://dietrich.ganx4.com/nusoap
|
||||
|
||||
NuSphere Corporation
|
||||
http://www.nusphere.com
|
||||
|
||||
*/
|
||||
|
||||
/*require_once('nusoap.php');*/
|
||||
/* PEAR Mail_MIME library */
|
||||
require_once('Mail/mimeDecode.php');
|
||||
require_once('Mail/mimePart.php');
|
||||
|
||||
/**
|
||||
* nusoap_client_mime client supporting MIME attachments defined at
|
||||
* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
|
||||
*
|
||||
* @author Scott Nichol <snichol@users.sourceforge.net>
|
||||
* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
|
||||
* @version $Id: nusoapmime.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_client_mime extends nusoap_client {
|
||||
/**
|
||||
* @var array Each array element in the return is an associative array with keys
|
||||
* data, filename, contenttype, cid
|
||||
* @access private
|
||||
*/
|
||||
var $requestAttachments = array();
|
||||
/**
|
||||
* @var array Each array element in the return is an associative array with keys
|
||||
* data, filename, contenttype, cid
|
||||
* @access private
|
||||
*/
|
||||
var $responseAttachments;
|
||||
/**
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $mimeContentType;
|
||||
|
||||
/**
|
||||
* adds a MIME attachment to the current request.
|
||||
*
|
||||
* If the $data parameter contains an empty string, this method will read
|
||||
* the contents of the file named by the $filename parameter.
|
||||
*
|
||||
* If the $cid parameter is false, this method will generate the cid.
|
||||
*
|
||||
* @param string $data The data of the attachment
|
||||
* @param string $filename The filename of the attachment (default is empty string)
|
||||
* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
|
||||
* @param string $cid The content-id (cid) of the attachment (default is false)
|
||||
* @return string The content-id (cid) of the attachment
|
||||
* @access public
|
||||
*/
|
||||
function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
|
||||
if (! $cid) {
|
||||
$cid = md5(uniqid(time()));
|
||||
}
|
||||
|
||||
$info['data'] = $data;
|
||||
$info['filename'] = $filename;
|
||||
$info['contenttype'] = $contenttype;
|
||||
$info['cid'] = $cid;
|
||||
|
||||
$this->requestAttachments[] = $info;
|
||||
|
||||
return $cid;
|
||||
}
|
||||
|
||||
/**
|
||||
* clears the MIME attachments for the current request.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function clearAttachments() {
|
||||
$this->requestAttachments = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the MIME attachments from the current response.
|
||||
*
|
||||
* Each array element in the return is an associative array with keys
|
||||
* data, filename, contenttype, cid. These keys correspond to the parameters
|
||||
* for addAttachment.
|
||||
*
|
||||
* @return array The attachments.
|
||||
* @access public
|
||||
*/
|
||||
function getAttachments() {
|
||||
return $this->responseAttachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP body for the current request.
|
||||
*
|
||||
* @param string $soapmsg The SOAP payload
|
||||
* @return string The HTTP body, which includes the SOAP payload
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPBody($soapmsg) {
|
||||
if (count($this->requestAttachments) > 0) {
|
||||
$params['content_type'] = 'multipart/related; type="text/xml"';
|
||||
$mimeMessage =& new Mail_mimePart('', $params);
|
||||
unset($params);
|
||||
|
||||
$params['content_type'] = 'text/xml';
|
||||
$params['encoding'] = '8bit';
|
||||
$params['charset'] = $this->soap_defencoding;
|
||||
$mimeMessage->addSubpart($soapmsg, $params);
|
||||
|
||||
foreach ($this->requestAttachments as $att) {
|
||||
unset($params);
|
||||
|
||||
$params['content_type'] = $att['contenttype'];
|
||||
$params['encoding'] = 'base64';
|
||||
$params['disposition'] = 'attachment';
|
||||
$params['dfilename'] = $att['filename'];
|
||||
$params['cid'] = $att['cid'];
|
||||
|
||||
if ($att['data'] == '' && $att['filename'] <> '') {
|
||||
if ($fd = fopen($att['filename'], 'rb')) {
|
||||
$data = fread($fd, filesize($att['filename']));
|
||||
fclose($fd);
|
||||
} else {
|
||||
$data = '';
|
||||
}
|
||||
$mimeMessage->addSubpart($data, $params);
|
||||
} else {
|
||||
$mimeMessage->addSubpart($att['data'], $params);
|
||||
}
|
||||
}
|
||||
|
||||
$output = $mimeMessage->encode();
|
||||
$mimeHeaders = $output['headers'];
|
||||
|
||||
foreach ($mimeHeaders as $k => $v) {
|
||||
$this->debug("MIME header $k: $v");
|
||||
if (strtolower($k) == 'content-type') {
|
||||
// PHP header() seems to strip leading whitespace starting
|
||||
// the second line, so force everything to one line
|
||||
$this->mimeContentType = str_replace("\r\n", " ", $v);
|
||||
}
|
||||
}
|
||||
|
||||
return $output['body'];
|
||||
}
|
||||
|
||||
return parent::getHTTPBody($soapmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP content type for the current request.
|
||||
*
|
||||
* Note: getHTTPBody must be called before this.
|
||||
*
|
||||
* @return string the HTTP content type for the current request.
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPContentType() {
|
||||
if (count($this->requestAttachments) > 0) {
|
||||
return $this->mimeContentType;
|
||||
}
|
||||
return parent::getHTTPContentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP content type charset for the current request.
|
||||
* returns false for non-text content types.
|
||||
*
|
||||
* Note: getHTTPBody must be called before this.
|
||||
*
|
||||
* @return string the HTTP content type charset for the current request.
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPContentTypeCharset() {
|
||||
if (count($this->requestAttachments) > 0) {
|
||||
return false;
|
||||
}
|
||||
return parent::getHTTPContentTypeCharset();
|
||||
}
|
||||
|
||||
/**
|
||||
* processes SOAP message returned from server
|
||||
*
|
||||
* @param array $headers The HTTP headers
|
||||
* @param string $data unprocessed response data from server
|
||||
* @return mixed value of the message, decoded into a PHP type
|
||||
* @access private
|
||||
*/
|
||||
function parseResponse($headers, $data) {
|
||||
$this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
|
||||
$this->responseAttachments = array();
|
||||
if (strstr($headers['content-type'], 'multipart/related')) {
|
||||
$this->debug('Decode multipart/related');
|
||||
$input = '';
|
||||
foreach ($headers as $k => $v) {
|
||||
$input .= "$k: $v\r\n";
|
||||
}
|
||||
$params['input'] = $input . "\r\n" . $data;
|
||||
$params['include_bodies'] = true;
|
||||
$params['decode_bodies'] = true;
|
||||
$params['decode_headers'] = true;
|
||||
|
||||
$structure = Mail_mimeDecode::decode($params);
|
||||
|
||||
foreach ($structure->parts as $part) {
|
||||
if (!isset($part->disposition) && (strstr($part->headers['content-type'], 'text/xml'))) {
|
||||
$this->debug('Have root part of type ' . $part->headers['content-type']);
|
||||
$root = $part->body;
|
||||
$return = parent::parseResponse($part->headers, $part->body);
|
||||
} else {
|
||||
$this->debug('Have an attachment of type ' . $part->headers['content-type']);
|
||||
$info['data'] = $part->body;
|
||||
$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
|
||||
$info['contenttype'] = $part->headers['content-type'];
|
||||
$info['cid'] = $part->headers['content-id'];
|
||||
$this->responseAttachments[] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($return)) {
|
||||
$this->responseData = $root;
|
||||
return $return;
|
||||
}
|
||||
|
||||
$this->setError('No root part found in multipart/related content');
|
||||
return '';
|
||||
}
|
||||
$this->debug('Not multipart/related');
|
||||
return parent::parseResponse($headers, $data);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For backwards compatiblity, define soapclientmime unless the PHP SOAP extension is loaded.
|
||||
*/
|
||||
if (!extension_loaded('soap')) {
|
||||
class soapclientmime extends nusoap_client_mime {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nusoap_server_mime server supporting MIME attachments defined at
|
||||
* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
|
||||
*
|
||||
* @author Scott Nichol <snichol@users.sourceforge.net>
|
||||
* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
|
||||
* @version $Id: nusoapmime.php,v 1.1 2008/02/17 15:29:23 oliver Exp $
|
||||
* @access public
|
||||
*/
|
||||
class nusoap_server_mime extends nusoap_server {
|
||||
/**
|
||||
* @var array Each array element in the return is an associative array with keys
|
||||
* data, filename, contenttype, cid
|
||||
* @access private
|
||||
*/
|
||||
var $requestAttachments = array();
|
||||
/**
|
||||
* @var array Each array element in the return is an associative array with keys
|
||||
* data, filename, contenttype, cid
|
||||
* @access private
|
||||
*/
|
||||
var $responseAttachments;
|
||||
/**
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $mimeContentType;
|
||||
|
||||
/**
|
||||
* adds a MIME attachment to the current response.
|
||||
*
|
||||
* If the $data parameter contains an empty string, this method will read
|
||||
* the contents of the file named by the $filename parameter.
|
||||
*
|
||||
* If the $cid parameter is false, this method will generate the cid.
|
||||
*
|
||||
* @param string $data The data of the attachment
|
||||
* @param string $filename The filename of the attachment (default is empty string)
|
||||
* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
|
||||
* @param string $cid The content-id (cid) of the attachment (default is false)
|
||||
* @return string The content-id (cid) of the attachment
|
||||
* @access public
|
||||
*/
|
||||
function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
|
||||
if (! $cid) {
|
||||
$cid = md5(uniqid(time()));
|
||||
}
|
||||
|
||||
$info['data'] = $data;
|
||||
$info['filename'] = $filename;
|
||||
$info['contenttype'] = $contenttype;
|
||||
$info['cid'] = $cid;
|
||||
|
||||
$this->responseAttachments[] = $info;
|
||||
|
||||
return $cid;
|
||||
}
|
||||
|
||||
/**
|
||||
* clears the MIME attachments for the current response.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function clearAttachments() {
|
||||
$this->responseAttachments = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the MIME attachments from the current request.
|
||||
*
|
||||
* Each array element in the return is an associative array with keys
|
||||
* data, filename, contenttype, cid. These keys correspond to the parameters
|
||||
* for addAttachment.
|
||||
*
|
||||
* @return array The attachments.
|
||||
* @access public
|
||||
*/
|
||||
function getAttachments() {
|
||||
return $this->requestAttachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP body for the current response.
|
||||
*
|
||||
* @param string $soapmsg The SOAP payload
|
||||
* @return string The HTTP body, which includes the SOAP payload
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPBody($soapmsg) {
|
||||
if (count($this->responseAttachments) > 0) {
|
||||
$params['content_type'] = 'multipart/related; type="text/xml"';
|
||||
$mimeMessage =& new Mail_mimePart('', $params);
|
||||
unset($params);
|
||||
|
||||
$params['content_type'] = 'text/xml';
|
||||
$params['encoding'] = '8bit';
|
||||
$params['charset'] = $this->soap_defencoding;
|
||||
$mimeMessage->addSubpart($soapmsg, $params);
|
||||
|
||||
foreach ($this->responseAttachments as $att) {
|
||||
unset($params);
|
||||
|
||||
$params['content_type'] = $att['contenttype'];
|
||||
$params['encoding'] = 'base64';
|
||||
$params['disposition'] = 'attachment';
|
||||
$params['dfilename'] = $att['filename'];
|
||||
$params['cid'] = $att['cid'];
|
||||
|
||||
if ($att['data'] == '' && $att['filename'] <> '') {
|
||||
if ($fd = fopen($att['filename'], 'rb')) {
|
||||
$data = fread($fd, filesize($att['filename']));
|
||||
fclose($fd);
|
||||
} else {
|
||||
$data = '';
|
||||
}
|
||||
$mimeMessage->addSubpart($data, $params);
|
||||
} else {
|
||||
$mimeMessage->addSubpart($att['data'], $params);
|
||||
}
|
||||
}
|
||||
|
||||
$output = $mimeMessage->encode();
|
||||
$mimeHeaders = $output['headers'];
|
||||
|
||||
foreach ($mimeHeaders as $k => $v) {
|
||||
$this->debug("MIME header $k: $v");
|
||||
if (strtolower($k) == 'content-type') {
|
||||
// PHP header() seems to strip leading whitespace starting
|
||||
// the second line, so force everything to one line
|
||||
$this->mimeContentType = str_replace("\r\n", " ", $v);
|
||||
}
|
||||
}
|
||||
|
||||
return $output['body'];
|
||||
}
|
||||
|
||||
return parent::getHTTPBody($soapmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP content type for the current response.
|
||||
*
|
||||
* Note: getHTTPBody must be called before this.
|
||||
*
|
||||
* @return string the HTTP content type for the current response.
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPContentType() {
|
||||
if (count($this->responseAttachments) > 0) {
|
||||
return $this->mimeContentType;
|
||||
}
|
||||
return parent::getHTTPContentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the HTTP content type charset for the current response.
|
||||
* returns false for non-text content types.
|
||||
*
|
||||
* Note: getHTTPBody must be called before this.
|
||||
*
|
||||
* @return string the HTTP content type charset for the current response.
|
||||
* @access private
|
||||
*/
|
||||
function getHTTPContentTypeCharset() {
|
||||
if (count($this->responseAttachments) > 0) {
|
||||
return false;
|
||||
}
|
||||
return parent::getHTTPContentTypeCharset();
|
||||
}
|
||||
|
||||
/**
|
||||
* processes SOAP message received from client
|
||||
*
|
||||
* @param array $headers The HTTP headers
|
||||
* @param string $data unprocessed request data from client
|
||||
* @return mixed value of the message, decoded into a PHP type
|
||||
* @access private
|
||||
*/
|
||||
function parseRequest($headers, $data) {
|
||||
$this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
|
||||
$this->requestAttachments = array();
|
||||
if (strstr($headers['content-type'], 'multipart/related')) {
|
||||
$this->debug('Decode multipart/related');
|
||||
$input = '';
|
||||
foreach ($headers as $k => $v) {
|
||||
$input .= "$k: $v\r\n";
|
||||
}
|
||||
$params['input'] = $input . "\r\n" . $data;
|
||||
$params['include_bodies'] = true;
|
||||
$params['decode_bodies'] = true;
|
||||
$params['decode_headers'] = true;
|
||||
|
||||
$structure = Mail_mimeDecode::decode($params);
|
||||
|
||||
foreach ($structure->parts as $part) {
|
||||
if (!isset($part->disposition) && (strstr($part->headers['content-type'], 'text/xml'))) {
|
||||
$this->debug('Have root part of type ' . $part->headers['content-type']);
|
||||
$return = parent::parseRequest($part->headers, $part->body);
|
||||
} else {
|
||||
$this->debug('Have an attachment of type ' . $part->headers['content-type']);
|
||||
$info['data'] = $part->body;
|
||||
$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
|
||||
$info['contenttype'] = $part->headers['content-type'];
|
||||
$info['cid'] = $part->headers['content-id'];
|
||||
$this->requestAttachments[] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($return)) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
$this->setError('No root part found in multipart/related content');
|
||||
return;
|
||||
}
|
||||
$this->debug('Not multipart/related');
|
||||
return parent::parseRequest($headers, $data);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For backwards compatiblity
|
||||
*/
|
||||
class nusoapservermime extends nusoap_server_mime {
|
||||
}
|
||||
|
||||
?>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user