Version 3.0.5
This commit is contained in:
1 parent
19b38c7c74
commit
1d4720f3e2
3755 files changed
+508378
-664541
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,29 @@
|
||||
Software License Agreement (New BSD License)
|
||||
|
||||
Copyright (c) 2006-2008, Christoph Dorn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Christoph Dorn nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* This file is part of FirePHP (http://www.firephp.org/).
|
||||
*
|
||||
* Software License Agreement (New BSD License)
|
||||
*
|
||||
* Copyright (c) 2006-2008, Christoph Dorn
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Christoph Dorn nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*
|
||||
* @copyright Copyright (C) 2007-2008 Christoph Dorn
|
||||
* @author Christoph Dorn <christoph@christophdorn.com>
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @package FirePHP
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__).'/FirePHP.class.php';
|
||||
|
||||
/**
|
||||
* Sends the given data to the FirePHP Firefox Extension.
|
||||
* The data can be displayed in the Firebug Console or in the
|
||||
* "Server" request tab.
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $Object
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
function fb()
|
||||
{
|
||||
$instance = FirePHP::getInstance(true);
|
||||
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array($instance,'fb'),$args);
|
||||
}
|
||||
|
||||
|
||||
class FB
|
||||
{
|
||||
/**
|
||||
* Enable and disable logging to Firebug
|
||||
*
|
||||
* @see FirePHP->setEnabled()
|
||||
* @param boolean $Enabled TRUE to enable, FALSE to disable
|
||||
* @return void
|
||||
*/
|
||||
public static function setEnabled($Enabled) {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$instance->setEnabled($Enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logging is enabled
|
||||
*
|
||||
* @see FirePHP->getEnabled()
|
||||
* @return boolean TRUE if enabled
|
||||
*/
|
||||
public static function getEnabled() {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
return $instance->getEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a filter to be used when encoding an object
|
||||
*
|
||||
* Filters are used to exclude object members.
|
||||
*
|
||||
* @see FirePHP->setObjectFilter()
|
||||
* @param string $Class The class name of the object
|
||||
* @param array $Filter An array or members to exclude
|
||||
* @return void
|
||||
*/
|
||||
public static function setObjectFilter($Class, $Filter) {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$instance->setObjectFilter($Class, $Filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some options for the library
|
||||
*
|
||||
* @see FirePHP->setOptions()
|
||||
* @param array $Options The options to be set
|
||||
* @return void
|
||||
*/
|
||||
public static function setOptions($Options) {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$instance->setOptions($Options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object to firebug
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $Object
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function send()
|
||||
{
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array($instance,'fb'),$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a group for following messages
|
||||
*
|
||||
* @param string $Name
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function group($Name) {
|
||||
return self::send(null, $Name, FirePHP::GROUP_START);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a group you have started before
|
||||
*
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function groupEnd() {
|
||||
return self::send(null, null, FirePHP::GROUP_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::LOG
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function log($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::LOG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::INFO
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function info($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::WARN
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function warn($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::WARN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::ERROR
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function error($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps key and variable to firebug server panel
|
||||
*
|
||||
* @see FirePHP::DUMP
|
||||
* @param string $Key
|
||||
* @param mixed $Variable
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function dump($Key, $Variable) {
|
||||
return self::send($Variable, $Key, FirePHP::DUMP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a trace in the firebug console
|
||||
*
|
||||
* @see FirePHP::TRACE
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function trace($Label) {
|
||||
return self::send($Label, FirePHP::TRACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a table in the firebug console
|
||||
*
|
||||
* @see FirePHP::TABLE
|
||||
* @param string $Label
|
||||
* @param string $Table
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function table($Label, $Table) {
|
||||
return self::send($Table, $Label, FirePHP::TABLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,806 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
* format. It is easy for humans to read and write. It is easy for machines
|
||||
* to parse and generate. It is based on a subset of the JavaScript
|
||||
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
||||
* This feature can also be found in Python. JSON is a text format that is
|
||||
* completely language independent but uses conventions that are familiar
|
||||
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
||||
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
||||
* ideal data-interchange language.
|
||||
*
|
||||
* This package provides a simple encoder and decoder for JSON notation. It
|
||||
* is intended for use with client-side Javascript applications that make
|
||||
* use of HTTPRequest to perform server communication functions - data can
|
||||
* be encoded into JSON notation for use in a client-side javascript, or
|
||||
* decoded from incoming Javascript requests. JSON format is native to
|
||||
* Javascript, and can be directly eval()'ed with no further parsing
|
||||
* overhead
|
||||
*
|
||||
* All strings should be in ASCII or UTF-8 format!
|
||||
*
|
||||
* LICENSE: Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met: Redistributions of source code must retain the
|
||||
* above copyright notice, this list of conditions and the following
|
||||
* disclaimer. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* @category
|
||||
* @package Services_JSON
|
||||
* @author Michal Migurski <mike-json@teczno.com>
|
||||
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
||||
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
||||
* @copyright 2005 Michal Migurski
|
||||
* @version CVS: $Id: JSON.php 268 2009-05-20 13:25:22Z bfarber $
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_SLICE', 1);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_STR', 2);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_ARR', 3);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_OBJ', 4);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_CMT', 5);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* Brief example of use:
|
||||
*
|
||||
* <code>
|
||||
* // create a new instance of Services_JSON
|
||||
* $json = new Services_JSON();
|
||||
*
|
||||
* // convert a complexe value to JSON notation, and send it to the browser
|
||||
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
||||
* $output = $json->encode($value);
|
||||
*
|
||||
* print($output);
|
||||
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
||||
*
|
||||
* // accept incoming POST data, assumed to be in JSON notation
|
||||
* $input = file_get_contents('php://input', 1000000);
|
||||
* $value = $json->decode($input);
|
||||
* </code>
|
||||
*/
|
||||
class Services_JSON
|
||||
{
|
||||
/**
|
||||
* constructs a new JSON instance
|
||||
*
|
||||
* @param int $use object behavior flags; combine with boolean-OR
|
||||
*
|
||||
* possible values:
|
||||
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
||||
* "{...}" syntax creates associative arrays
|
||||
* instead of objects in decode().
|
||||
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
||||
* Values which can't be encoded (e.g. resources)
|
||||
* appear as NULL instead of throwing errors.
|
||||
* By default, a deeply-nested resource will
|
||||
* bubble up with an error, so all return values
|
||||
* from encode() should be checked with isError()
|
||||
*/
|
||||
function Services_JSON($use = 0)
|
||||
{
|
||||
$this->use = $use;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-16 char to one UTF-8 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf16 UTF-16 character
|
||||
* @return string UTF-8 character
|
||||
* @access private
|
||||
*/
|
||||
function utf162utf8($utf16)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||
}
|
||||
|
||||
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
||||
|
||||
switch(true) {
|
||||
case ((0x7F & $bytes) == $bytes):
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x7F & $bytes);
|
||||
|
||||
case (0x07FF & $bytes) == $bytes:
|
||||
// return a 2-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
|
||||
case (0xFFFF & $bytes) == $bytes:
|
||||
// return a 3-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
||||
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-8 char to one UTF-16 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf8 UTF-8 character
|
||||
* @return string UTF-16 character
|
||||
* @access private
|
||||
*/
|
||||
function utf82utf16($utf8)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
}
|
||||
|
||||
switch(strlen($utf8)) {
|
||||
case 1:
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return $utf8;
|
||||
|
||||
case 2:
|
||||
// return a UTF-16 character from a 2-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x07 & (ord($utf8{0}) >> 2))
|
||||
. chr((0xC0 & (ord($utf8{0}) << 6))
|
||||
| (0x3F & ord($utf8{1})));
|
||||
|
||||
case 3:
|
||||
// return a UTF-16 character from a 3-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr((0xF0 & (ord($utf8{0}) << 4))
|
||||
| (0x0F & (ord($utf8{1}) >> 2)))
|
||||
. chr((0xC0 & (ord($utf8{1}) << 6))
|
||||
| (0x7F & ord($utf8{2})));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function encode($var)
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case 'boolean':
|
||||
return $var ? 'true' : 'false';
|
||||
|
||||
case 'NULL':
|
||||
return 'null';
|
||||
|
||||
case 'integer':
|
||||
return (int) $var;
|
||||
|
||||
case 'double':
|
||||
case 'float':
|
||||
return (float) $var;
|
||||
|
||||
case 'string':
|
||||
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
||||
$ascii = '';
|
||||
$strlen_var = strlen($var);
|
||||
|
||||
/*
|
||||
* Iterate over every character in the string,
|
||||
* escaping with a slash or encoding to UTF-8 where necessary
|
||||
*/
|
||||
for ($c = 0; $c < $strlen_var; ++$c) {
|
||||
|
||||
$ord_var_c = ord($var{$c});
|
||||
|
||||
switch (true) {
|
||||
case $ord_var_c == 0x08:
|
||||
$ascii .= '\b';
|
||||
break;
|
||||
case $ord_var_c == 0x09:
|
||||
$ascii .= '\t';
|
||||
break;
|
||||
case $ord_var_c == 0x0A:
|
||||
$ascii .= '\n';
|
||||
break;
|
||||
case $ord_var_c == 0x0C:
|
||||
$ascii .= '\f';
|
||||
break;
|
||||
case $ord_var_c == 0x0D:
|
||||
$ascii .= '\r';
|
||||
break;
|
||||
|
||||
case $ord_var_c == 0x22:
|
||||
case $ord_var_c == 0x2F:
|
||||
case $ord_var_c == 0x5C:
|
||||
// double quote, slash, slosh
|
||||
$ascii .= '\\'.$var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
||||
// characters U-00000000 - U-0000007F (same as ASCII)
|
||||
$ascii .= $var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xE0) == 0xC0):
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
||||
$c += 1;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF0) == 0xE0):
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}));
|
||||
$c += 2;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF8) == 0xF0):
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}));
|
||||
$c += 3;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFC) == 0xF8):
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}));
|
||||
$c += 4;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFE) == 0xFC):
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}),
|
||||
ord($var{$c + 5}));
|
||||
$c += 5;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '"'.$ascii.'"';
|
||||
|
||||
case 'array':
|
||||
/*
|
||||
* As per JSON spec if any array key is not an integer
|
||||
* we must treat the the whole array as an object. We
|
||||
* also try to catch a sparsely populated associative
|
||||
* array with numeric keys here because some JS engines
|
||||
* will create an array with empty indexes up to
|
||||
* max_index which can cause memory issues and because
|
||||
* the keys, which may be relevant, will be remapped
|
||||
* otherwise.
|
||||
*
|
||||
* As per the ECMA and JSON specification an object may
|
||||
* have any string as a property. Unfortunately due to
|
||||
* a hole in the ECMA specification if the key is a
|
||||
* ECMA reserved word or starts with a digit the
|
||||
* parameter is only accessible using ECMAScript's
|
||||
* bracket notation.
|
||||
*/
|
||||
|
||||
// treat as a JSON object
|
||||
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($var),
|
||||
array_values($var));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
}
|
||||
|
||||
// treat it like a regular array
|
||||
$elements = array_map(array($this, 'encode'), $var);
|
||||
|
||||
foreach($elements as $element) {
|
||||
if(Services_JSON::isError($element)) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
return '[' . join(',', $elements) . ']';
|
||||
|
||||
case 'object':
|
||||
$vars = get_object_vars($var);
|
||||
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($vars),
|
||||
array_values($vars));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
|
||||
default:
|
||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||
? 'null'
|
||||
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* array-walking function for use in generating JSON-formatted name-value pairs
|
||||
*
|
||||
* @param string $name name of key to use
|
||||
* @param mixed $value reference to an array element to be encoded
|
||||
*
|
||||
* @return string JSON-formatted name-value pair, like '"name":value'
|
||||
* @access private
|
||||
*/
|
||||
function name_value($name, $value)
|
||||
{
|
||||
$encoded_value = $this->encode($value);
|
||||
|
||||
if(Services_JSON::isError($encoded_value)) {
|
||||
return $encoded_value;
|
||||
}
|
||||
|
||||
return $this->encode(strval($name)) . ':' . $encoded_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* reduce a string by removing leading and trailing comments and whitespace
|
||||
*
|
||||
* @param $str string string value to strip of comments and whitespace
|
||||
*
|
||||
* @return string string value stripped of comments and whitespace
|
||||
* @access private
|
||||
*/
|
||||
function reduce_string($str)
|
||||
{
|
||||
$str = preg_replace(array(
|
||||
|
||||
// eliminate single line comments in '// ...' form
|
||||
'#^\s*//(.+)$#m',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at start of string
|
||||
'#^\s*/\*(.+)\*/#Us',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at end of string
|
||||
'#/\*(.+)\*/\s*$#Us'
|
||||
|
||||
), '', $str);
|
||||
|
||||
// eliminate extraneous space
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a JSON string into appropriate variable
|
||||
*
|
||||
* @param string $str JSON-formatted string
|
||||
*
|
||||
* @return mixed number, boolean, string, array, or object
|
||||
* corresponding to given JSON input string.
|
||||
* See argument 1 to Services_JSON() above for object-output behavior.
|
||||
* Note that decode() always returns strings
|
||||
* in ASCII or UTF-8 format!
|
||||
* @access public
|
||||
*/
|
||||
function decode($str)
|
||||
{
|
||||
$str = $this->reduce_string($str);
|
||||
|
||||
switch (strtolower($str)) {
|
||||
case 'true':
|
||||
return true;
|
||||
|
||||
case 'false':
|
||||
return false;
|
||||
|
||||
case 'null':
|
||||
return null;
|
||||
|
||||
default:
|
||||
$m = array();
|
||||
|
||||
if (is_numeric($str)) {
|
||||
// Lookie-loo, it's a number
|
||||
|
||||
// This would work on its own, but I'm trying to be
|
||||
// good about returning integers where appropriate:
|
||||
// return (float)$str;
|
||||
|
||||
// Return float or int, as appropriate
|
||||
return ((float)$str == (integer)$str)
|
||||
? (integer)$str
|
||||
: (float)$str;
|
||||
|
||||
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
||||
// STRINGS RETURNED IN UTF-8 FORMAT
|
||||
$delim = substr($str, 0, 1);
|
||||
$chrs = substr($str, 1, -1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
||||
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
$ord_chrs_c = ord($chrs{$c});
|
||||
|
||||
switch (true) {
|
||||
case $substr_chrs_c_2 == '\b':
|
||||
$utf8 .= chr(0x08);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\t':
|
||||
$utf8 .= chr(0x09);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\n':
|
||||
$utf8 .= chr(0x0A);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\f':
|
||||
$utf8 .= chr(0x0C);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\r':
|
||||
$utf8 .= chr(0x0D);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case $substr_chrs_c_2 == '\\"':
|
||||
case $substr_chrs_c_2 == '\\\'':
|
||||
case $substr_chrs_c_2 == '\\\\':
|
||||
case $substr_chrs_c_2 == '\\/':
|
||||
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
||||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
||||
$utf8 .= $chrs{++$c};
|
||||
}
|
||||
break;
|
||||
|
||||
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
||||
// single, escaped unicode character
|
||||
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
||||
$utf8 .= $this->utf162utf8($utf16);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
||||
$utf8 .= $chrs{$c};
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xE0) == 0xC0:
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 2);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF0) == 0xE0:
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 3);
|
||||
$c += 2;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF8) == 0xF0:
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 4);
|
||||
$c += 3;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFC) == 0xF8:
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 5);
|
||||
$c += 4;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFE) == 0xFC:
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 6);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $utf8;
|
||||
|
||||
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
||||
// array, or object notation
|
||||
|
||||
if ($str{0} == '[') {
|
||||
$stk = array(SERVICES_JSON_IN_ARR);
|
||||
$arr = array();
|
||||
} else {
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = array();
|
||||
} else {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = new stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
||||
'where' => 0,
|
||||
'delim' => false));
|
||||
|
||||
$chrs = substr($str, 1, -1);
|
||||
$chrs = $this->reduce_string($chrs);
|
||||
|
||||
if ($chrs == '') {
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} else {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//print("\nparsing {$chrs}\n");
|
||||
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
|
||||
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
||||
// found a comma that is not inside a string, array, etc.,
|
||||
// OR we've reached the end of the character list
|
||||
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
||||
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
// we are in an array, so just push an element onto the stack
|
||||
array_push($arr, $this->decode($slice));
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
// we are in an object, so figure
|
||||
// out the property name and set an
|
||||
// element in an associative array,
|
||||
// for now
|
||||
$parts = array();
|
||||
|
||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// "name":value pair
|
||||
$key = $this->decode($parts[1]);
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// name:value pair, where name is unquoted
|
||||
$key = $parts[1];
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
||||
// found a quote, and we are not inside a string
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
|
||||
//print("Found start of string at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == $top['delim']) &&
|
||||
($top['what'] == SERVICES_JSON_IN_STR) &&
|
||||
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
||||
// found a quote, we're in a string, and it's not escaped
|
||||
// we know that it's not escaped becase there is _not_ an
|
||||
// odd number of backslashes at the end of the string so far
|
||||
array_pop($stk);
|
||||
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '[') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-bracket, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of array at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
||||
// found a right-bracket, and we're in an array
|
||||
array_pop($stk);
|
||||
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '{') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-brace, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of object at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
||||
// found a right-brace, and we're in an object
|
||||
array_pop($stk);
|
||||
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '/*') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a comment start, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
||||
$c++;
|
||||
//print("Found start of comment at {$c}\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
||||
// found a comment end, and we're in one now
|
||||
array_pop($stk);
|
||||
$c++;
|
||||
|
||||
for ($i = $top['where']; $i <= $c; ++$i)
|
||||
$chrs = substr_replace($chrs, ' ', $i, 1);
|
||||
|
||||
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this should just call PEAR::isError()
|
||||
*/
|
||||
function isError($data, $code = null)
|
||||
{
|
||||
if (class_exists('pear')) {
|
||||
return PEAR::isError($data, $code);
|
||||
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||
is_subclass_of($data, 'services_json_error'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists('PEAR_Error')) {
|
||||
|
||||
class Services_JSON_Error extends PEAR_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||
*/
|
||||
class Services_JSON_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1 @@
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -1,14 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Text_Diff
|
||||
*
|
||||
* General API for generating and formatting diffs - the differences between
|
||||
* two sequences of strings.
|
||||
*
|
||||
* The PHP diff code used in this package was originally written by Geoffrey
|
||||
* T. Dairiki and is used with his permission.
|
||||
* The original PHP version of this code was written by Geoffrey T. Dairiki
|
||||
* <dairiki@dairiki.org>, and is used/adapted with his permission.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff.php,v 1.10 2004/11/01 11:51:15 mdjukic Exp $
|
||||
* $Horde: framework/Text_Diff/Diff.php,v 1.11.2.11 2008/02/24 10:57:46 jan Exp $
|
||||
*
|
||||
* Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
@@ -18,29 +22,38 @@ class Text_Diff {
|
||||
/**
|
||||
* Array of changes.
|
||||
*
|
||||
* @var array $_edits
|
||||
* @var array
|
||||
*/
|
||||
var $_edits;
|
||||
|
||||
/**
|
||||
* Computes diffs between sequences of strings.
|
||||
*
|
||||
* @param array $from_lines An array of strings. Typically these are
|
||||
* lines from a file.
|
||||
* @param array $to_lines An array of strings.
|
||||
* @param string $engine Name of the diffing engine to use. 'auto'
|
||||
* will automatically select the best.
|
||||
* @param array $params Parameters to pass to the diffing engine.
|
||||
* Normally an array of two arrays, each
|
||||
* containing the lines from a file.
|
||||
*/
|
||||
function Text_Diff($from_lines, $to_lines)
|
||||
function Text_Diff($engine, $params)
|
||||
{
|
||||
array_walk($from_lines, array($this, '_trimNewlines'));
|
||||
array_walk($to_lines, array($this, '_trimNewlines'));
|
||||
|
||||
if (extension_loaded('xdiff')) {
|
||||
$engine = &new Text_Diff_Engine_xdiff();
|
||||
} else {
|
||||
$engine = &new Text_Diff_Engine_native();
|
||||
// Backward compatibility workaround.
|
||||
if (!is_string($engine)) {
|
||||
$params = array($engine, $params);
|
||||
$engine = 'auto';
|
||||
}
|
||||
|
||||
$this->_edits = $engine->diff($from_lines, $to_lines);
|
||||
if ($engine == 'auto') {
|
||||
$engine = extension_loaded('xdiff') ? 'xdiff' : 'native';
|
||||
} else {
|
||||
$engine = basename($engine);
|
||||
}
|
||||
|
||||
require_once 'Text/Diff/Engine/' . $engine . '.php';
|
||||
$class = 'Text_Diff_Engine_' . $engine;
|
||||
$diff_engine = new $class();
|
||||
|
||||
$this->_edits = call_user_func_array(array($diff_engine, 'diff'), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,13 +63,53 @@ class Text_Diff {
|
||||
{
|
||||
return $this->_edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of new (added) lines in a given diff.
|
||||
*
|
||||
* @since Text_Diff 1.1.0
|
||||
* @since Horde 3.2
|
||||
*
|
||||
* @return integer The number of new lines
|
||||
*/
|
||||
function countAddedLines()
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($this->_edits as $edit) {
|
||||
if (is_a($edit, 'Text_Diff_Op_add') ||
|
||||
is_a($edit, 'Text_Diff_Op_change')) {
|
||||
$count += $edit->nfinal();
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of deleted (removed) lines in a given diff.
|
||||
*
|
||||
* @since Text_Diff 1.1.0
|
||||
* @since Horde 3.2
|
||||
*
|
||||
* @return integer The number of deleted lines
|
||||
*/
|
||||
function countDeletedLines()
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($this->_edits as $edit) {
|
||||
if (is_a($edit, 'Text_Diff_Op_delete') ||
|
||||
is_a($edit, 'Text_Diff_Op_change')) {
|
||||
$count += $edit->norig();
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a reversed diff.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $diff = &new Text_Diff($lines1, $lines2);
|
||||
* $diff = new Text_Diff($lines1, $lines2);
|
||||
* $rev = $diff->reverse();
|
||||
* </code>
|
||||
*
|
||||
@@ -68,7 +121,7 @@ class Text_Diff {
|
||||
function reverse()
|
||||
{
|
||||
if (version_compare(zend_version(), '2', '>')) {
|
||||
$rev = clone($obj);
|
||||
$rev = clone($this);
|
||||
} else {
|
||||
$rev = $this;
|
||||
}
|
||||
@@ -97,9 +150,9 @@ class Text_Diff {
|
||||
/**
|
||||
* Computes the length of the Longest Common Subsequence (LCS).
|
||||
*
|
||||
* This is mostly for diagnostic purposed.
|
||||
* This is mostly for diagnostic purposes.
|
||||
*
|
||||
* @return int The length of the LCS.
|
||||
* @return integer The length of the LCS.
|
||||
*/
|
||||
function lcs()
|
||||
{
|
||||
@@ -155,11 +208,48 @@ class Text_Diff {
|
||||
* @param string $line The line to trim.
|
||||
* @param integer $key The index of the line in the array. Not used.
|
||||
*/
|
||||
function _trimNewlines(&$line, $key)
|
||||
function trimNewlines(&$line, $key)
|
||||
{
|
||||
$line = str_replace(array("\n", "\r"), '', $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the location of the system temporary directory.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return string A directory name which can be used for temp files.
|
||||
* Returns false if one could not be found.
|
||||
*/
|
||||
function _getTempDir()
|
||||
{
|
||||
$tmp_locations = array('/tmp', '/var/tmp', 'c:\WUTemp', 'c:\temp',
|
||||
'c:\windows\temp', 'c:\winnt\temp');
|
||||
|
||||
/* Try PHP's upload_tmp_dir directive. */
|
||||
$tmp = ini_get('upload_tmp_dir');
|
||||
|
||||
/* Otherwise, try to determine the TMPDIR environment variable. */
|
||||
if (!strlen($tmp)) {
|
||||
$tmp = getenv('TMPDIR');
|
||||
}
|
||||
|
||||
/* If we still cannot determine a value, then cycle through a list of
|
||||
* preset possibilities. */
|
||||
while (!strlen($tmp) && count($tmp_locations)) {
|
||||
$tmp_check = array_shift($tmp_locations);
|
||||
if (@is_dir($tmp_check)) {
|
||||
$tmp = $tmp_check;
|
||||
}
|
||||
}
|
||||
|
||||
/* If it is still empty, we have failed, so return false; otherwise
|
||||
* return the directory determined. */
|
||||
return strlen($tmp) ? $tmp : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a diff for validity.
|
||||
*
|
||||
@@ -196,8 +286,6 @@ class Text_Diff {
|
||||
}
|
||||
|
||||
/**
|
||||
* $Horde: framework/Text_Diff/Diff.php,v 1.10 2004/11/01 11:51:15 mdjukic Exp $
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
@@ -222,8 +310,8 @@ class Text_MappedDiff extends Text_Diff {
|
||||
function Text_MappedDiff($from_lines, $to_lines,
|
||||
$mapped_from_lines, $mapped_to_lines)
|
||||
{
|
||||
@assert(count($from_lines) == count($mapped_from_lines));
|
||||
@assert(count($to_lines) == count($mapped_to_lines));
|
||||
assert(count($from_lines) == count($mapped_from_lines));
|
||||
assert(count($to_lines) == count($mapped_to_lines));
|
||||
|
||||
parent::Text_Diff($mapped_from_lines, $mapped_to_lines);
|
||||
|
||||
@@ -245,497 +333,18 @@ class Text_MappedDiff extends Text_Diff {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs. This class
|
||||
* uses the xdiff PECL package (http://pecl.php.net/package/xdiff) to compute
|
||||
* the differences between the two input arrays.
|
||||
*
|
||||
* @author Jon Parise <jon@horde.org>
|
||||
* @package Text_Diff
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Engine_xdiff {
|
||||
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
/* Convert the two input arrays into strings for xdiff processing. */
|
||||
$from_string = implode("\n", $from_lines);
|
||||
$to_string = implode("\n", $to_lines);
|
||||
|
||||
/* Diff the two strings and convert the result to an array. */
|
||||
$diff = xdiff_string_diff($from_string, $to_string, count($to_lines));
|
||||
$diff = explode("\n", $diff);
|
||||
|
||||
/* Walk through the diff one line at a time. We build the $edits
|
||||
* array of diff operations by reading the first character of the
|
||||
* xdiff output (which is in the "unified diff" format).
|
||||
*
|
||||
* Note that we don't have enough information to detect "changed"
|
||||
* lines using this approach, so we can't add Text_Diff_Op_changed
|
||||
* instances to the $edits array. The result is still perfectly
|
||||
* valid, albeit a little less descriptive and efficient. */
|
||||
$edits = array();
|
||||
foreach ($diff as $line) {
|
||||
switch ($line[0]) {
|
||||
case ' ':
|
||||
$edits[] = &new Text_Diff_Op_copy(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '+':
|
||||
$edits[] = &new Text_Diff_Op_add(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '-':
|
||||
$edits[] = &new Text_Diff_Op_delete(array(substr($line, 1)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs. This class is
|
||||
* implemented using native PHP code.
|
||||
*
|
||||
* The algorithm used here is mostly lifted from the perl module
|
||||
* Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
|
||||
* http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
|
||||
*
|
||||
* More ideas are taken from:
|
||||
* http://www.ics.uci.edu/~eppstein/161/960229.html
|
||||
*
|
||||
* Some ideas (and a bit of code) are from from analyze.c, from GNU
|
||||
* diffutils-2.7, which can be found at:
|
||||
* ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
|
||||
*
|
||||
* Some ideas (subdivision by NCHUNKS > 2, and some optimizations) are from
|
||||
* Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this
|
||||
* code was written by him, and is used/adapted with his permission.
|
||||
*
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @package Text_Diff
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Engine_native {
|
||||
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
$n_from = count($from_lines);
|
||||
$n_to = count($to_lines);
|
||||
|
||||
$this->xchanged = $this->ychanged = array();
|
||||
$this->xv = $this->yv = array();
|
||||
$this->xind = $this->yind = array();
|
||||
unset($this->seq);
|
||||
unset($this->in_seq);
|
||||
unset($this->lcs);
|
||||
|
||||
// Skip leading common lines.
|
||||
for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
|
||||
if ($from_lines[$skip] != $to_lines[$skip]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$skip] = $this->ychanged[$skip] = false;
|
||||
}
|
||||
|
||||
// Skip trailing common lines.
|
||||
$xi = $n_from; $yi = $n_to;
|
||||
for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
|
||||
if ($from_lines[$xi] != $to_lines[$yi]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$xi] = $this->ychanged[$yi] = false;
|
||||
}
|
||||
|
||||
// Ignore lines which do not exist in both files.
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$xhash[$from_lines[$xi]] = 1;
|
||||
}
|
||||
for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
|
||||
$line = $to_lines[$yi];
|
||||
if (($this->ychanged[$yi] = empty($xhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$yhash[$line] = 1;
|
||||
$this->yv[] = $line;
|
||||
$this->yind[] = $yi;
|
||||
}
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$line = $from_lines[$xi];
|
||||
if (($this->xchanged[$xi] = empty($yhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$this->xv[] = $line;
|
||||
$this->xind[] = $xi;
|
||||
}
|
||||
|
||||
// Find the LCS.
|
||||
$this->_compareseq(0, count($this->xv), 0, count($this->yv));
|
||||
|
||||
// Merge edits when possible.
|
||||
$this->_shiftBoundaries($from_lines, $this->xchanged, $this->ychanged);
|
||||
$this->_shiftBoundaries($to_lines, $this->ychanged, $this->xchanged);
|
||||
|
||||
// Compute the edit operations.
|
||||
$edits = array();
|
||||
$xi = $yi = 0;
|
||||
while ($xi < $n_from || $yi < $n_to) {
|
||||
@assert($yi < $n_to || $this->xchanged[$xi]);
|
||||
@assert($xi < $n_from || $this->ychanged[$yi]);
|
||||
|
||||
// Skip matching "snake".
|
||||
$copy = array();
|
||||
while ($xi < $n_from && $yi < $n_to
|
||||
&& !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
|
||||
$copy[] = $from_lines[$xi++];
|
||||
++$yi;
|
||||
}
|
||||
if ($copy) {
|
||||
$edits[] = &new Text_Diff_Op_copy($copy);
|
||||
}
|
||||
|
||||
// Find deletes & adds.
|
||||
$delete = array();
|
||||
while ($xi < $n_from && $this->xchanged[$xi]) {
|
||||
$delete[] = $from_lines[$xi++];
|
||||
}
|
||||
|
||||
$add = array();
|
||||
while ($yi < $n_to && $this->ychanged[$yi]) {
|
||||
$add[] = $to_lines[$yi++];
|
||||
}
|
||||
|
||||
if ($delete && $add) {
|
||||
$edits[] = &new Text_Diff_Op_change($delete, $add);
|
||||
} elseif ($delete) {
|
||||
$edits[] = &new Text_Diff_Op_delete($delete);
|
||||
} elseif ($add) {
|
||||
$edits[] = &new Text_Diff_Op_add($add);
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the Largest Common Subsequence (LCS) of the sequences (XOFF,
|
||||
* XLIM) and (YOFF, YLIM) into NCHUNKS approximately equally sized
|
||||
* segments.
|
||||
*
|
||||
* Returns (LCS, PTS). LCS is the length of the LCS. PTS is an array of
|
||||
* NCHUNKS+1 (X, Y) indexes giving the diving points between sub
|
||||
* sequences. The first sub-sequence is contained in (X0, X1), (Y0, Y1),
|
||||
* the second in (X1, X2), (Y1, Y2) and so on. Note that (X0, Y0) ==
|
||||
* (XOFF, YOFF) and (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
|
||||
*
|
||||
* This function assumes that the first lines of the specified portions of
|
||||
* the two files do not match, and likewise that the last lines do not
|
||||
* match. The caller must trim matching lines from the beginning and end
|
||||
* of the portions it is going to specify.
|
||||
*/
|
||||
function _diag ($xoff, $xlim, $yoff, $ylim, $nchunks)
|
||||
{
|
||||
$flip = false;
|
||||
|
||||
if ($xlim - $xoff > $ylim - $yoff) {
|
||||
/* Things seems faster (I'm not sure I understand why) when the
|
||||
* shortest sequence is in X. */
|
||||
$flip = true;
|
||||
list ($xoff, $xlim, $yoff, $ylim)
|
||||
= array($yoff, $ylim, $xoff, $xlim);
|
||||
}
|
||||
|
||||
if ($flip) {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->xv[$i]][] = $i;
|
||||
}
|
||||
} else {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->yv[$i]][] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
$this->lcs = 0;
|
||||
$this->seq[0]= $yoff - 1;
|
||||
$this->in_seq = array();
|
||||
$ymids[0] = array();
|
||||
|
||||
$numer = $xlim - $xoff + $nchunks - 1;
|
||||
$x = $xoff;
|
||||
for ($chunk = 0; $chunk < $nchunks; $chunk++) {
|
||||
if ($chunk > 0) {
|
||||
for ($i = 0; $i <= $this->lcs; $i++) {
|
||||
$ymids[$i][$chunk - 1] = $this->seq[$i];
|
||||
}
|
||||
}
|
||||
|
||||
$x1 = $xoff + (int)(($numer + ($xlim-$xoff)*$chunk) / $nchunks);
|
||||
for (; $x < $x1; $x++) {
|
||||
$line = $flip ? $this->yv[$x] : $this->xv[$x];
|
||||
if (empty($ymatches[$line])) {
|
||||
continue;
|
||||
}
|
||||
$matches = $ymatches[$line];
|
||||
foreach ($matches as $y) {
|
||||
if (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
@assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (list($junk, $y) = each($matches)) {
|
||||
if ($y > $this->seq[$k - 1]) {
|
||||
@assert($y < $this->seq[$k]);
|
||||
/* Optimization: this is a common case: next match is
|
||||
* just replacing previous match. */
|
||||
$this->in_seq[$this->seq[$k]] = false;
|
||||
$this->seq[$k] = $y;
|
||||
$this->in_seq[$y] = 1;
|
||||
} elseif (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
@assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
|
||||
$ymid = $ymids[$this->lcs];
|
||||
for ($n = 0; $n < $nchunks - 1; $n++) {
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
|
||||
$y1 = $ymid[$n] + 1;
|
||||
$seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
|
||||
}
|
||||
$seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
|
||||
|
||||
return array($this->lcs, $seps);
|
||||
}
|
||||
|
||||
function _lcsPos($ypos)
|
||||
{
|
||||
$end = $this->lcs;
|
||||
if ($end == 0 || $ypos > $this->seq[$end]) {
|
||||
$this->seq[++$this->lcs] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $this->lcs;
|
||||
}
|
||||
|
||||
$beg = 1;
|
||||
while ($beg < $end) {
|
||||
$mid = (int)(($beg + $end) / 2);
|
||||
if ($ypos > $this->seq[$mid]) {
|
||||
$beg = $mid + 1;
|
||||
} else {
|
||||
$end = $mid;
|
||||
}
|
||||
}
|
||||
|
||||
@assert($ypos != $this->seq[$end]);
|
||||
|
||||
$this->in_seq[$this->seq[$end]] = false;
|
||||
$this->seq[$end] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds LCS of two sequences.
|
||||
*
|
||||
* The results are recorded in the vectors $this->{x,y}changed[], by
|
||||
* storing a 1 in the element for each line that is an insertion or
|
||||
* deletion (ie. is not in the LCS).
|
||||
*
|
||||
* The subsequence of file 0 is (XOFF, XLIM) and likewise for file 1.
|
||||
*
|
||||
* Note that XLIM, YLIM are exclusive bounds. All line numbers are
|
||||
* origin-0 and discarded lines are not counted.
|
||||
*/
|
||||
function _compareseq ($xoff, $xlim, $yoff, $ylim)
|
||||
{
|
||||
/* Slide down the bottom initial diagonal. */
|
||||
while ($xoff < $xlim && $yoff < $ylim
|
||||
&& $this->xv[$xoff] == $this->yv[$yoff]) {
|
||||
++$xoff;
|
||||
++$yoff;
|
||||
}
|
||||
|
||||
/* Slide up the top initial diagonal. */
|
||||
while ($xlim > $xoff && $ylim > $yoff
|
||||
&& $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
|
||||
--$xlim;
|
||||
--$ylim;
|
||||
}
|
||||
|
||||
if ($xoff == $xlim || $yoff == $ylim) {
|
||||
$lcs = 0;
|
||||
} else {
|
||||
/* This is ad hoc but seems to work well. $nchunks =
|
||||
* sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5); $nchunks =
|
||||
* max(2,min(8,(int)$nchunks)); */
|
||||
$nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
|
||||
list($lcs, $seps)
|
||||
= $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
|
||||
}
|
||||
|
||||
if ($lcs == 0) {
|
||||
/* X and Y sequences have no common subsequence: mark all
|
||||
* changed. */
|
||||
while ($yoff < $ylim) {
|
||||
$this->ychanged[$this->yind[$yoff++]] = 1;
|
||||
}
|
||||
while ($xoff < $xlim) {
|
||||
$this->xchanged[$this->xind[$xoff++]] = 1;
|
||||
}
|
||||
} else {
|
||||
/* Use the partitions to split this problem into subproblems. */
|
||||
reset($seps);
|
||||
$pt1 = $seps[0];
|
||||
while ($pt2 = next($seps)) {
|
||||
$this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
|
||||
$pt1 = $pt2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts inserts/deletes of identical lines to join changes as much as
|
||||
* possible.
|
||||
*
|
||||
* We do something when a run of changed lines include a line at one end
|
||||
* and has an excluded, identical line at the other. We are free to
|
||||
* choose which identical line is included. `compareseq' usually chooses
|
||||
* the one at the beginning, but usually it is cleaner to consider the
|
||||
* following identical line to be the "change".
|
||||
*
|
||||
* This is extracted verbatim from analyze.c (GNU diffutils-2.7).
|
||||
*/
|
||||
function _shiftBoundaries($lines, &$changed, $other_changed)
|
||||
{
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
|
||||
@assert('count($lines) == count($changed)');
|
||||
$len = count($lines);
|
||||
$other_len = count($other_changed);
|
||||
|
||||
while (1) {
|
||||
/* Scan forward to find the beginning of another run of
|
||||
* changes. Also keep track of the corresponding point in the
|
||||
* other file.
|
||||
*
|
||||
* Throughout this code, $i and $j are adjusted together so that
|
||||
* the first $i elements of $changed and the first $j elements of
|
||||
* $other_changed both contain the same number of zeros (unchanged
|
||||
* lines).
|
||||
*
|
||||
* Furthermore, $j is always kept so that $j == $other_len or
|
||||
* $other_changed[$j] == false. */
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $len && ! $changed[$i]) {
|
||||
@assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$i++; $j++;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($i == $len) {
|
||||
break;
|
||||
}
|
||||
|
||||
$start = $i;
|
||||
|
||||
/* Find the end of this run of changes. */
|
||||
while (++$i < $len && $changed[$i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Record the length of this run of changes, so that we can
|
||||
* later determine whether the run has grown. */
|
||||
$runlength = $i - $start;
|
||||
|
||||
/* Move the changed region back, so long as the previous
|
||||
* unchanged line matches the last changed one. This merges
|
||||
* with previous changed regions. */
|
||||
while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = false;
|
||||
while ($start > 0 && $changed[$start - 1]) {
|
||||
$start--;
|
||||
}
|
||||
@assert('$j > 0');
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
@assert('$j >= 0 && !$other_changed[$j]');
|
||||
}
|
||||
|
||||
/* Set CORRESPONDING to the end of the changed run, at the
|
||||
* last point where it corresponds to a changed run in the
|
||||
* other file. CORRESPONDING == LEN means no such point has
|
||||
* been found. */
|
||||
$corresponding = $j < $other_len ? $i : $len;
|
||||
|
||||
/* Move the changed region forward, so long as the first
|
||||
* changed line matches the following unchanged one. This
|
||||
* merges with following changed regions. Do this second, so
|
||||
* that if there are no merges, the changed region is moved
|
||||
* forward as far as possible. */
|
||||
while ($i < $len && $lines[$start] == $lines[$i]) {
|
||||
$changed[$start++] = false;
|
||||
$changed[$i++] = 1;
|
||||
while ($i < $len && $changed[$i]) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
@assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$j++;
|
||||
if ($j < $other_len && $other_changed[$j]) {
|
||||
$corresponding = $i;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ($runlength != $i - $start);
|
||||
|
||||
/* If possible, move the fully-merged run of changes back to a
|
||||
* corresponding run in the other file. */
|
||||
while ($corresponding < $i) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = 0;
|
||||
@assert('$j > 0');
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
@assert('$j >= 0 && !$other_changed[$j]');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op {
|
||||
|
||||
var $orig;
|
||||
var $final;
|
||||
|
||||
function reverse()
|
||||
function &reverse()
|
||||
{
|
||||
trigger_error('Abstract method', E_USER_ERROR);
|
||||
}
|
||||
@@ -755,7 +364,8 @@ class Text_Diff_Op {
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_copy extends Text_Diff_Op {
|
||||
|
||||
@@ -770,7 +380,8 @@ class Text_Diff_Op_copy extends Text_Diff_Op {
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
return $reverse = &new Text_Diff_Op_copy($this->final, $this->orig);
|
||||
$reverse = new Text_Diff_Op_copy($this->final, $this->orig);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -778,7 +389,8 @@ class Text_Diff_Op_copy extends Text_Diff_Op {
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_delete extends Text_Diff_Op {
|
||||
|
||||
@@ -790,7 +402,8 @@ class Text_Diff_Op_delete extends Text_Diff_Op {
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
return $reverse = &new Text_Diff_Op_add($this->orig);
|
||||
$reverse = new Text_Diff_Op_add($this->orig);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -798,7 +411,8 @@ class Text_Diff_Op_delete extends Text_Diff_Op {
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_add extends Text_Diff_Op {
|
||||
|
||||
@@ -810,7 +424,8 @@ class Text_Diff_Op_add extends Text_Diff_Op {
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
return $reverse = &new Text_Diff_Op_delete($this->final);
|
||||
$reverse = new Text_Diff_Op_delete($this->final);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -818,7 +433,8 @@ class Text_Diff_Op_add extends Text_Diff_Op {
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_change extends Text_Diff_Op {
|
||||
|
||||
@@ -830,7 +446,8 @@ class Text_Diff_Op_change extends Text_Diff_Op {
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
return $reverse = &new Text_Diff_Op_change($this->final, $this->orig);
|
||||
$reverse = new Text_Diff_Op_change($this->final, $this->orig);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Text_Diff to actually compute the diffs.
|
||||
*
|
||||
* This class is implemented using native PHP code.
|
||||
*
|
||||
* The algorithm used here is mostly lifted from the perl module
|
||||
* Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
|
||||
* http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
|
||||
*
|
||||
* More ideas are taken from: http://www.ics.uci.edu/~eppstein/161/960229.html
|
||||
*
|
||||
* Some ideas (and a bit of code) are taken from analyze.c, of GNU
|
||||
* diffutils-2.7, which can be found at:
|
||||
* ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
|
||||
*
|
||||
* Some ideas (subdivision by NCHUNKS > 2, and some optimizations) are from
|
||||
* Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this
|
||||
* code was written by him, and is used/adapted with his permission.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Engine/native.php,v 1.7.2.4 2008/01/04 10:38:10 jan Exp $
|
||||
*
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Engine_native {
|
||||
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Text_Diff', 'trimNewlines'));
|
||||
|
||||
$n_from = count($from_lines);
|
||||
$n_to = count($to_lines);
|
||||
|
||||
$this->xchanged = $this->ychanged = array();
|
||||
$this->xv = $this->yv = array();
|
||||
$this->xind = $this->yind = array();
|
||||
unset($this->seq);
|
||||
unset($this->in_seq);
|
||||
unset($this->lcs);
|
||||
|
||||
// Skip leading common lines.
|
||||
for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
|
||||
if ($from_lines[$skip] !== $to_lines[$skip]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$skip] = $this->ychanged[$skip] = false;
|
||||
}
|
||||
|
||||
// Skip trailing common lines.
|
||||
$xi = $n_from; $yi = $n_to;
|
||||
for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
|
||||
if ($from_lines[$xi] !== $to_lines[$yi]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$xi] = $this->ychanged[$yi] = false;
|
||||
}
|
||||
|
||||
// Ignore lines which do not exist in both files.
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$xhash[$from_lines[$xi]] = 1;
|
||||
}
|
||||
for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
|
||||
$line = $to_lines[$yi];
|
||||
if (($this->ychanged[$yi] = empty($xhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$yhash[$line] = 1;
|
||||
$this->yv[] = $line;
|
||||
$this->yind[] = $yi;
|
||||
}
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$line = $from_lines[$xi];
|
||||
if (($this->xchanged[$xi] = empty($yhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$this->xv[] = $line;
|
||||
$this->xind[] = $xi;
|
||||
}
|
||||
|
||||
// Find the LCS.
|
||||
$this->_compareseq(0, count($this->xv), 0, count($this->yv));
|
||||
|
||||
// Merge edits when possible.
|
||||
$this->_shiftBoundaries($from_lines, $this->xchanged, $this->ychanged);
|
||||
$this->_shiftBoundaries($to_lines, $this->ychanged, $this->xchanged);
|
||||
|
||||
// Compute the edit operations.
|
||||
$edits = array();
|
||||
$xi = $yi = 0;
|
||||
while ($xi < $n_from || $yi < $n_to) {
|
||||
assert($yi < $n_to || $this->xchanged[$xi]);
|
||||
assert($xi < $n_from || $this->ychanged[$yi]);
|
||||
|
||||
// Skip matching "snake".
|
||||
$copy = array();
|
||||
while ($xi < $n_from && $yi < $n_to
|
||||
&& !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
|
||||
$copy[] = $from_lines[$xi++];
|
||||
++$yi;
|
||||
}
|
||||
if ($copy) {
|
||||
$edits[] = new Text_Diff_Op_copy($copy);
|
||||
}
|
||||
|
||||
// Find deletes & adds.
|
||||
$delete = array();
|
||||
while ($xi < $n_from && $this->xchanged[$xi]) {
|
||||
$delete[] = $from_lines[$xi++];
|
||||
}
|
||||
|
||||
$add = array();
|
||||
while ($yi < $n_to && $this->ychanged[$yi]) {
|
||||
$add[] = $to_lines[$yi++];
|
||||
}
|
||||
|
||||
if ($delete && $add) {
|
||||
$edits[] = new Text_Diff_Op_change($delete, $add);
|
||||
} elseif ($delete) {
|
||||
$edits[] = new Text_Diff_Op_delete($delete);
|
||||
} elseif ($add) {
|
||||
$edits[] = new Text_Diff_Op_add($add);
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the Largest Common Subsequence (LCS) of the sequences (XOFF,
|
||||
* XLIM) and (YOFF, YLIM) into NCHUNKS approximately equally sized
|
||||
* segments.
|
||||
*
|
||||
* Returns (LCS, PTS). LCS is the length of the LCS. PTS is an array of
|
||||
* NCHUNKS+1 (X, Y) indexes giving the diving points between sub
|
||||
* sequences. The first sub-sequence is contained in (X0, X1), (Y0, Y1),
|
||||
* the second in (X1, X2), (Y1, Y2) and so on. Note that (X0, Y0) ==
|
||||
* (XOFF, YOFF) and (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
|
||||
*
|
||||
* This function assumes that the first lines of the specified portions of
|
||||
* the two files do not match, and likewise that the last lines do not
|
||||
* match. The caller must trim matching lines from the beginning and end
|
||||
* of the portions it is going to specify.
|
||||
*/
|
||||
function _diag ($xoff, $xlim, $yoff, $ylim, $nchunks)
|
||||
{
|
||||
$flip = false;
|
||||
|
||||
if ($xlim - $xoff > $ylim - $yoff) {
|
||||
/* Things seems faster (I'm not sure I understand why) when the
|
||||
* shortest sequence is in X. */
|
||||
$flip = true;
|
||||
list ($xoff, $xlim, $yoff, $ylim)
|
||||
= array($yoff, $ylim, $xoff, $xlim);
|
||||
}
|
||||
|
||||
if ($flip) {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->xv[$i]][] = $i;
|
||||
}
|
||||
} else {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->yv[$i]][] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
$this->lcs = 0;
|
||||
$this->seq[0]= $yoff - 1;
|
||||
$this->in_seq = array();
|
||||
$ymids[0] = array();
|
||||
|
||||
$numer = $xlim - $xoff + $nchunks - 1;
|
||||
$x = $xoff;
|
||||
for ($chunk = 0; $chunk < $nchunks; $chunk++) {
|
||||
if ($chunk > 0) {
|
||||
for ($i = 0; $i <= $this->lcs; $i++) {
|
||||
$ymids[$i][$chunk - 1] = $this->seq[$i];
|
||||
}
|
||||
}
|
||||
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $chunk) / $nchunks);
|
||||
for (; $x < $x1; $x++) {
|
||||
$line = $flip ? $this->yv[$x] : $this->xv[$x];
|
||||
if (empty($ymatches[$line])) {
|
||||
continue;
|
||||
}
|
||||
$matches = $ymatches[$line];
|
||||
reset($matches);
|
||||
while (list(, $y) = each($matches)) {
|
||||
if (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (list(, $y) = each($matches)) {
|
||||
if ($y > $this->seq[$k - 1]) {
|
||||
assert($y <= $this->seq[$k]);
|
||||
/* Optimization: this is a common case: next match is
|
||||
* just replacing previous match. */
|
||||
$this->in_seq[$this->seq[$k]] = false;
|
||||
$this->seq[$k] = $y;
|
||||
$this->in_seq[$y] = 1;
|
||||
} elseif (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
|
||||
$ymid = $ymids[$this->lcs];
|
||||
for ($n = 0; $n < $nchunks - 1; $n++) {
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
|
||||
$y1 = $ymid[$n] + 1;
|
||||
$seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
|
||||
}
|
||||
$seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
|
||||
|
||||
return array($this->lcs, $seps);
|
||||
}
|
||||
|
||||
function _lcsPos($ypos)
|
||||
{
|
||||
$end = $this->lcs;
|
||||
if ($end == 0 || $ypos > $this->seq[$end]) {
|
||||
$this->seq[++$this->lcs] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $this->lcs;
|
||||
}
|
||||
|
||||
$beg = 1;
|
||||
while ($beg < $end) {
|
||||
$mid = (int)(($beg + $end) / 2);
|
||||
if ($ypos > $this->seq[$mid]) {
|
||||
$beg = $mid + 1;
|
||||
} else {
|
||||
$end = $mid;
|
||||
}
|
||||
}
|
||||
|
||||
assert($ypos != $this->seq[$end]);
|
||||
|
||||
$this->in_seq[$this->seq[$end]] = false;
|
||||
$this->seq[$end] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds LCS of two sequences.
|
||||
*
|
||||
* The results are recorded in the vectors $this->{x,y}changed[], by
|
||||
* storing a 1 in the element for each line that is an insertion or
|
||||
* deletion (ie. is not in the LCS).
|
||||
*
|
||||
* The subsequence of file 0 is (XOFF, XLIM) and likewise for file 1.
|
||||
*
|
||||
* Note that XLIM, YLIM are exclusive bounds. All line numbers are
|
||||
* origin-0 and discarded lines are not counted.
|
||||
*/
|
||||
function _compareseq ($xoff, $xlim, $yoff, $ylim)
|
||||
{
|
||||
/* Slide down the bottom initial diagonal. */
|
||||
while ($xoff < $xlim && $yoff < $ylim
|
||||
&& $this->xv[$xoff] == $this->yv[$yoff]) {
|
||||
++$xoff;
|
||||
++$yoff;
|
||||
}
|
||||
|
||||
/* Slide up the top initial diagonal. */
|
||||
while ($xlim > $xoff && $ylim > $yoff
|
||||
&& $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
|
||||
--$xlim;
|
||||
--$ylim;
|
||||
}
|
||||
|
||||
if ($xoff == $xlim || $yoff == $ylim) {
|
||||
$lcs = 0;
|
||||
} else {
|
||||
/* This is ad hoc but seems to work well. $nchunks =
|
||||
* sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5); $nchunks =
|
||||
* max(2,min(8,(int)$nchunks)); */
|
||||
$nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
|
||||
list($lcs, $seps)
|
||||
= $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
|
||||
}
|
||||
|
||||
if ($lcs == 0) {
|
||||
/* X and Y sequences have no common subsequence: mark all
|
||||
* changed. */
|
||||
while ($yoff < $ylim) {
|
||||
$this->ychanged[$this->yind[$yoff++]] = 1;
|
||||
}
|
||||
while ($xoff < $xlim) {
|
||||
$this->xchanged[$this->xind[$xoff++]] = 1;
|
||||
}
|
||||
} else {
|
||||
/* Use the partitions to split this problem into subproblems. */
|
||||
reset($seps);
|
||||
$pt1 = $seps[0];
|
||||
while ($pt2 = next($seps)) {
|
||||
$this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
|
||||
$pt1 = $pt2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts inserts/deletes of identical lines to join changes as much as
|
||||
* possible.
|
||||
*
|
||||
* We do something when a run of changed lines include a line at one end
|
||||
* and has an excluded, identical line at the other. We are free to
|
||||
* choose which identical line is included. `compareseq' usually chooses
|
||||
* the one at the beginning, but usually it is cleaner to consider the
|
||||
* following identical line to be the "change".
|
||||
*
|
||||
* This is extracted verbatim from analyze.c (GNU diffutils-2.7).
|
||||
*/
|
||||
function _shiftBoundaries($lines, &$changed, $other_changed)
|
||||
{
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
|
||||
assert('count($lines) == count($changed)');
|
||||
$len = count($lines);
|
||||
$other_len = count($other_changed);
|
||||
|
||||
while (1) {
|
||||
/* Scan forward to find the beginning of another run of
|
||||
* changes. Also keep track of the corresponding point in the
|
||||
* other file.
|
||||
*
|
||||
* Throughout this code, $i and $j are adjusted together so that
|
||||
* the first $i elements of $changed and the first $j elements of
|
||||
* $other_changed both contain the same number of zeros (unchanged
|
||||
* lines).
|
||||
*
|
||||
* Furthermore, $j is always kept so that $j == $other_len or
|
||||
* $other_changed[$j] == false. */
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $len && ! $changed[$i]) {
|
||||
assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$i++; $j++;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($i == $len) {
|
||||
break;
|
||||
}
|
||||
|
||||
$start = $i;
|
||||
|
||||
/* Find the end of this run of changes. */
|
||||
while (++$i < $len && $changed[$i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Record the length of this run of changes, so that we can
|
||||
* later determine whether the run has grown. */
|
||||
$runlength = $i - $start;
|
||||
|
||||
/* Move the changed region back, so long as the previous
|
||||
* unchanged line matches the last changed one. This merges
|
||||
* with previous changed regions. */
|
||||
while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = false;
|
||||
while ($start > 0 && $changed[$start - 1]) {
|
||||
$start--;
|
||||
}
|
||||
assert('$j > 0');
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
assert('$j >= 0 && !$other_changed[$j]');
|
||||
}
|
||||
|
||||
/* Set CORRESPONDING to the end of the changed run, at the
|
||||
* last point where it corresponds to a changed run in the
|
||||
* other file. CORRESPONDING == LEN means no such point has
|
||||
* been found. */
|
||||
$corresponding = $j < $other_len ? $i : $len;
|
||||
|
||||
/* Move the changed region forward, so long as the first
|
||||
* changed line matches the following unchanged one. This
|
||||
* merges with following changed regions. Do this second, so
|
||||
* that if there are no merges, the changed region is moved
|
||||
* forward as far as possible. */
|
||||
while ($i < $len && $lines[$start] == $lines[$i]) {
|
||||
$changed[$start++] = false;
|
||||
$changed[$i++] = 1;
|
||||
while ($i < $len && $changed[$i]) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$j++;
|
||||
if ($j < $other_len && $other_changed[$j]) {
|
||||
$corresponding = $i;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ($runlength != $i - $start);
|
||||
|
||||
/* If possible, move the fully-merged run of changes back to a
|
||||
* corresponding run in the other file. */
|
||||
while ($corresponding < $i) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = 0;
|
||||
assert('$j > 0');
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
assert('$j >= 0 && !$other_changed[$j]');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs.
|
||||
*
|
||||
* This class uses the Unix `diff` program via shell_exec to compute the
|
||||
* differences between the two input arrays.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Engine/shell.php,v 1.6.2.3 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* Copyright 2007-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Milian Wolff <mail@milianw.de>
|
||||
* @package Text_Diff
|
||||
* @since 0.3.0
|
||||
*/
|
||||
class Text_Diff_Engine_shell {
|
||||
|
||||
/**
|
||||
* Path to the diff executable
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_diffCommand = 'diff';
|
||||
|
||||
/**
|
||||
* Returns the array of differences.
|
||||
*
|
||||
* @param array $from_lines lines of text from old file
|
||||
* @param array $to_lines lines of text from new file
|
||||
*
|
||||
* @return array all changes made (array with Text_Diff_Op_* objects)
|
||||
*/
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Text_Diff', 'trimNewlines'));
|
||||
|
||||
$temp_dir = Text_Diff::_getTempDir();
|
||||
|
||||
// Execute gnu diff or similar to get a standard diff file.
|
||||
$from_file = tempnam($temp_dir, 'Text_Diff');
|
||||
$to_file = tempnam($temp_dir, 'Text_Diff');
|
||||
$fp = fopen($from_file, 'w');
|
||||
fwrite($fp, implode("\n", $from_lines));
|
||||
fclose($fp);
|
||||
$fp = fopen($to_file, 'w');
|
||||
fwrite($fp, implode("\n", $to_lines));
|
||||
fclose($fp);
|
||||
$diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file);
|
||||
unlink($from_file);
|
||||
unlink($to_file);
|
||||
|
||||
if (is_null($diff)) {
|
||||
// No changes were made
|
||||
return array(new Text_Diff_Op_copy($from_lines));
|
||||
}
|
||||
|
||||
$from_line_no = 1;
|
||||
$to_line_no = 1;
|
||||
$edits = array();
|
||||
|
||||
// Get changed lines by parsing something like:
|
||||
// 0a1,2
|
||||
// 1,2c4,6
|
||||
// 1,5d6
|
||||
preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff,
|
||||
$matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
if (!isset($match[5])) {
|
||||
// This paren is not set every time (see regex).
|
||||
$match[5] = false;
|
||||
}
|
||||
|
||||
if ($match[3] == 'a') {
|
||||
$from_line_no--;
|
||||
}
|
||||
|
||||
if ($match[3] == 'd') {
|
||||
$to_line_no--;
|
||||
}
|
||||
|
||||
if ($from_line_no < $match[1] || $to_line_no < $match[4]) {
|
||||
// copied lines
|
||||
assert('$match[1] - $from_line_no == $match[4] - $to_line_no');
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_copy(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[1] - 1),
|
||||
$this->_getLines($to_lines, $to_line_no, $match[4] - 1)));
|
||||
}
|
||||
|
||||
switch ($match[3]) {
|
||||
case 'd':
|
||||
// deleted lines
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_delete(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[2])));
|
||||
$to_line_no++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
// changed lines
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_change(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[2]),
|
||||
$this->_getLines($to_lines, $to_line_no, $match[5])));
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
// added lines
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_add(
|
||||
$this->_getLines($to_lines, $to_line_no, $match[5])));
|
||||
$from_line_no++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($from_lines)) {
|
||||
// Some lines might still be pending. Add them as copied
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_copy(
|
||||
$this->_getLines($from_lines, $from_line_no,
|
||||
$from_line_no + count($from_lines) - 1),
|
||||
$this->_getLines($to_lines, $to_line_no,
|
||||
$to_line_no + count($to_lines) - 1)));
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lines from either the old or new text
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param array &$text_lines Either $from_lines or $to_lines
|
||||
* @param int &$line_no Current line number
|
||||
* @param int $end Optional end line, when we want to chop more
|
||||
* than one line.
|
||||
*
|
||||
* @return array The chopped lines
|
||||
*/
|
||||
function _getLines(&$text_lines, &$line_no, $end = false)
|
||||
{
|
||||
if (!empty($end)) {
|
||||
$lines = array();
|
||||
// We can shift even more
|
||||
while ($line_no <= $end) {
|
||||
array_push($lines, array_shift($text_lines));
|
||||
$line_no++;
|
||||
}
|
||||
} else {
|
||||
$lines = array(array_shift($text_lines));
|
||||
$line_no++;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses unified or context diffs output from eg. the diff utility.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $patch = file_get_contents('example.patch');
|
||||
* $diff = new Text_Diff('string', array($patch));
|
||||
* $renderer = new Text_Diff_Renderer_inline();
|
||||
* echo $renderer->render($diff);
|
||||
* </code>
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Engine/string.php,v 1.5.2.5 2008/09/10 08:31:58 jan Exp $
|
||||
*
|
||||
* Copyright 2005 Örjan Persson <o@42mm.org>
|
||||
* Copyright 2005-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Örjan Persson <o@42mm.org>
|
||||
* @package Text_Diff
|
||||
* @since 0.2.0
|
||||
*/
|
||||
class Text_Diff_Engine_string {
|
||||
|
||||
/**
|
||||
* Parses a unified or context diff.
|
||||
*
|
||||
* First param contains the whole diff and the second can be used to force
|
||||
* a specific diff type. If the second parameter is 'autodetect', the
|
||||
* diff will be examined to find out which type of diff this is.
|
||||
*
|
||||
* @param string $diff The diff content.
|
||||
* @param string $mode The diff mode of the content in $diff. One of
|
||||
* 'context', 'unified', or 'autodetect'.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
function diff($diff, $mode = 'autodetect')
|
||||
{
|
||||
if ($mode != 'autodetect' && $mode != 'context' && $mode != 'unified') {
|
||||
return PEAR::raiseError('Type of diff is unsupported');
|
||||
}
|
||||
|
||||
if ($mode == 'autodetect') {
|
||||
$context = strpos($diff, '***');
|
||||
$unified = strpos($diff, '---');
|
||||
if ($context === $unified) {
|
||||
return PEAR::raiseError('Type of diff could not be detected');
|
||||
} elseif ($context === false || $unified === false) {
|
||||
$mode = $context !== false ? 'context' : 'unified';
|
||||
} else {
|
||||
$mode = $context < $unified ? 'context' : 'unified';
|
||||
}
|
||||
}
|
||||
|
||||
// Split by new line and remove the diff header, if there is one.
|
||||
$diff = explode("\n", $diff);
|
||||
if (($mode == 'context' && strpos($diff[0], '***') === 0) ||
|
||||
($mode == 'unified' && strpos($diff[0], '---') === 0)) {
|
||||
array_shift($diff);
|
||||
array_shift($diff);
|
||||
}
|
||||
|
||||
if ($mode == 'context') {
|
||||
return $this->parseContextDiff($diff);
|
||||
} else {
|
||||
return $this->parseUnifiedDiff($diff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an array containing the unified diff.
|
||||
*
|
||||
* @param array $diff Array of lines.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
function parseUnifiedDiff($diff)
|
||||
{
|
||||
$edits = array();
|
||||
$end = count($diff) - 1;
|
||||
for ($i = 0; $i < $end;) {
|
||||
$diff1 = array();
|
||||
switch (substr($diff[$i], 0, 1)) {
|
||||
case ' ':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == ' ');
|
||||
$edits[] = new Text_Diff_Op_copy($diff1);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
// get all new lines
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == '+');
|
||||
$edits[] = new Text_Diff_Op_add($diff1);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
// get changed or removed lines
|
||||
$diff2 = array();
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == '-');
|
||||
|
||||
while ($i < $end && substr($diff[$i], 0, 1) == '+') {
|
||||
$diff2[] = substr($diff[$i++], 1);
|
||||
}
|
||||
if (count($diff2) == 0) {
|
||||
$edits[] = new Text_Diff_Op_delete($diff1);
|
||||
} else {
|
||||
$edits[] = new Text_Diff_Op_change($diff1, $diff2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an array containing the context diff.
|
||||
*
|
||||
* @param array $diff Array of lines.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
function parseContextDiff(&$diff)
|
||||
{
|
||||
$edits = array();
|
||||
$i = $max_i = $j = $max_j = 0;
|
||||
$end = count($diff) - 1;
|
||||
while ($i < $end && $j < $end) {
|
||||
while ($i >= $max_i && $j >= $max_j) {
|
||||
// Find the boundaries of the diff output of the two files
|
||||
for ($i = $j;
|
||||
$i < $end && substr($diff[$i], 0, 3) == '***';
|
||||
$i++);
|
||||
for ($max_i = $i;
|
||||
$max_i < $end && substr($diff[$max_i], 0, 3) != '---';
|
||||
$max_i++);
|
||||
for ($j = $max_i;
|
||||
$j < $end && substr($diff[$j], 0, 3) == '---';
|
||||
$j++);
|
||||
for ($max_j = $j;
|
||||
$max_j < $end && substr($diff[$max_j], 0, 3) != '***';
|
||||
$max_j++);
|
||||
}
|
||||
|
||||
// find what hasn't been changed
|
||||
$array = array();
|
||||
while ($i < $max_i &&
|
||||
$j < $max_j &&
|
||||
strcmp($diff[$i], $diff[$j]) == 0) {
|
||||
$array[] = substr($diff[$i], 2);
|
||||
$i++;
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $max_i && ($max_j-$j) <= 1) {
|
||||
if ($diff[$i] != '' && substr($diff[$i], 0, 1) != ' ') {
|
||||
break;
|
||||
}
|
||||
$array[] = substr($diff[$i++], 2);
|
||||
}
|
||||
|
||||
while ($j < $max_j && ($max_i-$i) <= 1) {
|
||||
if ($diff[$j] != '' && substr($diff[$j], 0, 1) != ' ') {
|
||||
break;
|
||||
}
|
||||
$array[] = substr($diff[$j++], 2);
|
||||
}
|
||||
if (count($array) > 0) {
|
||||
$edits[] = new Text_Diff_Op_copy($array);
|
||||
}
|
||||
|
||||
if ($i < $max_i) {
|
||||
$diff1 = array();
|
||||
switch (substr($diff[$i], 0, 1)) {
|
||||
case '!':
|
||||
$diff2 = array();
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
if ($j < $max_j && substr($diff[$j], 0, 1) == '!') {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
}
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '!');
|
||||
$edits[] = new Text_Diff_Op_change($diff1, $diff2);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '+');
|
||||
$edits[] = new Text_Diff_Op_add($diff1);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '-');
|
||||
$edits[] = new Text_Diff_Op_delete($diff1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($j < $max_j) {
|
||||
$diff2 = array();
|
||||
switch (substr($diff[$j], 0, 1)) {
|
||||
case '+':
|
||||
do {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
} while ($j < $max_j && substr($diff[$j], 0, 1) == '+');
|
||||
$edits[] = new Text_Diff_Op_add($diff2);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
} while ($j < $max_j && substr($diff[$j], 0, 1) == '-');
|
||||
$edits[] = new Text_Diff_Op_delete($diff2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs.
|
||||
*
|
||||
* This class uses the xdiff PECL package (http://pecl.php.net/package/xdiff)
|
||||
* to compute the differences between the two input arrays.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Engine/xdiff.php,v 1.4.2.3 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Jon Parise <jon@horde.org>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Engine_xdiff {
|
||||
|
||||
/**
|
||||
*/
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Text_Diff', 'trimNewlines'));
|
||||
|
||||
/* Convert the two input arrays into strings for xdiff processing. */
|
||||
$from_string = implode("\n", $from_lines);
|
||||
$to_string = implode("\n", $to_lines);
|
||||
|
||||
/* Diff the two strings and convert the result to an array. */
|
||||
$diff = xdiff_string_diff($from_string, $to_string, count($to_lines));
|
||||
$diff = explode("\n", $diff);
|
||||
|
||||
/* Walk through the diff one line at a time. We build the $edits
|
||||
* array of diff operations by reading the first character of the
|
||||
* xdiff output (which is in the "unified diff" format).
|
||||
*
|
||||
* Note that we don't have enough information to detect "changed"
|
||||
* lines using this approach, so we can't add Text_Diff_Op_changed
|
||||
* instances to the $edits array. The result is still perfectly
|
||||
* valid, albeit a little less descriptive and efficient. */
|
||||
$edits = array();
|
||||
foreach ($diff as $line) {
|
||||
switch ($line[0]) {
|
||||
case ' ':
|
||||
$edits[] = new Text_Diff_Op_copy(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '+':
|
||||
$edits[] = new Text_Diff_Op_add(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '-':
|
||||
$edits[] = new Text_Diff_Op_delete(array(substr($line, 1)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* $Horde: framework/Text_Diff/Diff/Mapped.php,v 1.3.2.3 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* Copyright 2007-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
class Text_Diff_Mapped extends Text_Diff {
|
||||
|
||||
/**
|
||||
* Computes a diff between sequences of strings.
|
||||
*
|
||||
* This can be used to compute things like case-insensitve diffs, or diffs
|
||||
* which ignore changes in white-space.
|
||||
*
|
||||
* @param array $from_lines An array of strings.
|
||||
* @param array $to_lines An array of strings.
|
||||
* @param array $mapped_from_lines This array should have the same size
|
||||
* number of elements as $from_lines. The
|
||||
* elements in $mapped_from_lines and
|
||||
* $mapped_to_lines are what is actually
|
||||
* compared when computing the diff.
|
||||
* @param array $mapped_to_lines This array should have the same number
|
||||
* of elements as $to_lines.
|
||||
*/
|
||||
function Text_Diff_Mapped($from_lines, $to_lines,
|
||||
$mapped_from_lines, $mapped_to_lines)
|
||||
{
|
||||
assert(count($from_lines) == count($mapped_from_lines));
|
||||
assert(count($to_lines) == count($mapped_to_lines));
|
||||
|
||||
parent::Text_Diff($mapped_from_lines, $mapped_to_lines);
|
||||
|
||||
$xi = $yi = 0;
|
||||
for ($i = 0; $i < count($this->_edits); $i++) {
|
||||
$orig = &$this->_edits[$i]->orig;
|
||||
if (is_array($orig)) {
|
||||
$orig = array_slice($from_lines, $xi, count($orig));
|
||||
$xi += count($orig);
|
||||
}
|
||||
|
||||
$final = &$this->_edits[$i]->final;
|
||||
if (is_array($final)) {
|
||||
$final = array_slice($to_lines, $yi, count($final));
|
||||
$yi += count($final);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,12 @@
|
||||
* This class renders the diff in classic diff format. It is intended that
|
||||
* this class be customized via inheritance, to obtain fancier outputs.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.8 2005/05/02 19:44:53 chuck Exp $
|
||||
* $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.5.10.10 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
*/
|
||||
@@ -47,7 +52,14 @@ class Text_Diff_Renderer {
|
||||
*/
|
||||
function getParams()
|
||||
{
|
||||
return get_object_vars($this);
|
||||
$params = array();
|
||||
foreach (get_object_vars($this) as $k => $v) {
|
||||
if ($k[0] == '_') {
|
||||
$params[substr($k, 1)] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,31 +80,47 @@ class Text_Diff_Renderer {
|
||||
|
||||
$output = $this->_startDiff();
|
||||
|
||||
foreach ($diff->getDiff() as $edit) {
|
||||
$diffs = $diff->getDiff();
|
||||
foreach ($diffs as $i => $edit) {
|
||||
/* If these are unchanged (copied) lines, and we want to keep
|
||||
* leading or trailing context lines, extract them from the copy
|
||||
* block. */
|
||||
if (is_a($edit, 'Text_Diff_Op_copy')) {
|
||||
/* Do we have any diff blocks yet? */
|
||||
if (is_array($block)) {
|
||||
if (count($edit->orig) <= $nlead + $ntrail) {
|
||||
/* How many lines to keep as context from the copy
|
||||
* block. */
|
||||
$keep = $i == count($diffs) - 1 ? $ntrail : $nlead + $ntrail;
|
||||
if (count($edit->orig) <= $keep) {
|
||||
/* We have less lines in the block than we want for
|
||||
* context => keep the whole block. */
|
||||
$block[] = $edit;
|
||||
} else {
|
||||
if ($ntrail) {
|
||||
/* Create a new block with as many lines as we need
|
||||
* for the trailing context. */
|
||||
$context = array_slice($edit->orig, 0, $ntrail);
|
||||
$block[] = &new Text_Diff_Op_copy($context);
|
||||
$block[] = new Text_Diff_Op_copy($context);
|
||||
}
|
||||
/* @todo */
|
||||
$output .= $this->_block($x0, $ntrail + $xi - $x0,
|
||||
$y0, $ntrail + $yi - $y0,
|
||||
$block);
|
||||
$block = false;
|
||||
}
|
||||
}
|
||||
/* Keep the copy block as the context for the next block. */
|
||||
$context = $edit->orig;
|
||||
} else {
|
||||
/* Don't we have any diff blocks yet? */
|
||||
if (!is_array($block)) {
|
||||
/* Extract context lines from the preceding copy block. */
|
||||
$context = array_slice($context, count($context) - $nlead);
|
||||
$x0 = $xi - count($context);
|
||||
$y0 = $yi - count($context);
|
||||
$block = array();
|
||||
if ($context) {
|
||||
$block[] = &new Text_Diff_Op_copy($context);
|
||||
$block[] = new Text_Diff_Op_copy($context);
|
||||
}
|
||||
}
|
||||
$block[] = $edit;
|
||||
@@ -161,6 +189,13 @@ class Text_Diff_Renderer {
|
||||
$ybeg .= ',' . ($ybeg + $ylen - 1);
|
||||
}
|
||||
|
||||
// this matches the GNU Diff behaviour
|
||||
if ($xlen && !$ylen) {
|
||||
$ybeg--;
|
||||
} elseif (!$xlen) {
|
||||
$xbeg--;
|
||||
}
|
||||
|
||||
return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
|
||||
}
|
||||
|
||||
@@ -173,31 +208,25 @@ class Text_Diff_Renderer {
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Added by Matt Mecham
|
||||
* Space between prefix and string result
|
||||
* 25-07-2005
|
||||
*
|
||||
*/
|
||||
|
||||
function _lines($lines, $prefix = ' ')
|
||||
{
|
||||
return $prefix . ' ' . implode("\n$prefix", $lines) . "\n";
|
||||
return $prefix . implode("\n$prefix", $lines) . "\n";
|
||||
}
|
||||
|
||||
function _context($lines)
|
||||
{
|
||||
return $this->_lines($lines);
|
||||
return $this->_lines($lines, ' ');
|
||||
}
|
||||
|
||||
function _added($lines)
|
||||
{
|
||||
return $this->_lines($lines, '>');
|
||||
return $this->_lines($lines, '> ');
|
||||
}
|
||||
|
||||
function _deleted($lines)
|
||||
{
|
||||
return $this->_lines($lines, '<');
|
||||
return $this->_lines($lines, '< ');
|
||||
}
|
||||
|
||||
function _changed($orig, $final)
|
||||
@@ -205,4 +234,4 @@ class Text_Diff_Renderer {
|
||||
return $this->_deleted($orig) . "---\n" . $this->_added($final);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* "Context" diff renderer.
|
||||
*
|
||||
* This class renders the diff in classic "context diff" format.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Renderer/context.php,v 1.3.2.3 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
/** Text_Diff_Renderer */
|
||||
require_once 'Text/Diff/Renderer.php';
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Renderer_context extends Text_Diff_Renderer {
|
||||
|
||||
/**
|
||||
* Number of leading context "lines" to preserve.
|
||||
*/
|
||||
var $_leading_context_lines = 4;
|
||||
|
||||
/**
|
||||
* Number of trailing context "lines" to preserve.
|
||||
*/
|
||||
var $_trailing_context_lines = 4;
|
||||
|
||||
var $_second_block = '';
|
||||
|
||||
function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
if ($xlen != 1) {
|
||||
$xbeg .= ',' . $xlen;
|
||||
}
|
||||
if ($ylen != 1) {
|
||||
$ybeg .= ',' . $ylen;
|
||||
}
|
||||
$this->_second_block = "--- $ybeg ----\n";
|
||||
return "***************\n*** $xbeg ****";
|
||||
}
|
||||
|
||||
function _endBlock()
|
||||
{
|
||||
return $this->_second_block;
|
||||
}
|
||||
|
||||
function _context($lines)
|
||||
{
|
||||
$this->_second_block .= $this->_lines($lines, ' ');
|
||||
return $this->_lines($lines, ' ');
|
||||
}
|
||||
|
||||
function _added($lines)
|
||||
{
|
||||
$this->_second_block .= $this->_lines($lines, '+ ');
|
||||
return '';
|
||||
}
|
||||
|
||||
function _deleted($lines)
|
||||
{
|
||||
return $this->_lines($lines, '- ');
|
||||
}
|
||||
|
||||
function _changed($orig, $final)
|
||||
{
|
||||
$this->_second_block .= $this->_lines($final, '! ');
|
||||
return $this->_lines($orig, '! ');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<html>␍<head><title>Invision Power Board - Bulletin Board System</title></head>␍<body>␍<h1>403: Invision Power Board -> Forbidden</h1>␍<hr>␍You have reached this Page in error, please use␍your back button to return to Invision Board.␍<hr>␍<a href="http://anonym.to/http://www.invisionboard.com/">Invision Power Board</a>␍</body>␍</html>
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -2,9 +2,24 @@
|
||||
/**
|
||||
* "Inline" diff renderer.
|
||||
*
|
||||
* This class renders diffs in the Wiki-style "inline" format.
|
||||
* $Horde: framework/Text_Diff/Diff/Renderer/inline.php,v 1.4.10.14 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Renderer/inline.php,v 1.11 2005/05/02 19:49:39 chuck Exp $
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Ciprian Popovici
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
/** Text_Diff_Renderer */
|
||||
require_once 'Text/Diff/Renderer.php';
|
||||
|
||||
/**
|
||||
* "Inline" diff renderer.
|
||||
*
|
||||
* This class renders diffs in the Wiki-style "inline" format.
|
||||
*
|
||||
* @author Ciprian Popovici
|
||||
* @package Text_Diff
|
||||
@@ -52,15 +67,6 @@ class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
|
||||
*/
|
||||
var $_split_level = 'lines';
|
||||
|
||||
function _lines($lines, $prefix = ' ')
|
||||
{
|
||||
if ($this->_split_level == 'words') {
|
||||
return implode('', $lines);
|
||||
} else {
|
||||
return implode("\n", $lines) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
return $this->_block_header;
|
||||
@@ -71,18 +77,33 @@ class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
|
||||
return $header;
|
||||
}
|
||||
|
||||
function _lines($lines, $prefix = ' ', $encode = true)
|
||||
{
|
||||
if ($encode) {
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
}
|
||||
|
||||
if ($this->_split_level == 'words') {
|
||||
return implode('', $lines);
|
||||
} else {
|
||||
return implode("\n", $lines) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function _added($lines)
|
||||
{
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
$lines[0] = $this->_ins_prefix . $lines[0];
|
||||
$lines[count($lines) - 1] .= $this->_ins_suffix;
|
||||
return $this->_lines($lines);
|
||||
return $this->_lines($lines, ' ', false);
|
||||
}
|
||||
|
||||
function _deleted($lines, $words = false)
|
||||
{
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
$lines[0] = $this->_del_prefix . $lines[0];
|
||||
$lines[count($lines) - 1] .= $this->_del_suffix;
|
||||
return $this->_lines($lines);
|
||||
return $this->_lines($lines, ' ', false);
|
||||
}
|
||||
|
||||
function _changed($orig, $final)
|
||||
@@ -91,7 +112,9 @@ class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
|
||||
* display. */
|
||||
if ($this->_split_level == 'words') {
|
||||
$prefix = '';
|
||||
while (substr($orig[0], 0, 1) == substr($final[0], 0, 1)) {
|
||||
while ($orig[0] !== false && $final[0] !== false &&
|
||||
substr($orig[0], 0, 1) == ' ' &&
|
||||
substr($final[0], 0, 1) == ' ') {
|
||||
$prefix .= substr($orig[0], 0, 1);
|
||||
$orig[0] = substr($orig[0], 1);
|
||||
$final[0] = substr($final[0], 1);
|
||||
@@ -108,12 +131,12 @@ class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
|
||||
/* We want to split on word boundaries, but we need to
|
||||
* preserve whitespace as well. Therefore we split on words,
|
||||
* but include all blocks of whitespace in the wordlist. */
|
||||
$diff = &new Text_Diff($this->_splitOnWords($text1, $nl),
|
||||
$this->_splitOnWords($text2, $nl));
|
||||
$diff = new Text_Diff($this->_splitOnWords($text1, $nl),
|
||||
$this->_splitOnWords($text2, $nl));
|
||||
|
||||
/* Get the diff in inline format. */
|
||||
$renderer = &new Text_Diff_Renderer_inline(array_merge($this->getParams(),
|
||||
array('split_level' => 'words')));
|
||||
$renderer = new Text_Diff_Renderer_inline(array_merge($this->getParams(),
|
||||
array('split_level' => 'words')));
|
||||
|
||||
/* Run the diff and get the output. */
|
||||
return str_replace($nl, "\n", $renderer->render($diff)) . "\n";
|
||||
@@ -121,14 +144,17 @@ class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
|
||||
|
||||
function _splitOnWords($string, $newlineEscape = "\n")
|
||||
{
|
||||
// Ignore \0; otherwise the while loop will never finish.
|
||||
$string = str_replace("\0", '', $string);
|
||||
|
||||
$words = array();
|
||||
$length = strlen($string);
|
||||
$pos = 0;
|
||||
|
||||
while ($pos < $length) {
|
||||
// Eat a word with any preceding whitespace.
|
||||
$spaces = strspn($string, " \n", $pos);
|
||||
$nextpos = strcspn($string, " \n", $pos + $spaces);
|
||||
$spaces = strspn(substr($string, $pos), " \n");
|
||||
$nextpos = strcspn(substr($string, $pos + $spaces), " \n");
|
||||
$words[] = str_replace("\n", $newlineEscape, substr($string, $pos, $spaces + $nextpos));
|
||||
$pos += $spaces + $nextpos;
|
||||
}
|
||||
@@ -136,4 +162,9 @@ class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
|
||||
return $words;
|
||||
}
|
||||
|
||||
}
|
||||
function _encode(&$string)
|
||||
{
|
||||
$string = htmlspecialchars($string);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,8 +4,21 @@
|
||||
*
|
||||
* This class renders the diff in classic "unified diff" format.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/Renderer/unified.php,v 1.4 2005/03/07 14:58:30 jan Exp $
|
||||
* $Horde: framework/Text_Diff/Diff/Renderer/unified.php,v 1.3.10.6 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Ciprian Popovici
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
/** Text_Diff_Renderer */
|
||||
require_once 'Text/Diff/Renderer.php';
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Renderer_unified extends Text_Diff_Renderer {
|
||||
@@ -31,6 +44,11 @@ class Text_Diff_Renderer_unified extends Text_Diff_Renderer {
|
||||
return "@@ -$xbeg +$ybeg @@";
|
||||
}
|
||||
|
||||
function _context($lines)
|
||||
{
|
||||
return $this->_lines($lines, ' ');
|
||||
}
|
||||
|
||||
function _added($lines)
|
||||
{
|
||||
return $this->_lines($lines, '+');
|
||||
@@ -46,4 +64,4 @@ class Text_Diff_Renderer_unified extends Text_Diff_Renderer {
|
||||
return $this->_deleted($orig) . $this->_added($final);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* A class for computing three way diffs.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff/ThreeWay.php,v 1.3.2.3 2008/01/04 10:37:27 jan Exp $
|
||||
*
|
||||
* Copyright 2007-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @since 0.3.0
|
||||
*/
|
||||
|
||||
/** Text_Diff */
|
||||
require_once 'Text/Diff.php';
|
||||
|
||||
/**
|
||||
* A class for computing three way diffs.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
class Text_Diff_ThreeWay extends Text_Diff {
|
||||
|
||||
/**
|
||||
* Conflict counter.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $_conflictingBlocks = 0;
|
||||
|
||||
/**
|
||||
* Computes diff between 3 sequences of strings.
|
||||
*
|
||||
* @param array $orig The original lines to use.
|
||||
* @param array $final1 The first version to compare to.
|
||||
* @param array $final2 The second version to compare to.
|
||||
*/
|
||||
function Text_Diff_ThreeWay($orig, $final1, $final2)
|
||||
{
|
||||
if (extension_loaded('xdiff')) {
|
||||
$engine = new Text_Diff_Engine_xdiff();
|
||||
} else {
|
||||
$engine = new Text_Diff_Engine_native();
|
||||
}
|
||||
|
||||
$this->_edits = $this->_diff3($engine->diff($orig, $final1),
|
||||
$engine->diff($orig, $final2));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function mergedOutput($label1 = false, $label2 = false)
|
||||
{
|
||||
$lines = array();
|
||||
foreach ($this->_edits as $edit) {
|
||||
if ($edit->isConflict()) {
|
||||
/* FIXME: this should probably be moved somewhere else. */
|
||||
$lines = array_merge($lines,
|
||||
array('<<<<<<<' . ($label1 ? ' ' . $label1 : '')),
|
||||
$edit->final1,
|
||||
array("======="),
|
||||
$edit->final2,
|
||||
array('>>>>>>>' . ($label2 ? ' ' . $label2 : '')));
|
||||
$this->_conflictingBlocks++;
|
||||
} else {
|
||||
$lines = array_merge($lines, $edit->merged());
|
||||
}
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _diff3($edits1, $edits2)
|
||||
{
|
||||
$edits = array();
|
||||
$bb = new Text_Diff_ThreeWay_BlockBuilder();
|
||||
|
||||
$e1 = current($edits1);
|
||||
$e2 = current($edits2);
|
||||
while ($e1 || $e2) {
|
||||
if ($e1 && $e2 && is_a($e1, 'Text_Diff_Op_copy') && is_a($e2, 'Text_Diff_Op_copy')) {
|
||||
/* We have copy blocks from both diffs. This is the (only)
|
||||
* time we want to emit a diff3 copy block. Flush current
|
||||
* diff3 diff block, if any. */
|
||||
if ($edit = $bb->finish()) {
|
||||
$edits[] = $edit;
|
||||
}
|
||||
|
||||
$ncopy = min($e1->norig(), $e2->norig());
|
||||
assert($ncopy > 0);
|
||||
$edits[] = new Text_Diff_ThreeWay_Op_copy(array_slice($e1->orig, 0, $ncopy));
|
||||
|
||||
if ($e1->norig() > $ncopy) {
|
||||
array_splice($e1->orig, 0, $ncopy);
|
||||
array_splice($e1->final, 0, $ncopy);
|
||||
} else {
|
||||
$e1 = next($edits1);
|
||||
}
|
||||
|
||||
if ($e2->norig() > $ncopy) {
|
||||
array_splice($e2->orig, 0, $ncopy);
|
||||
array_splice($e2->final, 0, $ncopy);
|
||||
} else {
|
||||
$e2 = next($edits2);
|
||||
}
|
||||
} else {
|
||||
if ($e1 && $e2) {
|
||||
if ($e1->orig && $e2->orig) {
|
||||
$norig = min($e1->norig(), $e2->norig());
|
||||
$orig = array_splice($e1->orig, 0, $norig);
|
||||
array_splice($e2->orig, 0, $norig);
|
||||
$bb->input($orig);
|
||||
}
|
||||
|
||||
if (is_a($e1, 'Text_Diff_Op_copy')) {
|
||||
$bb->out1(array_splice($e1->final, 0, $norig));
|
||||
}
|
||||
|
||||
if (is_a($e2, 'Text_Diff_Op_copy')) {
|
||||
$bb->out2(array_splice($e2->final, 0, $norig));
|
||||
}
|
||||
}
|
||||
|
||||
if ($e1 && ! $e1->orig) {
|
||||
$bb->out1($e1->final);
|
||||
$e1 = next($edits1);
|
||||
}
|
||||
if ($e2 && ! $e2->orig) {
|
||||
$bb->out2($e2->final);
|
||||
$e2 = next($edits2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($edit = $bb->finish()) {
|
||||
$edits[] = $edit;
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_ThreeWay_Op {
|
||||
|
||||
function Text_Diff_ThreeWay_Op($orig = false, $final1 = false, $final2 = false)
|
||||
{
|
||||
$this->orig = $orig ? $orig : array();
|
||||
$this->final1 = $final1 ? $final1 : array();
|
||||
$this->final2 = $final2 ? $final2 : array();
|
||||
}
|
||||
|
||||
function merged()
|
||||
{
|
||||
if (!isset($this->_merged)) {
|
||||
if ($this->final1 === $this->final2) {
|
||||
$this->_merged = &$this->final1;
|
||||
} elseif ($this->final1 === $this->orig) {
|
||||
$this->_merged = &$this->final2;
|
||||
} elseif ($this->final2 === $this->orig) {
|
||||
$this->_merged = &$this->final1;
|
||||
} else {
|
||||
$this->_merged = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_merged;
|
||||
}
|
||||
|
||||
function isConflict()
|
||||
{
|
||||
return $this->merged() === false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_ThreeWay_Op_copy extends Text_Diff_ThreeWay_Op {
|
||||
|
||||
function Text_Diff_ThreeWay_Op_Copy($lines = false)
|
||||
{
|
||||
$this->orig = $lines ? $lines : array();
|
||||
$this->final1 = &$this->orig;
|
||||
$this->final2 = &$this->orig;
|
||||
}
|
||||
|
||||
function merged()
|
||||
{
|
||||
return $this->orig;
|
||||
}
|
||||
|
||||
function isConflict()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_ThreeWay_BlockBuilder {
|
||||
|
||||
function Text_Diff_ThreeWay_BlockBuilder()
|
||||
{
|
||||
$this->_init();
|
||||
}
|
||||
|
||||
function input($lines)
|
||||
{
|
||||
if ($lines) {
|
||||
$this->_append($this->orig, $lines);
|
||||
}
|
||||
}
|
||||
|
||||
function out1($lines)
|
||||
{
|
||||
if ($lines) {
|
||||
$this->_append($this->final1, $lines);
|
||||
}
|
||||
}
|
||||
|
||||
function out2($lines)
|
||||
{
|
||||
if ($lines) {
|
||||
$this->_append($this->final2, $lines);
|
||||
}
|
||||
}
|
||||
|
||||
function isEmpty()
|
||||
{
|
||||
return !$this->orig && !$this->final1 && !$this->final2;
|
||||
}
|
||||
|
||||
function finish()
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
$edit = new Text_Diff_ThreeWay_Op($this->orig, $this->final1, $this->final2);
|
||||
$this->_init();
|
||||
return $edit;
|
||||
}
|
||||
}
|
||||
|
||||
function _init()
|
||||
{
|
||||
$this->orig = $this->final1 = $this->final2 = array();
|
||||
}
|
||||
|
||||
function _append(&$array, $lines)
|
||||
{
|
||||
array_splice($array, sizeof($array), 0, $lines);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<html>␍<head><title>Invision Power Board - Bulletin Board System</title></head>␍<body>␍<h1>403: Invision Power Board -> Forbidden</h1>␍<hr>␍You have reached this Page in error, please use␍your back button to return to Invision Board.␍<hr>␍<a href="http://anonym.to/http://www.invisionboard.com/">Invision Power Board</a>␍</body>␍</html>
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -1,12 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* A class for computing three way diffs.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff3.php,v 1.2.10.6 2008/01/04 10:37:26 jan Exp $
|
||||
*
|
||||
* Copyright 2007-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @since 0.3.0
|
||||
*/
|
||||
|
||||
/** Text_Diff */
|
||||
require_once 'Text/Diff.php';
|
||||
|
||||
/**
|
||||
* A class for computing three way diffs.
|
||||
*
|
||||
* $Horde: framework/Text_Diff/Diff3.php,v 1.2 2004/10/13 09:30:20 jan Exp $
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
@@ -15,7 +27,7 @@ class Text_Diff3 extends Text_Diff {
|
||||
/**
|
||||
* Conflict counter.
|
||||
*
|
||||
* @var integer $_conflictCounter
|
||||
* @var integer
|
||||
*/
|
||||
var $_conflictingBlocks = 0;
|
||||
|
||||
@@ -29,15 +41,17 @@ class Text_Diff3 extends Text_Diff {
|
||||
function Text_Diff3($orig, $final1, $final2)
|
||||
{
|
||||
if (extension_loaded('xdiff')) {
|
||||
$engine = &new Text_Diff_Engine_xdiff();
|
||||
$engine = new Text_Diff_Engine_xdiff();
|
||||
} else {
|
||||
$engine = &new Text_Diff_Engine_native();
|
||||
$engine = new Text_Diff_Engine_native();
|
||||
}
|
||||
|
||||
$this->_edits = $this->_diff3($engine->diff($orig, $final1),
|
||||
$engine->diff($orig, $final2));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function mergedOutput($label1 = false, $label2 = false)
|
||||
{
|
||||
$lines = array();
|
||||
@@ -65,7 +79,7 @@ class Text_Diff3 extends Text_Diff {
|
||||
function _diff3($edits1, $edits2)
|
||||
{
|
||||
$edits = array();
|
||||
$bb = &new Text_Diff3_BlockBuilder();
|
||||
$bb = new Text_Diff3_BlockBuilder();
|
||||
|
||||
$e1 = current($edits1);
|
||||
$e2 = current($edits2);
|
||||
@@ -80,7 +94,7 @@ class Text_Diff3 extends Text_Diff {
|
||||
|
||||
$ncopy = min($e1->norig(), $e2->norig());
|
||||
assert($ncopy > 0);
|
||||
$edits[] = &new Text_Diff3_Op_copy(array_slice($e1->orig, 0, $ncopy));
|
||||
$edits[] = new Text_Diff3_Op_copy(array_slice($e1->orig, 0, $ncopy));
|
||||
|
||||
if ($e1->norig() > $ncopy) {
|
||||
array_splice($e1->orig, 0, $ncopy);
|
||||
@@ -136,7 +150,8 @@ class Text_Diff3 extends Text_Diff {
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff3_Op {
|
||||
|
||||
@@ -174,7 +189,8 @@ class Text_Diff3_Op {
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff3_Op_copy extends Text_Diff3_Op {
|
||||
|
||||
@@ -200,7 +216,8 @@ class Text_Diff3_Op_copy extends Text_Diff3_Op {
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff3_BlockBuilder {
|
||||
|
||||
@@ -240,7 +257,7 @@ class Text_Diff3_BlockBuilder {
|
||||
if ($this->isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
$edit = &new Text_Diff3_Op($this->orig, $this->final1, $this->final2);
|
||||
$edit = new Text_Diff3_Op($this->orig, $this->final1, $this->final2);
|
||||
$this->_init();
|
||||
return $edit;
|
||||
}
|
||||
@@ -256,4 +273,4 @@ class Text_Diff3_BlockBuilder {
|
||||
array_splice($array, sizeof($array), 0, $lines);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<html>␍<head><title>Invision Power Board - Bulletin Board System</title></head>␍<body>␍<h1>403: Invision Power Board -> Forbidden</h1>␍<hr>␍You have reached this Page in error, please use␍your back button to return to Invision Board.␍<hr>␍<a href="http://anonym.to/http://www.invisionboard.com/">Invision Power Board</a>␍</body>␍</html>
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -1,142 +1,281 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
|
||||
<package version="1.0" packagerversion="1.4.0a9">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<package packagerversion="1.7.2" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<name>Text_Diff</name>
|
||||
<channel>pear.php.net</channel>
|
||||
<summary>Engine for performing and rendering text diffs</summary>
|
||||
<description>This package provides a text-based diff engine and renderers for multiple diff output formats.
|
||||
</description>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>chagenbu</user>
|
||||
<name>Chuck Hagenbuch</name>
|
||||
<email>chuck@horde.org</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>jon</user>
|
||||
<name>Jon Parise</name>
|
||||
<email>jon@horde.org</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>pmjones</user>
|
||||
<name>Paul M Jones</name>
|
||||
<email>pmjones@memphis.edu</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>yunosh</user>
|
||||
<name>Jan Schneider</name>
|
||||
<email>jan@horde.org</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<release>
|
||||
<version>0.0.5</version>
|
||||
<date>2005-05-05</date>
|
||||
<license>LGPL</license>
|
||||
<state>beta</state>
|
||||
<notes>* Fixed variable name in Text_MappedDiff.
|
||||
<description>This package provides a text-based diff engine and renderers for multiple diff output formats.</description>
|
||||
<lead>
|
||||
<name>Chuck Hagenbuch</name>
|
||||
<user>chagenbu</user>
|
||||
<email>chuck@horde.org</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<lead>
|
||||
<name>Jan Schneider</name>
|
||||
<user>yunosh</user>
|
||||
<email>jan@horde.org</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<lead>
|
||||
<name>Paul M Jones</name>
|
||||
<user>pmjones</user>
|
||||
<email>pmjones@memphis.edu</email>
|
||||
<active>no</active>
|
||||
</lead>
|
||||
<date>2008-09-10</date>
|
||||
<time>10:52:52</time>
|
||||
<version>
|
||||
<release>1.1.0</release>
|
||||
<api>1.1.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Add countAddedLines() and countDeletedLines() methods (Christian King, PEAR Request #13183).
|
||||
* Improve string engine if patch data has no header (PEAR Bug #14533).
|
||||
* Fix autodetection of diff type in string engine (PEAR Bug #14625).</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
<file baseinstalldir="/Text" md5sum="b30ce3240eed85e2114b93e28095af90" name="Diff/Engine/native.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="4ccb7b5ea80041fcd6e5c5cd958931fa" name="Diff/Engine/shell.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="1daaca651ed46e5711b43e47e91e077f" name="Diff/Engine/string.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="05f00fc5c59664199eb533ff825a386c" name="Diff/Engine/xdiff.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="1263babf64df086001944b699014e59d" name="Diff/Renderer/context.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="e001548ef0b37702633a421cf7eed83d" name="Diff/Renderer/inline.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="c4dbae31ce515995100f6ad27a8c9c4e" name="Diff/Renderer/unified.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="96b1dc3ba33aba32a4b5662b22d8b58a" name="Diff/Mapped.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="d5ac2cccaacad465caa41fae23eae8ad" name="Diff/Renderer.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="abf74995fef0ba23d50dfc6a5652b5e1" name="Diff/ThreeWay.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="5fbdf5388905ed07026b876126aeee5a" name="docs/examples/1.txt" role="doc" />
|
||||
<file baseinstalldir="/Text" md5sum="011c4dad4506a4843ded1f12cab69909" name="docs/examples/2.txt" role="doc" />
|
||||
<file baseinstalldir="/Text" md5sum="6082891c438ee1ba70fd89b9b4e241e8" name="docs/examples/diff.php" role="doc" />
|
||||
<file baseinstalldir="/Text" md5sum="5fbdf5388905ed07026b876126aeee5a" name="tests/1.txt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="011c4dad4506a4843ded1f12cab69909" name="tests/2.txt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="308bfdcfb801c46d41d5d24b9fe003f4" name="tests/3.txt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="76af0d7919f307177aef831e62e48640" name="tests/4.txt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="ea33106f5d970bf5dc318b752c95e343" name="tests/5.txt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="38f7931505de496d7312a830b2880f2c" name="tests/6.txt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="aa40a9c049e89eb8c6f5b0f47e1aabd9" name="tests/context.patch" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="b0143ef7d5e9a1ace0ff747165f27c1f" name="tests/context.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="2a88e4c49d51bbdced9a4bd8a8a657c5" name="tests/context2.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="43e8b69ff75bc0e7ecab5b4e87827d19" name="tests/diff.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="2c2f13e357f691f3922d07f6e70fa43d" name="tests/inline.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="05e94365c047905009b1913a3600036f" name="tests/inline2.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="e05b5cf54cfaf541663fa802724e9549" name="tests/pear_bug12740.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="7949426acc1e64d6c10338bf6382257d" name="tests/pear_bug4879.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="7fb3cda23ca78409f72ac233784ff1a1" name="tests/pear_bug6251.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="c4d40a654a584d3f939dca33fff0a5c4" name="tests/pear_bug6428.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="e7011d4030f4a020d24efb6f1673a1bc" name="tests/string.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="359096964862ff26e28cc44609ca237f" name="tests/unified.patch" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="77977a033a539c5ccadaf728b95a1a2c" name="tests/unified.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="dab2830cf62f341f1046b883948c1851" name="tests/unified2.phpt" role="test" />
|
||||
<file baseinstalldir="/Text" md5sum="3f715ec0e86162bddc1ea794a04aa4d3" name="Diff.php" role="php" />
|
||||
<file baseinstalldir="/Text" md5sum="7b57773de584d2408214cb2c7a0d0a2e" name="Diff3.php" role="php" />
|
||||
</dir>
|
||||
</contents>
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>4.2.0</min>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0b1</min>
|
||||
</pearinstaller>
|
||||
</required>
|
||||
<optional>
|
||||
<extension>
|
||||
<name>xdiff</name>
|
||||
</extension>
|
||||
</optional>
|
||||
</dependencies>
|
||||
<phprelease />
|
||||
<changelog>
|
||||
<release>
|
||||
<version>
|
||||
<release>1.0.0</release>
|
||||
<api>1.0.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<date>2008-01-31</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Stable release; final non-bugfix PHP 4 release.</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.3.2</release>
|
||||
<api>0.3.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2007-01-04</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Fixed assertion in the native engine with PHP 5 (PEAR Bug #12740).</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.3.1</release>
|
||||
<api>0.3.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2007-10-28</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Fixed off-by-one errors with line numbers in default renderer output (Milian Wolff, PEAR Bugs #7839, #12111).
|
||||
* Restore compatibility with PHP 4 in the shell diff engine.</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.3.0</release>
|
||||
<api>0.3.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2007-09-20</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Converted to package.xml 2.0.
|
||||
* Added context diff renderer.
|
||||
* Stripped nul characters to avoid infinite loops (PEAR Bug #7921).
|
||||
* Fix assertion with PHP 5 (PEAR Bug #10423).
|
||||
* Add shell diff engine (Milian Wolff, PEAR Request #12051).</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.2.1</release>
|
||||
<api>0.2.1</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2006-02-06</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Fix Text_Diff::reverse() method with PHP 5 (PEAR Bug #6699).</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.2.0</release>
|
||||
<api>0.2.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2006-01-06</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Fix reference warnings with PHP 4.4 and PHP 5.1.
|
||||
* Fix too many trailing context lines for the last diff chunk. (PEAR Bug #6251).
|
||||
* Add diff engine for existing diffs/patches (Örjan Persson, PEAR Request #5373).
|
||||
* Fix problems with numbers, whitespace-only changes and the inline renderer (PEAR Bug #6428.</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.1.1</release>
|
||||
<api>0.1.1</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2005-08-19</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Restore compatibility with PHP 4.2.0 (PEAR Bug #5152).</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.1.0</release>
|
||||
<api>0.1.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2005-08-16</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Fix Renderer::getParams() (PEAR Bug #4549)
|
||||
* Encode HTML entities in the inline renderer (Horde Bug #2181)
|
||||
* Fix endless loop in inline renderer with certain whitespaces (PEAR Bug #4879)</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.0.5</release>
|
||||
<api>0.0.5</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2005-05-04</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Fixed variable name in Text_MappedDiff.
|
||||
* Removed output buffering code.
|
||||
* Fixed additional empty lines being added with the inline renderer (Bug 3730).
|
||||
* Fixed multiple calls to _endBlock per block (Bug 4065).
|
||||
</notes>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="4.2.0"/>
|
||||
<dep type="ext" rel="has" optional="yes">xdiff</dep>
|
||||
</deps>
|
||||
<provides type="class" name="Text_Diff" />
|
||||
<provides type="class" name="Text_Diff3" />
|
||||
<provides type="class" name="Text_MappedDiff" />
|
||||
<provides type="class" name="Text_Diff_Renderer" />
|
||||
<provides type="class" name="Text_Diff_Engine_xdiff" />
|
||||
<provides type="class" name="Text_Diff_Engine_native" />
|
||||
<provides type="class" name="Text_Diff_Op" />
|
||||
<provides type="class" name="Text_Diff_Op_copy" extends="Text_Diff_Op" />
|
||||
<provides type="class" name="Text_Diff_Op_delete" extends="Text_Diff_Op" />
|
||||
<provides type="class" name="Text_Diff_Op_add" extends="Text_Diff_Op" />
|
||||
<provides type="class" name="Text_Diff_Op_change" extends="Text_Diff_Op" />
|
||||
<provides type="function" name="Text_Diff::getDiff" />
|
||||
<provides type="function" name="Text_Diff::reverse" />
|
||||
<provides type="function" name="Text_Diff::isEmpty" />
|
||||
<provides type="function" name="Text_Diff::lcs" />
|
||||
<provides type="function" name="Text_Diff::getOriginal" />
|
||||
<provides type="function" name="Text_Diff::getFinal" />
|
||||
<provides type="function" name="Text_Diff_Engine_xdiff::diff" />
|
||||
<provides type="function" name="Text_Diff_Engine_native::diff" />
|
||||
<provides type="function" name="Text_Diff_Op::reverse" />
|
||||
<provides type="function" name="Text_Diff_Op::norig" />
|
||||
<provides type="function" name="Text_Diff_Op::nfinal" />
|
||||
<provides type="function" name="Text_Diff_Op_copy::reverse" />
|
||||
<provides type="function" name="Text_Diff_Op_delete::reverse" />
|
||||
<provides type="function" name="Text_Diff_Op_add::reverse" />
|
||||
<provides type="function" name="Text_Diff_Op_change::reverse" />
|
||||
<provides type="class" name="Text_Diff3_Op" />
|
||||
<provides type="class" name="Text_Diff3_Op_copy" extends="Text_Diff3_Op" />
|
||||
<provides type="class" name="Text_Diff3_BlockBuilder" />
|
||||
<provides type="function" name="Text_Diff3::mergedOutput" />
|
||||
<provides type="function" name="Text_Diff3_Op::merged" />
|
||||
<provides type="function" name="Text_Diff3_Op::isConflict" />
|
||||
<provides type="function" name="Text_Diff3_Op_copy::merged" />
|
||||
<provides type="function" name="Text_Diff3_Op_copy::isConflict" />
|
||||
<provides type="function" name="Text_Diff3_BlockBuilder::input" />
|
||||
<provides type="function" name="Text_Diff3_BlockBuilder::out1" />
|
||||
<provides type="function" name="Text_Diff3_BlockBuilder::out2" />
|
||||
<provides type="function" name="Text_Diff3_BlockBuilder::isEmpty" />
|
||||
<provides type="function" name="Text_Diff3_BlockBuilder::finish" />
|
||||
<provides type="function" name="Text_Diff_Renderer::getParams" />
|
||||
<provides type="function" name="Text_Diff_Renderer::render" />
|
||||
<provides type="class" name="Text_Diff_Renderer_inline" extends="Text_Diff_Renderer" />
|
||||
<provides type="class" name="Text_Diff_Renderer_unified" extends="Text_Diff_Renderer" />
|
||||
<filelist>
|
||||
<file role="php" baseinstalldir="/Text" md5sum="16ca4ec69bf44ecd1467ebb5ee70b5df" name="Diff.php"/>
|
||||
<file role="php" baseinstalldir="/Text" md5sum="7a1c6842b8b25822db3e37e5b9663da1" name="Diff3.php"/>
|
||||
<file role="php" baseinstalldir="/Text" md5sum="a32f238fd2bf80cce18a745df89d7e43" name="Diff/Renderer.php"/>
|
||||
<file role="php" baseinstalldir="/Text" md5sum="82ea5ce1668a6bc38ee7ece1020433b9" name="Diff/Renderer/inline.php"/>
|
||||
<file role="php" baseinstalldir="/Text" md5sum="37211108109573d335251c690293d7b9" name="Diff/Renderer/unified.php"/>
|
||||
<file role="doc" baseinstalldir="/Text" md5sum="d0e483e9f20738417d7a2a4fa56e074f" name="docs/examples/diff.php"/>
|
||||
<file role="doc" baseinstalldir="/Text" md5sum="5fbdf5388905ed07026b876126aeee5a" name="docs/examples/1.txt"/>
|
||||
<file role="doc" baseinstalldir="/Text" md5sum="011c4dad4506a4843ded1f12cab69909" name="docs/examples/2.txt"/>
|
||||
<file role="test" baseinstalldir="/Text" md5sum="5fbdf5388905ed07026b876126aeee5a" name="tests/1.txt"/>
|
||||
<file role="test" baseinstalldir="/Text" md5sum="011c4dad4506a4843ded1f12cab69909" name="tests/2.txt"/>
|
||||
<file role="test" baseinstalldir="/Text" md5sum="adbb8551c010b970f9feb184a023c79d" name="tests/diff.phpt"/>
|
||||
<file role="test" baseinstalldir="/Text" md5sum="7c2df75e9afc32c9fe4546f0322ebb0d" name="tests/inline.phpt"/>
|
||||
<file role="test" baseinstalldir="/Text" md5sum="3b1e784b27e9215081ec65340bc7621a" name="tests/inline2.phpt"/>
|
||||
<file role="test" baseinstalldir="/Text" md5sum="b8032a56a1ca4086caa4e90e76f1c486" name="tests/unified.phpt"/>
|
||||
<file role="test" baseinstalldir="/Text" md5sum="f71a1255bdc21a43f03ee070df7c99b9" name="tests/unified2.phpt"/>
|
||||
</filelist>
|
||||
</release>
|
||||
<changelog>
|
||||
<release>
|
||||
<version>0.0.4</version>
|
||||
<date>2004-10-13</date>
|
||||
<state>beta</state>
|
||||
<notes>* Generalized Diff Renderer parameter handling.
|
||||
* Added an inline renderer contributed by Ciprian Popovici (ciprian@zuavra.net).
|
||||
* Fixed PHPDoc.
|
||||
* Fixed a PHP 5 incompatibility.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.0.3</version>
|
||||
<date>2004-05-13</date>
|
||||
<state>alpha</state>
|
||||
<notes>Renamed final() and orig() methods to avoid conflict with final keyword in PHP5
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.0.2</version>
|
||||
<date>2004-03-16</date>
|
||||
<state>alpha</state>
|
||||
<notes>Added optional xdiff support
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.0.1</version>
|
||||
<date>2004-01-09</date>
|
||||
<state>alpha</state>
|
||||
<notes>Initial package release
|
||||
</notes>
|
||||
</release>
|
||||
* Fixed multiple calls to _endBlock per block (Bug 4065).</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.0.4</release>
|
||||
<api>0.0.4</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2004-10-13</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>* Generalized Diff Renderer parameter handling.
|
||||
* Added an inline renderer contributed by Ciprian Popovici (ciprian@zuavra.net).
|
||||
* Fixed PHPDoc.
|
||||
* Fixed a PHP 5 incompatibility.</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.0.3</release>
|
||||
<api>0.0.3</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>alpha</release>
|
||||
<api>alpha</api>
|
||||
</stability>
|
||||
<date>2004-05-13</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>Renamed final() and orig() methods to avoid conflict with final keyword in PHP5</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.0.2</release>
|
||||
<api>0.0.2</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>alpha</release>
|
||||
<api>alpha</api>
|
||||
</stability>
|
||||
<date>2004-03-16</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>Added optional xdiff support</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>0.0.1</release>
|
||||
<api>0.0.1</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>alpha</release>
|
||||
<api>alpha</api>
|
||||
</stability>
|
||||
<date>2004-01-09</date>
|
||||
<license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
|
||||
<notes>Initial package release</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
</package>
|
||||
@@ -1 +1 @@
|
||||
<html>␍<head><title>Invision Power Board - Bulletin Board System</title></head>␍<body>␍<h1>403: Invision Power Board -> Forbidden</h1>␍<hr>␍You have reached this Page in error, please use␍your back button to return to Invision Board.␍<hr>␍<a href="http://anonym.to/http://www.invisionboard.com/">Invision Power Board</a>␍</body>␍</html>
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* AJAX input parsing and handling
|
||||
* Last Updated: $Date: 2009-10-23 21:23:15 -0400 (Fri, 23 Oct 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 19th May 2006 17:33
|
||||
* @version $Revision: 341 $
|
||||
*/
|
||||
|
||||
|
||||
class classAjax
|
||||
{
|
||||
/**
|
||||
* XML output
|
||||
*
|
||||
* @var string Output
|
||||
* @access public
|
||||
*/
|
||||
public $xml_output;
|
||||
|
||||
/**
|
||||
* XML Header
|
||||
*
|
||||
* @var string XML doctype
|
||||
* @access public
|
||||
*/
|
||||
public $xml_header;
|
||||
|
||||
/**
|
||||
* Character sets
|
||||
*
|
||||
* @var array Charsets supported by html_entity_decode
|
||||
* @access private
|
||||
*/
|
||||
private $decodeCharsets = array( 'iso-8859-1' => 'ISO-8859-1',
|
||||
'iso8859-1' => 'ISO-8859-1',
|
||||
'iso-8859-15' => 'ISO-8859-15',
|
||||
'iso8859-15' => 'ISO-8859-15',
|
||||
'utf-8' => 'UTF-8',
|
||||
'cp866' => 'cp866',
|
||||
'ibm866' => 'cp866',
|
||||
'cp1251' => 'windows-1251',
|
||||
'windows-1251' => 'windows-1251',
|
||||
'win-1251' => 'windows-1251',
|
||||
'cp1252' => 'windows-1252',
|
||||
'windows-1252' => 'windows-1252',
|
||||
'koi8-r' => 'KOI8-R',
|
||||
'koi8-ru' => 'KOI8-R',
|
||||
'koi8r' => 'KOI8-R',
|
||||
'big5' => 'BIG5',
|
||||
'gb2312' => 'GB2312',
|
||||
'big5-hkscs' => 'BIG5-HKSCS',
|
||||
'shift_jis' => 'Shift_JIS',
|
||||
'sjis' => 'Shift_JIS',
|
||||
'euc-jp' => 'EUC-JP',
|
||||
'eucjp' => 'EUC-JP' );
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ( ! defined( 'IPS_DOC_CHAR_SET' ) )
|
||||
{
|
||||
define( 'IPS_DOC_CHAR_SET', 'UTF-8' );
|
||||
}
|
||||
|
||||
$this->xml_header = "<?xml version=\"1.0\" encoding=\"" . IPS_DOC_CHAR_SET . "\"?".'>';
|
||||
|
||||
/* Convert incoming $_POST fields */
|
||||
array_walk_recursive( $_POST, create_function( '&$value, $key', '$value = IPSText::convertUnicode($value);' ) );
|
||||
|
||||
// We use $_REQUEST in a lot of places, so we might need to do this, but based on the below comments I'll leave this
|
||||
// commented out for now...
|
||||
//array_walk_recursive( $_REQUEST, create_function( '&$value, $key', '$value = IPSText::convertUnicode($value);' ) );
|
||||
|
||||
/* Risky converting $_GET because it calls rawurldecode which could allow crafty users to hide html entities */
|
||||
//array_walk_recursive( $_GET , create_function( '&$value, $key', '$value = IPSText::convertUnicode($value);' ) );
|
||||
//array_walk_recursive( ipsRegistry::$request, create_function( '&$value, $key', '$value = IPSText::convertUnicode($value);' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert and make safe an incoming string
|
||||
*
|
||||
* @access public
|
||||
* @param string Raw input string
|
||||
* @param boolean Run through parse_incoming routine
|
||||
* @return string Cleaned string
|
||||
*/
|
||||
public function convertAndMakeSafe( $value, $parse_incoming=true )
|
||||
{
|
||||
$value = rawurldecode( $value );
|
||||
$value = $this->convertUnicode( $value );
|
||||
$value = $this->convertHtmlEntities( $value );
|
||||
|
||||
if( $parse_incoming )
|
||||
{
|
||||
$value = IPSText::parseCleanValue( $value );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an error
|
||||
*
|
||||
* @access public
|
||||
* @return void [Outputs XML document and exits]
|
||||
*/
|
||||
public function returnGenericError()
|
||||
{
|
||||
@header( "Content-type: text/xml" );
|
||||
$this->printNocacheHeaders();
|
||||
|
||||
$this->xml_output = $this->xml_header . "\r\n<errors>\r\n";
|
||||
$this->xml_output .= "<error><message>Вы должны быть залогинены для доступа к этой функции</message></error>\r\n";
|
||||
$this->xml_output .= "</errors>";
|
||||
|
||||
print $this->xml_output;
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a NULL result
|
||||
*
|
||||
* @access public
|
||||
* @param mixed Value to send
|
||||
* @return void [Outputs XML document and exits]
|
||||
*/
|
||||
public function returnNull( $val=0 )
|
||||
{
|
||||
@header( "Content-type: text/xml" );
|
||||
$this->printNocacheHeaders();
|
||||
|
||||
print $this->xml_header . "\r\n<null>{$val}</null>";
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string
|
||||
*
|
||||
* @access public
|
||||
* @param string String to output
|
||||
* @return void [Outputs plaintext string]
|
||||
*/
|
||||
public function returnString($string)
|
||||
{
|
||||
@header( "Content-type: text/plain;charset=" . IPS_DOC_CHAR_SET );
|
||||
$this->printNocacheHeaders();
|
||||
|
||||
print $string;
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSON error message
|
||||
*
|
||||
* @access public
|
||||
* @param string Error message
|
||||
* @return void [Outputs JSON string and exits]
|
||||
*/
|
||||
public function returnJsonError( $message )
|
||||
{
|
||||
$message = addslashes( $message );
|
||||
|
||||
@header( "Content-type: application/json;charset=" . IPS_DOC_CHAR_SET );
|
||||
$this->printNocacheHeaders();
|
||||
|
||||
print <<<EOF
|
||||
{
|
||||
'error' : "{$message}"
|
||||
}
|
||||
EOF;
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSON array
|
||||
*
|
||||
* @param array Single dimensional array of key => value fields
|
||||
* @return void [Outputs JSON string and exits]
|
||||
*/
|
||||
public function returnJsonArray( $json=array() )
|
||||
{
|
||||
@header( "Content-type: application/json;charset=" . IPS_DOC_CHAR_SET );
|
||||
$this->printNocacheHeaders();
|
||||
|
||||
/* Always return as UTF-8 */
|
||||
array_walk_recursive( $json, create_function( '&$value, $key', '$value = IPSText::convertCharsets($value, "' . IPS_DOC_CHAR_SET . '", "UTF-8");' ) );
|
||||
|
||||
$result = json_encode( $json );
|
||||
$result = IPSText::convertCharsets($result, "UTF-8", IPS_DOC_CHAR_SET);
|
||||
print $result;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML content
|
||||
*
|
||||
* @access public
|
||||
* @param string HTML to output
|
||||
* @return void [Outputs HTML and exits]
|
||||
*/
|
||||
public function returnHtml( $string )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Stop one from removing cookie protection
|
||||
//-----------------------------------------
|
||||
|
||||
$string = ( $string ) ? $string : '<!--nothing-->';
|
||||
$string = str_ireplace( "htmldocument.prototype", "HTMLDocument_prototype", $string );
|
||||
|
||||
// Fix IE bugs
|
||||
$string = str_ireplace( "§", "&sect", $string );
|
||||
|
||||
if ( strtolower( IPS_DOC_CHAR_SET ) == 'iso-8859-1' )
|
||||
{
|
||||
$string = str_replace( "ì", "“", $string );
|
||||
$string = str_replace( "î", "”", $string );
|
||||
}
|
||||
|
||||
// Other stuff
|
||||
$string = ipsRegistry::getClass('output')->replaceMacros( $string );
|
||||
|
||||
@header( "Content-type: text/html;charset=" . IPS_DOC_CHAR_SET );
|
||||
$this->printNocacheHeaders();
|
||||
|
||||
print $string;
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print nocache headers
|
||||
*
|
||||
* @access public
|
||||
* @return void [Outputs headers]
|
||||
*/
|
||||
public function printNocacheHeaders()
|
||||
{
|
||||
if ( isset( $_SERVER['SERVER_PROTOCOL'] ) AND strstr( $_SERVER['SERVER_PROTOCOL'], '/1.0' ) )
|
||||
{
|
||||
header( "HTTP/1.0 200 OK" );
|
||||
}
|
||||
else
|
||||
{
|
||||
header( "HTTP/1.1 200 OK" );
|
||||
}
|
||||
|
||||
header( "Cache-Control: no-cache, must-revalidate, max-age=0" );
|
||||
header( "Expires: 0" );
|
||||
header( "Pragma: no-cache" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert AJAX unicode to standard char codes
|
||||
*
|
||||
* @access public
|
||||
* @param string Input to convert
|
||||
* @return string UTF-8 Converted content
|
||||
*/
|
||||
public function convertUnicode( $t )
|
||||
{
|
||||
/* This is called at various stages through different ajax files but its no longer required */
|
||||
/* The ajax class cleans up (converts via IPSText::convertUnicode()) the post get and input vars in the constructor now so we don't need to manually use it */
|
||||
|
||||
return $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert HTML entities into raw characters
|
||||
*
|
||||
* @access public
|
||||
* @param string Input to convert
|
||||
* @return string HTML entity decoded content
|
||||
*/
|
||||
public function convertHtmlEntities($t)
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Try and fix up HTML entities with missing ;
|
||||
//-----------------------------------------
|
||||
|
||||
$t = preg_replace( "/&#(\d+?)([^\d;])/i", "&#\\1;\\2", $t );
|
||||
|
||||
//-----------------------------------------
|
||||
// Continue...
|
||||
//-----------------------------------------
|
||||
|
||||
if ( strtolower(IPS_DOC_CHAR_SET) != 'iso-8859-1' && strtolower(IPS_DOC_CHAR_SET) != 'utf-8' )
|
||||
{
|
||||
if ( isset($this->decodeCharsets[ strtolower(IPS_DOC_CHAR_SET) ]) )
|
||||
{
|
||||
$IPS_DOC_CHAR_SET = $this->decodeCharsets[strtolower(IPS_DOC_CHAR_SET)];
|
||||
|
||||
$t = html_entity_decode( $t, ENT_NOQUOTES, IPS_DOC_CHAR_SET );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take a crack at entities in other character sets
|
||||
|
||||
$t = str_replace( "&#", "&#", $t );
|
||||
|
||||
// If mb functions available, we can knock out html entities for a few more char sets
|
||||
|
||||
if( function_exists('mb_list_encodings') )
|
||||
{
|
||||
$valid_encodings = array();
|
||||
$valid_encodings = mb_list_encodings();
|
||||
|
||||
if( count($valid_encodings) )
|
||||
{
|
||||
if( in_array( strtoupper(IPS_DOC_CHAR_SET), $valid_encodings ) )
|
||||
{
|
||||
$t = mb_convert_encoding( $t, strtoupper(IPS_DOC_CHAR_SET), 'HTML-ENTITIES' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $t;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power KERNEL
|
||||
| Invision Power Board
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2006 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
| INVISION POWER BOARD IS NOT FREE SOFTWARE!
|
||||
| http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > API SERVER: Send and receive API data
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Friday 6th January 2006 (12:24)
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class API SERVER
|
||||
*
|
||||
* Class to send and receive API data
|
||||
* <code>
|
||||
* # APPLICATION: SEND AN API REQUEST AND PARSE DATA
|
||||
* $api_server->api_send_request( 'http://www.domain.com/xmlrpc.php', 'get_members', array( 'name' => 'matt', 'email' => 'matt@email.com' ) );
|
||||
* # APPLICATION: PICK UP REPLY AND PARSE
|
||||
* print_r( $api_server->params );
|
||||
*
|
||||
* # SERVER: PARSE DATA, MAKE DATA AND RETURN
|
||||
* $api_server->api_decode_request( $_SERVER['RAW_HTTP_POST_DATA'] );
|
||||
* print $api_server->method_name;
|
||||
* print_r( $api_server->params );
|
||||
* # SERVER: SEND DATA BACK
|
||||
* # Is complex array, so we choose to encode and send with the , 1 flag
|
||||
* $api_server->api_send_reply( array( 'matt' => array( 'email' => 'matt@email.com', 'joined' => '01-01-2005' ) ), 1 );
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* This class can act as an API server, handling API requests
|
||||
* Last Updated: $Date: 2009-10-01 10:02:41 -0400 (Thu, 01 Oct 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 6th January 2006 (12:24)
|
||||
* @version $Revision: 334 $
|
||||
*
|
||||
* Examples of sending and receiving API data
|
||||
* <code>
|
||||
* # APPLICATION: SEND AN API REQUEST AND PARSE DATA
|
||||
* $api_server->apiSendRequest( 'http://www.domain.com/xmlrpc.php', 'get_members', array( 'name' => 'matt', 'email' => 'matt@email.com' ) );
|
||||
* # APPLICATION: PICK UP REPLY AND PARSE
|
||||
* print_r( $api_server->params );
|
||||
*
|
||||
* # SERVER: PARSE DATA, MAKE DATA AND RETURN
|
||||
* $api_server->apiDecodeRequest( $_SERVER['RAW_HTTP_POST_DATA'] );
|
||||
* print $api_server->method_name;
|
||||
* print_r( $api_server->params );
|
||||
* # SERVER: SEND DATA BACK
|
||||
* # Is complex array, so we choose to encode and send with the , 1 flag
|
||||
* $api_server->apiSendReply( array( 'matt' => array( 'email' => 'matt@email.com', 'joined' => '01-01-2005' ) ), 1 );
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
@@ -53,84 +40,131 @@ if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class API Server
|
||||
*
|
||||
* Easy method of getting and sending data
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_api_server
|
||||
class classApiServer
|
||||
{
|
||||
/**
|
||||
* XML-RPC class
|
||||
* @var object
|
||||
*
|
||||
* @access public
|
||||
* @var object
|
||||
*/
|
||||
var $xmlrpc;
|
||||
public $xmlrpc;
|
||||
|
||||
/**
|
||||
* Raw incoming data
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
public $raw_request;
|
||||
|
||||
/**
|
||||
* Requested method name
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $method_name;
|
||||
|
||||
/**
|
||||
* Raw data incoming
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_raw_in_data;
|
||||
|
||||
/**
|
||||
* Raw data output
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_raw_out_data;
|
||||
|
||||
/**
|
||||
* Method params
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $params = array();
|
||||
|
||||
/**
|
||||
* XML-RPC serialized 64 key
|
||||
* @var string
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $serialized_key = '__serialized64__';
|
||||
private $serialized_key = '__serialized64__';
|
||||
|
||||
/**
|
||||
* Server function object
|
||||
* @var object
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
var $xml_server;
|
||||
private $xml_server;
|
||||
|
||||
/**
|
||||
* Return cookie information
|
||||
* @var array
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
var $cookies = array();
|
||||
public $cookies = array();
|
||||
|
||||
/**
|
||||
* XML-RPC cookie serialized 64 key
|
||||
* @var string
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $cookie_serialized_key = '__cookie__serialized64__';
|
||||
private $cookie_serialized_key = '__cookie__serialized64__';
|
||||
|
||||
/**
|
||||
* HTTP Auth required
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
var $auth_user = '';
|
||||
var $auth_pass = '';
|
||||
public $auth_user = '';
|
||||
public $auth_pass = '';
|
||||
|
||||
/**
|
||||
* Errors array
|
||||
* @var array
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
var $errors = array();
|
||||
public $errors = array();
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Constructor
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_api_server()
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ( ! is_object( $this->xmlrpc ) )
|
||||
{
|
||||
require_once( IPS_CLASSES_PATH . '/class_xml_rpc.php' );
|
||||
$this->xmlrpc = new class_xml_rpc();
|
||||
require_once( IPS_KERNEL_PATH . '/classXmlRpc.php' );
|
||||
$this->xmlrpc = new classXmlRpc();
|
||||
}
|
||||
|
||||
$this->cookies = array();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// MIMIC SOAP SERVER: Decode request
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Add object map to this class
|
||||
*
|
||||
* @access public
|
||||
* @param string Incoming data
|
||||
* @return string api
|
||||
*/
|
||||
function decode_request( $incoming='' )
|
||||
public function decodeRequest( $incoming='' )
|
||||
{
|
||||
if ( ! $incoming )
|
||||
{
|
||||
@@ -148,7 +182,7 @@ class class_api_server
|
||||
// Get data and dispatch
|
||||
//-----------------------------------------
|
||||
|
||||
$this->api_decode_request( $incoming );
|
||||
$this->apiDecodeRequest( $incoming );
|
||||
|
||||
$this->raw_request = $incoming;
|
||||
|
||||
@@ -162,49 +196,46 @@ class class_api_server
|
||||
}
|
||||
else
|
||||
{
|
||||
return "default";
|
||||
return 'default';
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// MIMIC SOAP SERVER: Add object map
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Add object map to this class
|
||||
*
|
||||
* @param object Server class object
|
||||
* @param string Document type
|
||||
* @return boolean
|
||||
*/
|
||||
function add_object_map( $server_class, $doc_type='UTF-8' )
|
||||
* Add object map to this class
|
||||
*
|
||||
* @access public
|
||||
* @param object Server class object
|
||||
* @param string Document type
|
||||
* @return boolean
|
||||
*/
|
||||
public function addObjectMap( $server_class, $doc_type='UTF-8' )
|
||||
{
|
||||
$this->xmlrpc->doc_type = $doc_type;
|
||||
|
||||
if ( is_object( $server_class ) )
|
||||
{
|
||||
$this->xml_server =& $server_class;
|
||||
return TRUE;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// MIMIC SOAP SERVER: get_xmlRPC
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Add object map to this class
|
||||
* Get the XML-RPC data
|
||||
*
|
||||
* @param string Incoming data
|
||||
* @return boolean
|
||||
* @access public
|
||||
* @param string Incoming data
|
||||
* @return mixed Boolean, Output error
|
||||
*/
|
||||
function get_xml_rpc( $incoming='' )
|
||||
public function getXmlRpc( $incoming='' )
|
||||
{
|
||||
if ( ! $this->xml_server )
|
||||
{
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
@@ -269,40 +300,36 @@ class class_api_server
|
||||
// Return false
|
||||
//-----------------------------------------
|
||||
|
||||
$this->api_send_error( 100, 'No methodRequest function -' . htmlspecialchars( $this->method_name ) . ' defined / found' );
|
||||
$this->apiSendError( 100, 'No methodRequest function -' . htmlspecialchars( $this->method_name ) . ' defined / found' );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Add cookies
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Return API Request
|
||||
* Set a cookie for the API request
|
||||
*
|
||||
* @param array Array of params to send
|
||||
* @param int Complex data: Encode before sending
|
||||
* @return nuffink
|
||||
* @access public
|
||||
* @param array Array of params to send
|
||||
* @return void
|
||||
*/
|
||||
function api_add_cookie_data( $data )
|
||||
public function apiAddCookieData( $data )
|
||||
{
|
||||
if ( $data['name'] )
|
||||
{
|
||||
$this->cookies[ $data['name'] ] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return API Request
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Return API Request
|
||||
*
|
||||
* @param array Array of params to send
|
||||
* @param int Complex data: Encode before sending
|
||||
* @return nuffink
|
||||
* @access public
|
||||
* @param array Array of params to send
|
||||
* @param int Complex data: Encode before sending
|
||||
* @param array Forced data type mapping
|
||||
* @return void
|
||||
*/
|
||||
function api_send_reply( $data=array(), $complex_data=0, $force=array() )
|
||||
public function apiSendReply( $data=array(), $complex_data=0, $force=array() )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Cookies?
|
||||
@@ -310,7 +337,7 @@ class class_api_server
|
||||
|
||||
if ( is_array( $this->cookies ) AND count( $this->cookies ) )
|
||||
{
|
||||
$data[ $this->cookie_serialized_key ] = $this->encode_base64_array( $this->cookies );
|
||||
$data[ $this->cookie_serialized_key ] = $this->_encodeBase64Array( $this->cookies );
|
||||
$this->xmlrpc->map_type_to_key[ $this->cookie_serialized_key ] = 'base64';
|
||||
}
|
||||
|
||||
@@ -320,12 +347,12 @@ class class_api_server
|
||||
|
||||
if ( ! is_array( $data ) )
|
||||
{
|
||||
$this->xmlrpc->xml_rpc_return_value( $data );
|
||||
$this->xmlrpc->returnValue( $data );
|
||||
}
|
||||
elseif ( ! count( $data ) )
|
||||
{
|
||||
# No data? Just return true
|
||||
$this->xmlrpc->xml_rpc_return_true();
|
||||
$this->xmlrpc->returnTrue();
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
@@ -336,7 +363,7 @@ class class_api_server
|
||||
{
|
||||
$_tmp = $data;
|
||||
$data = array();
|
||||
$data[ $this->serialized_key ] = $this->encode_base64_array( $_tmp );
|
||||
$data[ $this->serialized_key ] = $this->_encodeBase64Array( $_tmp );
|
||||
$this->xmlrpc->map_type_to_key[ $this->serialized_key ] = 'base64';
|
||||
}
|
||||
|
||||
@@ -356,65 +383,55 @@ class class_api_server
|
||||
// Send...
|
||||
//-----------------------------------------
|
||||
|
||||
$this->xmlrpc->xml_rpc_return_params( $data );
|
||||
$this->xmlrpc->returnParams( $data );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return API Request( ERROR )
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Return API Request (ERROR)
|
||||
*
|
||||
* @param int Error Code
|
||||
* @param string Error message
|
||||
* @return nuffink
|
||||
* @access public
|
||||
* @param int Error Code
|
||||
* @param string Error message
|
||||
* @return void
|
||||
*/
|
||||
function api_send_error( $error_code, $error_msg )
|
||||
public function apiSendError( $error_code, $error_msg )
|
||||
{
|
||||
$this->xmlrpc->xml_rpc_return_error( $error_code, $error_msg );
|
||||
$this->xmlrpc->returnError( $error_code, $error_msg );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Decode API Request
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Decode API Request
|
||||
*
|
||||
* @param string Raw data picked up
|
||||
* @return notsure
|
||||
* @access public
|
||||
* @param string Raw data picked up
|
||||
* @return void
|
||||
*/
|
||||
function api_decode_request( $raw_data )
|
||||
public function apiDecodeRequest( $raw_data )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
//-----------------------------------------
|
||||
// Get data...
|
||||
//-----------------------------------------
|
||||
|
||||
$raw = $this->xmlrpc->xml_rpc_decode( $raw_data );
|
||||
$raw = $this->xmlrpc->decodeXmlRpc( $raw_data );
|
||||
|
||||
//-----------------------------------------
|
||||
// Process return data
|
||||
//-----------------------------------------
|
||||
|
||||
$this->api_process_data( $raw );
|
||||
$this->apiProcessData( $raw );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Send API Request
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Send API Request
|
||||
*
|
||||
* @param string URL to send request to
|
||||
* @param string Method name for API to pick up
|
||||
* @param array Data to send
|
||||
* @param int Complex data: Encode before sending
|
||||
* @return notsure
|
||||
* @access public
|
||||
* @param string URL to send request to
|
||||
* @param string Method name for API to pick up
|
||||
* @param array Data to send
|
||||
* @param int Complex data: Encode before sending
|
||||
* @return boolean Data sent successfully
|
||||
*/
|
||||
function api_send_request( $url, $method_name, $data=array(), $complex_data=0 )
|
||||
public function apiSendRequest( $url, $method_name, $data=array(), $complex_data=0 )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
@@ -432,7 +449,7 @@ class class_api_server
|
||||
|
||||
if ( is_array( $this->cookies ) AND count( $this->cookies ) )
|
||||
{
|
||||
$data[ $this->cookie_serialized_key ] = $this->encode_base64_array( $this->cookies );
|
||||
$data[ $this->cookie_serialized_key ] = $this->_encodeBase64Array( $this->cookies );
|
||||
$this->xmlrpc->map_type_to_key[ $this->cookie_serialized_key ] = 'base64';
|
||||
}
|
||||
|
||||
@@ -444,7 +461,7 @@ class class_api_server
|
||||
{
|
||||
$_tmp = $data;
|
||||
$data = array();
|
||||
$data[ $this->serialized_key ] = $this->encode_base64_array( $_tmp );
|
||||
$data[ $this->serialized_key ] = $this->_encodeBase64Array( $_tmp );
|
||||
$this->xmlrpc->map_type_to_key[ $this->serialized_key ] = 'base64';
|
||||
}
|
||||
|
||||
@@ -452,38 +469,38 @@ class class_api_server
|
||||
// Get data...
|
||||
//-----------------------------------------
|
||||
|
||||
$return_data = $this->xmlrpc->xml_rpc_send( $url, $method_name, $data );
|
||||
$return_data = $this->xmlrpc->sendXmlRpc( $url, $method_name, $data );
|
||||
|
||||
if ( count( $this->xmlrpc->errors ) )
|
||||
{
|
||||
$this->errors = $this->xmlrpc->errors;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Process return data
|
||||
//-----------------------------------------
|
||||
|
||||
$this->api_process_data( $return_data );
|
||||
$this->apiProcessData( $return_data );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Process returned data
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Process returned data
|
||||
*
|
||||
* @param array Raw array
|
||||
* @return array Cleaned array
|
||||
* @access public
|
||||
* @param array Raw array
|
||||
* @return array Cleaned array
|
||||
*/
|
||||
function api_process_data( $raw=array() )
|
||||
public function apiProcessData( $raw=array() )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$_params = $this->xmlrpc->xml_rpc_get_params( $raw );
|
||||
$this->method_name = $this->xmlrpc->xml_rpc_get_method_name( $raw );
|
||||
$_params = $this->xmlrpc->getParams( $raw );
|
||||
$this->method_name = $this->xmlrpc->getMethodName( $raw );
|
||||
$this->params = array();
|
||||
$this->_raw_in_data = var_export( $raw, TRUE );
|
||||
$this->_raw_out_data = var_export( $_params, TRUE );
|
||||
@@ -494,8 +511,8 @@ class class_api_server
|
||||
|
||||
if ( IPS_XML_RPC_DEBUG_ON )
|
||||
{
|
||||
$this->xmlrpc->_add_debug( "API_PROCESS_DECODE: IN PARAMS: " . var_export( $raw, TRUE ) );
|
||||
$this->xmlrpc->_add_debug( "API_PROCESS_DECODE: OUT PARAMS: " . var_export( $_params, TRUE ) );
|
||||
$this->xmlrpc->addDebug( "API_PROCESS_DECODE: IN PARAMS: " . var_export( $raw, TRUE ) );
|
||||
$this->xmlrpc->addDebug( "API_PROCESS_DECODE: OUT PARAMS: " . var_export( $_params, TRUE ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
@@ -508,7 +525,7 @@ class class_api_server
|
||||
{
|
||||
if ( $k != '' && $k == $this->serialized_key )
|
||||
{
|
||||
$_tmp = $this->decode_base64_array( $v );
|
||||
$_tmp = $this->_decodeBase64Array( $v );
|
||||
|
||||
if ( is_array( $_tmp ) and count( $_tmp ) )
|
||||
{
|
||||
@@ -517,7 +534,7 @@ class class_api_server
|
||||
}
|
||||
else if ( $k != '' && $k == $this->cookie_serialized_key )
|
||||
{
|
||||
$_cookies = $this->decode_base64_array( $v );
|
||||
$_cookies = $this->_decodeBase64Array( $v );
|
||||
|
||||
if ( is_array( $_cookies ) and count( $_cookies ) )
|
||||
{
|
||||
@@ -534,7 +551,7 @@ class class_api_server
|
||||
|
||||
if ( IPS_XML_RPC_DEBUG_ON )
|
||||
{
|
||||
$this->xmlrpc->_add_debug( "API_PROCESS_DECODE: SETTING COOKIE: " . var_export( $cookie_data, TRUE ) );
|
||||
$this->xmlrpc->addDebug( "API_PROCESS_DECODE: SETTING COOKIE: " . var_export( $cookie_data, TRUE ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -555,45 +572,42 @@ class class_api_server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Encode array
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Encode array
|
||||
*
|
||||
* @access private
|
||||
* @param array Raw array
|
||||
* @return string Encoded string
|
||||
*/
|
||||
function encode_base64_array( $array )
|
||||
private function _encodeBase64Array( $array )
|
||||
{
|
||||
return base64_encode( serialize( $array ) );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Dencode array
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Dencode array
|
||||
* Decode array
|
||||
*
|
||||
* @access private
|
||||
* @param string Encoded string
|
||||
* @return array Raw array
|
||||
*/
|
||||
function decode_base64_array( $data )
|
||||
private function _decodeBase64Array( $data )
|
||||
{
|
||||
if ( ! is_array( $data ) )
|
||||
{
|
||||
return unserialize( base64_decode( $data ) );
|
||||
//return unserialize( base64_decode( $data ) );
|
||||
/**
|
||||
* @see http://community.invisionpower.com/tracker/issue-18676-xml-rpcapiserver-params-not-unserialized/
|
||||
* base64 data types are properly base-64 decoded in the XML-RPC library now, so it is redundant to do so here now
|
||||
*/
|
||||
return unserialize( $data );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* This class acts as a cache layer, allowing you to store and retrieve data in
|
||||
* external cache sources such as memcache or APC
|
||||
* Last Updated: $Date: 2009-07-07 21:22:30 -0400 (Tue, 07 Jul 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 19th May 2006 17:33
|
||||
* @version $Revision: 291 $
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $cache->putInCache( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $cache->removeFromCache( 'key' );
|
||||
* Retrieve
|
||||
* $cache->getFromCache( 'key' );
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
class classCacheApc implements interfaceCache
|
||||
{
|
||||
/**
|
||||
* Identifier
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $identifier = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string Unique identifier
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function __construct( $identifier='' )
|
||||
{
|
||||
if( !function_exists('apc_fetch') )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put data into remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to add
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function putInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
$ttl = $ttl > 0 ? intval($ttl) : 0;
|
||||
|
||||
return apc_store( md5( $this->identifier . $key ), $value, $ttl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value from remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return mixed Cached value
|
||||
*/
|
||||
public function getFromCache( $key )
|
||||
{
|
||||
return apc_fetch( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update value in remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to set
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function updateInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
$this->removeFromCache( $key );
|
||||
return $this->putInCache( $key, $value, $ttl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a value in the remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return boolean Cache removal successful
|
||||
*/
|
||||
public function removeFromCache( $key )
|
||||
{
|
||||
return apc_delete( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used by this library
|
||||
*
|
||||
* @return boolean Disconnect successful
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* This class acts as a cache layer, allowing you to store and retrieve data in
|
||||
* external cache sources such as memcache or APC
|
||||
* Last Updated: $Date: 2009-07-07 21:22:30 -0400 (Tue, 07 Jul 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 19th May 2006 17:33
|
||||
* @version $Revision: 291 $
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $cache->putInCache( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $cache->removeFromCache( 'key' );
|
||||
* Retrieve
|
||||
* $cache->getFromCache( 'key' );
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
class classCacheDiskcache implements interfaceCache
|
||||
{
|
||||
/**
|
||||
* Identifier
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $identifier = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string Unique identifier
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function __construct( $identifier='' )
|
||||
{
|
||||
if( !is_writeable( DOC_IPS_ROOT_PATH . 'cache' ) )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !file_exists( DOC_IPS_ROOT_PATH . 'cache/diskcache_lock.php' ) )
|
||||
{
|
||||
$fh = @fopen( DOC_IPS_ROOT_PATH . 'cache/diskcache_lock.php', 'wb' );
|
||||
|
||||
if( $fh )
|
||||
{
|
||||
flock( $fh, LOCK_EX );
|
||||
fwrite( $fh, 0 );
|
||||
flock( $fh, LOCK_UN );
|
||||
fclose( $fh );
|
||||
}
|
||||
}
|
||||
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put data into remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to add
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function putInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
$lock = @fopen( DOC_IPS_ROOT_PATH . 'cache/diskcache_lock.php', 'wb' );
|
||||
|
||||
if( $lock )
|
||||
{
|
||||
flock( $lock, LOCK_EX );
|
||||
}
|
||||
|
||||
$fh = @fopen( DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php', 'wb' );
|
||||
|
||||
if( !$fh )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$extra_flag = "";
|
||||
|
||||
if( is_array( $value ) )
|
||||
{
|
||||
$value = serialize($value);
|
||||
$extra_flag = "\n" . '$is_array = 1;' . "\n\n";
|
||||
}
|
||||
|
||||
$extra_flag .= "\n" . '$ttl = ' . $ttl . ";\n\n";
|
||||
|
||||
$value = '"' . addslashes( $value ) . '"';
|
||||
|
||||
$file_content = "<?" . "php\n\n" . '$value = ' . $value . ";\n" . $extra_flag . "\n?" . '>';
|
||||
|
||||
flock( $fh, LOCK_EX );
|
||||
fwrite( $fh, $file_content );
|
||||
flock( $fh, LOCK_UN );
|
||||
fclose( $fh );
|
||||
|
||||
@chmod( DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php', 0777 );
|
||||
|
||||
flock( $lock, LOCK_UN );
|
||||
fclose( $lock );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value from remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return mixed Cached value
|
||||
*/
|
||||
public function getFromCache( $key )
|
||||
{
|
||||
$lock = @fopen( DOC_IPS_ROOT_PATH . 'cache/diskcache_lock.php', 'wb' );
|
||||
|
||||
if( $lock )
|
||||
{
|
||||
flock( $lock, LOCK_SH );
|
||||
}
|
||||
|
||||
$return_val = "";
|
||||
|
||||
if( file_exists( DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php' ) )
|
||||
{
|
||||
require DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php';
|
||||
|
||||
$return_val = stripslashes($value);
|
||||
|
||||
if( isset($is_array) AND $is_array == 1 )
|
||||
{
|
||||
$return_val = unserialize($return_val);
|
||||
}
|
||||
|
||||
if( isset($ttl) AND $ttl > 0 )
|
||||
{
|
||||
if( $mtime = filemtime( DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php' ) )
|
||||
{
|
||||
if( time() - $mtime > $ttl )
|
||||
{
|
||||
@unlink( DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php' );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flock( $lock, LOCK_UN );
|
||||
fclose( $lock );
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update value in remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to set
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function updateInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
// The putInCache method opens in 'wb' mode, meaning
|
||||
// the file is truncated automatically, so no
|
||||
// need to delete - deletion is an unnecessary
|
||||
// expense with diskcache
|
||||
|
||||
return $this->putInCache( $key, $value, $ttl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a value in the remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return boolean Cache removal successful
|
||||
*/
|
||||
public function removeFromCache( $key )
|
||||
{
|
||||
$lock = @fopen( DOC_IPS_ROOT_PATH . 'cache/diskcache_lock.php', 'wb' );
|
||||
|
||||
if( $lock )
|
||||
{
|
||||
flock( $lock, LOCK_EX );
|
||||
}
|
||||
|
||||
if( file_exists( DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php' ) )
|
||||
{
|
||||
@unlink( DOC_IPS_ROOT_PATH . 'cache/' . md5( $this->identifier . $key ) . '.php' );
|
||||
}
|
||||
|
||||
flock( $lock, LOCK_UN );
|
||||
fclose( $lock );
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used by this library
|
||||
*
|
||||
* @return boolean Disconnect successful
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* This class acts as a cache layer, allowing you to store and retrieve data in
|
||||
* external cache sources such as memcache or APC
|
||||
* Last Updated: $Date: 2009-07-07 21:22:30 -0400 (Tue, 07 Jul 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 19th May 2006 17:33
|
||||
* @version $Revision: 291 $
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $cache->putInCache( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $cache->removeFromCache( 'key' );
|
||||
* Retrieve
|
||||
* $cache->getFromCache( 'key' );
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
class classCacheEaccelerator implements interfaceCache
|
||||
{
|
||||
/**
|
||||
* Identifier
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $identifier = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string Unique identifier
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function __construct( $identifier='' )
|
||||
{
|
||||
if( !function_exists('eaccelerator_get') )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Disconnect successful
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if( function_exists( 'eaccelerator_gc' ) )
|
||||
{
|
||||
eaccelerator_gc();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put data into remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to add
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function putInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
eaccelerator_lock( md5( $this->identifier . $key ) );
|
||||
$check = eaccelerator_put( md5( $this->identifier . $key ), $value, intval($ttl) );
|
||||
eaccelerator_unlock( md5( $this->identifier . $key ) );
|
||||
|
||||
return $check;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value from remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return mixed Cached value
|
||||
*/
|
||||
public function getFromCache( $key )
|
||||
{
|
||||
return eaccelerator_get( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update value in remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to set
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function updateInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
$this->removeFromCache( $key );
|
||||
return $this->putInCache( $key, $value, $ttl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a value in the remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return boolean Cache removal successful
|
||||
*/
|
||||
public function removeFromCache( $key )
|
||||
{
|
||||
return eaccelerator_rm( md5( $this->identifier . $key ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* This class acts as a cache layer, allowing you to store and retrieve data in
|
||||
* external cache sources such as memcache or APC
|
||||
* Last Updated: $Date: 2009-07-07 21:22:30 -0400 (Tue, 07 Jul 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 19th May 2006 17:33
|
||||
* @version $Revision: 291 $
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $cache->putInCache( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $cache->removeFromCache( 'key' );
|
||||
* Retrieve
|
||||
* $cache->getFromCache( 'key' );
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
class classCacheMemcache implements interfaceCache
|
||||
{
|
||||
/**
|
||||
* Identifier
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $identifier = '';
|
||||
|
||||
/**
|
||||
* Connection resource
|
||||
*
|
||||
* @access private
|
||||
* @var resource Connection resource
|
||||
*/
|
||||
private $link = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string Unique identifier
|
||||
* @param array Connection information
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function __construct( $identifier='', $server_info=array() )
|
||||
{
|
||||
if( !function_exists('memcache_connect') )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->identifier = $identifier;
|
||||
|
||||
return $this->_connect( $server_info );
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to memcache server
|
||||
*
|
||||
* @access private
|
||||
* @param array Connection information
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
private function _connect( $server_info=array() )
|
||||
{
|
||||
if( !count($server_info) )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !isset($server_info['memcache_server_1']) OR !isset($server_info['memcache_port_1']) )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->link = memcache_connect( $server_info['memcache_server_1'], $server_info['memcache_port_1'] );
|
||||
|
||||
if( !$this->link )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( isset($server_info['memcache_server_2']) AND isset($server_info['memcache_port_2']) )
|
||||
{
|
||||
memcache_add_server( $this->link, $server_info['memcache_server_2'], $server_info['memcache_port_2'] );
|
||||
}
|
||||
|
||||
if( isset($server_info['memcache_server_3']) AND isset($server_info['memcache_port_3']) )
|
||||
{
|
||||
memcache_add_server( $this->link, $server_info['memcache_server_3'], $server_info['memcache_port_3'] );
|
||||
}
|
||||
|
||||
if( function_exists('memcache_set_compress_threshold') )
|
||||
{
|
||||
memcache_set_compress_threshold( $this->link, 20000, 0.2 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Disconnect successful
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if( $this->link )
|
||||
{
|
||||
return memcache_close( $this->link );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put data into remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to add
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function putInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
return memcache_set( $this->link, md5( $this->identifier . $key ), $value, MEMCACHE_COMPRESSED, intval($ttl) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value from remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return mixed Cached value
|
||||
*/
|
||||
public function getFromCache( $key )
|
||||
{
|
||||
return memcache_get( $this->link, md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update value in remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to set
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function updateInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
$this->removeFromCache( $key );
|
||||
return $this->putInCache( $key, $value, $ttl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a value in the remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return boolean Cache removal successful
|
||||
*/
|
||||
public function removeFromCache( $key )
|
||||
{
|
||||
return memcache_delete( $this->link, md5( $this->identifier . $key ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* This class acts as a cache layer, allowing you to store and retrieve data in
|
||||
* external cache sources such as memcache or APC
|
||||
* Last Updated: $Date: 2009-07-07 21:22:30 -0400 (Tue, 07 Jul 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 19th May 2006 17:33
|
||||
* @version $Revision: 291 $
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $cache->putInCache( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $cache->removeFromCache( 'key' );
|
||||
* Retrieve
|
||||
* $cache->getFromCache( 'key' );
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
class classCacheXcache implements interfaceCache
|
||||
{
|
||||
/**
|
||||
* Identifier
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $identifier = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string Unique identifier
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function __construct( $identifier='' )
|
||||
{
|
||||
if( !function_exists('xcache_get') )
|
||||
{
|
||||
$this->crashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put data into remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to add
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function putInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
$ttl = $ttl > 0 ? intval($ttl) : '';
|
||||
|
||||
if( $ttl )
|
||||
{
|
||||
return xcache_set( md5( $this->identifier . $key ), $value, $ttl );
|
||||
}
|
||||
else
|
||||
{
|
||||
return xcache_set( md5( $this->identifier . $key ), $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value from remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return mixed Cached value
|
||||
*/
|
||||
public function getFromCache( $key )
|
||||
{
|
||||
$return_val = "";
|
||||
|
||||
if( xcache_isset( md5( $this->identifier . $key ) ) )
|
||||
{
|
||||
$return_val = xcache_get( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update value in remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @param string Cache value to set
|
||||
* @param integer [Optional] Time to live
|
||||
* @return boolean Cache update successful
|
||||
*/
|
||||
public function updateInCache( $key, $value, $ttl=0 )
|
||||
{
|
||||
$this->removeFromCache( $key );
|
||||
return $this->putInCache( $key, $value, $ttl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a value in the remote cache store
|
||||
*
|
||||
* @access public
|
||||
* @param string Cache unique key
|
||||
* @return boolean Cache removal successful
|
||||
*/
|
||||
public function removeFromCache( $key )
|
||||
{
|
||||
return xcache_unset( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used by this library
|
||||
*
|
||||
* @return boolean Disconnect successful
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* CAPTCHA abstraction - easily create, check and display CAPTHCA images
|
||||
* Last Updated: $Date: 2009-02-05 15:14:40 -0500 (Thu, 05 Feb 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 19th May 2006 17:33
|
||||
* @version $Revision: 224 $
|
||||
*/
|
||||
|
||||
class classCaptcha
|
||||
{
|
||||
/**
|
||||
* Registry object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $registry;
|
||||
|
||||
/**
|
||||
* Database object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $DB;
|
||||
|
||||
/**
|
||||
* Settings object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Request object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Language object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $lang;
|
||||
|
||||
/**
|
||||
* Member object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $member;
|
||||
|
||||
/**
|
||||
* Member data object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $memberData;
|
||||
|
||||
/**
|
||||
* Plug in class
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
private $_plugInClass;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param object ipsRegistry
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( ipsRegistry $registry )
|
||||
{
|
||||
$this->registry = $registry;
|
||||
$this->DB = $this->registry->DB();
|
||||
$this->settings =& $this->registry->fetchSettings();
|
||||
$this->request =& $this->registry->fetchRequest();
|
||||
$this->lang = $this->registry->getClass('class_localization');
|
||||
$this->member = $this->registry->member();
|
||||
$this->memberData =& $this->registry->member()->fetchMemberData();
|
||||
|
||||
$plugin = $this->settings['bot_antispam_type'];
|
||||
|
||||
if ( ! file_exists( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' ) )
|
||||
{
|
||||
$plugin = 'default';
|
||||
}
|
||||
|
||||
require_once( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' );
|
||||
$this->_plugInClass = new captchaPlugIn( $registry );
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Call method
|
||||
*
|
||||
* @param string Method Name
|
||||
* @param mixed Method arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call( $method, $arguments )
|
||||
{
|
||||
if ( method_exists( $this->_plugInClass, $method ) )
|
||||
{
|
||||
return $this->_plugInClass->$method( $arguments );
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error( $method . " не существует", E_USER_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic __get method
|
||||
*
|
||||
* @access public
|
||||
* @param mixed
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $name )
|
||||
{
|
||||
if ( property_exists( $this->_plugInClass, $name ) )
|
||||
{
|
||||
return $this->_plugInClass->$name;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error( $name . " не существует", E_USER_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+263
-239
@@ -1,109 +1,159 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power Dynamic v1.0.0
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2004 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
| INVISION POWER DYNAMIC IS NOT FREE SOFTWARE!
|
||||
| http://www.invisionpower.com/dynamic/
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Id$
|
||||
| > $Revision: 128 $
|
||||
| > $Date: 2006-01-20 12:46:26 +0000 (Fri, 20 Jan 2006) $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > CAPTCHA ANTI-SPAM CLASS
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Thursday 2 February (11:08)
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* CAPTCHA CLASS
|
||||
* PLUG IN: Default GD image
|
||||
* @package IPDYNAMIC
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 1.0
|
||||
*/
|
||||
* CAPTCHA CLASS
|
||||
* Database Table
|
||||
* <code>
|
||||
* CREATE TABLE captcha (
|
||||
* captcha_unique_id VARCHAR(32) NOT NULL default '',
|
||||
* captcha_string VARCHAR(100) NOT NULL default '',
|
||||
* captcha_ipaddress VARCHAR(16) NOT NULL default '',
|
||||
* captcha_date INT(10) NOT NULL default '',
|
||||
* PRIMARY KEY (captcha_unique_id )
|
||||
* );
|
||||
* </code>
|
||||
* PLUG IN: Default GD image
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* @package Invision Power Services Kernel
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class captchaPlugin
|
||||
{
|
||||
/**
|
||||
* Global IPS class array
|
||||
* @var object
|
||||
*/
|
||||
var $ipsclass;
|
||||
* GD version
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $gd_version = 0;
|
||||
|
||||
/**
|
||||
* GD version
|
||||
* @var integer
|
||||
*/
|
||||
var $gd_version = 0;
|
||||
* Backgrounds path
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $path_background = '';
|
||||
|
||||
/**
|
||||
* Backgrounds path
|
||||
* @var string
|
||||
*/
|
||||
var $path_background = '';
|
||||
* Fonts path
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $path_fonts = '';
|
||||
|
||||
/**
|
||||
* Fonts path
|
||||
* @var string
|
||||
*/
|
||||
var $path_fonts = '';
|
||||
* Return an error if GD is not installed?
|
||||
* My most verbose string name. I'm so proud.
|
||||
*
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
public $show_error_gd_img = false;
|
||||
|
||||
/**
|
||||
* Return an error if GD is not installed?
|
||||
* My most verbose string name. I'm so proud.
|
||||
* @var boolean
|
||||
*/
|
||||
var $show_error_gd_img = FALSE;
|
||||
* Registry object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $registry;
|
||||
|
||||
/**
|
||||
* Error string
|
||||
* @var string
|
||||
*/
|
||||
var $error_string = '';
|
||||
* Database object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $DB;
|
||||
|
||||
/**
|
||||
* Constructor bah to PHP 4
|
||||
*
|
||||
* @param object IPSClass object
|
||||
* @param string Captcha plug-in to use
|
||||
*/
|
||||
function captchaPlugin( $ipsclass )
|
||||
* Settings object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $settings;
|
||||
|
||||
/**
|
||||
* Request object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* Language object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $lang;
|
||||
|
||||
/**
|
||||
* Member object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $member;
|
||||
|
||||
/**
|
||||
* Member data object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $memberData;
|
||||
|
||||
/**
|
||||
* Captcha key
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $captchaKey = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param object Registry Object
|
||||
*/
|
||||
public function __construct( ipsRegistry $registry )
|
||||
{
|
||||
$this->ipsclass =& $ipsclass;
|
||||
$this->registry = $registry;
|
||||
$this->DB = $this->registry->DB();
|
||||
$this->settings =& $this->registry->fetchSettings();
|
||||
$this->request =& $this->registry->fetchRequest();
|
||||
$this->lang = $this->registry->getClass('class_localization');
|
||||
$this->member = $this->registry->member();
|
||||
$this->memberData =& $this->registry->member()->fetchMemberData();
|
||||
|
||||
$this->gd_version = $this->ipsclass->vars['gd_version'];
|
||||
$this->path_background = ROOT_PATH . 'style_captcha/captcha_backgrounds';
|
||||
$this->path_fonts = ROOT_PATH . 'style_captcha/captcha_fonts';
|
||||
/* Settings */
|
||||
$this->gd_version = $this->settings['gd_version'];
|
||||
$this->path_background = DOC_IPS_ROOT_PATH . 'public/style_captcha/captcha_backgrounds';
|
||||
$this->path_fonts = DOC_IPS_ROOT_PATH . 'public/style_captcha/captcha_fonts';
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Initializes captcha session
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initializes captcha session
|
||||
* Clears out "dead" entries, adds new row and returns
|
||||
* unique ID for use in an image
|
||||
*
|
||||
* @return string Captcha unique ID
|
||||
*/
|
||||
function getTemplate()
|
||||
* Returns the template bit
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplate()
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Clear old
|
||||
//-----------------------------------------
|
||||
|
||||
$this->_clearSessions( $this->ipsclass->ip_address );
|
||||
$this->_clearSessions( $this->member->ip_address );
|
||||
|
||||
//-----------------------------------------
|
||||
// Create new ID
|
||||
@@ -115,72 +165,67 @@ class captchaPlugin
|
||||
//-----------------------------------------
|
||||
// Create new string
|
||||
//-----------------------------------------
|
||||
|
||||
/* Seed the random number generator */
|
||||
$unique_id = uniqid( mt_rand(), TRUE );
|
||||
$unique_id .= md5( $this->ipsclass->vars['sql_pass'] );
|
||||
usleep( mt_rand( 15000,1000000 ) );
|
||||
mt_srand( (double) microtime() * 1000000 );
|
||||
|
||||
/* Array of characters */
|
||||
/**
|
||||
* Array of characters
|
||||
* Removed: 0, o, O, 1, l, I, i, L (because they're hard to differentiate)
|
||||
*/
|
||||
$array_of_chars = array(
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'
|
||||
'2', '3', '4', '5', '6', '7', '8', '9',
|
||||
);
|
||||
|
||||
/* Get 6 random characters */
|
||||
for( $i = 0; $i < 6; $i++ )
|
||||
{
|
||||
$idx = rand( 0, count( $array_of_chars ) );
|
||||
$idx = mt_rand( 0, count( $array_of_chars ) - 1 );
|
||||
$captcha_string .= $array_of_chars[ $idx ];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Add to the DB
|
||||
//-----------------------------------------
|
||||
|
||||
$this->ipsclass->DB->do_insert( 'reg_antispam', array( 'regid' => $captcha_unique_id,
|
||||
'regcode' => $captcha_string,
|
||||
'ip_address' => $this->ipsclass->ip_address,
|
||||
'ctime' => time() ) );
|
||||
|
||||
$this->DB->insert( 'captcha', array( 'captcha_unique_id' => $captcha_unique_id,
|
||||
'captcha_string' => $captcha_string,
|
||||
'captcha_ipaddress' => $this->member->ip_address,
|
||||
'captcha_date' => time() ) );
|
||||
|
||||
/* Make available */
|
||||
$this->captchaKey = $captcha_unique_id;
|
||||
|
||||
//-----------------------------------------
|
||||
// Return Template Bit
|
||||
//-----------------------------------------
|
||||
|
||||
return $this->ipsclass->compiled_templates['skin_global']->captchaGD( $captcha_unique_id );
|
||||
return $this->registry->output->getTemplate('global_other')->captchaGD( $captcha_unique_id );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Captcha validate
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Show the captcha bot image
|
||||
*
|
||||
* @return void
|
||||
* @since 1.0
|
||||
*/
|
||||
function validate()
|
||||
* Validate the captcha image
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$captcha_unique_id = $this->ipsclass->txt_alphanumerical_clean( $_REQUEST['regid'] );
|
||||
$captcha_input_NOT_CLEAN = trim( strtolower( $_REQUEST['reg_code'] ) );
|
||||
$captcha_unique_id = IPSText::alphanumericalClean( $_REQUEST['captcha_unique_id'] );
|
||||
$captcha_input_NOT_CLEAN = trim( $_REQUEST['captcha_string'] );
|
||||
|
||||
//-----------------------------------------
|
||||
// Get the info from the DB
|
||||
//-----------------------------------------
|
||||
|
||||
$captcha = $this->ipsclass->DB->build_and_exec_query( array( 'select' => '*',
|
||||
'from' => 'reg_antispam',
|
||||
'where' => "regid='". addslashes( $captcha_unique_id )."'" ) );
|
||||
$captcha = $this->DB->buildAndFetch( array( 'select' => '*',
|
||||
'from' => 'captcha',
|
||||
'where' => "captcha_unique_id='". addslashes( $captcha_unique_id )."'" ) );
|
||||
|
||||
if ( ! $captcha['regid'] )
|
||||
if ( ! $captcha['captcha_unique_id'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -189,71 +234,71 @@ class captchaPlugin
|
||||
// Check...
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $captcha['regcode'] != $captcha_input_NOT_CLEAN )
|
||||
if ( $captcha['captcha_string'] != $captcha_input_NOT_CLEAN )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_clearSessions( $this->ipsclass->ip_address );
|
||||
$this->_clearSessions( $this->member->ip_address );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Captcha show image
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Show the captcha bot image
|
||||
*
|
||||
* @param string captcha_unique_id
|
||||
* @return void
|
||||
* @since 1.0
|
||||
*/
|
||||
function captcha_show_image( $captcha_unique_id )
|
||||
* Show the captcha bot image
|
||||
*
|
||||
* @access public
|
||||
* @param string captcha_unique_id Unique captcha db row id
|
||||
* @return mixed [Boolean on failure],[Output image data/headers]
|
||||
* @since 1.0
|
||||
*/
|
||||
public function showImage( $captcha_unique_id )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// CHECK
|
||||
//-----------------------------------------
|
||||
|
||||
//-----------------------------------------
|
||||
// Magic _call method makes an array
|
||||
//-----------------------------------------
|
||||
|
||||
$captcha_unique_id = $captcha_unique_id[0];
|
||||
|
||||
if ( ! $captcha_unique_id )
|
||||
{
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Get the info from the DB
|
||||
//-----------------------------------------
|
||||
|
||||
$captcha = $this->ipsclass->DB->build_and_exec_query( array( 'select' => '*',
|
||||
'from' => 'reg_antispam',
|
||||
'where' => "regid='".addslashes( $captcha_unique_id )."'" ) );
|
||||
$captcha = $this->DB->buildAndFetch( array( 'select' => '*',
|
||||
'from' => 'captcha',
|
||||
'where' => "captcha_unique_id='" . $captcha_unique_id . "'",
|
||||
) );
|
||||
|
||||
if ( ! $captcha['regid'] )
|
||||
if ( ! $captcha['captcha_unique_id'] )
|
||||
{
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Show it...
|
||||
//-----------------------------------------
|
||||
|
||||
$this->_captcha_show_gd_img( $captcha['regcode'] );
|
||||
|
||||
$this->_showGDImage( $captcha['captcha_string'] );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Show GD created security image...
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* Show anti-spam bot GD image numbers
|
||||
*
|
||||
* @param string Number string
|
||||
* @return void
|
||||
* @since 1.0
|
||||
*/
|
||||
function _captcha_show_gd_img( $content="" )
|
||||
* Show anti-spam bot GD image numbers
|
||||
*
|
||||
* @param string Number string
|
||||
* @return void
|
||||
* @since 1.0
|
||||
*/
|
||||
private function _showGDImage( $content="" )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Is GD Available?
|
||||
@@ -278,7 +323,7 @@ class captchaPlugin
|
||||
//-----------------------------------------
|
||||
|
||||
$content = ' '. preg_replace( "/(\w)/", "\\1 ", $content ) .' ';
|
||||
$allow_fonts = isset( $this->ipsclass->vars['captcha_allow_fonts'] ) ? $this->ipsclass->vars['captcha_allow_fonts'] : 1;
|
||||
$allow_fonts = isset( $this->settings['captcha_allow_fonts'] ) ? $this->settings['captcha_allow_fonts'] : 1;
|
||||
$use_fonts = 0;
|
||||
$tmp_x = 135;
|
||||
$tmp_y = 20;
|
||||
@@ -292,21 +337,15 @@ class captchaPlugin
|
||||
// Get backgrounds and fonts...
|
||||
//-----------------------------------------
|
||||
|
||||
$backgrounds = $this->_captcha_show_gd_img_get_backgrounds();
|
||||
$fonts = $this->_captcha_show_gd_img_get_fonts();
|
||||
|
||||
//-----------------------------------------
|
||||
// Seed rand functions for PHP versions that don't
|
||||
//-----------------------------------------
|
||||
|
||||
mt_srand( (double) microtime() * 1000000 );
|
||||
|
||||
$backgrounds = $this->_getBackgrounds();
|
||||
$fonts = $this->_getFonts();
|
||||
|
||||
//-----------------------------------------
|
||||
// Got a background?
|
||||
//-----------------------------------------
|
||||
$_imgs = array();
|
||||
|
||||
if ( $this->ipsclass->vars['gd_version'] > 1 )
|
||||
if ( $this->gd_version > 1 )
|
||||
{
|
||||
while ( $continue_loop )
|
||||
{
|
||||
@@ -394,10 +433,10 @@ class captchaPlugin
|
||||
$alternate = ( $alternate > 2 ) ? 0 : $alternate;
|
||||
|
||||
/* Width of the strip */
|
||||
$end_strip = ( $i * $strips ) + rand( 1, $strips );
|
||||
$end_strip = ( $i * $strips ) + mt_rand( 1, $strips );
|
||||
|
||||
/* Copy the splice */
|
||||
imagecopymerge( $im, $_imgs[$alternate], $curr_offset, 0, $curr_offset, 0, $end_strip, $image_y, rand( 1, 100 ) );
|
||||
imagecopymerge( $im, $_imgs[$alternate], $curr_offset, 0, $curr_offset, 0, $end_strip, $image_y, mt_rand( 1, 100 ) );
|
||||
|
||||
/* Increment the offset */
|
||||
$curr_offset += $end_strip;
|
||||
@@ -413,7 +452,7 @@ class captchaPlugin
|
||||
|
||||
if ( $_started !== TRUE )
|
||||
{
|
||||
if ( $this->ipsclass->vars['gd_version'] == 1 )
|
||||
if ( $this->gd_version == 1 )
|
||||
{
|
||||
$im = imagecreate($image_x, $image_y);
|
||||
$tmp = imagecreate($tmp_x, $tmp_y);
|
||||
@@ -433,21 +472,21 @@ class captchaPlugin
|
||||
for ( $i = 1; $i <= $circles; $i++ )
|
||||
{
|
||||
$values = array(
|
||||
0 => rand(0, $tmp_x - 10),
|
||||
1 => rand(0, $tmp_y - 3),
|
||||
2 => rand(0, $tmp_x - 10),
|
||||
3 => rand(0, $tmp_y - 3),
|
||||
4 => rand(0, $tmp_x - 10),
|
||||
5 => rand(0, $tmp_y - 3),
|
||||
6 => rand(0, $tmp_x - 10),
|
||||
7 => rand(0, $tmp_y - 3),
|
||||
8 => rand(0, $tmp_x - 10),
|
||||
9 => rand(0, $tmp_y - 3),
|
||||
10 => rand(0, $tmp_x - 10),
|
||||
11 => rand(0, $tmp_y - 3),
|
||||
0 => mt_rand(0, $tmp_x - 10),
|
||||
1 => mt_rand(0, $tmp_y - 3),
|
||||
2 => mt_rand(0, $tmp_x - 10),
|
||||
3 => mt_rand(0, $tmp_y - 3),
|
||||
4 => mt_rand(0, $tmp_x - 10),
|
||||
5 => mt_rand(0, $tmp_y - 3),
|
||||
6 => mt_rand(0, $tmp_x - 10),
|
||||
7 => mt_rand(0, $tmp_y - 3),
|
||||
8 => mt_rand(0, $tmp_x - 10),
|
||||
9 => mt_rand(0, $tmp_y - 3),
|
||||
10 => mt_rand(0, $tmp_x - 10),
|
||||
11 => mt_rand(0, $tmp_y - 3),
|
||||
);
|
||||
|
||||
$randomcolor = imagecolorallocate( $tmp, rand(100,255), rand(100,255),rand(100,255) );
|
||||
$randomcolor = imagecolorallocate( $tmp, mt_rand(100,255), mt_rand(100,255), mt_rand(100,255) );
|
||||
imagefilledpolygon($tmp, $values, 6, $randomcolor );
|
||||
}
|
||||
|
||||
@@ -457,15 +496,15 @@ class captchaPlugin
|
||||
|
||||
for( $i = 0; $i < $num; $i++ )
|
||||
{
|
||||
$x_param += rand(-1,12);
|
||||
$y_param = rand(-3,8);
|
||||
$x_param += mt_rand(-1,12);
|
||||
$y_param = mt_rand(-3,8);
|
||||
|
||||
if( $x_param + 18 > $image_x )
|
||||
{
|
||||
$x_param -= ceil( $x_param + 18 - $image_x );
|
||||
}
|
||||
|
||||
$randomcolor = imagecolorallocate( $tmp, rand(0,150), rand(0,150),rand(0,150) );
|
||||
$randomcolor = imagecolorallocate( $tmp, mt_rand(0,150), mt_rand(0,150), mt_rand(0,150) );
|
||||
|
||||
imagestring($tmp, 5, $x_param+1, $y_param+1, $content{$i}, $grey);
|
||||
imagestring($tmp, 5, $x_param, $y_param, $content{$i}, $randomcolor);
|
||||
@@ -487,8 +526,8 @@ class captchaPlugin
|
||||
|
||||
for ($i = 0; $i < $random_pixels; $i++)
|
||||
{
|
||||
$randomcolor = imagecolorallocate( $im, rand(0,150), rand(0,150),rand(0,150) );
|
||||
ImageSetPixel($im, rand(0, $image_x), rand(0, $image_y), $randomcolor);
|
||||
$randomcolor = imagecolorallocate( $im, mt_rand(0,150), mt_rand(0,150), mt_rand(0,150) );
|
||||
ImageSetPixel($im, mt_rand(0, $image_x), mt_rand(0, $image_y), $randomcolor);
|
||||
}
|
||||
|
||||
$no_x_lines = ($image_x - 1) / 5;
|
||||
@@ -522,18 +561,18 @@ class captchaPlugin
|
||||
$num = strlen($content);
|
||||
$x_param = -10;
|
||||
$y_param = 0;
|
||||
|
||||
|
||||
for( $i = 0; $i < $num; $i++ )
|
||||
{
|
||||
/* Random Font */
|
||||
$_font = $fonts[ mt_rand( 0, count( $fonts ) - 1 ) ];
|
||||
|
||||
$y_param = rand( 35, 48 );
|
||||
$y_param = mt_rand( 35, 48 );
|
||||
|
||||
# Main color
|
||||
$col_r = rand(50,200);
|
||||
$col_g = rand(0,150);
|
||||
$col_b = rand(50,200);
|
||||
$col_r = mt_rand(50,200);
|
||||
$col_g = mt_rand(0,150);
|
||||
$col_b = mt_rand(50,200);
|
||||
# High light
|
||||
$col_r_l = ( $col_r + 50 > 255 ) ? 255 : $col_r + 50;
|
||||
$col_g_l = ( $col_g + 50 > 255 ) ? 255 : $col_g + 50;
|
||||
@@ -563,7 +602,7 @@ class captchaPlugin
|
||||
}
|
||||
}
|
||||
|
||||
$text_size = rand( 24, 30 ); //24
|
||||
$text_size = mt_rand( 24, 30 ); //24
|
||||
|
||||
if ( ! $_result = @imagettftext( $im, $text_size, $_slant, $x_param - 1, $y_param - 1, $color_light, $_font, $content[$i] ) )
|
||||
{
|
||||
@@ -576,14 +615,14 @@ class captchaPlugin
|
||||
@imagettftext( $im, $text_size, $_slant, $x_param, $y_param, $color_main, $_font, $content[$i] );
|
||||
}
|
||||
|
||||
$x_param += rand( 13, 16 ); //15,18
|
||||
$x_param += mt_rand( 13, 16 ); //15,18
|
||||
|
||||
if( $x_param + 18 > $image_x )
|
||||
{
|
||||
$x_param -= ceil( $x_param + 18 - $image_x );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$use_fonts = TRUE;
|
||||
}
|
||||
|
||||
@@ -613,7 +652,7 @@ class captchaPlugin
|
||||
{
|
||||
if ( $i > 0 )
|
||||
{
|
||||
$x_param += rand( 6, 12 );
|
||||
$x_param += mt_rand( 6, 12 );
|
||||
|
||||
if( $x_param + 18 > $image_x )
|
||||
{
|
||||
@@ -621,9 +660,9 @@ class captchaPlugin
|
||||
}
|
||||
}
|
||||
|
||||
$y_param = rand( 0, 5 );
|
||||
$y_param = mt_rand( 0, 5 );
|
||||
|
||||
$randomcolor = imagecolorallocate( $tmp, rand(50,200), rand(50,200),rand(50,200) );
|
||||
$randomcolor = imagecolorallocate( $tmp, mt_rand(50,200), mt_rand(50,200), mt_rand(50,200) );
|
||||
|
||||
imagestring( $tmp, 5, $x_param + 1, $y_param + 1, $content{$i}, $grey );
|
||||
imagestring( $tmp, 5, $x_param , $y_param , $content{$i}, $randomcolor );
|
||||
@@ -631,7 +670,7 @@ class captchaPlugin
|
||||
|
||||
imagecopyresized($tmp2, $tmp, 0, 0, 0, 0, $image_x, $image_y, $tmp_x, $tmp_y );
|
||||
|
||||
$tmp2 = $this->_captcha_show_gd_img_wave( $tmp2, 8, true );
|
||||
$tmp2 = $this->_showGDImageWave( $tmp2, 8, true );
|
||||
|
||||
imagecolortransparent( $tmp2, $transparent );
|
||||
imagecopymerge( $im, $tmp2, 0, 0, 0, 0, $image_x, $image_y, 100 );
|
||||
@@ -672,19 +711,17 @@ class captchaPlugin
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Create wave effect for GD images...
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* Create wave effect for GD images
|
||||
*
|
||||
* @param object Image resource
|
||||
* @return object Returned image resource
|
||||
* @since 1.0
|
||||
*/
|
||||
function _captcha_show_gd_img_wave( $im, $wave=10 )
|
||||
* Create wave effect for GD images
|
||||
*
|
||||
* @access private
|
||||
* @param resource Image resource
|
||||
* @param integer Wave factor
|
||||
* @return resource Returned image resource
|
||||
* @since 1.0
|
||||
*/
|
||||
private function _showGDImageWave( $im, $wave=10 )
|
||||
{
|
||||
$_width = imagesx( $im );
|
||||
$_height = imagesy( $im );
|
||||
@@ -720,46 +757,38 @@ class captchaPlugin
|
||||
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Removes extinct captcha sessions
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Removes extinct captcha sessions
|
||||
* Clears out "dead" entries
|
||||
*
|
||||
* @param string Optional IP address to clear out on
|
||||
* @return string void
|
||||
*/
|
||||
|
||||
function _clearSessions( $ip_address='' )
|
||||
* Removes extinct captcha sessions
|
||||
* Clears out "dead" entries
|
||||
*
|
||||
* @access private
|
||||
* @param string Optional IP address to clear out on
|
||||
* @return string void
|
||||
*/
|
||||
private function _clearSessions( $ip_address='' )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$time = time() - 60 * 3600;
|
||||
$extra = ( $ip_address ) ? ' OR ip_address="'.$ip_address.'"' : '';
|
||||
$extra = ( $ip_address ) ? " OR captcha_ipaddress='" . $ip_address . "'" : '';
|
||||
|
||||
//-----------------------------------------
|
||||
// Remove...
|
||||
//-----------------------------------------
|
||||
|
||||
$this->ipsclass->DB->build_and_exec_query( array( 'delete' => 'reg_antispam',
|
||||
'where' => 'ctime < ' . $time . $extra ) );
|
||||
|
||||
$this->DB->delete( 'captcha', 'captcha_date < ' . $time . $extra );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Load up the backgrounds
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Loads up the backgrounds.
|
||||
*
|
||||
* @return array backgrounds
|
||||
*/
|
||||
|
||||
function _captcha_show_gd_img_get_backgrounds()
|
||||
* Loads up the backgrounds.
|
||||
*
|
||||
* @access private
|
||||
* @return array backgrounds
|
||||
*/
|
||||
private function _getBackgrounds()
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
@@ -768,9 +797,9 @@ class captchaPlugin
|
||||
$images = array();
|
||||
$_path = $this->path_background;
|
||||
|
||||
if ( $_dir = @opendir( $_path ) )
|
||||
if ( $_dir = opendir( $_path ) )
|
||||
{
|
||||
while( false !== ( $_file = @readdir( $_dir ) ) )
|
||||
while( false !== ( $_file = readdir( $_dir ) ) )
|
||||
{
|
||||
if ( preg_match( "#\.(gif|jpeg|jpg|png)$#i", $_file ) )
|
||||
{
|
||||
@@ -778,20 +807,17 @@ class captchaPlugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Load up the fonts
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Loads up the fonts.
|
||||
*
|
||||
* @return array fonts
|
||||
*/
|
||||
|
||||
function _captcha_show_gd_img_get_fonts()
|
||||
* Loads up the fonts.
|
||||
*
|
||||
* @access private
|
||||
* @return array fonts
|
||||
*/
|
||||
private function _getFonts()
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
@@ -814,6 +840,4 @@ class captchaPlugin
|
||||
return $fonts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
+110
-86
@@ -1,38 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power Dynamic v1.0.0
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2004 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
| INVISION POWER DYNAMIC IS NOT FREE SOFTWARE!
|
||||
| http://www.invisionpower.com/dynamic/
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Id$
|
||||
| > $Revision: 128 $
|
||||
| > $Date: 2006-01-20 12:46:26 +0000 (Fri, 20 Jan 2006) $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > CAPTCHA ANTI-SPAM CLASS
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Thursday 2 February (11:08)
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* CAPTCHA CLASS
|
||||
* PLUG IN: Default GD image
|
||||
* @package IPDYNAMIC
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
* - Documentation and latest version
|
||||
@@ -77,44 +44,101 @@ define("RECAPTCHA_VERIFY_SERVER", "api-verify.recaptcha.net");
|
||||
class captchaPlugin
|
||||
{
|
||||
/**
|
||||
* Global IPS class array
|
||||
* @var object
|
||||
*/
|
||||
var $ipsclass;
|
||||
|
||||
* Registry object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $registry;
|
||||
|
||||
/**
|
||||
* Error string
|
||||
* @var string
|
||||
*/
|
||||
var $error_string = '';
|
||||
* Database object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $DB;
|
||||
|
||||
/**
|
||||
* Constructor bah to PHP 4
|
||||
*
|
||||
* @param object IPSClass object
|
||||
* @param string Captcha plug-in to use
|
||||
*/
|
||||
function captchaPlugin( $ipsclass )
|
||||
* Settings object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $settings;
|
||||
|
||||
/**
|
||||
* Request object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* Language object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $lang;
|
||||
|
||||
/**
|
||||
* Member object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $member;
|
||||
|
||||
/**
|
||||
* Member data object
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
public $memberData;
|
||||
|
||||
/**
|
||||
* Error code from reCAPTCHA
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
public $error;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param object Registry Object
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( ipsRegistry $registry )
|
||||
{
|
||||
$this->ipsclass =& $ipsclass;
|
||||
$this->registry = $registry;
|
||||
$this->DB = $this->registry->DB();
|
||||
$this->settings =& $this->registry->fetchSettings();
|
||||
$this->request =& $this->registry->fetchRequest();
|
||||
$this->lang = $this->registry->getClass('class_localization');
|
||||
$this->member = $this->registry->member();
|
||||
$this->memberData =& $this->registry->member()->fetchMemberData();
|
||||
|
||||
$this->public_key = $this->ipsclass->vars['recaptcha_public_key'];
|
||||
$this->private_key = $this->ipsclass->vars['recaptcha_private_key'];
|
||||
$this->useSSL = false; //$this->ipsclass->vars['logins_over_https']; - IPB3 feature...shhhh ;) :P
|
||||
/* Settings */
|
||||
$this->public_key = trim( $this->settings['recaptcha_public_key'] );
|
||||
$this->private_key = trim( $this->settings['recaptcha_private_key'] );
|
||||
$this->useSSL = $this->settings['logins_over_https'];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Initializes captcha session
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initializes captcha session
|
||||
* Clears out "dead" entries, adds new row and returns
|
||||
* unique ID for use in an image
|
||||
*
|
||||
* @return string HTML
|
||||
*/
|
||||
function getTemplate()
|
||||
* Gets the challenge HTML (javascript and non-javascript version).
|
||||
* This is called from the browser, and the resulting reCAPTCHA HTML widget
|
||||
* is embedded within the HTML form it was called from.
|
||||
*
|
||||
* @access public
|
||||
* @return string Form HTML to display
|
||||
*/
|
||||
public function getTemplate()
|
||||
{
|
||||
if ( ! $this->public_key )
|
||||
{
|
||||
@@ -131,11 +155,12 @@ class captchaPlugin
|
||||
}
|
||||
|
||||
$html = '';
|
||||
|
||||
if( $this->ipsclass->vars['recaptcha_language'] )
|
||||
{
|
||||
$html .= "<script type='text/javascript'>var RecaptchaOptions = { lang : '{$this->ipsclass->vars['recaptcha_language']}' };</script>";
|
||||
}
|
||||
$html .= "<script type='text/javascript'>
|
||||
var RecaptchaOptions = {
|
||||
lang : '{$this->settings['recaptcha_language']}',
|
||||
theme : '{$this->settings['recaptcha_theme']}'
|
||||
};
|
||||
</script>";
|
||||
|
||||
$html .= '<script type="text/javascript" src="'. $server . '/challenge?k=' . $this->public_key . '"></script>
|
||||
<noscript>
|
||||
@@ -148,20 +173,17 @@ class captchaPlugin
|
||||
// Return Template Bit
|
||||
//-----------------------------------------
|
||||
|
||||
return $this->ipsclass->compiled_templates['skin_global']->captchaRecaptcha( $html );
|
||||
return $this->registry->output->getTemplate('global_other')->captchaRecaptcha( $html );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Captcha validate
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* Show the captcha bot image
|
||||
*
|
||||
* @return void
|
||||
* @since 1.0
|
||||
*/
|
||||
function validate()
|
||||
* Validate the input code
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Validation successful
|
||||
* @since 1.0
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
if ( !$this->private_key )
|
||||
{
|
||||
@@ -179,7 +201,7 @@ class captchaPlugin
|
||||
$response = $this->_recaptchaPost( RECAPTCHA_VERIFY_SERVER, "/verify",
|
||||
array (
|
||||
'privatekey' => $this->private_key,
|
||||
'remoteip' => $this->ipsclass->ip_address,
|
||||
'remoteip' => $this->member->ip_address,
|
||||
'challenge' => $captcha_unique_id,
|
||||
'response' => $captcha_input
|
||||
)
|
||||
@@ -187,12 +209,16 @@ class captchaPlugin
|
||||
|
||||
$answers = explode( "\n", $response [1] );
|
||||
|
||||
if ( trim ($answers [0]) == 'true' )
|
||||
if ( trim($answers[0]) == 'true' )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* It's an error
|
||||
*/
|
||||
$this->error = $answers[1];
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -206,7 +232,7 @@ class captchaPlugin
|
||||
* @param string $domain The domain where the page is hosted
|
||||
* @param string $appname The name of your application
|
||||
*/
|
||||
function getSignupUrl( $domain = null, $appname = null )
|
||||
public function getSignupUrl( $domain = null, $appname = null )
|
||||
{
|
||||
return "http://recaptcha.net/api/getkey?" . $this->_encodeQueryString( array( 'domain' => $domain, 'app' => $appname ) );
|
||||
}
|
||||
@@ -221,7 +247,7 @@ class captchaPlugin
|
||||
* @param int port
|
||||
* @return array response
|
||||
*/
|
||||
function _recaptchaPost( $host, $path, $data, $port = 80 )
|
||||
private function _recaptchaPost( $host, $path, $data, $port = 80 )
|
||||
{
|
||||
$req = $this->_encodeQueryString( $data );
|
||||
|
||||
@@ -261,7 +287,7 @@ class captchaPlugin
|
||||
* @param array $data
|
||||
* @return string query string
|
||||
*/
|
||||
function _encodeQueryString( $data )
|
||||
private function _encodeQueryString( $data )
|
||||
{
|
||||
$req = "";
|
||||
|
||||
@@ -277,5 +303,3 @@ class captchaPlugin
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* HTTP Communications - send data via POST and read response
|
||||
* Last Updated: $Date: 2009-02-04 15:05:02 -0500 (Wed, 04 Feb 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 6th January 2006 (12:24)
|
||||
* @version $Revision: 222 $
|
||||
*
|
||||
* Usage
|
||||
* <code>
|
||||
* $communication = new classCommunication;
|
||||
* $return = $communication->communicationSendData( 'http://example.site.com/external.php', array( 'foo' => 'bar' ) );
|
||||
* $data = $communication->communicationReceiveData( $return );
|
||||
* print_r($data);
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
class classCommunication
|
||||
{
|
||||
/**
|
||||
* Use sockets flag
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $use_sockets = 0;
|
||||
|
||||
/**
|
||||
* Error array
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $error = array();
|
||||
|
||||
/**
|
||||
* Key prefix
|
||||
* Prefix to identify communication strings
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $key_prefix = '__xsx__';
|
||||
|
||||
/**#@+
|
||||
* Set Authentication
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
public $auth_req = 0;
|
||||
public $auth_user;
|
||||
public $auth_pass;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Receive data from the "send" function
|
||||
*
|
||||
* @access public
|
||||
* @param array Array of fields to return
|
||||
* @return array Array of fields
|
||||
*/
|
||||
public function communicationReceiveData( $return_fields=array() )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$return_array = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Get data...
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $_REQUEST as $k => $v )
|
||||
{
|
||||
if ( strstr( $k, $this->key_prefix ) )
|
||||
{
|
||||
$k = str_replace( $this->key_prefix, '', $k );
|
||||
|
||||
$return_array[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_filterFields( $return_array );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the data
|
||||
*
|
||||
* @access public
|
||||
* @param string URI to post to
|
||||
* @param array Arry of post fields
|
||||
* @return string File data
|
||||
*/
|
||||
public function communicationSendData( $file_location='', $post_array=array() )
|
||||
{
|
||||
if ( ! is_array( $post_array ) OR ! count( $post_array ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $file_location )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->_postData( $file_location, $post_array );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out fields (optional)
|
||||
*
|
||||
* @access private
|
||||
* @param array Array of fields to return
|
||||
* @return array Array of fields
|
||||
*/
|
||||
private function _filterFields( $in_fields=array(), $out_fields=array() )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$return_array = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Check
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! is_array( $in_fields ) or ! count( $in_fields ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! is_array( $out_fields ) or ! count( $out_fields ) )
|
||||
{
|
||||
return $in_fields;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Get data...
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $out_fields as $k => $type )
|
||||
{
|
||||
if ( $in_fields[ $k ] )
|
||||
{
|
||||
switch ( $type )
|
||||
{
|
||||
default:
|
||||
case 'string':
|
||||
case 'text':
|
||||
$return_array[ $k ] = trim( $in_fields[ $k ] );
|
||||
break;
|
||||
case 'int':
|
||||
case 'integar':
|
||||
$return_array[ $k ] = intval( $in_fields[ $k ] );
|
||||
break;
|
||||
case 'float':
|
||||
case 'floatval':
|
||||
$return_array[ $k ] = floatval( $in_fields[ $k ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file contents (with sockets)
|
||||
*
|
||||
* @access private
|
||||
* @param string URI to post to
|
||||
* @param array Arry of post fields
|
||||
* @return string File data
|
||||
* @todo [Future] Doesn't support "chunked" HTTP responses
|
||||
*/
|
||||
private function _postData( $file_location, $post_array )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$data = null;
|
||||
$fsocket_timeout = 10;
|
||||
$post_back = array();
|
||||
|
||||
//-------------------------------
|
||||
// Fix up post string
|
||||
//-------------------------------
|
||||
|
||||
foreach ( $post_array as $key => $val )
|
||||
{
|
||||
$post_back[] = $this->key_prefix . $key . '=' . urlencode($val);
|
||||
}
|
||||
|
||||
$post_back_str = implode('&', $post_back);
|
||||
|
||||
//-------------------------------
|
||||
// Parse URL
|
||||
//-------------------------------
|
||||
|
||||
$url_parts = parse_url($file_location);
|
||||
|
||||
if ( ! $url_parts['host'] )
|
||||
{
|
||||
$this->errors[] = "Не найден хост в URL '{$file_location}'!";
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Finalize
|
||||
//-------------------------------
|
||||
|
||||
$host = $url_parts['host'];
|
||||
$port = ( isset($url_parts['port']) ) ? $url_parts['port'] : ( $url_parts['scheme'] == 'https' ? 443 : 80 );
|
||||
|
||||
//-------------------------------
|
||||
// Tidy up path
|
||||
//-------------------------------
|
||||
|
||||
if ( ! empty( $url_parts["path"] ) )
|
||||
{
|
||||
$path = $url_parts["path"];
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = "/";
|
||||
}
|
||||
|
||||
if ( ! empty( $url_parts["query"] ) )
|
||||
{
|
||||
$path .= "?" . $url_parts["query"];
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Try CURL first...
|
||||
//-------------------------------
|
||||
|
||||
if ( function_exists("curl_init") AND function_exists("curl_exec") )
|
||||
{
|
||||
if ( $sock = curl_init() )
|
||||
{
|
||||
curl_setopt( $sock, CURLOPT_URL , $file_location );
|
||||
curl_setopt( $sock, CURLOPT_TIMEOUT , 15 );
|
||||
curl_setopt( $sock, CURLOPT_POST , TRUE );
|
||||
curl_setopt( $sock, CURLOPT_POSTFIELDS , $post_back_str );
|
||||
curl_setopt( $sock, CURLOPT_POSTFIELDSIZE , 0);
|
||||
curl_setopt( $sock, CURLOPT_RETURNTRANSFER , TRUE );
|
||||
|
||||
$result = curl_exec($sock);
|
||||
|
||||
curl_close($sock);
|
||||
|
||||
return $result ? $result : false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ( ! $fp = @fsockopen( $host, $port, $errno, $errstr, $fsocket_timeout ) )
|
||||
{
|
||||
$this->errors[] = "Невозможно соединение с {$host}";
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$final_carriage = "";
|
||||
|
||||
if ( ! $this->auth_req )
|
||||
{
|
||||
$final_carriage = "\r\n";
|
||||
}
|
||||
|
||||
$header = "POST $path HTTP/1.0\r\n";
|
||||
$header .= "Host: $host\r\n";
|
||||
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
$header .= "Content-Length: " . strlen($post_back_str) . "\r\n{$final_carriage}";
|
||||
|
||||
if ( ! fputs( $fp, $header . $post_back_str ) )
|
||||
{
|
||||
$this->errors[] = "Невозможно отправить запрос на {$host}!";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->auth_req )
|
||||
{
|
||||
if( $this->auth_user && $this->auth_pass )
|
||||
{
|
||||
$header = "Authorization: Basic ". base64_encode( "{$this->auth_user}:{$this->auth_pass}" ) . "\r\n\r\n";
|
||||
|
||||
if ( ! fputs( $fp, $header ) )
|
||||
{
|
||||
$this->errors[] = "Данные авторизации не верны!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@stream_set_timeout($fp, $fsocket_timeout);
|
||||
|
||||
$status = @socket_get_status($fp);
|
||||
|
||||
while( ! feof($fp) && ! $status['timed_out'] )
|
||||
{
|
||||
$data .= fgets ($fp,8192);
|
||||
$status = socket_get_status($fp);
|
||||
}
|
||||
|
||||
fclose ($fp);
|
||||
|
||||
//-------------------------------
|
||||
// Strip headers
|
||||
//-------------------------------
|
||||
|
||||
$tmp = split("\r\n\r\n", $data, 2);
|
||||
$data = $tmp[1];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,598 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Character set conversion library
|
||||
* Last Updated: $Date: 2009-09-25 07:10:57 -0400 (Fri, 25 Sep 2009) $
|
||||
*
|
||||
* @author $Author: matt $
|
||||
* @author Mikolaj Jedrzejak <mikolajj@op.pl>
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @copyright Copyright Mikolaj Jedrzejak (c) 2003-2004
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Friday 2nd December 2005 10:18
|
||||
* @version $Revision: 328 $
|
||||
* @version 1.0 2004-07-27 00:37
|
||||
* @link http://www.unicode.org Unicode Homepage
|
||||
* @link http://www.mikkom.pl My Homepage
|
||||
* @link https://www.invisionpower.com/index.php?appcomponent=downloads Downloads
|
||||
*
|
||||
* This class is an adaptation of the ConvertCharset.class.php provided by Mikolaj Jedrzejak.
|
||||
* In order to use character set conversions, you must first download the conversion libraries from our website. See the 'Downloads' link.
|
||||
* Upon downloading the tables, extract the zip and place the top-level i18n folder under ips_kernel/.
|
||||
* His original conversion class and License are provided in the download with the conversion libraries for reference.
|
||||
*
|
||||
* Convert from iso-8859-7 to utf-8
|
||||
* <code>
|
||||
* $convert = new classConvertCharset();
|
||||
* $converted_text = $convert->convertEncoding( $string, 'iso-8859-7', 'utf-8' );
|
||||
* print $converted_text;
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
class classConvertCharset
|
||||
{
|
||||
/**
|
||||
* Array of error messages associated with the conversion
|
||||
*
|
||||
* @access public
|
||||
* @var array Error messages
|
||||
*/
|
||||
public $errors = array();
|
||||
|
||||
/**
|
||||
* Should characters be turned into numeric entities
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $entities = false;
|
||||
|
||||
/**
|
||||
* Conversion method to use.
|
||||
* Valid values include: mb, iconv, recode, internal
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $method = 'internal';
|
||||
|
||||
/**
|
||||
* Path for character sets
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $charsetPath = '';
|
||||
|
||||
/**
|
||||
* Converts a text string from its current charset to a destination charset
|
||||
*
|
||||
* @access public
|
||||
* @param string Text string
|
||||
* @param string Text string char set (original)
|
||||
* @param string Desired character set (destination)
|
||||
* @return string Converted string
|
||||
*/
|
||||
public function convertEncoding( $string, $string_char_set, $destination_char_set='UTF-8' )
|
||||
{
|
||||
$string_char_set = strtolower($string_char_set);
|
||||
$t = $string;
|
||||
|
||||
if ( is_numeric( $t ) )
|
||||
{
|
||||
return $t;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Did we pass a destination?
|
||||
//-----------------------------------------
|
||||
|
||||
$destination_char_set = strtolower($destination_char_set);
|
||||
|
||||
//-----------------------------------------
|
||||
// Not the same?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $destination_char_set == $string_char_set )
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
|
||||
if( !$string_char_set )
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
|
||||
if( !$t OR $t == '' )
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Do the convert - internally..
|
||||
//-----------------------------------------
|
||||
|
||||
$method = "convertUsing_" . $this->method;
|
||||
$text = $this->$method( $string, $string_char_set, $destination_char_set );
|
||||
|
||||
return $text ? $text : $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a text string from its current charset to a destination charset using mb_convert_encoding
|
||||
*
|
||||
* @access private
|
||||
* @param string Text string
|
||||
* @param string Text string char set (original)
|
||||
* @param string Desired character set (destination)
|
||||
* @return string Converted string
|
||||
*/
|
||||
private function convertUsing_mb( $string, $string_char_set, $destination_char_set='UTF-8' )
|
||||
{
|
||||
if ( function_exists( 'mb_convert_encoding' ) )
|
||||
{
|
||||
$encodings = array_map( 'strtolower', mb_list_encodings() );
|
||||
|
||||
if( in_array( strtolower( $destination_char_set ), $encodings ) AND in_array( strtolower( $string_char_set ), $encodings ) )
|
||||
{
|
||||
$text = mb_convert_encoding( $string, $destination_char_set, $string_char_set );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "NO_MB_FUNCTION";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "NO_MB_FUNCTION";
|
||||
}
|
||||
|
||||
return $text ? $text : $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a text string from its current charset to a destination charset using iconv
|
||||
*
|
||||
* @access private
|
||||
* @param string Text string
|
||||
* @param string Text string char set (original)
|
||||
* @param string Desired character set (destination)
|
||||
* @return string Converted string
|
||||
*/
|
||||
private function convertUsing_iconv( $string, $string_char_set, $destination_char_set='UTF-8' )
|
||||
{
|
||||
if ( function_exists( 'iconv' ) )
|
||||
{
|
||||
$text = iconv( $string_char_set, $destination_char_set.'//TRANSLIT', $string );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "NO_ICONV_FUNCTION";
|
||||
}
|
||||
|
||||
return $text ? $text : $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a text string from its current charset to a destination charset using recode_string
|
||||
*
|
||||
* @access private
|
||||
* @param string Text string
|
||||
* @param string Text string char set (original)
|
||||
* @param string Desired character set (destination)
|
||||
* @return string Converted string
|
||||
*/
|
||||
private function convertUsing_recode( $string, $string_char_set, $destination_char_set='UTF-8' )
|
||||
{
|
||||
if ( function_exists( 'recode_string' ) )
|
||||
{
|
||||
$text = recode_string( $string_char_set.'..'.$destination_char_set, $string );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "NO_RECODE_FUNCTION";
|
||||
}
|
||||
|
||||
return $text ? $text : $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a text string from its current charset to a destination charset using internal conversion class.
|
||||
* The bulk of this function was written by Mikolaj Jedrzejak and used with permission via the License
|
||||
*
|
||||
* @access private
|
||||
* @param string Text string
|
||||
* @param string Text string char set (original)
|
||||
* @param string Desired character set (destination)
|
||||
* @return string Converted string
|
||||
*/
|
||||
private function convertUsing_internal( $string, $string_char_set, $destination_char_set='UTF-8' )
|
||||
{
|
||||
$text = '';
|
||||
$original = $string;
|
||||
|
||||
if( !$this->charsetPath )
|
||||
{
|
||||
$this->charsetPath = IPS_KERNEL_PATH . '/i18n/ConvertTables/';
|
||||
}
|
||||
|
||||
/**
|
||||
* This divison was made to prevent errors during convertion to/from utf-8 with
|
||||
* "entities" enabled, because we need to use proper destination(to)/source(from)
|
||||
* encoding table to write proper entities.
|
||||
*
|
||||
* This is the first case. We are convertinf from 1byte chars...
|
||||
**/
|
||||
if ($string_char_set != "utf-8")
|
||||
{
|
||||
/**
|
||||
* Now build table with both charsets for encoding change.
|
||||
**/
|
||||
if ($destination_char_set != "utf-8")
|
||||
{
|
||||
$charsetTable = $this->_makeConversionTable( $string_char_set, $destination_char_set );
|
||||
}
|
||||
else
|
||||
{
|
||||
$charsetTable = $this->_makeConversionTable( $string_char_set );
|
||||
}
|
||||
|
||||
if( !count($charsetTable) )
|
||||
{
|
||||
$this->errors[] = "Character set table not found";
|
||||
return $original;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each char in a string...
|
||||
**/
|
||||
for ($i = 0; $i < strlen($string); $i++)
|
||||
{
|
||||
$hexChar = "";
|
||||
$unicodeHexChar = "";
|
||||
$hexChar = strtoupper(dechex(ord($string[$i])));
|
||||
|
||||
// This is fix from Mario Klingemann, it prevents
|
||||
// droping chars below 16 because of missing leading 0 [zeros]
|
||||
if ( strlen($hexChar)==1 )
|
||||
{
|
||||
$hexChar = "0" . $hexChar;
|
||||
}
|
||||
|
||||
// This is quick fix of 10 chars in gsm0338
|
||||
// Thanks goes to Andrea Carpani who pointed on this problem and solve it ;)
|
||||
if ( ( $string_char_set == "gsm0338" ) && ( $hexChar == '1B' ) )
|
||||
{
|
||||
$i++;
|
||||
$hexChar .= strtoupper(dechex(ord($string[$i])));
|
||||
}
|
||||
|
||||
if ( $destination_char_set != "utf-8" )
|
||||
{
|
||||
if ( in_array( $hexChar, $charsetTable[$string_char_set] ) )
|
||||
{
|
||||
$unicodeHexChar = array_search( $hexChar, $charsetTable[$string_char_set] );
|
||||
$unicodeHexChars = explode( "+",$unicodeHexChar );
|
||||
|
||||
for( $unicodeHexCharElement = 0; $unicodeHexCharElement < count($unicodeHexChars); $unicodeHexCharElement++ )
|
||||
{
|
||||
if ( array_key_exists( $unicodeHexChars[$unicodeHexCharElement], $charsetTable[$destination_char_set] ) )
|
||||
{
|
||||
if ( $this->entities == true )
|
||||
{
|
||||
$text .= $this->_unicodeEntity( $this->_hexToUtf( $unicodeHexChars[$unicodeHexCharElement] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= chr(hexdec($charsetTable[$destination_char_set][$unicodeHexChars[$unicodeHexCharElement]]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "NO_CHAR_IN_DESTINATION: {$string[$i]}";
|
||||
return $original;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "NO_CHAR_IN_SOURCE: {$string[$i]}";
|
||||
return $original;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( in_array( $hexChar, $charsetTable[$string_char_set] ) )
|
||||
{
|
||||
$unicodeHexChar = array_search( $hexChar, $charsetTable[$string_char_set] );
|
||||
$unicodeHexChars = explode( "+", $unicodeHexChar );
|
||||
|
||||
/**
|
||||
* Sometimes there are two or more utf-8 chars per one regular char.
|
||||
* Extream, example is polish old Mazovia encoding, where one char contains
|
||||
* two lettes 007a (z) and 0142 (l slash), we need to figure out how to
|
||||
* solve this problem.
|
||||
* The letters are merge with "plus" sign, there can be more than two chars.
|
||||
* In Mazowia we have 007A+0142, but sometimes it can look like this
|
||||
* 0x007A+0x0142+0x2034 (that string means nothing, it just shows the possibility...)
|
||||
**/
|
||||
for( $unicodeHexCharElement = 0; $unicodeHexCharElement < count($unicodeHexChars); $unicodeHexCharElement++)
|
||||
{
|
||||
if ( $this->entities == true )
|
||||
{
|
||||
$text .= $this->_unicodeEntity( $this->_hexToUtf( $unicodeHexChars[$unicodeHexCharElement] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= $this->_hexToUtf( $unicodeHexChars[$unicodeHexCharElement] );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "NO_CHAR_IN_SOURCE: {$string[$i]}";
|
||||
return $original;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is second case. We are encoding from multibyte char string.
|
||||
**/
|
||||
|
||||
else if( $string_char_set == "utf-8" )
|
||||
{
|
||||
$hexChar = "";
|
||||
$unicodeHexChar = "";
|
||||
$charsetTable = $this->_makeConversionTable( $destination_char_set );
|
||||
|
||||
if( is_array($charsetTable[$destination_char_set]) AND count($charsetTable[$destination_char_set]) )
|
||||
{
|
||||
foreach ( $charsetTable[$destination_char_set] as $unicodeHexChar => $hexChar )
|
||||
{
|
||||
if ($this->entities == true)
|
||||
{
|
||||
$entityOrChar = $this->_unicodeEntity($this->_hexToUtf($unicodeHexChar));
|
||||
}
|
||||
else
|
||||
{
|
||||
$entityOrChar = chr(hexdec($hexChar));
|
||||
}
|
||||
|
||||
$string = str_replace( $this->_hexToUtf( $unicodeHexChar), $entityOrChar, $string );
|
||||
}
|
||||
}
|
||||
|
||||
$text = $string;
|
||||
}
|
||||
|
||||
return $text ? $text : $original;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert unicode characters to unicode HTML entities
|
||||
*
|
||||
* @access private
|
||||
* @param string $unicodeString Input Unicode string (1 char can take more than 1 byte)
|
||||
* @return string This is an input string olso with unicode chars, bus saved as entities
|
||||
* @see _hexToUtf()
|
||||
**/
|
||||
private function _unicodeEntity( $unicodeString )
|
||||
{
|
||||
$outString = "";
|
||||
$stringLength = strlen( $unicodeString );
|
||||
|
||||
for( $charPosition = 0; $charPosition < $stringLength; $charPosition++ )
|
||||
{
|
||||
$char = $unicodeString [$charPosition];
|
||||
$asciiChar = ord ($char);
|
||||
|
||||
if ($asciiChar < 128) //1 7 0bbbbbbb (127)
|
||||
{
|
||||
$outString .= $char;
|
||||
}
|
||||
else if ($asciiChar >> 5 == 6) //2 11 110bbbbb 10bbbbbb (2047)
|
||||
{
|
||||
$firstByte = ($asciiChar & 31);
|
||||
$charPosition++;
|
||||
$char = $unicodeString [$charPosition];
|
||||
$asciiChar = ord ($char);
|
||||
$secondByte = ($asciiChar & 63);
|
||||
$asciiChar = ($firstByte * 64) + $secondByte;
|
||||
|
||||
$entity = sprintf ( "&#%d;", $asciiChar );
|
||||
$outString .= $entity;
|
||||
}
|
||||
else if ($asciiChar >> 4 == 14) //3 16 1110bbbb 10bbbbbb 10bbbbbb
|
||||
{
|
||||
$firstByte = ($asciiChar & 31);
|
||||
$charPosition++;
|
||||
$char = $unicodeString [$charPosition];
|
||||
$asciiChar = ord ($char);
|
||||
$secondByte = ($asciiChar & 63);
|
||||
$charPosition++;
|
||||
$char = $unicodeString [$charPosition];
|
||||
$asciiChar = ord ($char);
|
||||
$thirdByte = ($asciiChar & 63);
|
||||
$asciiChar = ((($firstByte * 64) + $secondByte) * 64) + $thirdByte;
|
||||
|
||||
$entity = sprintf ("&#%d;", $asciiChar);
|
||||
$outString .= $entity;
|
||||
}
|
||||
else if ($asciiChar >> 3 == 30) //4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
|
||||
{
|
||||
$firstByte = ($asciiChar & 31);
|
||||
$charPosition++;
|
||||
$char = $unicodeString [$charPosition];
|
||||
$asciiChar = ord ($char);
|
||||
$secondByte = ($asciiChar & 63);
|
||||
$charPosition++;
|
||||
$char = $unicodeString [$charPosition];
|
||||
$asciiChar = ord ($char);
|
||||
$thirdByte = ($asciiChar & 63);
|
||||
$charPosition++;
|
||||
$char = $unicodeString [$charPosition];
|
||||
$asciiChar = ord ($char);
|
||||
$fourthByte = ($asciiChar & 63);
|
||||
$asciiChar = ((((($firstByte * 64) + $secondByte) * 64) + $thirdByte) * 64) + $fourthByte;
|
||||
|
||||
$entity = sprintf ("&#%d;", $asciiChar);
|
||||
$outString .= $entity;
|
||||
}
|
||||
}
|
||||
|
||||
return $outString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert unicode characters to unicode HTML entities.
|
||||
* It is very similar to _unicodeEntity function (link below). There is one difference
|
||||
* in returned format. This time it's a regular char(s), in most cases it will be one or two chars.
|
||||
*
|
||||
* @access private
|
||||
* @param string $utfCharInHex Hexadecimal value of a unicode char.
|
||||
* @return string Encoded hexadecimal value as a regular char.
|
||||
* @see _unicodeEntity()
|
||||
**/
|
||||
private function _hexToUtf( $utfCharInHex )
|
||||
{
|
||||
$outputChar = "";
|
||||
$utfCharInDec = hexdec($utfCharInHex);
|
||||
|
||||
if( $utfCharInDec < 128 )
|
||||
{
|
||||
$outputChar .= chr($utfCharInDec);
|
||||
}
|
||||
else if( $utfCharInDec < 2048 )
|
||||
{
|
||||
$outputChar .= chr( ( $utfCharInDec>>6 ) + 192 ) . chr( ( $utfCharInDec&63 ) + 128 );
|
||||
}
|
||||
else if( $utfCharInDec < 65536 )
|
||||
{
|
||||
$outputChar .= chr( ( $utfCharInDec>>12 ) + 224 ) . chr( ( ( $utfCharInDec>>6 ) &63 ) + 128 ) . chr( ( $utfCharInDec&63 ) + 128 );
|
||||
}
|
||||
else if( $utfCharInDec < 2097152 )
|
||||
{
|
||||
$outputChar .= chr( $utfCharInDec>>18+240 ) . chr( ( ( $utfCharInDec>>12 ) &63 ) + 128 ) . chr( ( $utfCharInDec>>6 ) &63 + 128 ) . chr( $utfCharInDec&63 + 128 );
|
||||
}
|
||||
|
||||
return $outputChar;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the conversion tables to use.
|
||||
*
|
||||
* This function creates table with two SBCS (Single Byte Character Set). Every conversion is through this table.
|
||||
*
|
||||
* - The file with encoding tables have to be save in "Format A" of unicode.org charset table format.
|
||||
* - BOTH charsets MUST be SBCS
|
||||
* - The files with encoding tables have to be complete (None of chars can be missing, unles you are sure you are not going to use it)
|
||||
*
|
||||
* "Format A" encoding file, if you have to build it by yourself should aplly these rules:
|
||||
* - you can comment everything with #
|
||||
* - first column contains 1 byte chars in hex starting from 0x..
|
||||
* - second column contains unicode equivalent in hex starting from 0x....
|
||||
* - then every next column is optional, but in "Format A" it should contain unicode char name or/and your own comment
|
||||
* - the columns can be splited by "spaces", "tabs", "," or any combination of these
|
||||
* - below is an example
|
||||
*
|
||||
* <code>
|
||||
* #
|
||||
* # The entries are in ANSI X3.4 order.
|
||||
* #
|
||||
* 0x00 0x0000 # NULL end extra comment, if needed
|
||||
* 0x01 0x0001 # START OF HEADING
|
||||
* # Oh, one more thing, you can make comments inside of a rows if you like.
|
||||
* 0x02 0x0002 # START OF TEXT
|
||||
* 0x03 0x0003 # END OF TEXT
|
||||
* next line, and so on...
|
||||
* </code>
|
||||
*
|
||||
* You can get full tables with encodings from http://www.unicode.org
|
||||
*
|
||||
* @access private
|
||||
* @param string $firstEncoding Name of first encoding and first encoding filename (thay have to be the same)
|
||||
* @param string $secondEncoding Name of second encoding and second encoding filename (thay have to be the same). Optional for building a joined table.
|
||||
* @return array Table necessary to change one encoding to another.
|
||||
**/
|
||||
private function _makeConversionTable( $firstEncoding, $secondEncoding = "" )
|
||||
{
|
||||
$convertTable = array();
|
||||
|
||||
for( $i = 0; $i < func_num_args(); $i++ )
|
||||
{
|
||||
/**
|
||||
* Because func_*** can't be used inside of another function call
|
||||
* we have to save it as a separate value.
|
||||
**/
|
||||
$fileName = func_get_arg($i);
|
||||
|
||||
if ( !is_file( $this->charsetPath . $fileName ) )
|
||||
{
|
||||
$this->errors[] = "FILE_NOT_FOUND: {$fileName}";
|
||||
return;
|
||||
}
|
||||
|
||||
$fileWithEncTabe = fopen( $this->charsetPath . $fileName, "r" ) or die(); //This die(); is just to make sure...
|
||||
|
||||
while(!feof($fileWithEncTabe))
|
||||
{
|
||||
/**
|
||||
* We asume that line is not longer
|
||||
* than 1024 which is the default value for fgets function
|
||||
**/
|
||||
if( $oneLine = trim( fgets( $fileWithEncTabe, 1024 ) ) )
|
||||
{
|
||||
/**
|
||||
* We don't need all comment lines. I check only for "#" sign, because
|
||||
* this is a way of making comments by unicode.org in thair encoding files
|
||||
* and that's where the files are from :-)
|
||||
**/
|
||||
|
||||
if ( substr( $oneLine, 0, 1 ) != "#" )
|
||||
{
|
||||
/**
|
||||
* Sometimes inside the charset file the hex walues are separated by
|
||||
* "space" and sometimes by "tab", the below preg_split can also be used
|
||||
* to split files where separator is a ",", "\r", "\n" and "\f"
|
||||
**/
|
||||
$hexValue = preg_split ( "/[\s,]+/", $oneLine, 3 ); //We need only first 2 values
|
||||
|
||||
/**
|
||||
* Sometimes char is UNDEFINED, or missing so we can't use it for convertion
|
||||
**/
|
||||
|
||||
if (substr($hexValue[1], 0, 1) != "#")
|
||||
{
|
||||
$arrayKey = strtoupper(str_replace(strtolower("0x"), "", $hexValue[1]));
|
||||
$arrayValue = strtoupper(str_replace(strtolower("0x"), "", $hexValue[0]));
|
||||
|
||||
$convertTable[ func_get_arg($i) ][ $arrayKey ] = $arrayValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $convertTable;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,914 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Custom fields library
|
||||
* Last Updated: $Date: 2009-11-03 04:08:58 -0500 (Tue, 03 Nov 2009) $
|
||||
*
|
||||
* @author $Author: matt $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Thursday 8th May 2008 10:31
|
||||
* @version $Revision: 342 $
|
||||
*
|
||||
*/
|
||||
|
||||
abstract class customFieldPlugin
|
||||
{
|
||||
/**
|
||||
* Custom field name
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $name = '';
|
||||
|
||||
/**
|
||||
* Custom field title
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $title = '';
|
||||
|
||||
/**
|
||||
* Custom field id
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
**/
|
||||
public $id = 0;
|
||||
|
||||
/**
|
||||
* Custom field attributes
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
**/
|
||||
public $attributes = array();
|
||||
|
||||
/**
|
||||
* Custom field value
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
**/
|
||||
public $raw_data = array();
|
||||
|
||||
/**
|
||||
* Custom field mode
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $mode = '';
|
||||
|
||||
/**
|
||||
* Allows you to treat a custom field type as a string
|
||||
*
|
||||
* @access public
|
||||
* @return string Current value of $this->parsed
|
||||
**/
|
||||
public function __tostring()
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the field
|
||||
*
|
||||
* @access public
|
||||
* @return string Current value of $this->parsed
|
||||
**/
|
||||
public function getValue()
|
||||
{
|
||||
if( is_array( $this->parsed ) )
|
||||
{
|
||||
return implode( ",", $this->parsed );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->parsed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an attribute string from an array
|
||||
*
|
||||
* @access protected
|
||||
* @return string
|
||||
**/
|
||||
protected function _compileAttributes()
|
||||
{
|
||||
$_attributes = '';
|
||||
|
||||
if( is_array( $this->attributes ) )
|
||||
{
|
||||
foreach( $this->attributes as $k => $v )
|
||||
{
|
||||
$_attributes .= " {$k}='{$v}'";
|
||||
}
|
||||
}
|
||||
|
||||
return $_attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes harmful html from display
|
||||
*
|
||||
* @access protected
|
||||
* @var string String to make safe
|
||||
* @return string
|
||||
**/
|
||||
protected function makeSafeForView( $t )
|
||||
{
|
||||
$t = htmlspecialchars( $t, ENT_QUOTES );
|
||||
$t = preg_replace("/&#([0-9]+);/s", "&#\\1;", $t );
|
||||
$t = nl2br( $t );
|
||||
|
||||
return $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format value for display in a form field
|
||||
*
|
||||
* @access protected
|
||||
* @var string String to make safe
|
||||
* @return string
|
||||
**/
|
||||
protected function makeSafeForForm( $t )
|
||||
{
|
||||
return str_replace( "'", "'", $t );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for custom fields
|
||||
*
|
||||
**/
|
||||
interface interfaceCustomFieldPlugin
|
||||
{
|
||||
/**
|
||||
* Editing a custom field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function edit();
|
||||
|
||||
/**
|
||||
* Viewing a custom field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function view();
|
||||
}
|
||||
|
||||
/**
|
||||
* Text input custom fields
|
||||
*
|
||||
**/
|
||||
class customFieldText extends customFieldPlugin implements interfaceCustomFieldPlugin
|
||||
{
|
||||
/**
|
||||
* Plugin type
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $plugin_type = '';
|
||||
|
||||
/**
|
||||
* Value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $value = '';
|
||||
|
||||
/**
|
||||
* Parsed value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $parsed = '';
|
||||
|
||||
/**
|
||||
* CONSTRUCTOR
|
||||
*
|
||||
* @access public
|
||||
* @param array $field Array of field data { id, data, value, class }
|
||||
* @param string $mode Set to 'view' or 'edit'
|
||||
* @return void
|
||||
**/
|
||||
public function __construct( $field, $mode )
|
||||
{
|
||||
/* INI */
|
||||
$this->value = $field['value'];
|
||||
$this->plugin_type = $field['type'];
|
||||
$this->name = 'field_' . $field['id'];
|
||||
$this->id = $field['id'];
|
||||
$this->title = isset( $field['title'] ) ? $field['title'] : '';
|
||||
$this->attributes = isset( $field['attributes'] ) ? $field['attributes'] : '';
|
||||
$this->raw_data = $field;
|
||||
$this->mode = $mode;
|
||||
|
||||
if( $mode == 'edit' )
|
||||
{
|
||||
$this->edit();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* edit a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function edit()
|
||||
{
|
||||
/* Attributes */
|
||||
$_attributes = $this->_compileAttributes();
|
||||
|
||||
/* Make Safe */
|
||||
$this->value = $this->makeSafeForForm( $this->value );
|
||||
|
||||
if( $this->plugin_type == 'input' )
|
||||
{
|
||||
$this->parsed = "<input type='text' id='{$this->name}' size='40' class='input_text' name='{$this->name}' value='{$this->value}'{$_attributes}/>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parsed = "<textarea id='{$this->name}' class='input_text' cols='60' rows='4' name='{$this->name}'{$_attributes}>{$this->value}</textarea>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* view a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function view()
|
||||
{
|
||||
/* Make Safe */
|
||||
$this->value = $this->makeSafeForView( $this->value );
|
||||
$this->parsed = $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check boxes button custom fields
|
||||
*
|
||||
**/
|
||||
class customFieldCbox extends customFieldPlugin implements interfaceCustomFieldPlugin
|
||||
{
|
||||
/**
|
||||
* Plugin type
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $plugin_type = 'radio';
|
||||
|
||||
/**
|
||||
* Value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $value = '';
|
||||
|
||||
/**
|
||||
* Parsed value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $parsed = '';
|
||||
|
||||
/**
|
||||
* Data
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $data = '';
|
||||
|
||||
/**
|
||||
* CONSTRUCTOR
|
||||
*
|
||||
* @access public
|
||||
* @param array $field Array of field data { id, data, value, class }
|
||||
* @param string $mode Set to 'view' or 'edit'
|
||||
* @return void
|
||||
**/
|
||||
public function __construct( $field, $mode )
|
||||
{
|
||||
/* INI */
|
||||
$this->data = $field['data'];
|
||||
$this->value = $field['value'];
|
||||
$this->name = 'field_' . $field['id'];
|
||||
$this->id = $field['id'];
|
||||
$this->title = $field['title'];
|
||||
$this->attributes = $field['attributes'];
|
||||
$this->raw_data = $field;
|
||||
$this->mode = $mode;
|
||||
|
||||
if( $mode == 'edit' )
|
||||
{
|
||||
$this->edit();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* edit a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function edit()
|
||||
{
|
||||
/* INI */
|
||||
$carray = explode( '|', $this->data );
|
||||
$def_values = ( is_array( $this->value ) ) ? $this->value : explode( '|', $this->value );
|
||||
$_attributes = $this->_compileAttributes();
|
||||
|
||||
/* Make Safe */
|
||||
foreach( $def_values as $k => $v )
|
||||
{
|
||||
$def_values[$k] = $this->makeSafeForForm( $v );
|
||||
}
|
||||
|
||||
foreach( $carray as $entry )
|
||||
{
|
||||
$value = explode( '=', $entry );
|
||||
|
||||
$ov = trim( $value[0] );
|
||||
$td = trim( $value[1] );
|
||||
|
||||
if( in_array( $ov, $def_values ) )
|
||||
{
|
||||
$this->parsed .= "<p><input type='checkbox' class='input_check' id='{$this->name}_{$ov}' name='{$this->name}[$ov]' value='1' checked='checked'{$_attributes}/> $td</p>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parsed .= "<p><input type='checkbox' class='input_check' id='{$this->name}_{$ov}' name='{$this->name}[$ov]' value='1'{$_attributes}/> $td</p>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* view a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function view()
|
||||
{
|
||||
/* INI */
|
||||
$carray = explode( '|', $this->data );
|
||||
$curr_values = ( is_array( $this->value ) ) ? $this->value : explode( '|', $this->value );
|
||||
$parsed = array();
|
||||
|
||||
/* Make Safe */
|
||||
foreach( $curr_values as $k => $v )
|
||||
{
|
||||
$curr_values[$k] = $this->makeSafeForView( $v );
|
||||
}
|
||||
|
||||
foreach( $carray as $entry )
|
||||
{
|
||||
$value = explode( '=', $entry );
|
||||
|
||||
if( in_array( trim( $value[0] ), $curr_values ) )
|
||||
{
|
||||
$this->parsed[] = trim( $value[1] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Radio button custom fields
|
||||
*
|
||||
**/
|
||||
class customFieldRadio extends customFieldPlugin implements interfaceCustomFieldPlugin
|
||||
{
|
||||
/**
|
||||
* Plugin type
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $plugin_type = 'radio';
|
||||
|
||||
/**
|
||||
* Value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $value = '';
|
||||
|
||||
/**
|
||||
* Parsed value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $parsed = '';
|
||||
|
||||
/**
|
||||
* Data
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $data = '';
|
||||
|
||||
/**
|
||||
* CONSTRUCTOR
|
||||
*
|
||||
* @access public
|
||||
* @param array $field Array of field data { id, data, value, class }
|
||||
* @param string $mode Set to 'view' or 'edit'
|
||||
* @return void
|
||||
**/
|
||||
public function __construct( $field, $mode )
|
||||
{
|
||||
/* INI */
|
||||
$this->data = $field['data'];
|
||||
$this->value = $field['value'];
|
||||
$this->name = 'field_' . $field['id'];
|
||||
$this->id = $field['id'];
|
||||
$this->title = $field['title'];
|
||||
$this->attributes = $field['attributes'];
|
||||
$this->raw_data = $field;
|
||||
$this->mode = $mode;
|
||||
|
||||
if( $mode == 'edit' )
|
||||
{
|
||||
$this->edit();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* edit a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function edit()
|
||||
{
|
||||
/* Attributes */
|
||||
$_attributes = $this->_compileAttributes();
|
||||
|
||||
$carray = explode( '|', $this->data );
|
||||
|
||||
foreach( $carray as $entry )
|
||||
{
|
||||
$value = explode( '=', $entry );
|
||||
|
||||
$ov = trim( $value[0] );
|
||||
$td = trim( $value[1] );
|
||||
|
||||
/* Make Safe */
|
||||
$this->value = $this->makeSafeForForm( $this->value );
|
||||
|
||||
if( $this->value == $ov and $this->value )
|
||||
{
|
||||
$this->parsed .= "<input type='radio' class='input_radio' id='{$this->name}_{$ov}' name='{$this->name}' value='$ov' checked='checked'{$_attributes}/> $td\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parsed .= "<input type='radio' class='input_radio' id='{$this->name}_{$ov}' name='{$this->name}' value='$ov'{$_attributes}/> $td\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* view a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function view()
|
||||
{
|
||||
/* INI */
|
||||
$carray = explode( '|', $this->data );
|
||||
$curr_values = ( is_array( $this->value ) ) ? $this->value : array( $this->value );
|
||||
|
||||
/* Make Safe */
|
||||
foreach( $curr_values as $k => $v )
|
||||
{
|
||||
$curr_values[$k] = $this->makeSafeForView( $v );
|
||||
}
|
||||
|
||||
foreach( $carray as $entry )
|
||||
{
|
||||
$value = explode( '=', $entry );
|
||||
|
||||
if( in_array( trim( $value[0] ), $curr_values ) )
|
||||
{
|
||||
$this->parsed = trim( $value[1] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dropdown custom fields
|
||||
*
|
||||
**/
|
||||
class customFieldDrop extends customFieldPlugin implements interfaceCustomFieldPlugin
|
||||
{
|
||||
/**
|
||||
* Plugin type
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $plugin_type = 'drop';
|
||||
|
||||
/**
|
||||
* Value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $value = '';
|
||||
|
||||
/**
|
||||
* Parsed value
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $parsed = '';
|
||||
|
||||
/**
|
||||
* Data
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
**/
|
||||
public $data = '';
|
||||
|
||||
/**
|
||||
* Allow multi-input
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
**/
|
||||
private $multi = false;
|
||||
|
||||
/**
|
||||
* CONSTRUCTOR
|
||||
*
|
||||
* @access public
|
||||
* @param array $field Array of field data { id, data, value, class }
|
||||
* @param string $mode Set to 'view' or 'edit'
|
||||
* @return void
|
||||
**/
|
||||
public function __construct( $field, $mode )
|
||||
{
|
||||
/* INI */
|
||||
$this->data = $field['data'];
|
||||
$this->value = $field['value'];
|
||||
$this->multi = ( isset( $field['multi'] ) && $field['multi'] == 1 ) ? 1 : 0;
|
||||
$this->name = $this->multi ? 'field_' . $field['id'] . '[]' : 'field_' . $field['id'];
|
||||
$this->id = $field['id'];
|
||||
$this->title = isset( $field['title'] ) ? $field['title'] : '';
|
||||
$this->attributes = isset( $field['attributes'] ) ? $field['attributes'] : '';
|
||||
$this->raw_data = $field;
|
||||
$this->mode = $mode;
|
||||
|
||||
if( $mode == 'edit' )
|
||||
{
|
||||
$this->edit();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* edit a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function edit()
|
||||
{
|
||||
/* INI */
|
||||
$carray = explode( '|', $this->data );
|
||||
$multi = ( isset( $this->multi ) && $this->multi ) ? " multiple='multiple'" : '';
|
||||
$def_values = ( is_array( $this->value ) ) ? $this->value : array( $this->value );
|
||||
$_attributes = $this->_compileAttributes();
|
||||
|
||||
/* Make Safe */
|
||||
foreach( $def_values as $k => $v )
|
||||
{
|
||||
$def_values[$k] = $this->makeSafeForForm( $v );
|
||||
}
|
||||
|
||||
/* Start the select tag */
|
||||
$this->parsed = "<select id='{$this->name}' class='input_select' name='{$this->name}'{$multi}{$_attributes}>\n";
|
||||
|
||||
foreach( $carray as $entry )
|
||||
{
|
||||
$value = explode( '=', $entry );
|
||||
|
||||
$ov = trim( $value[0] );
|
||||
$td = trim( $value[1] );
|
||||
|
||||
if( in_array( $ov, $def_values ) )
|
||||
{
|
||||
$this->parsed .= "<option value='$ov' selected='selected'>$td</option>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parsed .= "<option value='$ov'>$td</option>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* End the tag */
|
||||
$this->parsed .= "</select>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* view a field
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function view()
|
||||
{
|
||||
/* INI */
|
||||
$carray = explode( '|', $this->data );
|
||||
$curr_values = ( is_array( $this->value ) ) ? $this->value : array( $this->value );
|
||||
|
||||
/* Make Safe */
|
||||
foreach( $curr_values as $k => $v )
|
||||
{
|
||||
$curr_values[$k] = $this->makeSafeForView( $v );
|
||||
}
|
||||
|
||||
foreach( $carray as $entry )
|
||||
{
|
||||
$value = explode( '=', $entry );
|
||||
|
||||
if( in_array( trim( $value[0] ), $curr_values ) )
|
||||
{
|
||||
$this->parsed[] = trim( $value[1] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Primary custom fields class
|
||||
*
|
||||
**/
|
||||
class classCustomFields
|
||||
{
|
||||
/**
|
||||
* List of fields
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
**/
|
||||
private $field_list = array();
|
||||
|
||||
/**
|
||||
* Loaded plugins
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
**/
|
||||
public $loaded_plugins = array();
|
||||
|
||||
/**
|
||||
* Mode
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
**/
|
||||
private $mode = '';
|
||||
|
||||
/**
|
||||
* Custom Fields
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
**/
|
||||
public $cfields = array();
|
||||
|
||||
/**
|
||||
* CONSTRUCTOR
|
||||
*
|
||||
* @access public
|
||||
* @param array Field data
|
||||
* @param string Mode
|
||||
* @return void
|
||||
**/
|
||||
public function __construct( $field_data, $mode='view' )
|
||||
{
|
||||
/* Setup */
|
||||
$this->field_list = $field_data;
|
||||
$this->mode = $mode;
|
||||
|
||||
$this->loaded_plugins['drop'] = 'customFieldDrop';
|
||||
$this->loaded_plugins['radio'] = 'customFieldRadio';
|
||||
$this->loaded_plugins['text'] = 'customFielText';
|
||||
$this->loaded_plugins['cbox'] = 'customFieldCbox';
|
||||
|
||||
/* Loop through and build custom fields */
|
||||
foreach( $this->field_list as $field )
|
||||
{
|
||||
$this->cfields[ $field['id'] ] = $this->parseField( $field );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of supported field types
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
**/
|
||||
public function getFieldTypes()
|
||||
{
|
||||
return array(
|
||||
array( 'drop' , ipsRegistry::instance()->getClass('class_localization')->words['cf_drop'] ),
|
||||
array( 'cbox' , ipsRegistry::instance()->getClass('class_localization')->words['cf_cbox'] ),
|
||||
array( 'radio' , ipsRegistry::instance()->getClass('class_localization')->words['cf_radio'] ),
|
||||
array( 'input' , ipsRegistry::instance()->getClass('class_localization')->words['cf_input'] ),
|
||||
array( 'textarea' , ipsRegistry::instance()->getClass('class_localization')->words['cf_textarea'] ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a submitted form for custom fields
|
||||
*
|
||||
* @access public
|
||||
* @param array Array of field data
|
||||
* @return array ( 'save_array', 'errors' )
|
||||
**/
|
||||
public function getFieldsToSave( $input_array )
|
||||
{
|
||||
/* INI */
|
||||
$save_data = array();
|
||||
$errors = array();
|
||||
|
||||
/* Loop through all the fields */
|
||||
foreach( $this->field_list as $field )
|
||||
{
|
||||
/* Submitted Value */
|
||||
$submit_value = $this->formatTextToSave( $input_array[ 'field_' . $field['id'] ] );
|
||||
|
||||
if( ! is_array( $submit_value ) )
|
||||
{
|
||||
$submit_value = trim( $submit_value );
|
||||
}
|
||||
|
||||
/* Check for restrictions */
|
||||
if( isset( $field['restrictions'] ) && is_array( $field['restrictions'] ) )
|
||||
{
|
||||
/* Size Restriction */
|
||||
if( $field['restrictions']['max_size'] && IPSText::mbstrlen( $submit_value ) > $field['restrictions']['max_size'] )
|
||||
{
|
||||
$errors[ 'field_' . $field['id'] ][] = 'too_big';
|
||||
}
|
||||
|
||||
/* Size Restriction */
|
||||
if( $field['restrictions']['min_size'] && IPSText::mbstrlen( $submit_value ) < $field['restrictions']['min_size'] )
|
||||
{
|
||||
$errors[ 'field_' . $field['id'] ][] = 'too_small';
|
||||
}
|
||||
|
||||
/* Null restriction */
|
||||
if( $field['restrictions']['not_null'] && ( (string)$submit_value !== '0' AND !$submit_value) )
|
||||
{
|
||||
$errors[ 'field_' . $field['id'] ][] = 'empty';
|
||||
}
|
||||
|
||||
/* Format Restriction */
|
||||
if( $field['restrictions']['format'] && $submit_value )
|
||||
{
|
||||
$regex = str_replace( 'n', '\\d', preg_quote( $field['restrictions']['format'], "#" ) );
|
||||
$regex = str_replace( 'a', '\\w', $regex );
|
||||
|
||||
if ( ! preg_match( "#^".$regex."$#i", $submit_value ) )
|
||||
{
|
||||
$errors[ 'field_' . $field['id'] ][] = 'invalid';
|
||||
}
|
||||
}
|
||||
|
||||
/* Check box? */
|
||||
if ( $field['type'] == 'cbox' )
|
||||
{
|
||||
if ( is_array( $input_array[ 'field_' . $field['id'] ] ) AND count( $input_array[ 'field_' . $field['id'] ] ) )
|
||||
{
|
||||
$submit_value = '|' . implode( '|', array_keys( $input_array[ 'field_' . $field['id'] ] ) ) . '|';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add to save */
|
||||
$this->field_list[$field['id']]['value'] = $submit_value;
|
||||
$save_data[ 'field_' . $field['id'] ] = $submit_value;
|
||||
}
|
||||
|
||||
return array( 'save_array' => $save_data, 'errors' => $errors );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsed a field for display
|
||||
*
|
||||
* @access private
|
||||
* @param array $field Array of field data
|
||||
* @param string [$mode] View/Edit, or blank for class default
|
||||
* @return object
|
||||
**/
|
||||
private function parseField( $field, $mode='' )
|
||||
{
|
||||
/* INI */
|
||||
$mode = ( $mode ) ? $mode : $this->mode;
|
||||
|
||||
/* Check the type of field */
|
||||
if( isset( $this->loaded_plugins[$field['type']] ) && class_exists( $this->loaded_plugins[$field['type']] ) )
|
||||
{
|
||||
return new $this->loaded_plugins[$field['type']]( $field, $mode );
|
||||
}
|
||||
else
|
||||
{
|
||||
return new customFieldText( $field, $mode );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the content field for a textarea
|
||||
*
|
||||
* @access public
|
||||
* @param string Content to format
|
||||
* @return string
|
||||
**/
|
||||
public function formatContentForEdit( $c )
|
||||
{
|
||||
return str_replace( '|', "\n", $c );
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the content field for saveing in the database
|
||||
*
|
||||
* @access public
|
||||
* @param string Content to format
|
||||
* @return string
|
||||
**/
|
||||
public function formatContentForSave( $c )
|
||||
{
|
||||
$c = str_replace( "\r" , "\n", $c );
|
||||
$c = str_replace( "'", "'" , $c );
|
||||
return str_replace( "\n", '|', str_replace( "\n\n", "\n", trim($c) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Foramts text for saving into the database
|
||||
*
|
||||
* @access public
|
||||
* @var string String to make safe
|
||||
* @return string
|
||||
**/
|
||||
private function formatTextToSave( $t )
|
||||
{
|
||||
$t = str_replace( "<br>" , "\n", $t );
|
||||
$t = str_replace( "<br />", "\n", $t );
|
||||
$t = str_replace( "'" , "'" , $t );
|
||||
|
||||
if ( @get_magic_quotes_gpc() )
|
||||
{
|
||||
$t = stripslashes($t);
|
||||
}
|
||||
|
||||
return $t;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,609 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* MySQL Database Driver :: MySQL client
|
||||
* Last Updated: $Date: 2009-09-15 08:34:24 -0400 (Tue, 15 Sep 2009) $
|
||||
*
|
||||
* @author $Author: matt $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Monday 28th February 2005 16:46
|
||||
* @version $Revision: 327 $
|
||||
*/
|
||||
|
||||
class db_driver_mysql extends db_main_mysql implements interfaceDb
|
||||
{
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if( !defined('MYSQLI_USED') )
|
||||
{
|
||||
define( 'MYSQLI_USED', 1 );
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
// Set up any required connect vars here
|
||||
//--------------------------------------
|
||||
|
||||
$this->connect_vars['mysql_tbl_type'] = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database server
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Connection successful
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Done SQL prefix yet?
|
||||
//-----------------------------------------
|
||||
|
||||
$this->_setPrefix();
|
||||
|
||||
//-----------------------------------------
|
||||
// Load query file
|
||||
//-----------------------------------------
|
||||
|
||||
$this->_loadCacheFile();
|
||||
|
||||
//-----------------------------------------
|
||||
// Connect
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $this->obj['persistent'] AND ! IPS_MAIN_DB_CLASS_LEGACY )
|
||||
{
|
||||
$this->connection_id = @mysql_pconnect( $this->obj['sql_host'] ,
|
||||
$this->obj['sql_user'] ,
|
||||
$this->obj['sql_pass'] ,
|
||||
$this->obj['force_new_connection']
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( IPS_MAIN_DB_CLASS_LEGACY )
|
||||
{
|
||||
$this->connection_id = @mysql_connect( $this->obj['sql_host'] ,
|
||||
$this->obj['sql_user'] ,
|
||||
$this->obj['sql_pass']
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connection_id = @mysql_connect( $this->obj['sql_host'] ,
|
||||
$this->obj['sql_user'] ,
|
||||
$this->obj['sql_pass'] ,
|
||||
$this->obj['force_new_connection']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $this->connection_id )
|
||||
{
|
||||
$this->throwFatalError();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! mysql_select_db($this->obj['sql_database'], $this->connection_id) )
|
||||
{
|
||||
$this->throwFatalError();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Remove sensitive data
|
||||
//-----------------------------------------
|
||||
|
||||
unset( $this->obj['sql_host'] );
|
||||
unset( $this->obj['sql_user'] );
|
||||
unset( $this->obj['sql_pass'] );
|
||||
|
||||
//-----------------------------------------
|
||||
// If there's a charset set, run it
|
||||
//-----------------------------------------
|
||||
|
||||
if( $this->obj['sql_charset'] )
|
||||
{
|
||||
$this->query( "SET NAMES '{$this->obj['sql_charset']}'" );
|
||||
$this->query( "SET CHARACTER SET '{$this->obj['sql_charset']}'");
|
||||
$this->query( "SET character_set_connection = " .$this->obj['sql_charset']);
|
||||
|
||||
$res = mysql_query( "SHOW CHARSET LIKE '" . $this->obj['sql_charset'] . "'", $this->connection_id );
|
||||
|
||||
$charset = mysql_fetch_row($res);
|
||||
|
||||
$this->query( "SET collation_connection = " . $charset[2] );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close database connection
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Closed successfully
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if ( $this->connection_id )
|
||||
{
|
||||
return @mysql_close( $this->connection_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a direct database query
|
||||
*
|
||||
* @access public
|
||||
* @param string Database query
|
||||
* @param boolean [Optional] Do not convert table prefix
|
||||
* @return resource Query id
|
||||
*/
|
||||
public function query( $the_query, $bypass=false )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Change the table prefix if needed
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $this->no_prefix_convert )
|
||||
{
|
||||
$bypass = 1;
|
||||
}
|
||||
|
||||
if ( ! $bypass )
|
||||
{
|
||||
if ( $this->obj['sql_tbl_prefix'] != "ibf_" and ! $this->prefix_changed )
|
||||
{
|
||||
//$the_query = preg_replace("/\sibf_(\S+?)([\s\.,]|$)/", " ".$this->obj['sql_tbl_prefix']."\\1\\2", $the_query);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Debug?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $this->obj['debug'] OR ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] ) )
|
||||
{
|
||||
IPSDebug::startTimer();
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Stop sub selects? (UNION)
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! IPS_DB_ALLOW_SUB_SELECTS )
|
||||
{
|
||||
# On the spot allowance?
|
||||
if ( ! $this->allow_sub_select )
|
||||
{
|
||||
$_tmp = strtolower( $this->_removeAllQuotes($the_query) );
|
||||
|
||||
if ( preg_match( "#(?:/\*|\*/)#i", $_tmp ) )
|
||||
{
|
||||
$this->throwFatalError( "Не разрешается использовать комментарии в SQL запросе.\nДобавьте \ipsRegistry::DB()->allow_sub_select=1; перед запросом, чтобы разрешить их\n{$the_query}" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( preg_match( "#[^_a-zA-Z]union[^_a-zA-Z]#s", $_tmp ) )
|
||||
{
|
||||
$this->throwFatalError( "Использование UNION в запросах запрещено.\nДобавьте \ipsRegistry::DB()->allow_sub_select=1; перед запросом, чтобы разрешить использование\n{$the_query}" );
|
||||
return false;
|
||||
}
|
||||
else if ( preg_match_all( "#[^_a-zA-Z](select)[^_a-zA-Z]#s", $_tmp, $matches ) )
|
||||
{
|
||||
if ( count( $matches ) > 1 )
|
||||
{
|
||||
$this->throwFatalError( "Вложенные SELECT в запросах запрещены.\nДобавьте \ipsRegistry::DB()->allow_sub_select=1; перед запросом, чтобы разрешить их\n{$the_query}" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Run the query
|
||||
//-----------------------------------------
|
||||
|
||||
#I had to switch this around... The query goes first, connection id second. Otherwise it just breaks - KF
|
||||
#$this->query_id = mysql_query($this->connection_id, $the_query );
|
||||
$this->query_id = mysql_query( $the_query, $this->connection_id );
|
||||
|
||||
//-----------------------------------------
|
||||
// Reset array...
|
||||
//-----------------------------------------
|
||||
|
||||
$this->force_data_type = array();
|
||||
$this->allow_sub_select = false;
|
||||
|
||||
if (! $this->query_id )
|
||||
{
|
||||
$this->throwFatalError("mySQL query error: $the_query");
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Debug?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] ) OR ( $this->obj['use_bad_log'] AND $this->obj['bad_log'] ) OR ( $this->obj['use_slow_log'] AND $this->obj['slow_log'] ) )
|
||||
{
|
||||
$endtime = IPSDebug::endTimer();
|
||||
$_data = '';
|
||||
|
||||
if ( preg_match( "/^(?:\()?select/i", $the_query ) )
|
||||
{
|
||||
$eid = mysql_query("EXPLAIN {$the_query}", $this->connection_id);
|
||||
$_bad = false;
|
||||
|
||||
while( $array = mysql_fetch_array($eid) )
|
||||
{
|
||||
$array['extra'] = isset( $array['extra'] ) ? $array['extra'] : '';
|
||||
|
||||
$_data .= "\n+------------------------------------------------------------------------------+";
|
||||
$_data .= "\n|Table: ". $array['table'];
|
||||
$_data .= "\n|Type: ". $array['type'];
|
||||
$_data .= "\n|Possible Keys: ". $array['possible_keys'];
|
||||
$_data .= "\n|Key: ". $array['key'];
|
||||
$_data .= "\n|Key Len: ". $array['key_len'];
|
||||
$_data .= "\n|Ref: ". $array['ref'];
|
||||
$_data .= "\n|Rows: ". $array['rows'];
|
||||
$_data .= "\n|Extra: ". $array['Extra'];
|
||||
//$_data .= "\n+------------------------------------------------------------------------------+";
|
||||
|
||||
if ( ( $this->obj['use_bad_log'] AND $this->obj['bad_log'] ) AND stristr( $array['Extra'], 'filesort' ) OR stristr( $array['Extra'], 'temporary' ) )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime, $this->obj['bad_log'], TRUE );
|
||||
}
|
||||
|
||||
if ( ( $this->obj['use_slow_log'] AND $this->obj['slow_log'] ) AND $endtime >= $this->obj['use_slow_log'] )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime, $this->obj['slow_log'], TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Debugging?
|
||||
//-----------------------------------------
|
||||
|
||||
if ($this->obj['debug'])
|
||||
{
|
||||
$endtime = IPSDebug::endTimer();
|
||||
|
||||
$shutdown = $this->is_shutdown ? 'SHUTDOWN QUERY: ' : '';
|
||||
|
||||
if ( preg_match( "/^(?:\()?select/i", $the_query ) )
|
||||
{
|
||||
$eid = mysql_query( "EXPLAIN {$the_query}", $this->connection_id );
|
||||
|
||||
$this->debug_html .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FFE8F3' align='center'>
|
||||
<tr>
|
||||
<td colspan='8' style='font-size:14px' bgcolor='#FFC5Cb'><b>{$shutdown}Select Query</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='8' style='font-family:courier, monaco, arial;font-size:14px;color:black'>$the_query</td>
|
||||
</tr>
|
||||
<tr bgcolor='#FFC5Cb'>
|
||||
<td><b>table</b></td><td><b>type</b></td><td><b>possible_keys</b></td>
|
||||
<td><b>key</b></td><td><b>key_len</b></td><td><b>ref</b></td>
|
||||
<td><b>rows</b></td><td><b>Extra</b></td>
|
||||
</tr>\n";
|
||||
while( $array = mysql_fetch_array($eid) )
|
||||
{
|
||||
$type_col = '#FFFFFF';
|
||||
|
||||
if ($array['type'] == 'ref' or $array['type'] == 'eq_ref' or $array['type'] == 'const')
|
||||
{
|
||||
$type_col = '#D8FFD4';
|
||||
}
|
||||
else if ($array['type'] == 'ALL')
|
||||
{
|
||||
$type_col = '#FFEEBA';
|
||||
}
|
||||
|
||||
$this->debug_html .= "<tr bgcolor='#FFFFFF'>
|
||||
<td>$array[table] </td>
|
||||
<td bgcolor='$type_col'>$array[type] </td>
|
||||
<td>$array[possible_keys] </td>
|
||||
<td>$array[key] </td>
|
||||
<td>$array[key_len] </td>
|
||||
<td>$array[ref] </td>
|
||||
<td>$array[rows] </td>
|
||||
<td>$array[Extra] </td>
|
||||
</tr>\n";
|
||||
}
|
||||
|
||||
$this->sql_time += $endtime;
|
||||
|
||||
if ($endtime > 0.1)
|
||||
{
|
||||
$endtime = "<span style='color:red'><b>$endtime</b></span>";
|
||||
}
|
||||
|
||||
$this->debug_html .= "<tr>
|
||||
<td colspan='8' bgcolor='#FFD6DC' style='font-size:14px'><b>MySQL time</b>: $endtime</b></td>
|
||||
</tr>
|
||||
</table>\n<br />\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->debug_html .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FEFEFE' align='center'>
|
||||
<tr>
|
||||
<td style='font-size:14px' bgcolor='#EFEFEF'><b>{$shutdown}Non Select Query</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='font-family:courier, monaco, arial;font-size:14px'>$the_query</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='font-size:14px' bgcolor='#EFEFEF'><b>MySQL time</b>: $endtime</span></td>
|
||||
</tr>
|
||||
</table><br />\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
$this->query_count++;
|
||||
|
||||
$this->obj['cached_queries'][] = $the_query;
|
||||
|
||||
return $this->query_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve number of rows affected by last query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Number of rows affected by last query
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return mysql_affected_rows( $this->connection_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve number of rows in result set
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query id
|
||||
* @return integer Number of rows in result set
|
||||
*/
|
||||
public function getTotalRows( $query_id=null )
|
||||
{
|
||||
if ( ! $query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
return mysql_num_rows( $query_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve latest autoincrement insert id
|
||||
*
|
||||
* @access public
|
||||
* @return integer Last autoincrement id assigned
|
||||
*/
|
||||
public function getInsertId()
|
||||
{
|
||||
return mysql_insert_id($this->connection_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current thread id
|
||||
*
|
||||
* @access public
|
||||
* @return integer Current thread id
|
||||
*/
|
||||
public function getThreadId()
|
||||
{
|
||||
return mysql_thread_id($this->connection_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free result set from memory
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query id
|
||||
* @return void
|
||||
*/
|
||||
public function freeResult( $query_id=null )
|
||||
{
|
||||
if ( ! $query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
@mysql_free_result( $query_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve row from database
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query result id
|
||||
* @return mixed Result set array, or void
|
||||
*/
|
||||
public function fetch( $query_id=null )
|
||||
{
|
||||
if ( ! $query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
$this->record_row = mysql_fetch_array( $query_id, MYSQL_ASSOC );
|
||||
|
||||
return $this->record_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number calculated rows (as if there was no limit clause)
|
||||
*
|
||||
* @access public
|
||||
* @param string [ alias name for the count(*) ]
|
||||
* @return int The number of rows
|
||||
*/
|
||||
public function fetchCalculatedRows( $alias='count' )
|
||||
{
|
||||
$calcRowsHandle = mysql_query( "SELECT FOUND_ROWS() as " . $alias, $this->connection_id );
|
||||
|
||||
$val = mysql_fetch_array( $calcRowsHandle, MYSQL_ASSOC );
|
||||
|
||||
return intval( $val[ $alias ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of fields in result set
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query id
|
||||
* @return array Fields in result set
|
||||
*/
|
||||
public function getResultFields( $query_id=null )
|
||||
{
|
||||
$fields = array();
|
||||
|
||||
if ( !$query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
while( $field = mysql_fetch_field($query_id) )
|
||||
{
|
||||
$fields[] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of table names in database
|
||||
*
|
||||
* @access public
|
||||
* @return array SQL tables
|
||||
*/
|
||||
public function getTableNames()
|
||||
{
|
||||
if ( is_array( $this->cached_tables ) AND count( $this->cached_tables ) )
|
||||
{
|
||||
return $this->cached_tables;
|
||||
}
|
||||
|
||||
$current = $this->return_die;
|
||||
$this->return_die = true;
|
||||
|
||||
$qid = $this->query( "SHOW TABLES FROM `{$this->obj['sql_database']}`" );
|
||||
|
||||
$this->return_die = $current;
|
||||
|
||||
if( $qid AND $this->getTotalRows($qid) )
|
||||
{
|
||||
while( $result = mysql_fetch_array($qid) )
|
||||
{
|
||||
$this->cached_tables[] = $result[0];
|
||||
}
|
||||
}
|
||||
|
||||
mysql_free_result($qid);
|
||||
|
||||
return $this->cached_tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve SQL server version
|
||||
*
|
||||
* @access public
|
||||
* @return string SQL Server version
|
||||
*/
|
||||
public function getSqlVersion()
|
||||
{
|
||||
if ( ! $this->sql_version and ! $this->true_version )
|
||||
{
|
||||
$this->query( "SELECT VERSION() AS version" );
|
||||
|
||||
if ( ! $row = $this->fetch() )
|
||||
{
|
||||
$this->query( "SHOW VARIABLES LIKE 'version' ");
|
||||
$row = $this->fetch();
|
||||
}
|
||||
|
||||
$this->true_version = $row['version'];
|
||||
$tmp = explode( '.', preg_replace( "#[^\d\.]#", "\\1", $row['version'] ) );
|
||||
|
||||
$this->sql_version = sprintf('%d%02d%02d', $tmp[0], $tmp[1], $tmp[2] );
|
||||
}
|
||||
|
||||
return $this->sql_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape strings for DB insertion
|
||||
*
|
||||
* @access public
|
||||
* @param string Text to escape
|
||||
* @return string Escaped text
|
||||
*/
|
||||
public function addSlashes( $t )
|
||||
{
|
||||
return ( IPS_MAIN_DB_CLASS_LEGACY ) ? mysql_escape_string($t) : mysql_real_escape_string($t, $this->connection_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SQL error number
|
||||
*
|
||||
* @access protected
|
||||
* @return mixed Error number/code
|
||||
*/
|
||||
protected function _getErrorNumber()
|
||||
{
|
||||
if( $this->connection_id )
|
||||
{
|
||||
return @mysql_errno( $this->connection_id );
|
||||
}
|
||||
else
|
||||
{
|
||||
return @mysql_errno();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SQL error message
|
||||
*
|
||||
* @access protected
|
||||
* @return string Error message
|
||||
*/
|
||||
protected function _getErrorString()
|
||||
{
|
||||
if( $this->connection_id )
|
||||
{
|
||||
return @mysql_error( $this->connection_id );
|
||||
}
|
||||
else
|
||||
{
|
||||
return @mysql_error();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end class
|
||||
@@ -0,0 +1,625 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* MySQL Database Driver :: MySQLi client
|
||||
* Last Updated: $Date: 2009-09-15 08:34:24 -0400 (Tue, 15 Sep 2009) $
|
||||
*
|
||||
* @author $Author: matt $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Monday 28th February 2005 16:46
|
||||
* @version $Revision: 327 $
|
||||
*/
|
||||
|
||||
class db_driver_mysql extends db_main_mysql implements interfaceDb
|
||||
{
|
||||
/**
|
||||
* Connection failed flag
|
||||
*
|
||||
* @access private
|
||||
* @var boolean Connection failed
|
||||
*/
|
||||
private $connect_failed = false;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if( !defined('MYSQLI_USED') )
|
||||
{
|
||||
define( 'MYSQLI_USED', 1 );
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
// Set up any required connect vars here
|
||||
//--------------------------------------
|
||||
|
||||
$this->connect_vars['mysql_tbl_type'] = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database server
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Connection successful
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Done SQL prefix yet?
|
||||
//-----------------------------------------
|
||||
|
||||
$this->_setPrefix();
|
||||
|
||||
//-----------------------------------------
|
||||
// Load query file
|
||||
//-----------------------------------------
|
||||
|
||||
$this->_loadCacheFile();
|
||||
|
||||
//-----------------------------------------
|
||||
// Connect
|
||||
//-----------------------------------------
|
||||
|
||||
/* Did we add a port inline? */
|
||||
if ( ! $this->obj['sql_port'] AND strstr( $this->obj['sql_host'], ':' ) )
|
||||
{
|
||||
list( $host, $port ) = explode( ':', $this->obj['sql_host'] );
|
||||
|
||||
$this->obj['sql_host'] = $host;
|
||||
$this->obj['sql_port'] = intval( $port );
|
||||
}
|
||||
|
||||
if( $this->obj['sql_port'] )
|
||||
{
|
||||
$this->connection_id = @mysqli_connect( $this->obj['sql_host'] ,
|
||||
$this->obj['sql_user'] ,
|
||||
$this->obj['sql_pass'],
|
||||
$this->obj['sql_database'],
|
||||
$this->obj['sql_port']
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connection_id = @mysqli_connect( $this->obj['sql_host'] ,
|
||||
$this->obj['sql_user'] ,
|
||||
$this->obj['sql_pass'],
|
||||
$this->obj['sql_database']
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $this->connection_id )
|
||||
{
|
||||
$this->connect_failed = true;
|
||||
$this->throwFatalError();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mysqli_autocommit( $this->connection_id, TRUE );
|
||||
|
||||
//-----------------------------------------
|
||||
// Remove sensitive data
|
||||
//-----------------------------------------
|
||||
|
||||
unset( $this->obj['sql_host'] );
|
||||
unset( $this->obj['sql_user'] );
|
||||
unset( $this->obj['sql_pass'] );
|
||||
|
||||
//-----------------------------------------
|
||||
// If there's a charset set, run it
|
||||
//-----------------------------------------
|
||||
|
||||
if( $this->obj['sql_charset'] )
|
||||
{
|
||||
$this->query( "SET NAMES '{$this->obj['sql_charset']}'" );
|
||||
$this->query( "SET CHARACTER SET '{$this->obj['sql_charset']}'");
|
||||
$this->query( "SET character_set_connection = " .$this->obj['sql_charset']);
|
||||
|
||||
$res = mysqli_query($this->connection_id, "SHOW CHARSET LIKE '" . $this->obj['sql_charset'] . "'" );
|
||||
|
||||
$charset = mysqli_fetch_row($res);
|
||||
|
||||
$this->query( "SET collation_connection = " . $charset[2] );
|
||||
}
|
||||
|
||||
parent::connect();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close database connection
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Closed successfully
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if ( $this->connection_id )
|
||||
{
|
||||
return @mysqli_close( $this->connection_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a direct database query
|
||||
*
|
||||
* @access public
|
||||
* @param string Database query
|
||||
* @param boolean [Optional] Do not convert table prefix
|
||||
* @return resource Query id
|
||||
*/
|
||||
public function query( $the_query, $bypass=false )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Change the table prefix if needed
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $this->no_prefix_convert )
|
||||
{
|
||||
$bypass = 1;
|
||||
}
|
||||
|
||||
if ( ! $bypass )
|
||||
{
|
||||
if ( $this->obj['sql_tbl_prefix'] != "ibf_" and ! $this->prefix_changed )
|
||||
{
|
||||
//$the_query = preg_replace("/\sibf_(\S+?)([\s\.,]|$)/", " ".$this->obj['sql_tbl_prefix']."\\1\\2", $the_query);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Debug?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $this->obj['debug'] OR ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] ) OR ( $this->obj['use_bad_log'] AND $this->obj['bad_log'] ) )
|
||||
{
|
||||
IPSDebug::startTimer();
|
||||
$_MEMORY = IPSDebug::getMemoryDebugFlag();
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Stop sub selects? (UNION)
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! IPS_DB_ALLOW_SUB_SELECTS )
|
||||
{
|
||||
# On the spot allowance?
|
||||
if ( ! $this->allow_sub_select )
|
||||
{
|
||||
$_tmp = strtolower( $this->_removeAllQuotes($the_query) );
|
||||
|
||||
if ( preg_match( "#(?:/\*|\*/)#i", $_tmp ) )
|
||||
{
|
||||
$this->throwFatalError( "Не разрешается использовать комментарии в SQL запросе.\nДобавьте \ipsRegistry::DB()->allow_sub_select=1; перед запросом, чтобы разрешить их\n{$the_query}" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( preg_match( "#[^_a-zA-Z]union[^_a-zA-Z]#s", $_tmp ) )
|
||||
{
|
||||
$this->throwFatalError( "Использование UNION в запросах запрещено.\nДобавьте \ipsRegistry::DB()->allow_sub_select=1; перед запросом, чтобы разрешить использование\n{$the_query}" );
|
||||
return false;
|
||||
}
|
||||
else if ( preg_match_all( "#[^_a-zA-Z](select)[^_a-zA-Z]#s", $_tmp, $matches ) )
|
||||
{
|
||||
if ( count( $matches ) > 1 )
|
||||
{
|
||||
$this->throwFatalError( "Вложенные SELECT в запросах запрещены.\nДобавьте \ipsRegistry::DB()->allow_sub_select=1; перед запросом, чтобы разрешить их\n{$the_query}" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Run the query
|
||||
//-----------------------------------------
|
||||
$this->_tmpQ = substr( $the_query, 0, 100 ) . '...';
|
||||
$this->query_id = mysqli_query($this->connection_id, $the_query );
|
||||
|
||||
//-----------------------------------------
|
||||
// Reset array...
|
||||
//-----------------------------------------
|
||||
|
||||
$this->force_data_type = array();
|
||||
$this->allow_sub_select = false;
|
||||
|
||||
if (! $this->query_id )
|
||||
{
|
||||
$this->throwFatalError("mySQL query error: $the_query");
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Logging?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] ) OR ( $this->obj['use_bad_log'] AND $this->obj['bad_log'] ) OR ( $this->obj['use_slow_log'] AND $this->obj['slow_log'] ) )
|
||||
{
|
||||
$endtime = IPSDebug::endTimer();
|
||||
$_data = '';
|
||||
|
||||
if ( preg_match( "/^(?:\()?select/i", $the_query ) )
|
||||
{
|
||||
$eid = mysqli_query($this->connection_id, "EXPLAIN {$the_query}");
|
||||
$_bad = false;
|
||||
|
||||
while( $array = mysqli_fetch_array($eid) )
|
||||
{
|
||||
$array['extra'] = isset( $array['extra'] ) ? $array['extra'] : '';
|
||||
|
||||
$_data .= "\n+------------------------------------------------------------------------------+";
|
||||
$_data .= "\n|Table: ". $array['table'];
|
||||
$_data .= "\n|Type: ". $array['type'];
|
||||
$_data .= "\n|Possible Keys: ". $array['possible_keys'];
|
||||
$_data .= "\n|Key: ". $array['key'];
|
||||
$_data .= "\n|Key Len: ". $array['key_len'];
|
||||
$_data .= "\n|Ref: ". $array['ref'];
|
||||
$_data .= "\n|Rows: ". $array['rows'];
|
||||
$_data .= "\n|Extra: ". $array['Extra'];
|
||||
//$_data .= "\n+------------------------------------------------------------------------------+";
|
||||
|
||||
if ( ( $this->obj['use_bad_log'] AND $this->obj['bad_log'] ) AND stristr( $array['Extra'], 'filesort' ) OR stristr( $array['Extra'], 'temporary' ) )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime, $this->obj['bad_log'], TRUE );
|
||||
}
|
||||
|
||||
if ( ( $this->obj['use_slow_log'] AND $this->obj['slow_log'] ) AND $endtime >= $this->obj['use_slow_log'] )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime, $this->obj['slow_log'], TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this->obj['use_debug_log'] AND $this->obj['debug_log'] )
|
||||
{
|
||||
$this->writeDebugLog( $the_query, $_data, $endtime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Debugging?
|
||||
//-----------------------------------------
|
||||
|
||||
if ($this->obj['debug'])
|
||||
{
|
||||
$endtime = IPSDebug::endTimer();
|
||||
$memoryUsed = IPSDebug::setMemoryDebugFlag( '', $_MEMORY );
|
||||
$memory = '';
|
||||
$shutdown = $this->is_shutdown ? 'SHUTDOWN QUERY: ' : '';
|
||||
|
||||
if ( preg_match( "/^(?:\()?select/i", $the_query ) )
|
||||
{
|
||||
$eid = mysqli_query( $this->connection_id, "EXPLAIN {$the_query}" );
|
||||
|
||||
$this->debug_html .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FFE8F3' align='center'>
|
||||
<tr>
|
||||
<td colspan='8' style='font-size:14px' bgcolor='#FFC5Cb'><b>{$shutdown}Select Query</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='8' style='font-family:courier, monaco, arial;font-size:14px;color:black'>$the_query</td>
|
||||
</tr>
|
||||
<tr bgcolor='#FFC5Cb'>
|
||||
<td><b>table</b></td><td><b>type</b></td><td><b>possible_keys</b></td>
|
||||
<td><b>key</b></td><td><b>key_len</b></td><td><b>ref</b></td>
|
||||
<td><b>rows</b></td><td><b>Extra</b></td>
|
||||
</tr>\n";
|
||||
while( $array = mysqli_fetch_array($eid) )
|
||||
{
|
||||
$type_col = '#FFFFFF';
|
||||
|
||||
if ($array['type'] == 'ref' or $array['type'] == 'eq_ref' or $array['type'] == 'const')
|
||||
{
|
||||
$type_col = '#D8FFD4';
|
||||
}
|
||||
else if ($array['type'] == 'ALL')
|
||||
{
|
||||
$type_col = '#FFEEBA';
|
||||
}
|
||||
|
||||
$this->debug_html .= "<tr bgcolor='#FFFFFF'>
|
||||
<td>$array[table] </td>
|
||||
<td bgcolor='$type_col'>$array[type] </td>
|
||||
<td>$array[possible_keys] </td>
|
||||
<td>$array[key] </td>
|
||||
<td>$array[key_len] </td>
|
||||
<td>$array[ref] </td>
|
||||
<td>$array[rows] </td>
|
||||
<td>$array[Extra] </td>
|
||||
</tr>\n";
|
||||
}
|
||||
|
||||
$this->sql_time += $endtime;
|
||||
|
||||
if ($endtime > 0.1)
|
||||
{
|
||||
$endtime = "<span style='color:red'><b>$endtime</b></span>";
|
||||
}
|
||||
|
||||
if ( $memoryUsed )
|
||||
{
|
||||
$memory = '<br />Memory Used: ' . IPSLib::sizeFormat( $memoryUsed, TRUE );
|
||||
}
|
||||
|
||||
$this->debug_html .= "<tr>
|
||||
<td colspan='8' bgcolor='#FFD6DC' style='font-size:14px'><b>MySQL time</b>: $endtime{$memory}</b></td>
|
||||
</tr>
|
||||
</table>\n<br />\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->debug_html .= "<table width='95%' border='1' cellpadding='6' cellspacing='0' bgcolor='#FEFEFE' align='center'>
|
||||
<tr>
|
||||
<td style='font-size:14px' bgcolor='#EFEFEF'><b>{$shutdown}Non Select Query</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='font-family:courier, monaco, arial;font-size:14px'>$the_query</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='font-size:14px' bgcolor='#EFEFEF'><b>MySQL time</b>: $endtime</span></td>
|
||||
</tr>
|
||||
</table><br />\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
$this->query_count++;
|
||||
|
||||
$this->obj['cached_queries'][] = $the_query;
|
||||
|
||||
return $this->query_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve number of rows affected by last query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Number of rows affected by last query
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return mysqli_affected_rows( $this->connection_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve number of rows in result set
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query id
|
||||
* @return integer Number of rows in result set
|
||||
*/
|
||||
public function getTotalRows( $query_id=null )
|
||||
{
|
||||
if ( ! $query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
return mysqli_num_rows( $query_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve latest autoincrement insert id
|
||||
*
|
||||
* @access public
|
||||
* @return integer Last autoincrement id assigned
|
||||
*/
|
||||
public function getInsertId()
|
||||
{
|
||||
return mysqli_insert_id($this->connection_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current thread id
|
||||
*
|
||||
* @access public
|
||||
* @return integer Current thread id
|
||||
*/
|
||||
public function getThreadId()
|
||||
{
|
||||
return mysqli_thread_id($this->connection_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free result set from memory
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query id
|
||||
* @return void
|
||||
*/
|
||||
public function freeResult( $query_id=null )
|
||||
{
|
||||
if ( ! $query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
@mysqli_free_result( $query_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve row from database
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query result id
|
||||
* @return mixed Result set array, or void
|
||||
*/
|
||||
public function fetch( $query_id=null )
|
||||
{
|
||||
//$_MEMORY = IPSDebug::getMemoryDebugFlag();
|
||||
|
||||
if ( ! $query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
$this->record_row = mysqli_fetch_assoc( $query_id );
|
||||
|
||||
/*if ( is_array( $this->record_row ) )
|
||||
{
|
||||
$tmp = $this->record_row;
|
||||
$boo = array_shift( $tmp );
|
||||
}
|
||||
|
||||
$poo = IPSDebug::setMemoryDebugFlag( 'Fetch Row: ' . $boo . ' ' . $this->_tmpQ, $_MEMORY );
|
||||
$this->_tmpT += $poo;*/
|
||||
return $this->record_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number calculated rows (as if there was no limit clause)
|
||||
*
|
||||
* @access public
|
||||
* @param string [ alias name for the count(*) ]
|
||||
* @return int The number of rows
|
||||
*/
|
||||
public function fetchCalculatedRows( $alias='count' )
|
||||
{
|
||||
$calcRowsHandle = mysqli_query( $this->connection_id, "SELECT FOUND_ROWS() as " . $alias );
|
||||
|
||||
$val = mysqli_fetch_assoc( $calcRowsHandle );
|
||||
|
||||
return intval( $val[ $alias ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of fields in result set
|
||||
*
|
||||
* @access public
|
||||
* @param resource [Optional] Query id
|
||||
* @return array Fields in result set
|
||||
*/
|
||||
public function getResultFields( $query_id=null )
|
||||
{
|
||||
$fields = array();
|
||||
|
||||
if ( !$query_id )
|
||||
{
|
||||
$query_id = $this->query_id;
|
||||
}
|
||||
|
||||
while( $field = mysqli_fetch_field($query_id) )
|
||||
{
|
||||
$fields[] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of table names in database
|
||||
*
|
||||
* @access public
|
||||
* @return array SQL tables
|
||||
*/
|
||||
public function getTableNames()
|
||||
{
|
||||
if ( is_array( $this->cached_tables ) AND count( $this->cached_tables ) )
|
||||
{
|
||||
return $this->cached_tables;
|
||||
}
|
||||
|
||||
$current = $this->return_die;
|
||||
$this->return_die = true;
|
||||
|
||||
$qid = $this->query( "SHOW TABLES FROM `{$this->obj['sql_database']}`" );
|
||||
|
||||
$this->return_die = $current;
|
||||
|
||||
if( $qid AND $this->getTotalRows($qid) )
|
||||
{
|
||||
while( $result = mysqli_fetch_array($qid) )
|
||||
{
|
||||
$this->cached_tables[] = $result[0];
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_free_result($qid);
|
||||
|
||||
return $this->cached_tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve SQL server version
|
||||
*
|
||||
* @access public
|
||||
* @return string SQL Server version
|
||||
*/
|
||||
public function getSqlVersion()
|
||||
{
|
||||
if ( ! $this->sql_version and ! $this->true_version )
|
||||
{
|
||||
$version = mysqli_get_server_info($this->connection_id);
|
||||
|
||||
$this->true_version = $version;
|
||||
$tmp = explode( '.', preg_replace( "#[^\d\.]#", "\\1", $version ) );
|
||||
|
||||
$this->sql_version = sprintf('%d%02d%02d', $tmp[0], $tmp[1], $tmp[2] );
|
||||
}
|
||||
|
||||
return $this->sql_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape strings for DB insertion
|
||||
*
|
||||
* @access public
|
||||
* @param string Text to escape
|
||||
* @return string Escaped text
|
||||
*/
|
||||
public function addSlashes( $t )
|
||||
{
|
||||
return mysqli_real_escape_string( $this->connection_id, $t );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SQL error number
|
||||
*
|
||||
* @access protected
|
||||
* @return mixed Error number/code
|
||||
*/
|
||||
protected function _getErrorNumber()
|
||||
{
|
||||
if( $this->connect_failed )
|
||||
{
|
||||
return mysqli_connect_errno();
|
||||
}
|
||||
else
|
||||
{
|
||||
return mysqli_errno( $this->connection_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SQL error message
|
||||
*
|
||||
* @access protected
|
||||
* @return string Error message
|
||||
*/
|
||||
protected function _getErrorString()
|
||||
{
|
||||
if( $this->connect_failed )
|
||||
{
|
||||
return mysqli_connect_error( );
|
||||
}
|
||||
else
|
||||
{
|
||||
return mysqli_error( $this->connection_id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end class
|
||||
@@ -0,0 +1,432 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Compare and highlight differences between two strings or files
|
||||
* Last Updated: $Date: 2009-03-24 17:32:58 -0400 (Tue, 24 Mar 2009) $
|
||||
*
|
||||
* @author $Author: josh $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Thursday 10th February 2005 (10:47)
|
||||
* @version $Revision: 249 $
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
class classDifference
|
||||
{
|
||||
# Globals
|
||||
|
||||
/**
|
||||
* Shell command
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $diff_command = 'diff';
|
||||
|
||||
/**
|
||||
* Type of diff to use
|
||||
*
|
||||
* @access public
|
||||
* @var string [EXEC, CGI, PHP]
|
||||
*/
|
||||
public $method = 'EXEC';
|
||||
|
||||
/**
|
||||
* Differences found?
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $diff_found = 0;
|
||||
|
||||
/**
|
||||
* Post process DIFF result?
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $post_process = 1;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//-------------------------------
|
||||
// Server?
|
||||
//-------------------------------
|
||||
|
||||
if( strpos( strtolower( PHP_OS ), 'win' ) === 0 OR ( ! function_exists('exec') ) )
|
||||
{
|
||||
$this->method = 'CGI';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function to get differences
|
||||
*
|
||||
* @access public
|
||||
* @param string Original string
|
||||
* @param string New string
|
||||
* @return string Diff data
|
||||
*/
|
||||
public function getDifferences( $str1, $str2 )
|
||||
{
|
||||
$this->diff_found = 0;
|
||||
|
||||
$str1 = $this->_diffTagSpace($str1);
|
||||
$str2 = $this->_diffTagSpace($str2);
|
||||
$str1_lines = $this->_diffExplodeStringIntoWords($str1);
|
||||
$str2_lines = $this->_diffExplodeStringIntoWords($str2);
|
||||
|
||||
if ( $this->method == 'CGI' )
|
||||
{
|
||||
$diff_res = $this->_getCgiDiff( implode( chr(10), $str1_lines ) . chr(10), implode( chr(10), $str2_lines ) . chr(10) );
|
||||
}
|
||||
else if ( $this->method == 'PHP' )
|
||||
{
|
||||
$diff_res = $this->_getPhpDiff( implode( chr(10), $str1_lines ) . chr(10), implode( chr(10), $str2_lines ) . chr(10) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$diff_res = $this->_getExecDiff( implode( chr(10), $str1_lines ) . chr(10), implode( chr(10), $str2_lines ) . chr(10) );
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Post process?
|
||||
//-------------------------------
|
||||
|
||||
if ( $this->post_process )
|
||||
{
|
||||
if ( is_array($diff_res) )
|
||||
{
|
||||
reset($diff_res);
|
||||
$c = 0;
|
||||
$diff_res_array = array();
|
||||
|
||||
foreach( $diff_res as $l_val )
|
||||
{
|
||||
if ( intval($l_val) )
|
||||
{
|
||||
$c = intval($l_val);
|
||||
$diff_res_array[$c]['changeInfo'] = $l_val;
|
||||
}
|
||||
|
||||
if (substr($l_val,0,1) == '<')
|
||||
{
|
||||
$diff_res_array[$c]['old'][] = substr($l_val,2);
|
||||
}
|
||||
|
||||
if (substr($l_val,0,1) == '>')
|
||||
{
|
||||
$diff_res_array[$c]['new'][] = substr($l_val,2);
|
||||
}
|
||||
}
|
||||
|
||||
$out_str = '';
|
||||
$clr_buffer = '';
|
||||
|
||||
for ( $a = -1; $a < count($str1_lines); $a++ )
|
||||
{
|
||||
if ( is_array( $diff_res_array[$a+1] ) )
|
||||
{
|
||||
if ( strstr( $diff_res_array[$a+1]['changeInfo'], 'a') )
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
$clr_buffer .= htmlspecialchars($str1_lines[$a]).' ';
|
||||
}
|
||||
|
||||
$out_str .= $clr_buffer;
|
||||
$clr_buffer = '';
|
||||
|
||||
if (is_array($diff_res_array[$a+1]['old']))
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
$out_str.='<del style="-ips-match:1">'.htmlspecialchars(implode(' ',$diff_res_array[$a+1]['old'])).'</del> ';
|
||||
}
|
||||
|
||||
if (is_array($diff_res_array[$a+1]['new']))
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
$out_str.='<ins style="-ips-match:1">'.htmlspecialchars(implode(' ',$diff_res_array[$a+1]['new'])).'</ins> ';
|
||||
}
|
||||
|
||||
$cip = explode(',',$diff_res_array[$a+1]['changeInfo']);
|
||||
|
||||
if ( ! strcmp( $cip[0], $a + 1 ) )
|
||||
{
|
||||
$new_line = intval($cip[1])-1;
|
||||
|
||||
if ( $new_line > $a )
|
||||
{
|
||||
$a = $new_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$clr_buffer .= htmlspecialchars($str1_lines[$a]).' ';
|
||||
}
|
||||
}
|
||||
|
||||
$out_str .= $clr_buffer;
|
||||
|
||||
$out_str = str_replace(' ',chr(10),$out_str);
|
||||
|
||||
$out_str = $this->_diffTagSpace($out_str,1);
|
||||
|
||||
return $out_str;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $diff_res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds space character after HTML tags
|
||||
*
|
||||
* @access private
|
||||
* @param string String
|
||||
* @param integer [Optional][0=reverse, 1=normal]
|
||||
* @return string Converted string
|
||||
*/
|
||||
private function _diffTagSpace( $str, $rev=0 )
|
||||
{
|
||||
if ( $rev )
|
||||
{
|
||||
return str_replace(' <','<',str_replace('> ','>',$str) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return str_replace('<',' <',str_replace('>','> ',$str) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Explodes input string into words
|
||||
*
|
||||
* @access private
|
||||
* @param string Input string
|
||||
* @return array Array of words in string
|
||||
*/
|
||||
private function _diffExplodeStringIntoWords( $str )
|
||||
{
|
||||
$str_array = $this->_explodeTrim( chr(10), $str );
|
||||
$out_array = array();
|
||||
|
||||
reset($str_array);
|
||||
|
||||
foreach( $str_array as $low )
|
||||
{
|
||||
$all_words = $this->_explodeTrim( ' ', $low, 1 );
|
||||
$out_array = array_merge($out_array, $all_words);
|
||||
$out_array[] = '';
|
||||
$out_array[] = '';
|
||||
}
|
||||
|
||||
return $out_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode into array and trim
|
||||
*
|
||||
* @access private
|
||||
* @param string Delimiter
|
||||
* @param string String to check
|
||||
* @param integer [Optional] Remove blank lines
|
||||
* @return array Array of lines in string
|
||||
*/
|
||||
private function _explodeTrim( $delim, $str, $remove_blank=0 )
|
||||
{
|
||||
$tmp = explode( $delim, trim($str) );
|
||||
$final = array();
|
||||
|
||||
foreach( $tmp as $i )
|
||||
{
|
||||
if ( $remove_blank AND ( $i === '' OR $i === NULL ) ) //!$i AND $i !== 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$final[] = trim($i);
|
||||
}
|
||||
}
|
||||
|
||||
return $final;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce differences using PHP
|
||||
*
|
||||
* @access private
|
||||
* @param string comapre string 1
|
||||
* @param string comapre string 2
|
||||
* @return string
|
||||
*/
|
||||
private function _getPhpDiff( $str1 , $str2 )
|
||||
{
|
||||
$str1 = explode( "\n", str_replace( "\r\n", "\n", $str1 ) );
|
||||
$str2 = explode( "\n", str_replace( "\r\n", "\n", $str2 ) );
|
||||
|
||||
/* Set include path.. */
|
||||
@set_include_path( IPS_KERNEL_PATH . 'PEAR/' );
|
||||
|
||||
/* OMG.. too many PHP 5 errors under strict standards */
|
||||
$oldReportLevel = error_reporting( 0 );
|
||||
error_reporting( $oldReportLevel ^ E_STRICT );
|
||||
|
||||
require_once 'Text/Diff.php';
|
||||
require_once 'Text/Diff/Renderer.php';
|
||||
require_once 'Text/Diff/Renderer/inline.php';
|
||||
|
||||
$diff = new Text_Diff( 'auto', array( $str1, $str2 ) );
|
||||
|
||||
$renderer = new Text_Diff_Renderer_inline();
|
||||
$result = $renderer->render($diff);
|
||||
|
||||
/* Go back to old reporting level */
|
||||
error_reporting( $oldReportLevel | E_STRICT );
|
||||
|
||||
$result = str_replace( "<ins>", '<ins style="-ips-match:1">', $result );
|
||||
$result = str_replace( "<del>", '<del style="-ips-match:1">', $result );
|
||||
|
||||
# Got a match?
|
||||
if ( strstr( $result, 'style="-ips-match:1"' ) )
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
}
|
||||
|
||||
# No post processing please
|
||||
$this->post_process = 0;
|
||||
|
||||
# Convert lines to a space, and two spaces to a single line
|
||||
$result = str_replace(' ', chr(10), str_replace( "\n", " ", $result ) );
|
||||
$result = $this->_diffTagSpace($result,1);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce differences using unix diff
|
||||
*
|
||||
* @access private
|
||||
* @param string comapre string 1
|
||||
* @param string comapre string 2
|
||||
* @return string
|
||||
*/
|
||||
private function _getExecDiff( $str1, $str2 )
|
||||
{
|
||||
//-------------------------------
|
||||
// Write the tmp files
|
||||
//-------------------------------
|
||||
|
||||
$file1 = IPS_ROOT_PATH . 'uploads/'.time().'-1';
|
||||
$file2 = IPS_ROOT_PATH . 'uploads/'.time().'-2';
|
||||
|
||||
if ( $FH1 = @fopen( $file1, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH1, $str1, strlen($str1) );
|
||||
@fclose( $FH1 );
|
||||
}
|
||||
|
||||
if ( $FH2 = @fopen( $file2, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH2, $str2, strlen($str2) );
|
||||
@fclose( $FH2 );
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Check
|
||||
//-------------------------------
|
||||
|
||||
if ( file_exists( $file1 ) and file_exists( $file2 ) )
|
||||
{
|
||||
exec( $this->diff_command.' '.$file1.' '.$file2, $result );
|
||||
|
||||
@unlink( $file1 );
|
||||
@unlink( $file2 );
|
||||
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Ошибка, файлы не были записаны на диск";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce differences using CGI
|
||||
*
|
||||
* @access private
|
||||
* @param string comapre string 1
|
||||
* @param string comapre string 2
|
||||
* @return string
|
||||
*/
|
||||
private function _getCgiDiff( $str1, $str2 )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Load file management class
|
||||
//-----------------------------------------
|
||||
|
||||
require_once( IPS_KERNEL_PATH . '/classFileManagement.php' );
|
||||
$this->classFileManagement = new classFileManagement();
|
||||
$this->classFileManagement->use_sockets = ipsRegistry::$settings['enable_sockets'];
|
||||
|
||||
//-------------------------------
|
||||
// Write the tmp files
|
||||
//-------------------------------
|
||||
|
||||
$file1 = 'tmp-1';
|
||||
$file2 = 'tmp-2';
|
||||
|
||||
if ( $FH1 = @fopen( IPS_ROOT_PATH.'uploads/'.$file1, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH1, $str1, strlen($str1) );
|
||||
@fclose( $FH1 );
|
||||
}
|
||||
|
||||
if ( $FH2 = @fopen( IPS_ROOT_PATH.'uploads/'.$file2, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH2, $str2, strlen($str2) );
|
||||
@fclose( $FH2 );
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Check
|
||||
//-------------------------------
|
||||
|
||||
if ( file_exists( IPS_ROOT_PATH . 'uploads/' . $file1 ) AND file_exists( IPS_ROOT_PATH . 'uploads/' . $file2 ) )
|
||||
{
|
||||
$result = $this->classFileManagement->getFileContents( ipsRegistry::$settings['board_url'] . "/" . CP_DIRECTORY . "/" . IPS_CGI_DIRECTORY . "/cgi_getdifference.cgi" );
|
||||
|
||||
@unlink( IPS_ROOT_PATH . 'uploads/' . $file1 );
|
||||
@unlink( IPS_ROOT_PATH . 'uploads/' . $file2 );
|
||||
|
||||
return explode( "\n", $result );
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Ошибка, файлы не были записаны на диск";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,581 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Wrapper for retrieving file contents. Methods available for removing files and directories as well.
|
||||
* Last Updated: $Date: 2009-12-02 21:34:26 -0500 (Wed, 02 Dec 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Tuesday 22nd February 2005 (16:55)
|
||||
* @version $Revision: 350 $
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
class classFileManagement
|
||||
{
|
||||
/**
|
||||
* Use sockets flag
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $use_sockets = 0;
|
||||
|
||||
/**
|
||||
* Error array
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $errors = array();
|
||||
|
||||
/**
|
||||
* HTTP Status Code/Text
|
||||
*
|
||||
* @access public
|
||||
* @var integer HTTP Status code
|
||||
* @var string HTTP Status text
|
||||
*/
|
||||
public $http_status_code = 0;
|
||||
public $http_status_text = "";
|
||||
|
||||
/**#@+
|
||||
* Set Authentication
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
public $auth_req = 0;
|
||||
public $auth_user;
|
||||
public $auth_pass;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Timeout setting
|
||||
*
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $timeout = 15;
|
||||
|
||||
/**
|
||||
* Get file contents (accepts URL or path)
|
||||
*
|
||||
* @access public
|
||||
* @param string URI / File path
|
||||
* @param string HTTP User
|
||||
* @param string HTTP Pass
|
||||
* @return string File data
|
||||
*/
|
||||
public function getFileContents( $file_location, $http_user='', $http_pass='' )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$contents = "";
|
||||
$file_location = str_replace( '&', '&', $file_location );
|
||||
|
||||
//-----------------------------------------
|
||||
// Inline user/pass?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $http_user and $http_pass )
|
||||
{
|
||||
$this->auth_req = 1;
|
||||
$this->auth_user = $http_user;
|
||||
$this->auth_pass = $http_pass;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Hello
|
||||
//-------------------------------
|
||||
|
||||
if ( ! $file_location )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! stristr( $file_location, 'http://' ) AND ! stristr( $file_location, 'https://' ) )
|
||||
{
|
||||
//-------------------------------
|
||||
// It's a path!
|
||||
//-------------------------------
|
||||
|
||||
if ( ! file_exists( $file_location ) )
|
||||
{
|
||||
$this->errors[] = "Файл '{$file_location}' не существует, Проверье правильность пути.";
|
||||
return;
|
||||
}
|
||||
|
||||
$contents = $this->_getContentsWithFopen( $file_location );
|
||||
}
|
||||
else
|
||||
{
|
||||
//-------------------------------
|
||||
// Is URL, try curl and then fall back
|
||||
//-------------------------------
|
||||
|
||||
if( ($contents = $this->_getContentsWithCurl( $file_location )) === false )
|
||||
{
|
||||
if ( $this->use_sockets )
|
||||
{
|
||||
$contents = $this->_getContentsWithSocket( $file_location );
|
||||
}
|
||||
else
|
||||
{
|
||||
$contents = $this->_getContentsWithFopen( $file_location );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file contents (with PHP's fopen)
|
||||
*
|
||||
* @access private
|
||||
* @param string File location
|
||||
* @return string File data
|
||||
*/
|
||||
private function _getContentsWithFopen( $file_location )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$buffer = "";
|
||||
|
||||
@clearstatcache();
|
||||
|
||||
if ( $FILE = fopen( $file_location, "r" ) )
|
||||
{
|
||||
@stream_set_timeout( $FILE, $this->timeout );
|
||||
$status = @stream_get_meta_data($FILE);
|
||||
|
||||
while ( ! feof( $FILE ) && ! $status['timed_out'] )
|
||||
{
|
||||
$buffer .= fgets( $FILE, 4096 );
|
||||
|
||||
$status = stream_get_meta_data($FILE);
|
||||
}
|
||||
|
||||
fclose($FILE);
|
||||
}
|
||||
|
||||
if ( $buffer )
|
||||
{
|
||||
$this->http_status_code = 200;
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file contents (with sockets)
|
||||
*
|
||||
* @access private
|
||||
* @param string File location
|
||||
* @return string File data
|
||||
*/
|
||||
private function _getContentsWithSocket( $file_location )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$data = null;
|
||||
$fsocket_timeout = $this->timeout;
|
||||
|
||||
//-------------------------------
|
||||
// Parse URL
|
||||
//-------------------------------
|
||||
|
||||
$url_parts = @parse_url($file_location);
|
||||
|
||||
if ( ! $url_parts['host'] )
|
||||
{
|
||||
$this->errors[] = "Не найден хост в URL '{$file_location}'!";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Finalize
|
||||
//-------------------------------
|
||||
|
||||
$host = $url_parts['host'];
|
||||
$port = ( isset($url_parts['port']) ) ? $url_parts['port'] : ( $url_parts['scheme'] == 'https' ? 443 : 80 );
|
||||
|
||||
//-------------------------------
|
||||
// Tidy up path
|
||||
//-------------------------------
|
||||
|
||||
if ( !empty( $url_parts["path"] ) )
|
||||
{
|
||||
$path = $url_parts["path"];
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = "/";
|
||||
}
|
||||
|
||||
if ( !empty( $url_parts["query"] ) )
|
||||
{
|
||||
$path .= "?" . $url_parts["query"];
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Open connection
|
||||
//-------------------------------
|
||||
|
||||
if ( ! $fp = @fsockopen( $host, $port, $errno, $errstr, $fsocket_timeout ) )
|
||||
{
|
||||
$this->errors[] = "Не могу установить соединение с {$host}";
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$final_carriage = "";
|
||||
|
||||
if ( ! $this->auth_req )
|
||||
{
|
||||
$final_carriage = "\r\n";
|
||||
}
|
||||
|
||||
if ( ! fputs( $fp, "GET $path HTTP/1.0\r\nHost:$host\r\nConnection: Keep-Alive\r\n{$final_carriage}" ) )
|
||||
{
|
||||
$this->errors[] = "Невозможно отправить запрос на $host!";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( $this->auth_req )
|
||||
{
|
||||
if ( $this->auth_user && $this->auth_pass )
|
||||
{
|
||||
$header = "Authorization: Basic ".base64_encode("{$this->auth_user}:{$this->auth_pass}")."\r\n\r\n";
|
||||
|
||||
if ( ! fputs( $fp, $header ) )
|
||||
{
|
||||
$this->errors[] = "Неверные данные авторизации!";
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@stream_set_timeout($fp, $fsocket_timeout);
|
||||
|
||||
$status = @stream_get_meta_data($fp);
|
||||
|
||||
while( ! feof($fp) && ! $status['timed_out'] )
|
||||
{
|
||||
$data .= fgets ($fp,8192);
|
||||
$status = stream_get_meta_data($fp);
|
||||
}
|
||||
|
||||
fclose ($fp);
|
||||
|
||||
//-------------------------------
|
||||
// Strip headers
|
||||
//-------------------------------
|
||||
|
||||
// HTTP/1.1 ### ABCD
|
||||
$this->http_status_code = substr( $data, 9, 3 );
|
||||
$this->http_status_text = substr( $data, 13, ( strpos( $data, "\r\n" ) - 13 ) );
|
||||
|
||||
//-----------------------------------------
|
||||
// Try to deal with chunked..
|
||||
//-----------------------------------------
|
||||
|
||||
$_chunked = false;
|
||||
|
||||
if( preg_match( "/Transfer\-Encoding:\s*chunked/i", $data ) )
|
||||
{
|
||||
$_chunked = true;
|
||||
}
|
||||
|
||||
$tmp = split("\r\n\r\n", $data, 2);
|
||||
$data = trim($tmp[1]);
|
||||
|
||||
//-----------------------------------------
|
||||
// Easy way out :P
|
||||
//-----------------------------------------
|
||||
|
||||
if( $_chunked )
|
||||
{
|
||||
$lines = explode( "\n", $data );
|
||||
array_pop($lines);
|
||||
array_shift($lines);
|
||||
$data = implode( "\n", $lines );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file contents (with cURL)
|
||||
*
|
||||
* @access private
|
||||
* @param string File location
|
||||
* @return string File data
|
||||
*/
|
||||
private function _getContentsWithCurl( $file_location )
|
||||
{
|
||||
if ( function_exists( 'curl_init' ) AND function_exists("curl_exec") )
|
||||
{
|
||||
$ch = curl_init( $file_location );
|
||||
|
||||
curl_setopt( $ch, CURLOPT_HEADER , 0);
|
||||
curl_setopt( $ch, CURLOPT_TIMEOUT , $this->timeout );
|
||||
curl_setopt( $ch, CURLOPT_POST , 0 );
|
||||
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
|
||||
curl_setopt( $ch, CURLOPT_FAILONERROR , 1 );
|
||||
curl_setopt( $ch, CURLOPT_MAXREDIRS , 10 );
|
||||
|
||||
/**
|
||||
* Cannot set this when safe_mode or open_basedir is enabled
|
||||
* @link http://forums.invisionpower.com/index.php?autocom=tracker&showissue=11334
|
||||
*/
|
||||
if( !ini_get('open_basedir') AND !ini_get('safe_mode') )
|
||||
{
|
||||
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
|
||||
}
|
||||
|
||||
if( $this->auth_req )
|
||||
{
|
||||
curl_setopt( $ch, CURLOPT_USERPWD , "{$this->auth_user}:{$this->auth_pass}" );
|
||||
}
|
||||
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ( $data )
|
||||
{
|
||||
$this->http_status_code = 200;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies contents of one directory to another, creating if necessary
|
||||
*
|
||||
* @access public
|
||||
* @param string File location [from]
|
||||
* @param string File location [destination]
|
||||
* @param string [Optional] CHMOD mode to set
|
||||
* @return boolean Copy successful
|
||||
*/
|
||||
public function copyDirectory($from_path, $to_path, $mode = 0777)
|
||||
{
|
||||
$this->errors = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Strip off trailing slashes...
|
||||
//-----------------------------------------
|
||||
|
||||
$from_path = rtrim( $from_path, '/' );
|
||||
$to_path = rtrim( $to_path, '/' );
|
||||
|
||||
if ( ! is_dir( $from_path ) )
|
||||
{
|
||||
$this->errors[] = "Невозможно найти директорию '{$from_path}'";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! is_dir( $to_path ) )
|
||||
{
|
||||
if ( ! @mkdir( $to_path, $mode ) )
|
||||
{
|
||||
$this->errors[] = "Невозможно создать директорию '{$to_path}', проверьте права доступа и попробуйте снова";
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@chmod( $to_path, $mode );
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_dir( $from_path ) )
|
||||
{
|
||||
$handle = opendir($from_path);
|
||||
|
||||
while ( ($file = readdir($handle)) !== false )
|
||||
{
|
||||
if ( ($file != ".") && ($file != "..") )
|
||||
{
|
||||
if ( is_dir( $from_path."/".$file ) )
|
||||
{
|
||||
$this->copyDirectory( $from_path."/".$file, $to_path."/".$file );
|
||||
}
|
||||
|
||||
if ( is_file( $from_path."/".$file ) )
|
||||
{
|
||||
copy( $from_path."/".$file, $to_path."/".$file );
|
||||
@chmod( $to_path."/".$file, 0777 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
if ( ! count( $this->errors ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a directory
|
||||
*
|
||||
* @access public
|
||||
* @param string File location [from]
|
||||
* @return boolean Removal successful
|
||||
*/
|
||||
public function removeDirectory($file)
|
||||
{
|
||||
$errors = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Remove trailing slashes..
|
||||
//-----------------------------------------
|
||||
|
||||
$file = rtrim( $file, '/' );
|
||||
|
||||
if ( file_exists($file) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Attempt CHMOD
|
||||
//-----------------------------------------
|
||||
|
||||
@chmod( $file, 0777 );
|
||||
|
||||
if ( is_dir( $file ) )
|
||||
{
|
||||
$handle = opendir( $file );
|
||||
|
||||
while ( ($filename = readdir($handle)) !== false )
|
||||
{
|
||||
if ( ($filename != ".") && ($filename != "..") )
|
||||
{
|
||||
$this->removeDirectory( $file."/".$filename );
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
|
||||
if ( ! @rmdir($file) )
|
||||
{
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! @unlink($file) )
|
||||
{
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( $errors == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties a directory
|
||||
*
|
||||
* @access public
|
||||
* @param string File location [from]
|
||||
* @param int In a loop (not root folder)
|
||||
* @return boolean Empty successful
|
||||
*/
|
||||
public function emptyDirectory($file, $inLoop=0)
|
||||
{
|
||||
$errors = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Remove trailing slashes..
|
||||
//-----------------------------------------
|
||||
|
||||
$file = rtrim( $file, '/' );
|
||||
|
||||
if ( file_exists($file) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Attempt CHMOD
|
||||
//-----------------------------------------
|
||||
|
||||
@chmod( $file, 0777 );
|
||||
|
||||
if ( is_dir( $file ) )
|
||||
{
|
||||
$handle = opendir( $file );
|
||||
|
||||
while ( ($filename = readdir($handle)) !== false )
|
||||
{
|
||||
if ( ($filename != ".") && ($filename != "..") )
|
||||
{
|
||||
$this->emptyDirectory( $file."/".$filename, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
|
||||
if ( $inLoop )
|
||||
{
|
||||
if ( ! @rmdir($file) )
|
||||
{
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! @unlink($file) )
|
||||
{
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( $errors == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Image Handler: create thumbnails, apply watermarks and copyright tests, save or display final image
|
||||
* Last Updated: $Date: 2009-06-12 22:35:26 -0400 (Fri, 12 Jun 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Monday 5th May 2008 14:00
|
||||
* @version $Revision: 282 $
|
||||
*
|
||||
* GD Example
|
||||
* <code>
|
||||
* $image = new classImageGd();
|
||||
* $image->init( array(
|
||||
* 'image_path' => "/path/to/images/",
|
||||
* 'image_file' => "image_filename.jpg",
|
||||
* ) );
|
||||
*
|
||||
* if( $image->error )
|
||||
* {
|
||||
* print $image->error;exit;
|
||||
* }
|
||||
*
|
||||
* Set max width and height
|
||||
* $image->resizeImage( 600, 480 );
|
||||
* // Add a watermark
|
||||
* $image->addWatermark( "/path/to/watermark/trans.png" );
|
||||
* //$image->addCopyrightText( "Hello World!", array( 'color' => '#ffffff', 'font' => 3 ) );
|
||||
* $image->displayImage();
|
||||
* </code>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Image interface
|
||||
*
|
||||
*/
|
||||
interface interfaceImage
|
||||
{
|
||||
/**
|
||||
* Initiate image handler, perform any necessary setup
|
||||
*
|
||||
* @param array Necessary options to init module
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function init( $opts=array() );
|
||||
|
||||
/**
|
||||
* Add a supported image type (assumes you have properly extended the class to add the support)
|
||||
*
|
||||
* @param string Image extension type to add support for
|
||||
* @return boolean Addition successful
|
||||
*/
|
||||
public function addImagetype( $ext );
|
||||
|
||||
/**
|
||||
* Resize image proportionately
|
||||
*
|
||||
* @param integer Maximum width
|
||||
* @param integer Maximum height
|
||||
* @return array Dimensons of the original image and the resized dimensions
|
||||
*/
|
||||
public function resizeImage( $width, $height );
|
||||
|
||||
/**
|
||||
* Write image to file
|
||||
*
|
||||
* @param string File location (including file name)
|
||||
* @return boolean File write successful
|
||||
*/
|
||||
public function writeImage( $path );
|
||||
|
||||
/**
|
||||
* Print image to screen
|
||||
*
|
||||
* @return void Image printed and script exits
|
||||
*/
|
||||
public function displayImage();
|
||||
|
||||
/**
|
||||
* Add watermark to image
|
||||
*
|
||||
* @param string Watermark image path
|
||||
* @param integer [Optional] Opacity 0-100
|
||||
* @return boolean Watermark addition successful
|
||||
*/
|
||||
public function addWatermark( $path, $opacity=100 );
|
||||
|
||||
/**
|
||||
* Add copyright text to image
|
||||
*
|
||||
* @param string Copyright text to add
|
||||
* @param array [Optional] Text options (color, background color, font [1-5])
|
||||
* @return boolean Watermark addition successful
|
||||
*/
|
||||
public function addCopyrightText( $text, $textOpts=array() );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Image abstract class
|
||||
*
|
||||
*/
|
||||
abstract class classImage
|
||||
{
|
||||
/**
|
||||
* Error encountered
|
||||
*
|
||||
* @access public
|
||||
* @var string Error Message
|
||||
*/
|
||||
public $error = '';
|
||||
|
||||
/**
|
||||
* Image Path
|
||||
*
|
||||
* @access protected
|
||||
* @var string Path to image
|
||||
*/
|
||||
protected $image_path = '';
|
||||
|
||||
/**
|
||||
* Image File
|
||||
*
|
||||
* @access protected
|
||||
* @var string Image file to work with
|
||||
*/
|
||||
protected $image_file = '';
|
||||
|
||||
/**
|
||||
* Image path + file
|
||||
*
|
||||
* @access protected
|
||||
* @var string Full image path and filename
|
||||
*/
|
||||
protected $image_full = '';
|
||||
|
||||
/**
|
||||
* Image dimensions
|
||||
*
|
||||
* @access protected
|
||||
* @var array Original Image Dimensions
|
||||
*/
|
||||
protected $orig_dimensions = array( 'width' => 0, 'height' => 0 );
|
||||
|
||||
/**
|
||||
* Image current dimensions
|
||||
*
|
||||
* @access public
|
||||
* @var array Curernt/New Image Dimensions
|
||||
*/
|
||||
public $cur_dimensions = array( 'width' => 0, 'height' => 0 );
|
||||
|
||||
/**
|
||||
* Image Types Supported
|
||||
*
|
||||
* @access protected
|
||||
* @var array Image types we can work with
|
||||
*/
|
||||
protected $image_types = array( 'gif', 'jpeg', 'jpg', 'jpe', 'png' );
|
||||
|
||||
/**
|
||||
* Extension of image
|
||||
*
|
||||
* @access public
|
||||
* @var string Image extension
|
||||
*/
|
||||
public $image_extension = '';
|
||||
|
||||
/**
|
||||
* Resize image anyways (e.g. if we have added watermark)
|
||||
*
|
||||
* @access public
|
||||
* @var bool
|
||||
*/
|
||||
public $force_resize = false;
|
||||
|
||||
/**
|
||||
* Image handler constructor
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Construction successful
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image handler desctructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cleans up paths, generates var $in_file_complete
|
||||
*
|
||||
* @access protected
|
||||
* @param string Path to clean
|
||||
* @return string Cleaned path
|
||||
*/
|
||||
protected function _cleanPaths( $path='' )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Remove trailing slash
|
||||
//---------------------------------------------------------
|
||||
|
||||
return rtrim( $path, '/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a supported image type (assumes you have properly extended the class to add the support)
|
||||
*
|
||||
* @access public
|
||||
* @param string Image extension type to add support for
|
||||
* @return boolean Addition successful
|
||||
*/
|
||||
public function addImagetype( $ext )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Add a supported image extension
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !in_array( $ext, $this->image_types ) )
|
||||
{
|
||||
$this->image_types[] = $ext;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get new dimensions for resizing
|
||||
*
|
||||
* @access protected
|
||||
* @param integer Maximum width
|
||||
* @param integer Maximum height
|
||||
* @return array [img_width,img_height]
|
||||
*/
|
||||
protected function _getResizeDimensions( $width, $height )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Verify width and height are valid and > 0
|
||||
//---------------------------------------------------------
|
||||
|
||||
$width = intval($width);
|
||||
$height = intval($height);
|
||||
|
||||
if( !$width OR !$height )
|
||||
{
|
||||
$this->error = 'bad_dimensions';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Is the current image already smaller?
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( $width > $this->cur_dimensions['width'] AND $height > $this->cur_dimensions['height'] )
|
||||
{
|
||||
$this->error = 'already_smaller';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Return new dimensions
|
||||
//---------------------------------------------------------
|
||||
|
||||
return $this->_scaleImage( array(
|
||||
'cur_height' => $this->cur_dimensions['height'],
|
||||
'cur_width' => $this->cur_dimensions['width'],
|
||||
'max_height' => $height,
|
||||
'max_width' => $width,
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return proportionate image dimensions based on current and max dimension settings
|
||||
*
|
||||
* @access protected
|
||||
* @param array [ cur_height, cur_width, max_width, max_height ]
|
||||
* @return array [ img_height, img_width ]
|
||||
*/
|
||||
protected function _scaleImage( $arg )
|
||||
{
|
||||
$ret = array(
|
||||
'img_width' => $arg['cur_width'],
|
||||
'img_height' => $arg['cur_height']
|
||||
);
|
||||
|
||||
if ( $arg['cur_width'] > $arg['max_width'] )
|
||||
{
|
||||
$ret['img_width'] = $arg['max_width'];
|
||||
$ret['img_height'] = ceil( ( $arg['cur_height'] * ( ( $arg['max_width'] * 100 ) / $arg['cur_width'] ) ) / 100 );
|
||||
$arg['cur_height'] = $ret['img_height'];
|
||||
$arg['cur_width'] = $ret['img_width'];
|
||||
}
|
||||
|
||||
if ( $arg['cur_height'] > $arg['max_height'] )
|
||||
{
|
||||
$ret['img_height'] = $arg['max_height'];
|
||||
$ret['img_width'] = ceil( ( $arg['cur_width'] * ( ( $arg['max_height'] * 100 ) / $arg['cur_height'] ) ) / 100 );
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,605 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Image Handler: GD2 Library
|
||||
* Last Updated: $Date: 2009-11-24 18:10:32 -0500 (Tue, 24 Nov 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Monday 5th May 2008 14:00
|
||||
* @version $Revision: 347 $
|
||||
*
|
||||
* GD Example
|
||||
* <code>
|
||||
* $image = new classImageGd();
|
||||
* $image->init( array(
|
||||
* 'image_path' => "/path/to/images/",
|
||||
* 'image_file' => "image_filename.jpg",
|
||||
* ) );
|
||||
*
|
||||
* if( $image->error )
|
||||
* {
|
||||
* print $image->error;exit;
|
||||
* }
|
||||
*
|
||||
* Set max width and height
|
||||
* $image->resizeImage( 600, 480 );
|
||||
* // Add a watermark
|
||||
* $image->addWatermark( "/path/to/watermark/trans.png" );
|
||||
* //$image->addCopyrightText( "Hello World!", array( 'color' => '#ffffff', 'font' => 3 ) );
|
||||
* $image->displayImage();
|
||||
* </code>
|
||||
*/
|
||||
|
||||
class classImageGd extends classImage implements interfaceImage
|
||||
{
|
||||
/**
|
||||
* Image resource
|
||||
*
|
||||
* @access private
|
||||
* @var resource Image resource
|
||||
*/
|
||||
private $image = null;
|
||||
|
||||
/**
|
||||
* Image quality settings
|
||||
*
|
||||
* @access public
|
||||
* @var array Image quality settings
|
||||
*/
|
||||
public $quality = array( 'png' => 8, 'jpg' => 75 );
|
||||
|
||||
/**
|
||||
* Initiate image handler, perform any necessary setup
|
||||
*
|
||||
* @access public
|
||||
* @param array Necessary options to init module [image_path, image_file]
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function init( $opts=array() )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Verify input
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !isset($opts['image_path']) OR !$opts['image_path'] )
|
||||
{
|
||||
$this->error = 'no_image_path';
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !isset($opts['image_file']) OR !$opts['image_file'] )
|
||||
{
|
||||
$this->error = 'no_image_file';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Store paths
|
||||
//---------------------------------------------------------
|
||||
|
||||
$this->image_path = $this->_cleanPaths( $opts['image_path'] );
|
||||
$this->image_file = $opts['image_file'];
|
||||
$this->image_full = $this->image_path . '/' . $this->image_file;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get extension
|
||||
//---------------------------------------------------------
|
||||
|
||||
$this->image_extension = strtolower(pathinfo( $this->image_file, PATHINFO_EXTENSION ));
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Verify this is a valid image type
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !in_array( $this->image_extension, $this->image_types ) )
|
||||
{
|
||||
$this->error = 'image_not_supported';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Quality values
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( isset($opts['jpg_quality']) AND $opts['jpg_quality'] )
|
||||
{
|
||||
$this->quality['jpg'] = $opts['jpg_quality'];
|
||||
}
|
||||
|
||||
if( isset($opts['png_quality']) AND $opts['png_quality'] )
|
||||
{
|
||||
$this->quality['png'] = $opts['png_quality'];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get and remember dimensions
|
||||
//---------------------------------------------------------
|
||||
|
||||
$dimensions = getimagesize( $this->image_full );
|
||||
|
||||
$this->orig_dimensions = array( 'width' => $dimensions[0], 'height' => $dimensions[1] );
|
||||
$this->cur_dimensions = $this->orig_dimensions;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Create image resource
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'gif':
|
||||
$this->image = @imagecreatefromgif( $this->image_full );
|
||||
break;
|
||||
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'jpe':
|
||||
$this->image = @imagecreatefromjpeg( $this->image_full );
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
$this->image = @imagecreatefrompng( $this->image_full );
|
||||
break;
|
||||
}
|
||||
|
||||
if( !$this->image )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Fallback
|
||||
// @see http://forums.invisionpower.com/index.php?app=tracker&showissue=17836
|
||||
//-----------------------------------------
|
||||
|
||||
if( $this->image = @imagecreatefromstring( file_get_contents( $this->image_full ) ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->error = 'no_full_image';
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize image proportionately
|
||||
*
|
||||
* @access public
|
||||
* @param integer Maximum width
|
||||
* @param integer Maximum height
|
||||
* @return array Dimensons of the original image and the resized dimensions
|
||||
*/
|
||||
public function resizeImage( $width, $height )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Get proportionate dimensions and store
|
||||
//---------------------------------------------------------
|
||||
|
||||
$new_dims = $this->_getResizeDimensions( $width, $height );
|
||||
|
||||
if( !is_array($new_dims) OR !count($new_dims) OR !$new_dims['img_width'] )
|
||||
{
|
||||
if( !$this->force_resize )
|
||||
{
|
||||
return array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$new_dims['img_width'] = $width;
|
||||
$new_dims['img_height'] = $height;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Create new image resource
|
||||
//---------------------------------------------------------
|
||||
|
||||
$new_img = imagecreatetruecolor( $new_dims['img_width'], $new_dims['img_height'] );
|
||||
|
||||
if( !$new_img )
|
||||
{
|
||||
$this->error = 'image_creation_failed';
|
||||
return array();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Apply alpha blending
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'jpe':
|
||||
imagealphablending( $new_img, TRUE );
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
imagealphablending( $new_img, FALSE );
|
||||
imagesavealpha( $new_img, TRUE );
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Copy image resampled
|
||||
//---------------------------------------------------------
|
||||
|
||||
@imagecopyresampled( $new_img, $this->image, 0, 0, 0 ,0, $new_dims['img_width'], $new_dims['img_height'], $this->cur_dimensions['width'], $this->cur_dimensions['height'] );
|
||||
|
||||
$this->cur_dimensions = array( 'width' => $new_dims['img_width'], 'height' => $new_dims['img_height'] );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Don't forget the alpha blending
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'png':
|
||||
imagealphablending( $new_img, FALSE );
|
||||
imagesavealpha( $new_img, TRUE );
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Destroy original resource and store new resource
|
||||
//---------------------------------------------------------
|
||||
|
||||
@imagedestroy( $this->image );
|
||||
|
||||
$this->image = $new_img;
|
||||
|
||||
return array( 'originalWidth' => $this->orig_dimensions['width'],
|
||||
'originalHeight' => $this->orig_dimensions['height'],
|
||||
'newWidth' => $new_dims['img_width'],
|
||||
'newHeight' => $new_dims['img_height'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Write image to file
|
||||
*
|
||||
* @access public
|
||||
* @param string File location (including file name)
|
||||
* @return boolean File write successful
|
||||
*/
|
||||
public function writeImage( $path )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Remove image if it exists
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( file_exists( $path ) )
|
||||
{
|
||||
@unlink( $path );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Write file and verify
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'gif':
|
||||
@imagegif( $this->image, $path );
|
||||
break;
|
||||
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'jpe':
|
||||
@imagejpeg( $this->image, $path, $this->quality['jpg'] );
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
@imagepng( $this->image, $path, $this->quality['png'] );
|
||||
break;
|
||||
}
|
||||
|
||||
if( !file_exists( $path ) )
|
||||
{
|
||||
$this->error = 'unable_to_write_image';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Chmod 777
|
||||
//---------------------------------------------------------
|
||||
|
||||
@chmod( $path, 0777 );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Destroy image resource
|
||||
//---------------------------------------------------------
|
||||
|
||||
@imagedestroy( $this->image );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print image to screen
|
||||
*
|
||||
* @access public
|
||||
* @return void Image printed and script exits
|
||||
*/
|
||||
public function displayImage()
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Send appropriate header and output image
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'gif':
|
||||
@header('Content-type: image/gif');
|
||||
@imagegif( $this->image );
|
||||
break;
|
||||
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'jpe':
|
||||
@header('Content-Type: image/jpeg' );
|
||||
@imagejpeg( $this->image, null, $this->quality['jpg'] );
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
@header('Content-Type: image/png' );
|
||||
@imagepng( $this->image, null, $this->quality['png'] );
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Destroy image resource
|
||||
//---------------------------------------------------------
|
||||
|
||||
@imagedestroy( $this->image );
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add watermark to image
|
||||
*
|
||||
* @access public
|
||||
* @param string Watermark image path
|
||||
* @param integer [Optional] Opacity 0-100
|
||||
* @return boolean Watermark addition successful
|
||||
*/
|
||||
public function addWatermark( $path, $opacity=100 )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Verify input
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !$path )
|
||||
{
|
||||
$this->error = 'no_watermark_path';
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = strtolower( pathinfo( basename($path), PATHINFO_EXTENSION ) );
|
||||
$opacity = $opacity > 100 ? 100 : ( $opacity < 0 ? 1 : $opacity );
|
||||
|
||||
if( !in_array( $type, $this->image_types ) )
|
||||
{
|
||||
$this->error = 'bad_watermark_type';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Create resource from watermark and verify
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $type )
|
||||
{
|
||||
case 'gif':
|
||||
$mark = imagecreatefromgif( $path );
|
||||
break;
|
||||
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'jpe':
|
||||
$mark = imagecreatefromjpeg( $path );
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
$mark = imagecreatefrompng( $path );
|
||||
break;
|
||||
}
|
||||
|
||||
if( !$mark )
|
||||
{
|
||||
$this->error = 'image_creation_failed';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Alpha blending..
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'jpe':
|
||||
case 'png':
|
||||
@imagealphablending( $this->image, TRUE );
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get dimensions of watermark
|
||||
//---------------------------------------------------------
|
||||
|
||||
$img_info = @getimagesize( $path );
|
||||
$locate_x = $this->cur_dimensions['width'] - $img_info[0];
|
||||
$locate_y = $this->cur_dimensions['height'] - $img_info[1];
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Merge watermark image onto original image
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( $type == 'png' )
|
||||
{
|
||||
@imagecopy( $this->image, $mark, $locate_x, $locate_y, 0, 0, $img_info[0], $img_info[1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@imagecopymerge( $this->image, $mark, $locate_x, $locate_y, 0, 0, $img_info[0], $img_info[1], $opacity );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// And alpha blending again...
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'png':
|
||||
@imagealphablending( $this->image, FALSE );
|
||||
@imagesavealpha( $this->image, TRUE );
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Destroy watermark image resource and return
|
||||
//---------------------------------------------------------
|
||||
|
||||
imagedestroy( $mark );
|
||||
|
||||
$this->force_resize = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add copyright text to image
|
||||
*
|
||||
* @access public
|
||||
* @param string Copyright text to add
|
||||
* @param array [Optional] Text options (color, halign, valign, padding, font [1-5])
|
||||
* @return boolean Watermark addition successful
|
||||
*/
|
||||
public function addCopyrightText( $text, $textOpts=array() )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Verify input
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !$text )
|
||||
{
|
||||
$this->error = 'no_text_for_copyright';
|
||||
return false;
|
||||
}
|
||||
|
||||
$font = $textOpts['font'] ? $textOpts['font'] : 3;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Colors input as hex...convert to rgb
|
||||
//---------------------------------------------------------
|
||||
|
||||
$color = $textOpts['color'] ? array(
|
||||
hexdec( substr( ltrim( $textOpts['color'], '#' ), 0, 2 ) ),
|
||||
hexdec( substr( ltrim( $textOpts['color'], '#' ), 2, 2 ) ),
|
||||
hexdec( substr( ltrim( $textOpts['color'], '#' ), 5, 2 ) )
|
||||
) : array( 255, 255, 255 );
|
||||
$width = $this->cur_dimensions['width'] - 10;
|
||||
$halign = ( isset($textOpts['halign']) AND in_array( $textOpts['halign'], array( 'right', 'center', 'left' ) ) )
|
||||
? $textOpts['halign'] : 'right';
|
||||
$valign = ( isset($textOpts['valign']) AND in_array( $textOpts['valign'], array( 'top', 'middle', 'bottom' ) ) )
|
||||
? $textOpts['valign'] : 'bottom';
|
||||
$padding = $textOpts['padding'] ? $textOpts['padding'] : 5;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get some size info and set properties
|
||||
//---------------------------------------------------------
|
||||
|
||||
$fontwidth = imagefontwidth($font);
|
||||
$fontheight = imagefontheight($font);
|
||||
|
||||
$margin = floor($padding / 2 );
|
||||
|
||||
if ( $width > 0 )
|
||||
{
|
||||
$maxcharsperline = floor( ($width - ($margin * 2)) / $fontwidth);
|
||||
|
||||
if( $maxcharsperline )
|
||||
{
|
||||
$text = wordwrap( $text, $maxcharsperline, "\n", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
$lines = explode( "\n", $text );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Top, middle or bottom?
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $valign )
|
||||
{
|
||||
case "middle":
|
||||
$y = ( imagesy($this->image) - ( $fontheight * count($lines) ) ) / 2;
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
$y = imagesy($this->image) - ( ( $fontheight * count($lines) ) + $margin );
|
||||
break;
|
||||
|
||||
default:
|
||||
$y = $margin;
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Allocate colors for text/bg
|
||||
//---------------------------------------------------------
|
||||
|
||||
$color = imagecolorallocate( $this->image, $color[0], $color[1], $color[2] );
|
||||
$rect_back = imagecolorallocate( $this->image, 0,0,0 );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Switch on horizontal position and write text lines
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $halign )
|
||||
{
|
||||
case "right":
|
||||
while( list($numl, $line) = each($lines) )
|
||||
{
|
||||
imagefilledrectangle( $this->image, ( imagesx($this->image) - $fontwidth * strlen($line) ) - $margin, $y, imagesx($this->image) - 1, imagesy($this->image) - 1, $rect_back );
|
||||
imagestring( $this->image, $font, ( imagesx($this->image) - $fontwidth * strlen($line) ) - $margin, $y, $line, $color );
|
||||
$y += $fontheight;
|
||||
}
|
||||
break;
|
||||
|
||||
case "center":
|
||||
while( list($numl, $line) = each($lines) )
|
||||
{
|
||||
imagefilledrectangle( $this->image, floor( ( imagesx($this->image) - $fontwidth * strlen($line) ) / 2 ), $y, imagesx($this->image), imagesy($this->image), $rect_back );
|
||||
imagestring( $this->image, $font, floor( ( imagesx($this->image) - $fontwidth * strlen($line) ) / 2 ), $y, $line, $color );
|
||||
$y += $fontheight;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
while( list($numl, $line) = each($lines) )
|
||||
{
|
||||
imagefilledrectangle( $this->image, $margin, $y, imagesx($this->image), imagesy($this->image), $rect_back );
|
||||
imagestring( $this->image, $font, $margin, $y, $line, $color );
|
||||
$y += $fontheight;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$this->force_resize = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,519 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Image Handler: ImageMagick Library
|
||||
* Last Updated: $Date: 2009-07-29 21:58:46 -0400 (Wed, 29 Jul 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Monday 5th May 2008 14:00
|
||||
* @version $Revision: 303 $
|
||||
*
|
||||
* ImageMagick Example
|
||||
* <code>
|
||||
* $image = new classImageImagemagick();
|
||||
* $image->init( array(
|
||||
* 'image_path' => "/path/to/images/",
|
||||
* 'image_file' => "image_filename.jpg",
|
||||
* 'im_path' => '/path/to/imagemagick/folder/',
|
||||
* 'temp_path' => '/tmp/',
|
||||
* ) );
|
||||
*
|
||||
* if( $image->error )
|
||||
* {
|
||||
* print $image->error;exit;
|
||||
* }
|
||||
*
|
||||
* Set max width and height
|
||||
* $image->resizeImage( 600, 480 );
|
||||
* // Add a watermark
|
||||
* $image->addWatermark( "/path/to/watermark/trans.png" );
|
||||
* //$image->addCopyrightText( "Hello World!", array( 'color' => '#ffffff', 'font' => 3 ) );
|
||||
* $image->displayImage();
|
||||
* </code>
|
||||
*/
|
||||
|
||||
class classImageImagemagick extends classImage implements interfaceImage
|
||||
{
|
||||
/**
|
||||
* ImageMagick Path
|
||||
*
|
||||
* @access private
|
||||
* @var string Path to imagemagick binary (folder, no trailing slash)
|
||||
*/
|
||||
private $im_path = null;
|
||||
|
||||
/**
|
||||
* Temp directory (must be writable)
|
||||
*
|
||||
* @access private
|
||||
* @var string Path to a temp directory
|
||||
*/
|
||||
private $temp_path = '';
|
||||
|
||||
/**
|
||||
* Temp file (directory, name, .temp)
|
||||
*
|
||||
* @access private
|
||||
* @var string Full path to the temp file
|
||||
*/
|
||||
private $temp_file = '';
|
||||
|
||||
/**
|
||||
* Image quality settings
|
||||
*
|
||||
* @access public
|
||||
* @var array Image quality settings
|
||||
*/
|
||||
public $quality = array( 'png' => 8, 'jpg' => 75 );
|
||||
|
||||
/**
|
||||
* Initiate image handler, perform any necessary setup
|
||||
*
|
||||
* @access public
|
||||
* @param array Necessary options to init module [image_path, image_file, im_path, temp_path]
|
||||
* @return boolean Initiation successful
|
||||
*/
|
||||
public function init( $opts=array() )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Verify params
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !isset($opts['image_path']) OR !$opts['image_path'] )
|
||||
{
|
||||
$this->error = 'no_image_path';
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !isset($opts['image_file']) OR !$opts['image_file'] )
|
||||
{
|
||||
$this->error = 'no_image_file';
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !isset($opts['im_path']) OR !$opts['im_path'] )
|
||||
{
|
||||
$this->error = 'no_imagemagick_path';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Store params
|
||||
//---------------------------------------------------------
|
||||
|
||||
$this->image_path = $this->_cleanPaths( $opts['image_path'] );
|
||||
$this->image_file = basename( $opts['image_file'] );
|
||||
$this->image_full = $this->image_path . '/' . $this->image_file;
|
||||
$this->im_path = $this->_cleanPaths( $opts['im_path'] );
|
||||
$this->temp_path = $this->_cleanPaths( $opts['temp_path'] );
|
||||
$this->temp_file = $this->temp_path . '/' . $this->image_file . '.temp';
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Check paths and files
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !is_dir( $this->im_path ) )
|
||||
{
|
||||
$this->error = 'bad_imagemagick_path';
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !is_dir( $this->temp_path ) )
|
||||
{
|
||||
$this->error = 'bad_temp_path';
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !is_writable( $this->temp_path ) )
|
||||
{
|
||||
$this->error = 'temp_path_not_writable';
|
||||
return false;
|
||||
}
|
||||
|
||||
if( file_exists( $this->temp_file ) )
|
||||
{
|
||||
@unlink( $this->temp_file );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get image extension
|
||||
//---------------------------------------------------------
|
||||
|
||||
$this->image_extension = strtolower( pathinfo( $this->image_file, PATHINFO_EXTENSION ) );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Verify this is a valid image type
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !in_array( $this->image_extension, $this->image_types ) )
|
||||
{
|
||||
$this->error = 'image_not_supported';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Quality values
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( isset($opts['jpg_quality']) AND $opts['jpg_quality'] )
|
||||
{
|
||||
$this->quality['jpg'] = $opts['jpg_quality'];
|
||||
}
|
||||
|
||||
if( isset($opts['png_quality']) AND $opts['png_quality'] )
|
||||
{
|
||||
$this->quality['png'] = $opts['png_quality'];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get and store dimensions
|
||||
//---------------------------------------------------------
|
||||
|
||||
$dimensions = getimagesize( $this->image_full );
|
||||
|
||||
$this->orig_dimensions = array( 'width' => $dimensions[0], 'height' => $dimensions[1] );
|
||||
$this->cur_dimensions = $this->orig_dimensions;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize image proportionately
|
||||
*
|
||||
* @access public
|
||||
* @param integer Maximum width
|
||||
* @param integer Maximum height
|
||||
* @return array Dimensons of the original image and the resized dimensions
|
||||
*/
|
||||
public function resizeImage( $width, $height )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Grab proportionate dimensions and remember
|
||||
//---------------------------------------------------------
|
||||
|
||||
$new_dims = $this->_getResizeDimensions( $width, $height );
|
||||
|
||||
if( !is_array($new_dims) OR !count($new_dims) OR !$new_dims['img_width'] )
|
||||
{
|
||||
if( !$this->force_resize )
|
||||
{
|
||||
return array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$new_dims['width'] = $width;
|
||||
$new_dims['height'] = $height;
|
||||
}
|
||||
}
|
||||
|
||||
$this->cur_dimensions = array( 'width' => $new_dims['img_width'], 'height' => $new_dims['img_height'] );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Need image type for quality setting
|
||||
//---------------------------------------------------------
|
||||
|
||||
$type = strtolower( pathinfo( basename($this->image_full), PATHINFO_EXTENSION ) );
|
||||
$quality = '';
|
||||
|
||||
if( $type == 'jpg' OR $type == 'jpeg' )
|
||||
{
|
||||
$quality = " -quality {$this->quality['jpg']}";
|
||||
}
|
||||
else if( $type == 'png' )
|
||||
{
|
||||
$quality = " -quality {$this->quality['png']}";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Resize image to temp file
|
||||
//---------------------------------------------------------
|
||||
|
||||
system("{$this->im_path}/convert{$quality} -geometry {$new_dims['img_width']}x{$new_dims['img_height']} {$this->image_full} {$this->temp_file}" );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Successful?
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( file_exists( $this->temp_file ) )
|
||||
{
|
||||
return array( 'originalWidth' => $this->orig_dimensions['width'],
|
||||
'originalHeight' => $this->orig_dimensions['height'],
|
||||
'newWidth' => $new_dims['img_width'],
|
||||
'newHeight' => $new_dims['img_height'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write image to file
|
||||
*
|
||||
* @access public
|
||||
* @param string File location (including file name)
|
||||
* @return boolean File write successful
|
||||
*/
|
||||
public function writeImage( $path )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Remove image if it exists
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( file_exists( $path ) )
|
||||
{
|
||||
@unlink( $path );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Temp file doesn't exist
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !file_exists( $this->temp_file ) )
|
||||
{
|
||||
$this->error = 'temp_image_not_exists';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Rename temp file to final destination
|
||||
//---------------------------------------------------------
|
||||
|
||||
rename( $this->temp_file, $path );
|
||||
|
||||
if( !file_exists( $path ) )
|
||||
{
|
||||
$this->error = 'unable_to_write_image';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Chmod 777 and return
|
||||
//---------------------------------------------------------
|
||||
|
||||
@chmod( $path, 0777 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print image to screen
|
||||
*
|
||||
* @access public
|
||||
* @return void Image printed and script exits
|
||||
*/
|
||||
public function displayImage()
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Print appropriate header
|
||||
//---------------------------------------------------------
|
||||
|
||||
switch( $this->image_extension )
|
||||
{
|
||||
case 'gif':
|
||||
@header('Content-type: image/gif');
|
||||
break;
|
||||
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'jpe':
|
||||
@header('Content-Type: image/jpeg' );
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
@header('Content-Type: image/png' );
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Print file contents and exit
|
||||
//---------------------------------------------------------
|
||||
|
||||
print file_get_contents( $this->temp_file );
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add watermark to image
|
||||
*
|
||||
* @access public
|
||||
* @param string Watermark image path
|
||||
* @param integer [Optional] Opacity 0-100
|
||||
* @return boolean Watermark addition successful
|
||||
*/
|
||||
public function addWatermark( $path, $opacity=100 )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Verify input
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !$path )
|
||||
{
|
||||
$this->error = 'no_watermark_path';
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = strtolower( pathinfo( basename($path), PATHINFO_EXTENSION ) );
|
||||
$opacity = $opacity > 100 ? 100 : ( $opacity < 0 ? 1 : $opacity );
|
||||
|
||||
if( !in_array( $type, $this->image_types ) )
|
||||
{
|
||||
$this->error = 'bad_watermark_type';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Get dimensions
|
||||
//---------------------------------------------------------
|
||||
|
||||
$img_info = @getimagesize( $path );
|
||||
$locate_x = $this->cur_dimensions['width'] - $img_info[0];
|
||||
$locate_y = $this->cur_dimensions['height'] - $img_info[1];
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Working with original file or temp file?
|
||||
//---------------------------------------------------------
|
||||
|
||||
$file = file_exists( $this->temp_file ) ? $this->temp_file : $this->image_full;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Apply watermark and verify
|
||||
//---------------------------------------------------------
|
||||
|
||||
system("{$this->im_path}/composite -geometry +{$locate_x}+{$locate_y} {$path} {$file} {$this->temp_file}" );
|
||||
|
||||
if( file_exists( $this->temp_file ) )
|
||||
{
|
||||
$this->force_resize = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add copyright text to image
|
||||
*
|
||||
* @access public
|
||||
* @param string Copyright text to add
|
||||
* @param array [Optional] Text options (color, halign, valign, font [1-5])
|
||||
* @return boolean Watermark addition successful
|
||||
*/
|
||||
public function addCopyrightText( $text, $textOpts=array() )
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Have text?
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( !$text )
|
||||
{
|
||||
$this->error = 'no_text_for_copyright';
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// @ causes IM to try to read text from file specified by @
|
||||
//---------------------------------------------------------
|
||||
$text = ltrim( $text, '@' );
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Verify options
|
||||
//---------------------------------------------------------
|
||||
|
||||
$font = $textOpts['font'] ? $textOpts['font'] : 3;
|
||||
$color = $textOpts['color'] ? $textOpts['color'] : '#ffffff';
|
||||
$width = $this->cur_dimensions['width'] - 10;
|
||||
$halign = ( isset($textOpts['halign']) AND in_array( $textOpts['halign'], array( 'right', 'center', 'left' ) ) )
|
||||
? $textOpts['halign'] : 'right';
|
||||
$valign = ( isset($textOpts['valign']) AND in_array( $textOpts['valign'], array( 'top', 'middle', 'bottom' ) ) )
|
||||
? $textOpts['valign'] : 'bottom';
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Working with orig file or temp file?
|
||||
//---------------------------------------------------------
|
||||
|
||||
$file = file_exists( $this->temp_file ) ? $this->temp_file : $this->image_full;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Set gravity (location of text)
|
||||
//---------------------------------------------------------
|
||||
|
||||
$gravity = "";
|
||||
|
||||
switch( $valign )
|
||||
{
|
||||
case 'top':
|
||||
$gravity = "North";
|
||||
break;
|
||||
|
||||
case 'bottom':
|
||||
$gravity = "South";
|
||||
break;
|
||||
}
|
||||
|
||||
if( $valign == 'middle' AND $halign == 'center' )
|
||||
{
|
||||
$gravity = "Center";
|
||||
}
|
||||
|
||||
switch( $halign )
|
||||
{
|
||||
case 'right':
|
||||
$gravity .= "East";
|
||||
break;
|
||||
|
||||
case 'left':
|
||||
$gravity .= "West";
|
||||
break;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Apply annotation to image and verify
|
||||
//---------------------------------------------------------
|
||||
|
||||
system("{$this->im_path}/composite {$file} -fill {$color} -undercolor #000000 -gravity {$gravity} -annotate +0+5 '{$text}' {$this->temp_file}" );
|
||||
|
||||
if( file_exists( $this->temp_file ) )
|
||||
{
|
||||
$this->force_resize = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Image handler desctructor
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
//---------------------------------------------------------
|
||||
// Remove temp file if it hasn't been saved
|
||||
//---------------------------------------------------------
|
||||
|
||||
if( file_exists( $this->temp_file ) )
|
||||
{
|
||||
@unlink( $this->temp_file );
|
||||
}
|
||||
|
||||
parent::__destruct();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Wrapper for interfacing with stopforumspam.com
|
||||
* Class written by Matt Mecham
|
||||
* Last Updated: $Date: 2009-02-04 20:05:25 +0000 (Wed, 04 Feb 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Tuesday 22nd February 2005 (16:55)
|
||||
* @version $Revision: 222 $
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_KERNEL_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_KERNEL_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
class classStopForumSpam
|
||||
{
|
||||
/**
|
||||
* Minimum frequency to check for
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
private $_minF = 3;
|
||||
|
||||
/**
|
||||
* XML object
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
private $_xml = null;
|
||||
|
||||
/**
|
||||
* ClassFileManagement object
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
private $_cfm = null;
|
||||
|
||||
/**
|
||||
* Load XML and classFileManagement libraries
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
/* CFM */
|
||||
require_once( IPS_KERNEL_PATH . 'classFileManagement.php' );
|
||||
$this->_cfm = new classFileManagement();
|
||||
|
||||
/* XML */
|
||||
require_once( IPS_KERNEL_PATH . 'classXML.php' );
|
||||
$this->_xml = new classXML('utf-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a frequency
|
||||
*
|
||||
* @access public
|
||||
* @param int
|
||||
* @return void
|
||||
*/
|
||||
public function setFrequency( $f )
|
||||
{
|
||||
$this->_minF = $f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if IP address is blacklisted
|
||||
*
|
||||
* @access public
|
||||
* @param string IP Address
|
||||
* @return boolean TRUE = blacklisted, FALSE = clean
|
||||
*/
|
||||
public function checkForIpAddress( $ip )
|
||||
{
|
||||
$result = $this->_cfm->getFileContents( "http://www.stopforumspam.com/api?ip=" . $ip );
|
||||
|
||||
/* We're only interested in this, currently */
|
||||
if ( $result )
|
||||
{
|
||||
$this->_xml->loadXML( $result );
|
||||
|
||||
foreach( $this->_xml->fetchElements( 'response' ) as $_el )
|
||||
{
|
||||
$data = $this->_xml->fetchElementsFromRecord( $_el );
|
||||
|
||||
if ( $data['appears'] AND intval( $data['frequency'] ) > $this->_minF )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if email address is blacklisted
|
||||
*
|
||||
* @access public
|
||||
* @param string Email address
|
||||
* @return boolean TRUE = blacklisted, FALSE = clean
|
||||
*/
|
||||
public function checkForEmailAddress( $email )
|
||||
{
|
||||
$result = $this->_cfm->getFileContents( "http://www.stopforumspam.com/api?email=" . $email );
|
||||
|
||||
/* We're only interested in this, currently */
|
||||
if ( $result )
|
||||
{
|
||||
$this->_xml->loadXML( $result );
|
||||
|
||||
foreach( $this->_xml->fetchElements( 'response' ) as $_el )
|
||||
{
|
||||
$data = $this->_xml->fetchElementsFromRecord( $_el );
|
||||
|
||||
if ( $data['appears'] AND intval( $data['frequency'] ) > $this->_minF )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
+581
-265
File diff suppressed because it is too large.
Load diff
@@ -1,236 +1,208 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
| Licence Info: http://www.invisionboard.com/?license
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2005-10-10 14:03:20 +0100 (Mon, 10 Oct 2005) $
|
||||
| > $Revision: 22 $
|
||||
| > $Author: matt $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > UPLOAD handling methods (KERNEL)
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: 15th March 2004
|
||||
|
|
||||
| > Module Version Number: 1.0.0
|
||||
+--------------------------------------------------------------------------
|
||||
| ERRORS:
|
||||
| 1: No upload
|
||||
| 2: Not valid upload type
|
||||
| 3: Upload exceeds $max_file_size
|
||||
| 4: Could not move uploaded file, upload deleted
|
||||
| 5: File pretending to be an image but isn't (poss XSS attack)
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Upload
|
||||
*
|
||||
* This class contains all generic functions to handle
|
||||
* the parsing of $_FILE data.
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
* $upload = new class_upload();
|
||||
* $upload->out_file_dir = './uploads';
|
||||
* $upload->max_file_size = '10000000';
|
||||
* $upload->make_script_safe = 1;
|
||||
* $upload->allowed_file_ext = array( 'gif', 'jpg', 'jpeg', 'png' );
|
||||
* $upload->upload_process();
|
||||
*
|
||||
* if ( $upload->error_no )
|
||||
* {
|
||||
* switch( $upload->error_no )
|
||||
* {
|
||||
* case 1:
|
||||
* // No upload
|
||||
* print "No upload"; exit();
|
||||
* case 2:
|
||||
* case 5:
|
||||
* // Invalid file ext
|
||||
* print "Invalid File Extension"; exit();
|
||||
* case 3:
|
||||
* // Too big...
|
||||
* print "File too big"; exit();
|
||||
* case 4:
|
||||
* // Cannot move uploaded file
|
||||
* print "Move failed"; exit();
|
||||
* }
|
||||
* }
|
||||
* print $upload->saved_upload_name . " uploaded!";
|
||||
* </code>
|
||||
* ERRORS:
|
||||
* 1: No upload
|
||||
* 2: Not valid upload type
|
||||
* 3: Upload exceeds $max_file_size
|
||||
* 4: Could not move uploaded file, upload deleted
|
||||
* 5: File pretending to be an image but isn't (poss XSS attack)
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 2.1
|
||||
*/
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* Upload handler : Handles $_FILES and checks for security
|
||||
* Last Updated: $Date: 2009-02-23 17:45:20 -0500 (Mon, 23 Feb 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since 15th March 2004
|
||||
* @version $Revision: 229 $
|
||||
*
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
* $upload = new classUpload();
|
||||
* $upload->out_file_dir = './uploads';
|
||||
* $upload->max_file_size = '10000000';
|
||||
* $upload->make_script_safe = 1;
|
||||
* $upload->allowed_file_ext = array( 'gif', 'jpg', 'jpeg', 'png' );
|
||||
* $upload->process();
|
||||
*
|
||||
* if ( $upload->error_no )
|
||||
* {
|
||||
* switch( $upload->error_no )
|
||||
* {
|
||||
* case 1:
|
||||
* // No upload
|
||||
* print "No upload"; exit();
|
||||
* case 2:
|
||||
* case 5:
|
||||
* // Invalid file ext
|
||||
* print "Invalid File Extension"; exit();
|
||||
* case 3:
|
||||
* // Too big...
|
||||
* print "File too big"; exit();
|
||||
* case 4:
|
||||
* // Cannot move uploaded file
|
||||
* print "Move failed"; exit();
|
||||
* }
|
||||
* }
|
||||
* print $upload->saved_upload_name . " uploaded!";
|
||||
* </code>
|
||||
* ERRORS:
|
||||
* 1: No upload
|
||||
* 2: Not valid upload type
|
||||
* 3: Upload exceeds $max_file_size
|
||||
* 4: Could not move uploaded file, upload deleted
|
||||
* 5: File pretending to be an image but isn't (poss XSS attack)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Upload Class
|
||||
*
|
||||
* Methods and functions for handling file uploads
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_upload
|
||||
class classUpload
|
||||
{
|
||||
/**
|
||||
* Name of upload form field
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $upload_form_field = 'FILE_UPLOAD';
|
||||
public $upload_form_field = 'FILE_UPLOAD';
|
||||
|
||||
/**
|
||||
* Out filename *without* extension
|
||||
* (Leave blank to retain user filename)
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $out_file_name = '';
|
||||
public $out_file_name = '';
|
||||
|
||||
/**
|
||||
* Out dir (./upload) - no trailing slash
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $out_file_dir = './';
|
||||
public $out_file_dir = './';
|
||||
|
||||
/**
|
||||
* maximum file size of this upload
|
||||
* Maximum file size of this upload
|
||||
*
|
||||
* @var integer
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
var $max_file_size = 0;
|
||||
public $max_file_size = 0;
|
||||
|
||||
/**
|
||||
* Forces PHP, CGI, etc to text
|
||||
*
|
||||
* @var integer
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
var $make_script_safe = 1;
|
||||
public $make_script_safe = 1;
|
||||
|
||||
/**
|
||||
* Force non-img file extenstion (leave blank if not) (ex: 'ibf' makes upload.doc => upload.ibf)
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $force_data_ext = '';
|
||||
public $force_data_ext = '';
|
||||
|
||||
/**
|
||||
* Allowed file extensions array( 'gif', 'jpg', 'jpeg'..)
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
var $allowed_file_ext = array();
|
||||
public $allowed_file_ext = array();
|
||||
|
||||
/**
|
||||
* Check file extension allowed
|
||||
*
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
public $check_file_ext = true;
|
||||
|
||||
/**
|
||||
* Array of IMAGE file extensions
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
var $image_ext = array( 'gif', 'jpeg', 'jpg', 'jpe', 'png' );
|
||||
public $image_ext = array( 'gif', 'jpeg', 'jpg', 'jpe', 'png' );
|
||||
|
||||
/**
|
||||
* Check to make sure an image is an image
|
||||
*
|
||||
* @var boolean flag
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
var $image_check = 1;
|
||||
public $image_check = true;
|
||||
|
||||
/**
|
||||
* Returns current file extension
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $file_extension = '';
|
||||
public $file_extension = '';
|
||||
|
||||
/**
|
||||
* If force_data_ext == 1, this will return the 'real' extension
|
||||
* and $file_extension will return the 'force_data_ext'
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $real_file_extension = '';
|
||||
public $real_file_extension = '';
|
||||
|
||||
/**
|
||||
* Returns error number
|
||||
* Returns error number [1-5]
|
||||
*
|
||||
* @var integer
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
var $error_no = 0;
|
||||
public $error_no = 0;
|
||||
|
||||
/**
|
||||
* Returns if upload is img or not
|
||||
*
|
||||
* @var integer
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
var $is_image = 0;
|
||||
public $is_image = 0;
|
||||
|
||||
/**
|
||||
* Returns file name as was uploaded by user
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $original_file_name = "";
|
||||
public $original_file_name = "";
|
||||
|
||||
/**
|
||||
* Returns final file name as is saved on disk. (no path info)
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $parsed_file_name = "";
|
||||
public $parsed_file_name = "";
|
||||
|
||||
/**
|
||||
* Returns final file name with path info
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $saved_upload_name = "";
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// CONSTRUCTOR
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_upload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// PROCESS THE UPLOAD
|
||||
/*-------------------------------------------------------------------------*/
|
||||
public $saved_upload_name = "";
|
||||
|
||||
/**
|
||||
* Processes the upload
|
||||
*
|
||||
* @access public
|
||||
* @return boolean Upload successful
|
||||
*/
|
||||
|
||||
function upload_process()
|
||||
public function process()
|
||||
{
|
||||
$this->_clean_paths();
|
||||
$this->_cleanPaths();
|
||||
|
||||
//-------------------------------------------------
|
||||
// Check for getimagesize
|
||||
@@ -262,10 +234,11 @@ class class_upload
|
||||
//-------------------------------------------------
|
||||
|
||||
if ( !isset($_FILES[ $this->upload_form_field ]['name'])
|
||||
or $_FILES[ $this->upload_form_field ]['name'] == ""
|
||||
or !$_FILES[ $this->upload_form_field ]['name']
|
||||
or !$_FILES[ $this->upload_form_field ]['size']
|
||||
or ($_FILES[ $this->upload_form_field ]['name'] == "none") )
|
||||
or $_FILES[ $this->upload_form_field ]['name'] == ""
|
||||
or !$_FILES[ $this->upload_form_field ]['name']
|
||||
or !$_FILES[ $this->upload_form_field ]['size']
|
||||
or ($_FILES[ $this->upload_form_field ]['name'] == "none")
|
||||
)
|
||||
{
|
||||
if( $_FILES[ $this->upload_form_field ]['error'] == 2 )
|
||||
{
|
||||
@@ -275,36 +248,39 @@ class class_upload
|
||||
{
|
||||
$this->error_no = 1;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !is_uploaded_file($_FILES[ $this->upload_form_field ]['tmp_name']) )
|
||||
if( !is_uploaded_file( $_FILES[ $this->upload_form_field ]['tmp_name'] ) )
|
||||
{
|
||||
$this->error_no = 1;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// De we have allowed file_extensions?
|
||||
// Do we have allowed file_extensions?
|
||||
//-------------------------------------------------
|
||||
|
||||
if ( ! is_array( $this->allowed_file_ext ) or ! count( $this->allowed_file_ext ) )
|
||||
if( $this->check_file_ext )
|
||||
{
|
||||
$this->error_no = 2;
|
||||
return;
|
||||
if ( ! is_array( $this->allowed_file_ext ) or ! count( $this->allowed_file_ext ) )
|
||||
{
|
||||
$this->error_no = 2;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Get file extension
|
||||
//-------------------------------------------------
|
||||
|
||||
$this->file_extension = $this->_get_file_extension( $FILE_NAME );
|
||||
$this->file_extension = $this->_getFileExtension( $FILE_NAME );
|
||||
|
||||
if ( ! $this->file_extension )
|
||||
{
|
||||
$this->error_no = 2;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->real_file_extension = $this->file_extension;
|
||||
@@ -313,10 +289,10 @@ class class_upload
|
||||
// Valid extension?
|
||||
//-------------------------------------------------
|
||||
|
||||
if ( ! in_array( $this->file_extension, $this->allowed_file_ext ) )
|
||||
if ( $this->check_file_ext AND !in_array( $this->file_extension, $this->allowed_file_ext ) )
|
||||
{
|
||||
$this->error_no = 2;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@@ -326,17 +302,18 @@ class class_upload
|
||||
if ( ( $this->max_file_size ) and ( $FILE_SIZE > $this->max_file_size ) )
|
||||
{
|
||||
$this->error_no = 3;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Make the uploaded file safe
|
||||
// Storing original_file_name before replacements
|
||||
//-------------------------------------------------
|
||||
|
||||
$this->original_file_name = $FILE_NAME;
|
||||
|
||||
$FILE_NAME = preg_replace( "/[^\w\.]/", "_", $FILE_NAME );
|
||||
|
||||
$this->original_file_name = $FILE_NAME;
|
||||
|
||||
//-------------------------------------------------
|
||||
// Convert file name?
|
||||
// In any case, file name is WITHOUT extension
|
||||
@@ -348,7 +325,7 @@ class class_upload
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parsed_file_name = str_replace( '.'.$this->file_extension, "", $FILE_NAME );
|
||||
$this->parsed_file_name = str_replace( '.' . $this->file_extension, "", $FILE_NAME );
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@@ -390,7 +367,7 @@ class class_upload
|
||||
$this->file_extension = str_replace( ".", "", $this->force_data_ext );
|
||||
}
|
||||
|
||||
$this->parsed_file_name .= '.'.$this->file_extension;
|
||||
$this->parsed_file_name .= '.' . $this->file_extension;
|
||||
|
||||
//-------------------------------------------------
|
||||
// Copy the upload to the uploads directory
|
||||
@@ -399,9 +376,9 @@ class class_upload
|
||||
// We'll just unlink if it doesn't checkout
|
||||
//-------------------------------------------------
|
||||
|
||||
$this->saved_upload_name = $this->out_file_dir.'/'.$this->parsed_file_name;
|
||||
$this->saved_upload_name = $this->out_file_dir . '/' . $this->parsed_file_name;
|
||||
|
||||
if ( ! @move_uploaded_file( $_FILES[ $this->upload_form_field ]['tmp_name'], $this->saved_upload_name) )
|
||||
if ( ! @move_uploaded_file( $_FILES[ $this->upload_form_field ]['tmp_name'], $this->saved_upload_name ) )
|
||||
{
|
||||
$this->error_no = 4;
|
||||
return;
|
||||
@@ -411,13 +388,13 @@ class class_upload
|
||||
@chmod( $this->saved_upload_name, 0777 );
|
||||
}
|
||||
|
||||
if( !$renamed )
|
||||
if( !$renamed AND $this->file_extension != 'txt' )
|
||||
{
|
||||
$this->check_xss_infile();
|
||||
|
||||
$this->_checkXSSInfile();
|
||||
|
||||
if( $this->error_no )
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,26 +412,24 @@ class class_upload
|
||||
{
|
||||
$img_attributes = @getimagesize( $this->saved_upload_name );
|
||||
|
||||
if ( ! is_array( $img_attributes ) or ! count( $img_attributes ) )
|
||||
if ( ! is_array( $img_attributes ) or !count( $img_attributes ) )
|
||||
{
|
||||
// Unlink the file first
|
||||
@unlink( $this->saved_upload_name );
|
||||
$this->error_no = 5;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
else if ( ! $img_attributes[2] )
|
||||
{
|
||||
// Unlink the file first
|
||||
@unlink( $this->saved_upload_name );
|
||||
$this->error_no = 5;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
else if ( $img_attributes[2] == 1 AND ( $this->file_extension == 'jpg' OR $this->file_extension == 'jpeg' ) )
|
||||
{
|
||||
// Potential XSS attack with a fake GIF header in a JPEG
|
||||
@unlink( $this->saved_upload_name );
|
||||
$this->error_no = 5;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,24 +443,19 @@ class class_upload
|
||||
if( filesize($this->saved_upload_name) != $_FILES[ $this->upload_form_field ]['size'] )
|
||||
{
|
||||
@unlink( $this->saved_upload_name );
|
||||
|
||||
|
||||
$this->error_no = 1;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// INTERNAL: Check for XSS inside file
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* Checks for XSS inside file. If found, sets error_no to 5 and returns
|
||||
* Checks for XSS inside file. If found, deletes file, sets error_no to 5 and returns
|
||||
*
|
||||
* @param void
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function check_xss_infile()
|
||||
private function _checkXSSInfile()
|
||||
{
|
||||
// HTML added inside an inline file is not good in IE...
|
||||
|
||||
@@ -499,7 +469,7 @@ class class_upload
|
||||
{
|
||||
@unlink( $this->saved_upload_name );
|
||||
$this->error_no = 5;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
# Thanks to Nicolas Grekas from comments at www.splitbrain.org for helping to identify all vulnerable HTML tags
|
||||
@@ -508,41 +478,32 @@ class class_upload
|
||||
{
|
||||
@unlink( $this->saved_upload_name );
|
||||
$this->error_no = 5;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// INTERNAL: Get file extension
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Returns the file extension of the current filename
|
||||
*
|
||||
* @param string Filename
|
||||
* @access public
|
||||
* @param string Filename
|
||||
* @return string File extension
|
||||
*/
|
||||
|
||||
function _get_file_extension($file)
|
||||
public function _getFileExtension($file)
|
||||
{
|
||||
return strtolower( str_replace( ".", "", substr( $file, strrpos( $file, '.' ) ) ) );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// INTERNAL: Clean paths
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* Trims off trailing slashes
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function _clean_paths()
|
||||
private function _cleanPaths()
|
||||
{
|
||||
$this->out_file_dir = preg_replace( "#/$#", "", $this->out_file_dir );
|
||||
$this->out_file_dir = rtrim( $this->out_file_dir, '/' );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,718 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* XML Handler: Rewritten for PHP5
|
||||
* By Matt Mecham
|
||||
* Last Updated: $Date: 2009-08-06 12:51:21 -0400 (Thu, 06 Aug 2009) $
|
||||
*
|
||||
* @author $Author: bfarber $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since 25th February 2004
|
||||
* @version $Revision: 307 $
|
||||
*
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
* <productlist name="myname" version="1.0">
|
||||
* <productgroup name="thisgroup">
|
||||
* <product id="1.0">
|
||||
* <description>This is a descrption</description>
|
||||
* <title>Baked Beans</title>
|
||||
* <room store="1">103</room>
|
||||
* </product>
|
||||
* <product id="2.0">
|
||||
* <description>This is another descrption</description>
|
||||
* <title>Green Beans</title>
|
||||
* <room store="2">104</room>
|
||||
* </product>
|
||||
* </productgroup>
|
||||
* </productlist>
|
||||
*
|
||||
* Creating...
|
||||
* $xml = new classXML( 'utf-8' );
|
||||
* $xml->newXMLDocument();
|
||||
*
|
||||
* /* Create a root element * /
|
||||
* $xml->addElement( 'productlist', '', array( 'name' => 'myname', 'version' => '1.0' ) );
|
||||
* /* Add a child.... * /
|
||||
* $xml->addElement( 'productgroup', 'productlist', array( 'name' => 'thisgroup' ) );
|
||||
* $xml->addElementAsRecord( 'productgroup',
|
||||
* array( 'product', array( 'id' => '1.0' ) ),
|
||||
* array( 'description' => array( 'This is a description' ),
|
||||
* 'title' => array( 'Baked Beans' ),
|
||||
* 'room' => array( '103', array( 'store' => 1 ) )
|
||||
* )
|
||||
* );
|
||||
* $xml->addElementAsRecord( 'productgroup',
|
||||
* array( 'product', array( 'id' => '2.0' ) ),
|
||||
* array( 'description' => array( 'This is another description' ),
|
||||
* 'title' => array( 'Green Beans' ),
|
||||
* 'room' => array( '104', array( 'store' => 2 ) )
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* $xmlData = $xml->fetchDocument();
|
||||
*
|
||||
* /*Convering XML into an array * /
|
||||
* $xml->loadXML( $xmlData );
|
||||
*
|
||||
* /* Grabbing specific data values from all 'products'... * /
|
||||
* foreach( $xml->fetchElements('product') as $products )
|
||||
* {
|
||||
* print $xml->fetchItem( $products, 'title' ) . "\";
|
||||
* }
|
||||
*
|
||||
* /* Prints... * /
|
||||
* Baked Beans
|
||||
* Green Beans
|
||||
*
|
||||
* /* Print all array data - auto converts XML_TEXT_NODE and XML_CDATA_SECTION_NODE into #alltext for brevity * /
|
||||
* print_r( $xml->fetchXMLAsArray() );
|
||||
*
|
||||
* /* Prints * /
|
||||
* Array
|
||||
* (
|
||||
* [productlist] => Array
|
||||
* (
|
||||
* [@attributes] => Array
|
||||
* (
|
||||
* [name] => myname
|
||||
* [version] => 1.0
|
||||
* )
|
||||
* [productgroup] => Array
|
||||
* (
|
||||
* [@attributes] => Array
|
||||
* (
|
||||
* [name] => thisgroup
|
||||
* )
|
||||
* [product] => Array
|
||||
* (
|
||||
* [0] => Array
|
||||
* (
|
||||
* [@attributes] => Array
|
||||
* (
|
||||
* [id] => 1.0
|
||||
* )
|
||||
* [description] => Array
|
||||
* (
|
||||
* [#alltext] => This is a description
|
||||
* )
|
||||
* [title] => Array
|
||||
* (
|
||||
* [#alltext] => Baked Beans
|
||||
* )
|
||||
* [room] => Array
|
||||
* (
|
||||
* [@attributes] => Array
|
||||
* (
|
||||
* [store] => 1.0
|
||||
* )
|
||||
* [#alltext] => 103
|
||||
* )
|
||||
* )
|
||||
* [1] => Array
|
||||
* (
|
||||
* [@attributes] => Array
|
||||
* (
|
||||
* [id] => 2.0
|
||||
* )
|
||||
* [description] => Array
|
||||
* (
|
||||
* [#alltext] => This is another description
|
||||
* )
|
||||
* [title] => Array
|
||||
* (
|
||||
* [#alltext] => Green Beans
|
||||
* )
|
||||
* [room] => Array
|
||||
* (
|
||||
* [@attributes] => Array
|
||||
* (
|
||||
* [store] => 1.0
|
||||
* )
|
||||
* [#alltext] => 104
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
|
||||
class classXML
|
||||
{
|
||||
/**
|
||||
* Document character set
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_docCharSet = 'utf-8';
|
||||
|
||||
/**
|
||||
* Current document object
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
private $_dom;
|
||||
|
||||
/**
|
||||
* Array of DOM objects
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_domObjects = array();
|
||||
|
||||
/**
|
||||
* XML array
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_xmlArray = array();
|
||||
|
||||
/**
|
||||
* Conversion class
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
private static $classConvertCharset;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string Character Set
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $charSet )
|
||||
{
|
||||
$this->_docCharSet = strtolower( $charSet );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new document
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function newXMLDocument()
|
||||
{
|
||||
$this->_dom = new DOMDocument( '1.0', 'utf-8' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the document
|
||||
*
|
||||
* @access public
|
||||
* @return XML data
|
||||
*/
|
||||
public function fetchDocument()
|
||||
{
|
||||
$this->_dom->formatOutput = TRUE;
|
||||
return $this->_dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add element into the document
|
||||
*
|
||||
* @access public
|
||||
* @param string Name of tag to create
|
||||
* @param string [Name of parent tag (optional)]
|
||||
* @param array [Attributes]
|
||||
* @return void
|
||||
*/
|
||||
public function addElement( $tag, $parentTag='', $attributes=array() )
|
||||
{
|
||||
$this->_domObjects[ $tag ] = $this->_node( $parentTag )->appendChild( new DOMElement( $tag ) );
|
||||
$this->addAttributes( $tag, $attributes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add element into the document as a record row
|
||||
* You can pass $tag as either a string or an array
|
||||
*
|
||||
* $xml->addElementAsRecord( 'parentTag', 'myTag', $data );
|
||||
* $xml->addElementAsRecord( 'parentTag', array( 'myTag', array( 'attr' => 'value' ) ), $data );
|
||||
*
|
||||
* @access public
|
||||
* @param string Name of parent tag
|
||||
* @param mixed Tag wrapper
|
||||
* @param array Array of data to add
|
||||
* @return void
|
||||
*/
|
||||
public function addElementAsRecord( $parentTag, $tag, $data )
|
||||
{
|
||||
/* A little set up if you please... */
|
||||
$_tag = $tag;
|
||||
$_tag_attr = array();
|
||||
|
||||
if ( is_array( $tag ) )
|
||||
{
|
||||
$_tag = $tag[0];
|
||||
$_tag_attr = $tag[1];
|
||||
}
|
||||
|
||||
$record = $this->_node( $parentTag )->appendChild( new DOMElement( $_tag ) );
|
||||
|
||||
if ( is_array( $_tag_attr ) AND count( $_tag_attr ) )
|
||||
{
|
||||
foreach( $_tag_attr as $k => $v )
|
||||
{
|
||||
$record->appendChild( new DOMAttr( $k, $v ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Now to add the data */
|
||||
if ( is_array( $data ) AND count( $data ) )
|
||||
{
|
||||
foreach( $data as $rowTag => $rowData )
|
||||
{
|
||||
/* You can pass an array.. or not if you don't need attributes */
|
||||
if ( ! is_array( $rowData ) )
|
||||
{
|
||||
$rowData = array( 0 => $rowData );
|
||||
}
|
||||
|
||||
if ( preg_match( "/['\"\[\]<>&]/", $rowData[0] ) )
|
||||
{
|
||||
$_child = $record->appendChild( new DOMElement( $rowTag ) );
|
||||
$_child->appendChild( new DOMCDATASection( $this->_inputToXml( $rowData[0] ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$_child = $record->appendChild( new DOMElement( $rowTag, $this->_inputToXml( $rowData[0] ) ) );
|
||||
}
|
||||
|
||||
if ( $rowData[1] )
|
||||
{
|
||||
foreach( $rowData[1] as $_k => $_v )
|
||||
{
|
||||
$_child->appendChild( new DOMAttr( $_k, $_v ) );
|
||||
}
|
||||
}
|
||||
|
||||
unset( $_child );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add attributes to a node
|
||||
*
|
||||
* @access public
|
||||
* @param string Name of tag
|
||||
* @param array Array of attributes in key => value format
|
||||
* @return void
|
||||
*/
|
||||
public function addAttributes( $tag, $data )
|
||||
{
|
||||
if ( is_array( $data ) AND count( $data ) )
|
||||
{
|
||||
foreach( $data as $k => $v )
|
||||
{
|
||||
$this->_node( $tag )->appendChild( new DOMAttr( $k, $v ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a document from a file
|
||||
*
|
||||
* @access public
|
||||
* @param string File name
|
||||
* @return void
|
||||
*/
|
||||
public function load( $filename )
|
||||
{
|
||||
$this->_dom = new DOMDocument;
|
||||
$this->_dom->load( $filename );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a document from a string
|
||||
*
|
||||
* @access public
|
||||
* @param string XML Data
|
||||
* @return void
|
||||
*/
|
||||
public function loadXML( $xmlData )
|
||||
{
|
||||
$this->_dom = new DOMDocument;
|
||||
$this->_dom->loadXML( $xmlData );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function: Fetch elements based on tag name
|
||||
*
|
||||
* @access public
|
||||
* @param string Tag Name to fetch from the DOM tree
|
||||
* @param object Node to start from
|
||||
* @return array Node elements
|
||||
*/
|
||||
public function fetchElements( $tag, $node=null )
|
||||
{
|
||||
$start = $node ? $node : $this->_dom;
|
||||
$_elements = $start->getElementsByTagName( $tag );
|
||||
|
||||
return ( $_elements->length ) ? $_elements : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function: Fetch all items within a parent tag
|
||||
*
|
||||
* @access public
|
||||
* @param object DOM object as returned from getElementsByTagName
|
||||
* @param array array of node names to skip
|
||||
* @return array Array of elements
|
||||
*/
|
||||
public function fetchElementsFromRecord( $dom, $skip=array() )
|
||||
{
|
||||
$array = array();
|
||||
|
||||
foreach( $dom->childNodes as $node )
|
||||
{
|
||||
if ( $node->nodeType == XML_ELEMENT_NODE )
|
||||
{
|
||||
if ( is_array( $skip ) )
|
||||
{
|
||||
if ( in_array( $node->nodeName, $skip ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$array[ $node->nodeName ] = $this->_xmlToOutput( $node->nodeValue );
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function: Fetch items from an element node
|
||||
*
|
||||
* @access public
|
||||
* @param object DOM object as returned from getElementsByTagName
|
||||
* @param string [Optional: Tag name if the DOM is a parent]
|
||||
* @return string Returned item
|
||||
*/
|
||||
public function fetchItem( $dom, $tag='' )
|
||||
{
|
||||
if ( $tag )
|
||||
{
|
||||
$_child = $dom->getElementsByTagName( $tag );
|
||||
return $this->_xmlToOutput( $_child->item(0)->firstChild->nodeValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->_xmlToOutput( $dom->nodeValue );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function: Fetch attributes from an element node's item
|
||||
*
|
||||
* @access public
|
||||
* @param object DOM object as returned from getElementsByTagName
|
||||
* @param string Attribute name required...
|
||||
* @param string [Optional: Tag name if the DOM is a parent]
|
||||
* @return string Attribute
|
||||
*/
|
||||
public function fetchAttribute( $dom, $attribute, $tag='' )
|
||||
{
|
||||
if ( $tag )
|
||||
{
|
||||
$_child = $dom->getElementsByTagName( $tag );
|
||||
return $_child->item(0)->getAttribute( $attribute );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $dom->getAttribute( $attribute );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function: Fetch all attributes from an element node's item
|
||||
*
|
||||
* @access public
|
||||
* @param object DOM object as returned from getElementsByTagName
|
||||
* @param string Tag name to fetch attribute from
|
||||
* @return array Array of node items
|
||||
*/
|
||||
public function fetchAttributesAsArray( $dom, $tag )
|
||||
{
|
||||
$attrs = array();
|
||||
$_child = $dom->getElementsByTagName( $tag );
|
||||
$attributes = $_child->item(0)->attributes;
|
||||
|
||||
foreach( $attributes as $val )
|
||||
{
|
||||
$attrs[ $val->nodeName ] = $val->nodeValue;
|
||||
}
|
||||
|
||||
return $attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch entire DOM tree into a single array
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function fetchXMLAsArray()
|
||||
{
|
||||
return $this->_fetchXMLAsArray( $this->_dom );
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to recurse through and collect nodes and data
|
||||
*
|
||||
* @access private
|
||||
* @param DOM object Node element
|
||||
* @return array
|
||||
*/
|
||||
private function _fetchXMLAsArray( $node )
|
||||
{
|
||||
$_xmlArray = array();
|
||||
|
||||
if ( $node->nodeType == XML_TEXT_NODE )
|
||||
{
|
||||
$_xmlArray = $node->nodeValue;
|
||||
}
|
||||
else if ( $node->nodeType == XML_CDATA_SECTION_NODE )
|
||||
{
|
||||
$_xmlArray = $this->_xmlToOutput( $node->nodeValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $node->hasAttributes() )
|
||||
{
|
||||
$attributes = $node->attributes;
|
||||
|
||||
if ( ! is_null( $attributes ) )
|
||||
{
|
||||
foreach( $attributes as $index => $attr )
|
||||
{
|
||||
$_xmlArray['@attributes'][ $attr->name ] = $attr->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $node->hasChildNodes() )
|
||||
{
|
||||
$children = $node->childNodes;
|
||||
$occurance = array();
|
||||
|
||||
foreach( $children as $nc)
|
||||
{
|
||||
if ( $nc->nodeName != '#text' AND $nc->nodeName != '#cdata-section' )
|
||||
{
|
||||
$occurance[ $nc->nodeName ]++;
|
||||
}
|
||||
}
|
||||
|
||||
for( $i = 0 ; $i < $children->length ; $i++ )
|
||||
{
|
||||
$child = $children->item( $i );
|
||||
$_name = $child->nodeName;
|
||||
|
||||
if ( $child->nodeName == '#text' OR $child->nodeName == '#cdata-section' )
|
||||
{
|
||||
$_name = '#alltext';
|
||||
}
|
||||
|
||||
if ( $occurance[ $child->nodeName ] > 1 )
|
||||
{
|
||||
$_xmlArray[ $_name ][] = $this->_fetchXMLAsArray( $child, $ignoreDOMTags );
|
||||
}
|
||||
else
|
||||
{
|
||||
$_xmlArray[ $_name ] = $this->_fetchXMLAsArray( $child, $ignoreDOMTags );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_xmlArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode CDATA XML attribute (Make safe for transport)
|
||||
*
|
||||
* @access private
|
||||
* @param string Raw data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
private function _xmlConvertSafecdata( $v )
|
||||
{
|
||||
$v = str_replace( "<![CDATA[", "<!#^#|CDATA|", $v );
|
||||
$v = str_replace( "]]>" , "|#^#]>" , $v );
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode CDATA XML attribute (Make safe for transport)
|
||||
*
|
||||
* @access private
|
||||
* @param string Raw data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
private function _xmlUnconvertSafecdata( $v )
|
||||
{
|
||||
$v = str_replace( "<!#^#|CDATA|", "<![CDATA[", $v );
|
||||
$v = str_replace( "|#^#]>" , "]]>" , $v );
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a tag object
|
||||
*
|
||||
* @access private
|
||||
* @param string Name of tag
|
||||
* @return object
|
||||
*/
|
||||
private function _node( $tag )
|
||||
{
|
||||
if ( isset($this->_domObjects[ $tag ]) )
|
||||
{
|
||||
return $this->_domObjects[ $tag ];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->_dom;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from native to UTF-8 for saving XML
|
||||
*
|
||||
* @access private
|
||||
* @param string Input Text
|
||||
* @return string Converted Text ready for XML saving
|
||||
*/
|
||||
private function _inputToXml( $text )
|
||||
{
|
||||
/* Do we need to make safe on CDATA? */
|
||||
if ( preg_match( "/['\"\[\]<>&]/", $text ) )
|
||||
{
|
||||
$text = $this->_xmlConvertSafecdata( $text );
|
||||
}
|
||||
|
||||
/* Using UTF-8 */
|
||||
if ( $this->_docCharSet == 'utf-8' )
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
/* Are we using the most common ISO-8559-1... */
|
||||
else if ( $this->_docCharSet == 'iso-8859-1' )
|
||||
{
|
||||
return utf8_encode( $text );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->_convertCharsets( $text, $this->_docCharSet, 'utf-8' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from UTF-8 to native for saving XML
|
||||
*
|
||||
* @access private
|
||||
* @param string Input Text
|
||||
* @return string Converted Text ready for returning to app
|
||||
*/
|
||||
private function _xmlToOutput( $text )
|
||||
{
|
||||
/* Unconvert cdata */
|
||||
$text = $this->_xmlUnconvertSafecdata( $text );
|
||||
|
||||
/* Using UTF-8 */
|
||||
if ( $this->_docCharSet == 'utf-8' )
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
/* Are we using the most common ISO-8559-1... */
|
||||
else if ( $this->_docCharSet == 'iso-8859-1' )
|
||||
{
|
||||
return utf8_decode( $text );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->_convertCharsets( $text, 'utf-8', $this->_docCharSet );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string between charsets. XML will always be UTF-8
|
||||
*
|
||||
* @access private
|
||||
* @param string Input String
|
||||
* @param string Current char set
|
||||
* @param string Destination char set
|
||||
* @return string Parsed string
|
||||
* @todo [Future] If an error is set in classConvertCharset, show it or log it somehow
|
||||
*/
|
||||
private function _convertCharsets( $text, $original_cset, $destination_cset="UTF-8" )
|
||||
{
|
||||
$original_cset = strtolower($original_cset);
|
||||
$destination_cset = strtolower( $destination_cset );
|
||||
$t = $text;
|
||||
|
||||
//-----------------------------------------
|
||||
// Not the same?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $destination_cset == $original_cset )
|
||||
{
|
||||
return $t;
|
||||
}
|
||||
|
||||
if ( ! is_object( self::$classConvertCharset ) )
|
||||
{
|
||||
require_once( dirname(__FILE__) . '/classConvertCharset.php' );
|
||||
self::$classConvertCharset = new classConvertCharset();
|
||||
|
||||
//-----------------------------------------
|
||||
// Ok, mb functions only support limited number
|
||||
// of charsets, so if mb functions are enabled
|
||||
// but using e.g. windows-1250, no conversion
|
||||
// ends up happening. Let's force internal.
|
||||
//-----------------------------------------
|
||||
|
||||
//if ( function_exists( 'mb_convert_encoding' ) )
|
||||
//{
|
||||
// self::$classConvertCharset->method = 'mb';
|
||||
//}
|
||||
//else if ( function_exists( 'iconv' ) )
|
||||
//{
|
||||
// self::$classConvertCharset->method = 'iconv';
|
||||
//}
|
||||
//else if ( function_exists( 'recode_string' ) )
|
||||
//{
|
||||
// self::$classConvertCharset->method = 'recode';
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
self::$classConvertCharset->method = 'internal';
|
||||
//}
|
||||
}
|
||||
|
||||
$text = self::$classConvertCharset->convertEncoding( $text, $original_cset, $destination_cset );
|
||||
|
||||
return $text ? $text : $t;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,736 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* XML Archive Hanlder: Can create XML Archives (gzips) of multiple files, binary and ascii
|
||||
* Last Updated: $Date: 2009-06-09 11:51:16 -0400 (Tue, 09 Jun 2009) $
|
||||
*
|
||||
* @author $Author: matt $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since 25th February 2004
|
||||
* @version $Revision: 280 $
|
||||
*
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
* Sample file set:
|
||||
*
|
||||
* someDir/
|
||||
* someDir/index.html
|
||||
* someDir/file.html
|
||||
* someDir/images/
|
||||
* someDir/images/pic.jpg
|
||||
* anotherDir/
|
||||
* anotherDir/anotherFile.html
|
||||
*
|
||||
* # READING ARCHIVE
|
||||
* $archive = new classXMLArchive();
|
||||
* try
|
||||
* {
|
||||
* $archive->read( "/path/to/archive.xml" );
|
||||
* }
|
||||
* catch ( Exception $err ) {}
|
||||
*
|
||||
* print $archive->getFile('someDir/file.html');
|
||||
* print_r( $archive->asArray() );
|
||||
*
|
||||
* # CREATING ARCHIVE
|
||||
*
|
||||
* $archive = new classXMLArchive();
|
||||
*
|
||||
* try
|
||||
* {
|
||||
* $archive->add( "someDir" );
|
||||
* $archive->add( "anotherDir/anotherFile.html" );
|
||||
* $archive->add( "Create a new file from scratch!", "anotherDir/brandNewFile.html" );
|
||||
* }
|
||||
* catch ( Exception $err ) {}
|
||||
*
|
||||
* # Save gzipped
|
||||
* $archive->saveGZIP( "/path/to/archive.xml.gzip" );
|
||||
* # Save normally
|
||||
* $archive->save( "/path/to/archive.xml" );
|
||||
* # Just return the data
|
||||
* $archive->getArchiveContents();
|
||||
* </code>
|
||||
*
|
||||
*
|
||||
* Exception Codes:
|
||||
* <ul>
|
||||
* <li>FILE_OR_DIR_NOT_EXISTS: No such directory or file
|
||||
* <li>NOT_A_DIR: Not a directory
|
||||
* <li>CANNOT_WRITE_TO_DISK: Could not write archive to disk
|
||||
* <li>NOTHING_TO_SAVE: No XML document to save
|
||||
* <li>COULD_NOT_LOAD_XML_DATA: Could not load xml data
|
||||
* <li>WRITE_NOT_VALID_INPUT: The input (XML or filename) is not valid
|
||||
* <li>NO_FILES_TO_WRITE: The archive contains nothing to write back
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
|
||||
class classXMLArchive
|
||||
{
|
||||
/**
|
||||
* XML Object
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
private $_xml = null;
|
||||
|
||||
/**
|
||||
* File array
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
public $_fileArray = array();
|
||||
|
||||
/**
|
||||
* Error number
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $error_number = 0;
|
||||
|
||||
/**
|
||||
* Error message
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $error_message = "";
|
||||
|
||||
/**
|
||||
* Work files
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
public $_workFiles = array();
|
||||
|
||||
/**
|
||||
* Non binary file extensions
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $non_binary = 'txt htm html xml css js cgi php php3';
|
||||
|
||||
/**
|
||||
* Strip path
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $_stripPathString = "";
|
||||
|
||||
/**
|
||||
* Allow hidden files
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $_allowHiddenFiles = FALSE;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string Script root path
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//-----------------------------------
|
||||
// Get the XML class
|
||||
//-----------------------------------
|
||||
|
||||
require_once( dirname( __FILE__ ) . '/classXML.php' );
|
||||
$this->_xml = new classXML( IPS_DOC_CHAR_SET );
|
||||
|
||||
$this->error_number = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow hidden files to be added when using addDir
|
||||
*
|
||||
* @access public
|
||||
* @return null
|
||||
*/
|
||||
public function allowHiddenFiles()
|
||||
{
|
||||
$this->_allowHiddenFiles = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to 'strip' from the path data
|
||||
*
|
||||
* @access public
|
||||
* @param string Full path to remove
|
||||
*/
|
||||
public function setStripPath( $path )
|
||||
{
|
||||
/* Ensure that there is no trailing slash */
|
||||
$path = rtrim( $path, '/' );
|
||||
|
||||
$this->_stripPathString = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return data as array
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function asArray()
|
||||
{
|
||||
return $this->_fileArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a file from the fileArray
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getFile( $key )
|
||||
{
|
||||
if ( isset( $this->_fileArray[ $key ] ) )
|
||||
{
|
||||
return $this->_fileArray[ $key ]['content'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of files contained in the expanded archive
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function countFileArray()
|
||||
{
|
||||
return intval( count( $this->_fileArray ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an XML document from disk
|
||||
*
|
||||
* @access public
|
||||
* @param string File name
|
||||
* @return void
|
||||
*/
|
||||
public function read( $filename )
|
||||
{
|
||||
if ( file_exists( $filename ) )
|
||||
{
|
||||
if ( strstr( $filename, '.gz' ) )
|
||||
{
|
||||
if ( $FH = @gzopen( $filename, 'r' ) )
|
||||
{
|
||||
$data = @gzread( $FH, $filename );
|
||||
@gzclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "COULD_NOT_LOAD_XML_DATA" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $FH = @fopen( $filename, 'r' ) )
|
||||
{
|
||||
$data = @fread( $FH, filesize( $filename ) );
|
||||
@fclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "COULD_NOT_LOAD_XML_DATA" );
|
||||
}
|
||||
}
|
||||
|
||||
$this->readXML( $data );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "FILE_OR_DIR_NOT_EXISTS" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an XML document from passed data
|
||||
*
|
||||
* @access public
|
||||
* @param string Raw XML Data
|
||||
* @return void
|
||||
*/
|
||||
public function readXML( $data )
|
||||
{
|
||||
if ( $data )
|
||||
{
|
||||
$this->_xml->loadXML( $data );
|
||||
|
||||
foreach( $this->_xml->fetchElements('file') as $file )
|
||||
{
|
||||
$_file = $this->_xml->fetchElementsFromRecord( $file );
|
||||
$_file['content'] = base64_decode( preg_replace( "/\s/", "", $_file['content'] ) );
|
||||
|
||||
$this->_fileArray[ ltrim( $_file['path'] . '/' . $_file['filename'], '/' ) ] = $_file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the XML document as a GZIP file
|
||||
*
|
||||
* @access public
|
||||
* @param string Filename
|
||||
* @return void
|
||||
*/
|
||||
public function saveGZIP( $filename )
|
||||
{
|
||||
$this->_create();
|
||||
|
||||
if ( $this->_xml->fetchDocument() )
|
||||
{
|
||||
if ( $FH = @gzopen( $filename, 'wb' ) )
|
||||
{
|
||||
@gzwrite( $FH, $this->_xml->fetchDocument() );
|
||||
@gzclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "CANNOT_WRITE_TO_DISK" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "NOTHING_TO_SAVE" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the XML document as a normal file
|
||||
*
|
||||
* @access public
|
||||
* @param string FIlename
|
||||
* @return void
|
||||
*/
|
||||
public function save( $filename )
|
||||
{
|
||||
$this->_create();
|
||||
|
||||
$_doc = $this->_xml->fetchDocument();
|
||||
|
||||
if ( $_doc )
|
||||
{
|
||||
if ( $FH = @fopen( $filename, 'wb' ) )
|
||||
{
|
||||
@fwrite( $FH, $_doc );
|
||||
@fclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "CANNOT_WRITE_TO_DISK" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "NOTHING_TO_SAVE" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method of getting XML document from this class
|
||||
*
|
||||
* @access public
|
||||
* @return string XML document
|
||||
*/
|
||||
public function getArchiveContents()
|
||||
{
|
||||
$this->_create();
|
||||
return $this->_xml->fetchDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the archive back to disk
|
||||
*
|
||||
* Note: Ensure that if you intend to make XMLArchives available for others
|
||||
* that you create it with setStripPath otherwise you may get unexpected results!
|
||||
*
|
||||
* @access public
|
||||
* @param mixed Filename (must end with .xml or .gz) or raw data
|
||||
* @param string Base path to write to
|
||||
* @return boolean Or exceptions
|
||||
*
|
||||
* Exception Codes:
|
||||
* WRITE_NOT_VALID_INPUT The input (XML or filename) is not valid
|
||||
* NO_FILES_TO_WRITE The archive contains nothing to write back
|
||||
*/
|
||||
public function write( $input, $basePath='/' )
|
||||
{
|
||||
/* Gather the data */
|
||||
if ( substr( $input, -3 ) == '.gz' OR substr( $input, -3 ) == '.xml' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->read( $input );
|
||||
}
|
||||
catch( Exception $e )
|
||||
{
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
else if ( strstr( $input, '<xmlarchive' ) )
|
||||
{
|
||||
$this->readXML( $input );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "WRITE_NOT_VALID_INPUT" );
|
||||
}
|
||||
|
||||
/* Did we get anything? */
|
||||
if ( ! $this->countFileArray() )
|
||||
{
|
||||
throw new Exception( "NO_FILES_TO_WRITE" );
|
||||
}
|
||||
|
||||
$basePath = rtrim( $basePath, '/' );
|
||||
|
||||
/* So, write 'em! */
|
||||
$files = $this->asArray();
|
||||
|
||||
foreach( $files as $path => $data )
|
||||
{
|
||||
$path = trim( $path, '/' );
|
||||
|
||||
if ( $this->_writeContents( $basePath . '/' . $path, $data['content'] ) !== TRUE )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Done */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main "Add" function handles a lot of stuff.
|
||||
* It's good like that!
|
||||
*
|
||||
* @access public
|
||||
* @param string Filename or data
|
||||
* @param string FIle to store as
|
||||
* @return mixed
|
||||
*/
|
||||
public function add( $data, $saveName='' )
|
||||
{
|
||||
/* Is this just data? */
|
||||
if ( $saveName )
|
||||
{
|
||||
return $this->addData( $data, $saveName );
|
||||
}
|
||||
else if ( is_dir( $data ) )
|
||||
{
|
||||
return $this->addDirectory( $data );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->addFile( $data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand function
|
||||
*
|
||||
* @access public
|
||||
* @return mixed addDirectory
|
||||
*/
|
||||
public function addDir( $dir )
|
||||
{
|
||||
return $this->addDirectory( $dir );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add directory to archive
|
||||
*
|
||||
* @access public
|
||||
* @param string Directory to add
|
||||
* @return mixed Boolean on error, void
|
||||
*/
|
||||
public function addDirectory( $dir )
|
||||
{
|
||||
//-----------------------------------
|
||||
// Got dir?
|
||||
//-----------------------------------
|
||||
|
||||
if ( ! is_dir($dir) )
|
||||
{
|
||||
throw new Exception( "FILE_OR_DIR_NOT_EXISTS" );
|
||||
return false;
|
||||
}
|
||||
|
||||
$dir = rtrim( $dir, '/' );
|
||||
|
||||
//-----------------------------------
|
||||
// Populate this->workfiles
|
||||
//-----------------------------------
|
||||
|
||||
$this->_workFiles = array();
|
||||
$this->_getDirContents( $dir );
|
||||
|
||||
//-----------------------------------
|
||||
// Add them into the file array
|
||||
//-----------------------------------
|
||||
|
||||
foreach ( $this->_workFiles as $f )
|
||||
{
|
||||
$this->addFile( $f );
|
||||
}
|
||||
|
||||
$this->_workFiles = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add file to archive
|
||||
*
|
||||
* @access public
|
||||
* @param string File to add
|
||||
* @param array Extra tags
|
||||
* @return mixed Boolean on error, void
|
||||
*/
|
||||
public function addFile( $filename, $extra_tags=array() )
|
||||
{
|
||||
//-----------------------------------
|
||||
// Kill hidden files
|
||||
//-----------------------------------
|
||||
|
||||
$_temp = explode( '/', $filename );
|
||||
|
||||
$actual_file = array_pop( $_temp );
|
||||
|
||||
if ( in_array( strtolower($actual_file), array( '.ds_store', 'thumbs.db' ) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( file_exists( $filename ) )
|
||||
{
|
||||
if ( $FH = @fopen( $filename, 'rb' ) )
|
||||
{
|
||||
$data = @fread( $FH, filesize( $filename ) );
|
||||
@fclose( $FH );
|
||||
}
|
||||
|
||||
$this->addData( $data, $filename, $extra_tags );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "FILE_OR_DIR_NOT_EXISTS" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add filecontents to archive
|
||||
*
|
||||
* @access public
|
||||
* @param string File data
|
||||
* @param string File name
|
||||
* @param array Extra tags
|
||||
* @return void
|
||||
*/
|
||||
public function addData( $data, $filename, $extra_tags=array() )
|
||||
{
|
||||
$ext = preg_replace( "/.*\.(.+?)$/", "\\1", $filename );
|
||||
|
||||
$binary = 1;
|
||||
|
||||
//-----------------------------------
|
||||
// ASCII?
|
||||
//-----------------------------------
|
||||
|
||||
if ( strstr( ' ' . $this->non_binary . ' ', ' '.$ext.' ' ) )
|
||||
{
|
||||
$binary = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// Get dir / filename
|
||||
//-----------------------------------
|
||||
|
||||
$dir_path = array();
|
||||
$dir_path = explode( "/", $filename );
|
||||
|
||||
if ( count( $dir_path ) )
|
||||
{
|
||||
$real_filename = array_pop( $dir_path );
|
||||
}
|
||||
|
||||
$real_filename = $real_filename ? $real_filename : $filename;
|
||||
|
||||
$path = implode( "/", $dir_path );
|
||||
|
||||
$path = $this->_stripPath( $path );
|
||||
|
||||
$this_array = array(
|
||||
'filename' => $real_filename,
|
||||
'content' => $data,
|
||||
'path' => $path,
|
||||
'binary' => $binary
|
||||
);
|
||||
|
||||
foreach( $extra_tags as $k => $v )
|
||||
{
|
||||
if ( $k and ! in_array( $k, array_keys($this_array) ) )
|
||||
{
|
||||
$this_array[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_fileArray[] = $this_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the XML archive
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function _create()
|
||||
{
|
||||
$this->_xml->newXMLDocument();
|
||||
$this->_xml->addElement( 'xmlarchive', '', array( 'generator' => 'IPS_KERNEL', 'created' => time() ) );
|
||||
$this->_xml->addElement( 'fileset', 'xmlarchive' );
|
||||
|
||||
foreach( $this->_fileArray as $f )
|
||||
{
|
||||
$f['content'] = chunk_split(base64_encode($f['content']));
|
||||
|
||||
$this->_xml->addElementAsRecord( 'fileset', 'file', $f );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write contents of a file to disk
|
||||
* Creates directories, etc as it goes
|
||||
*
|
||||
* @access private
|
||||
* @param string Path with filename to write to
|
||||
* @param string Data to write
|
||||
* @return boolean
|
||||
*/
|
||||
private function _writeContents( $path, $content )
|
||||
{
|
||||
$path = $this->_stripPath( $path );
|
||||
$_path = DOC_IPS_ROOT_PATH;
|
||||
$_dirParts = explode( '/', str_replace( DOC_IPS_ROOT_PATH, '', $path ) );
|
||||
$file = array_pop( $_dirParts );
|
||||
|
||||
foreach( $_dirParts as $_p )
|
||||
{
|
||||
$_path .= '/' . $_p;
|
||||
|
||||
if ( ! is_dir( $_path ) )
|
||||
{
|
||||
if ( ! @mkdir( $_path, 0777 ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@chmod( $_path, 0777 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! @file_put_contents( $_path . '/' . $file, $content ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@chmod( $_path . '/' . $file, 0777 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip path information from the real path
|
||||
*
|
||||
* @access private
|
||||
* @param string Input path
|
||||
* @return string Converted path
|
||||
*/
|
||||
private function _stripPath( $path )
|
||||
{
|
||||
if ( $this->_stripPathString )
|
||||
{
|
||||
$path = trim( str_ireplace( $this->_stripPathString, '', $path ), '/' );
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get directory contents
|
||||
*
|
||||
* @access private
|
||||
* @param string Directory
|
||||
* @return boolean Successful
|
||||
*/
|
||||
private function _getDirContents( $dir )
|
||||
{
|
||||
if ( file_exists( $dir ) AND is_dir( $dir ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach( new DirectoryIterator( $dir ) as $file )
|
||||
{
|
||||
if ( ! $file->isDot() )
|
||||
{
|
||||
$filename = $file->getFileName();
|
||||
|
||||
/* Allow files? */
|
||||
if ( $this->_allowHiddenFiles !== TRUE )
|
||||
{
|
||||
if ( substr( $filename, 0, 1 ) == '.' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_dir( $dir."/".$filename ) )
|
||||
{
|
||||
$this->_getDirContents( $dir . "/" . $filename );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_workFiles[] = $dir . "/" . $filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch ( Exception $e ) {}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "FILE_OR_DIR_NOT_EXISTS" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,367 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
| Licence Info: http://www.invisionboard.com/?license
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2006-08-01 17:02:55 +0100 (Tue, 01 Aug 2006) $
|
||||
| > $Revision: 425 $
|
||||
| > $Author: matt $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > AJAX Functions
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: Wednesday 2nd August 2006
|
||||
|
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
class class_ajax
|
||||
{
|
||||
/**
|
||||
* Global IPS class
|
||||
*/
|
||||
var $ipsclass;
|
||||
|
||||
/**
|
||||
* XML output
|
||||
*/
|
||||
var $xml_output;
|
||||
|
||||
/**
|
||||
* XML Header
|
||||
*/
|
||||
var $xml_header;
|
||||
|
||||
/**
|
||||
* Character sets
|
||||
*/
|
||||
var $decode_charsets = array( 'iso-8859-1' => 'ISO-8859-1',
|
||||
'iso8859-1' => 'ISO-8859-1',
|
||||
'iso-8859-15' => 'ISO-8859-15',
|
||||
'iso8859-15' => 'ISO-8859-15',
|
||||
'utf-8' => 'UTF-8',
|
||||
'cp866' => 'cp866',
|
||||
'ibm866' => 'cp866',
|
||||
'cp1251' => 'windows-1251',
|
||||
'windows-1251' => 'windows-1251',
|
||||
'win-1251' => 'windows-1251',
|
||||
'cp1252' => 'windows-1252',
|
||||
'windows-1252' => 'windows-1252',
|
||||
'koi8-r' => 'KOI8-R',
|
||||
'koi8-ru' => 'KOI8-R',
|
||||
'koi8r' => 'KOI8-R',
|
||||
'big5' => 'BIG5',
|
||||
'gb2312' => 'GB2312',
|
||||
'big5-hkscs' => 'BIG5-HKSCS',
|
||||
'shift_jis' => 'Shift_JIS',
|
||||
'sjis' => 'Shift_JIS',
|
||||
'euc-jp' => 'EUC-JP',
|
||||
'eucjp' => 'EUC-JP' );
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Initialize the class
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* INIT the class
|
||||
*/
|
||||
function class_init()
|
||||
{
|
||||
$this->xml_header = "<?xml version=\"1.0\" encoding=\"{$this->ipsclass->vars['gb_char_set']}\"?".'>';
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Convert and make safe an incoming string
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Convert and make safe an incoming string
|
||||
*/
|
||||
function convert_and_make_safe( $value, $parse_incoming=1 )
|
||||
{
|
||||
$value = rawurldecode( $value );
|
||||
|
||||
$value = $this->convert_unicode( $value );
|
||||
|
||||
// This is apparently not needed with the convert_unicode changes I made
|
||||
|
||||
$value = $this->convert_html_entities( $value );
|
||||
|
||||
if( $parse_incoming OR ( strtolower($this->ipsclass->vars['gb_char_set']) != 'iso-8859-1' &&
|
||||
strtolower($this->ipsclass->vars['gb_char_set']) != 'utf-8' ) )
|
||||
{
|
||||
$value = $this->ipsclass->parse_clean_value( $value );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// make string XML safe
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Make a string safe for XML transport
|
||||
*/
|
||||
function _make_safe_for_xml( $t )
|
||||
{
|
||||
return str_replace( '&#39;', ''', htmlspecialchars( $t ) );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Error handler
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Print an error
|
||||
*/
|
||||
function error_handler()
|
||||
{
|
||||
@header( "Content-type: text/xml" );
|
||||
$this->print_nocache_headers();
|
||||
$this->xml_output = $this->xml_header."\r\n<errors>\r\n";
|
||||
$this->xml_output .= "<error><message>You must be logged in to access this feature</message></error>\r\n";
|
||||
$this->xml_output .= "</errors>";
|
||||
print $this->xml_output;
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return NOTHING :o
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Return a NULL result
|
||||
*/
|
||||
function return_null($val=0)
|
||||
{
|
||||
@header( "Content-type: text/xml" );
|
||||
$this->print_nocache_headers();
|
||||
print $this->xml_header."\r\n<null>{$val}</null>";
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return string
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Return a string
|
||||
*/
|
||||
function return_string($string)
|
||||
{
|
||||
@header( "Content-type: text/plain;charset={$this->ipsclass->vars['gb_char_set']}" );
|
||||
$this->print_nocache_headers();
|
||||
print $string;
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return HTML
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Return a HTML
|
||||
*/
|
||||
function return_html($string)
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Stop one from removing cookie protection
|
||||
//-----------------------------------------
|
||||
|
||||
$string = ( $string ) ? $string : '<!--nothing-->';
|
||||
$string = preg_replace( "#htmldocument\.prototype#is", "HTMLDocument_prototype", $string );
|
||||
|
||||
// Fix IE bugs
|
||||
$string = str_replace( "§", "&sect", $string );
|
||||
|
||||
if ( strtolower( $this->ipsclass->vars['gb_char_set'] ) == 'iso-8859-1' )
|
||||
{
|
||||
$string = str_replace( "ì", "“", $string );
|
||||
$string = str_replace( "î", "”", $string );
|
||||
}
|
||||
|
||||
// Other stuff
|
||||
$string = str_replace( "<#IMG_DIR#>", $this->ipsclass->skin['_imagedir'], $string );
|
||||
$string = str_replace( "<#EMO_DIR#>", $this->ipsclass->skin['_emodir'] , $string );
|
||||
|
||||
@header( "Content-type: text/html;charset=".$this->ipsclass->vars['gb_char_set'] );
|
||||
$this->print_nocache_headers();
|
||||
print $string;
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Print no cache headers
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Print nocache headers
|
||||
*/
|
||||
function print_nocache_headers()
|
||||
{
|
||||
header("HTTP/1.0 200 OK");
|
||||
header("HTTP/1.1 200 OK");
|
||||
header("Cache-Control: no-cache, must-revalidate, max-age=0");
|
||||
header("Expires: 0");
|
||||
header("Pragma: no-cache");
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Convert decimal character references to UTF-8
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Convert a decimal character to UTF-8
|
||||
*/
|
||||
function dec_char_ref_to_utf8($int=0)
|
||||
{
|
||||
$return = '';
|
||||
|
||||
if ( $int < 0 )
|
||||
{
|
||||
return chr(0);
|
||||
}
|
||||
else if ( $int <= 0x007f )
|
||||
{
|
||||
$return .= chr($int);
|
||||
}
|
||||
else if ( $int <= 0x07ff )
|
||||
{
|
||||
$return .= chr(0xc0 | ($int >> 6));
|
||||
$return .= chr(0x80 | ($int & 0x003f));
|
||||
}
|
||||
else if ( $int <= 0xffff )
|
||||
{
|
||||
$return .= chr(0xe0 | ($int >> 12));
|
||||
$return .= chr(0x80 | (($int >> 6) & 0x003f));
|
||||
$return .= chr(0x80 | ($int & 0x003f));
|
||||
}
|
||||
else if ( $int <= 0x10ffff )
|
||||
{
|
||||
$return .= chr(0xf0 | ($int >> 18));
|
||||
$return .= chr(0x80 | (($int >> 12) & 0x3f));
|
||||
$return .= chr(0x80 | (($int >> 6) & 0x3f));
|
||||
$return .= chr(0x80 | ($int & 0x3f));
|
||||
}
|
||||
else
|
||||
{
|
||||
return chr(0);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Helper function
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function dec_char_ref_to_utf8_hexdec( $matches )
|
||||
{
|
||||
return $this->dec_char_ref_to_utf8( hexdec( $matches[1] ) );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Convert Ajax unicode
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function convert_unicode($t)
|
||||
{
|
||||
if ( strtolower($this->ipsclass->vars['gb_char_set']) == 'utf-8' )
|
||||
{
|
||||
return preg_replace_callback( '#%u([0-9A-F]{1,4})#i', array( &$this, 'dec_char_ref_to_utf8_hexdec' ), utf8_encode($t) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return preg_replace_callback( '#%u([0-9A-F]{1,4})#i', create_function( '$matches', "return '&#' . hexdec(\$matches[1]) . ';';" ), $t );
|
||||
}
|
||||
|
||||
// Javascript escape function always sends unicode
|
||||
|
||||
$text = preg_replace_callback( '#%u([0-9A-F]{1,4})#i', array( &$this, 'dec_char_ref_to_utf8_hexdec' ), utf8_encode($t) );
|
||||
|
||||
if ( strtolower($this->ipsclass->vars['gb_char_set']) != 'utf-8' )
|
||||
{
|
||||
$text = $this->ipsclass->txt_convert_charsets( $text, 'UTF-8' );
|
||||
}
|
||||
|
||||
return $text ? $text : $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert HTML entities and respect character sets
|
||||
*/
|
||||
function convert_html_entities($t)
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Try and fix up HTML entities with missing ;
|
||||
//-----------------------------------------
|
||||
|
||||
$t = preg_replace( "/&#(\d+?)([^\d;])/i", "&#\\1;\\2", $t );
|
||||
|
||||
//-----------------------------------------
|
||||
// Continue...
|
||||
//-----------------------------------------
|
||||
|
||||
if ( strtolower($this->ipsclass->vars['gb_char_set']) != 'iso-8859-1' &&
|
||||
strtolower($this->ipsclass->vars['gb_char_set']) != 'utf-8' )
|
||||
{
|
||||
if ( array_key_exists( strtolower($this->ipsclass->vars['gb_char_set']), $this->decode_charsets ) )
|
||||
{
|
||||
$this->ipsclass->vars['gb_char_set'] = $this->decode_charsets[strtolower($this->ipsclass->vars['gb_char_set'])];
|
||||
|
||||
$t = html_entity_decode( $t, ENT_NOQUOTES, $this->ipsclass->vars['gb_char_set'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take a crack at entities in other character sets
|
||||
|
||||
$t = str_replace( "&#", "&#", $t );
|
||||
|
||||
// If mb functions available, we can knock out html entities for a few more char sets
|
||||
|
||||
if( function_exists('mb_list_encodings') )
|
||||
{
|
||||
// PHP 5, preferred method
|
||||
|
||||
$valid_encodings = array();
|
||||
$valid_encodings = mb_list_encodings();
|
||||
|
||||
if( count($valid_encodings) )
|
||||
{
|
||||
if( in_array( strtoupper($this->ipsclass->vars['gb_char_set']), $valid_encodings ) )
|
||||
{
|
||||
$t = mb_convert_encoding( $t, strtoupper($this->ipsclass->vars['gb_char_set']), 'HTML-ENTITIES' );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( function_exists('mb_convert_encoding') )
|
||||
{
|
||||
// PHP 4 support
|
||||
|
||||
// Though this is quite tedious, let's check to see if encoding is supported....
|
||||
// http://us2.php.net/manual/en/ref.mbstring.php
|
||||
|
||||
$valid_encodings = array( 'UCS-4', 'UCS-4BE', 'UCS-4LE', 'UCS-2', 'UCS-2BE', 'UCS-2LE', 'UTF-32', 'UTF-32BE',
|
||||
'UTF-32LE', 'UTF-16', 'UTF-16BE', 'UTF-16LE', 'UTF-7', 'UTF7-IMAP', 'UTF-8',
|
||||
'ASCII', 'EUC-JP', 'SJIS', 'EUCJP-WIN', 'SJIS-WIN', 'ISO-2022-JP', 'JIS', 'ISO-8859-1',
|
||||
'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7',
|
||||
'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15',
|
||||
'EUC-CN', 'CP936', 'EUC-TW', 'HZ', 'CP950', 'BIG-5', 'EUC-KR', 'CP949', 'ISO-2022-KR',
|
||||
'WINDOWS-1251', 'CP1251', 'WINDOWS-1252', 'CP1252', 'CP866', 'KOI8-R' );
|
||||
|
||||
if( in_array( strtoupper($this->ipsclass->vars['gb_char_set']), $valid_encodings ) )
|
||||
{
|
||||
$t = mb_convert_encoding( $t, strtoupper($this->ipsclass->vars['gb_char_set']), 'HTML-ENTITIES' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $t;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Cache Abstraction]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Core Module
|
||||
| > Module written by Brandon Farber
|
||||
| > Date started: Friday 19th May 2006 17:33
|
||||
|
|
||||
| > Module Version Number: 1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Cache Object Core
|
||||
* -- APC Cache Storage
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $db->do_put( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $db->do_remove( 'key' );
|
||||
* Retrieve
|
||||
* $db->do_get( 'key' );
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage Cache Abstraction
|
||||
* @author Brandon Mecham
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class cache_lib
|
||||
{
|
||||
var $identifier;
|
||||
var $crashed = 0;
|
||||
|
||||
|
||||
function cache_lib( $identifier='' )
|
||||
{
|
||||
if( !function_exists('apc_fetch') )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !$identifier )
|
||||
{
|
||||
$this->identifier = md5( uniqid( rand(), TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
unset( $identifier );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function do_put( $key, $value, $ttl=0 )
|
||||
{
|
||||
$ttl = $ttl > 0 ? intval($ttl) : 0;
|
||||
|
||||
apc_store( md5( $this->identifier . $key ),
|
||||
$value,
|
||||
$ttl );
|
||||
}
|
||||
|
||||
function do_get( $key )
|
||||
{
|
||||
$return_val = "";
|
||||
|
||||
$return_val = apc_fetch( md5( $this->identifier . $key ) );
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function do_remove( $key )
|
||||
{
|
||||
apc_delete( md5( $this->identifier . $key ) );
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,150 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Cache Abstraction]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Core Module
|
||||
| > Module written by Brandon Farber
|
||||
| > Date started: Friday 19th May 2006 17:33
|
||||
|
|
||||
| > Module Version Number: 1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Cache Object Core
|
||||
* -- Hard-disk Cache Storage
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $db->do_put( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $db->do_remove( 'key' );
|
||||
* Retrieve
|
||||
* $db->do_get( 'key' );
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage Cache Abstraction
|
||||
* @author Brandon Mecham
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class cache_lib
|
||||
{
|
||||
var $identifier;
|
||||
var $crashed = 0;
|
||||
|
||||
|
||||
function cache_lib( $identifier='' )
|
||||
{
|
||||
if( !is_writeable( ROOT_PATH.'cache' ) )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !$identifier )
|
||||
{
|
||||
$this->identifier = md5( uniqid( rand(), TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
unset( $identifier );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function do_put( $key, $value, $ttl=0 )
|
||||
{
|
||||
// We ignore TTL
|
||||
|
||||
$fh = fopen( ROOT_PATH.'cache/'.md5( $this->identifier . $key ).'.php', 'wb' );
|
||||
|
||||
if( !$fh )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$extra_flag = "";
|
||||
|
||||
if( is_array( $value ) )
|
||||
{
|
||||
$value = serialize($value);
|
||||
$extra_flag = "\n".'$is_array = 1;'."\n\n";
|
||||
}
|
||||
|
||||
$extra_flag .= "\n".'$ttl = '.$ttl.";\n\n";
|
||||
|
||||
$value = '"'.addslashes( $value ).'"';
|
||||
|
||||
$file_content = "<?"."php\n\n".'$value = '.$value.";\n".$extra_flag."\n?".'>';
|
||||
|
||||
flock( $fh, LOCK_EX );
|
||||
fwrite( $fh, $file_content );
|
||||
flock( $fh, LOCK_UN );
|
||||
fclose( $fh );
|
||||
|
||||
@chmod( ROOT_PATH.'cache/'.md5( $this->identifier . $key ).'.php', 0777 );
|
||||
}
|
||||
|
||||
function do_get( $key )
|
||||
{
|
||||
$return_val = "";
|
||||
|
||||
if( file_exists( ROOT_PATH.'cache/'.md5( $this->identifier . $key ).'.php' ) )
|
||||
{
|
||||
require ROOT_PATH.'cache/'.md5( $this->identifier . $key ).'.php';
|
||||
|
||||
$return_val = stripslashes($value);
|
||||
|
||||
if( isset($is_array) AND $is_array == 1 )
|
||||
{
|
||||
$return_val = unserialize($return_val);
|
||||
}
|
||||
|
||||
if( isset($ttl) AND $ttl > 0 )
|
||||
{
|
||||
if( $mtime = filemtime( ROOT_PATH.'cache/'.md5( $this->identifier . $key ).'.php' ) )
|
||||
{
|
||||
if( time() - $mtime > $ttl )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function do_remove( $key )
|
||||
{
|
||||
if( file_exists( ROOT_PATH.'cache/'.md5( $this->identifier . $key ).'.php' ) )
|
||||
{
|
||||
@unlink( ROOT_PATH.'cache/'.md5( $this->identifier . $key ).'.php' );
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,107 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Cache Abstraction]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Core Module
|
||||
| > Module written by Brandon Farber
|
||||
| > Date started: Friday 19th May 2006 17:33
|
||||
|
|
||||
| > Module Version Number: 1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Cache Object Core
|
||||
* -- Eaccelerator Cache Storage
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $db->do_put( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $db->do_remove( 'key' );
|
||||
* Retrieve
|
||||
* $db->do_get( 'key' );
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage Cache Abstraction
|
||||
* @author Brandon Mecham
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class cache_lib
|
||||
{
|
||||
var $identifier;
|
||||
var $crashed = 0;
|
||||
|
||||
|
||||
function cache_lib( $identifier='' )
|
||||
{
|
||||
if( !function_exists('eaccelerator_get') )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !$identifier )
|
||||
{
|
||||
$this->identifier = md5( uniqid( rand(), TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
unset( $identifier );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
if( function_exists( 'eaccelerator_gc' ) )
|
||||
{
|
||||
eaccelerator_gc();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function do_put( $key, $value, $ttl=0 )
|
||||
{
|
||||
eaccelerator_lock( md5( $this->identifier . $key ) );
|
||||
|
||||
eaccelerator_put( md5( $this->identifier . $key ),
|
||||
$value,
|
||||
intval($ttl) );
|
||||
|
||||
eaccelerator_unlock( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
function do_get( $key )
|
||||
{
|
||||
$return_val = eaccelerator_get( md5( $this->identifier . $key ) );
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function do_remove( $key )
|
||||
{
|
||||
eaccelerator_rm( md5( $this->identifier . $key ) );
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,146 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Cache Abstraction]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Core Module
|
||||
| > Module written by Brandon Farber
|
||||
| > Date started: Friday 19th May 2006 17:33
|
||||
|
|
||||
| > Module Version Number: 1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Cache Object Core
|
||||
* -- Memcache Cache Storage
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $db->do_put( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $db->do_remove( 'key' );
|
||||
* Retrieve
|
||||
* $db->do_get( 'key' );
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage Cache Abstraction
|
||||
* @author Brandon Mecham
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class cache_lib
|
||||
{
|
||||
var $identifier;
|
||||
var $crashed = 0;
|
||||
|
||||
var $link;
|
||||
|
||||
|
||||
function cache_lib( $identifier='' )
|
||||
{
|
||||
if( !function_exists('memcache_connect') )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !$identifier )
|
||||
{
|
||||
$this->identifier = md5( uniqid( rand(), TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
unset( $identifier );
|
||||
}
|
||||
|
||||
|
||||
function connect( $server_info=array() )
|
||||
{
|
||||
if( !count($server_info) )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !isset($server_info['memcache_server_1']) OR !isset($server_info['memcache_port_1']) )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->link = memcache_connect( $server_info['memcache_server_1'], $server_info['memcache_port_1'] );
|
||||
|
||||
if( !$this->link )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( isset($server_info['memcache_server_2']) AND isset($server_info['memcache_port_2']) )
|
||||
{
|
||||
memcache_add_server( $this->link, $server_info['memcache_server_2'], $server_info['memcache_port_2'] );
|
||||
}
|
||||
|
||||
if( isset($server_info['memcache_server_3']) AND isset($server_info['memcache_port_3']) )
|
||||
{
|
||||
memcache_add_server( $this->link, $server_info['memcache_server_3'], $server_info['memcache_port_3'] );
|
||||
}
|
||||
|
||||
if( function_exists('memcache_set_compress_threshold') )
|
||||
{
|
||||
memcache_set_compress_threshold( $this->link, 20000, 0.2 );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
if( $this->link )
|
||||
{
|
||||
memcache_close( $this->link );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function do_put( $key, $value, $ttl=0 )
|
||||
{
|
||||
memcache_set( $this->link, md5( $this->identifier . $key ),
|
||||
$value,
|
||||
MEMCACHE_COMPRESSED,
|
||||
intval($ttl) );
|
||||
}
|
||||
|
||||
function do_get( $key )
|
||||
{
|
||||
$return_val = memcache_get( $this->link, md5( $this->identifier . $key ) );
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function do_remove( $key )
|
||||
{
|
||||
memcache_delete( $this->link, md5( $this->identifier . $key ) );
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Cache Abstraction]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Core Module
|
||||
| > Module written by Brandon Farber
|
||||
| > Date started: Friday 19th May 2006 17:33
|
||||
|
|
||||
| > Module Version Number: 1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Cache Object Core
|
||||
* -- Turck-MMCache Cache Storage
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $db->do_put( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $db->do_remove( 'key' );
|
||||
* Retrieve
|
||||
* $db->do_get( 'key' );
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage Cache Abstraction
|
||||
* @author Brandon Mecham
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class cache_lib
|
||||
{
|
||||
var $identifier;
|
||||
var $crashed = 0;
|
||||
|
||||
|
||||
function cache_lib( $identifier='' )
|
||||
{
|
||||
if( !function_exists('mmcache_get') )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !$identifier )
|
||||
{
|
||||
$this->identifier = md5( uniqid( rand(), TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
unset( $identifier );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function do_put( $key, $value, $ttl=0 )
|
||||
{
|
||||
mmcache_lock( md5( $this->identifier . $key ) );
|
||||
|
||||
mmcache_put( md5( $this->identifier . $key ),
|
||||
$value,
|
||||
intval($ttl) );
|
||||
|
||||
mmcache_unlock( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
function do_get( $key )
|
||||
{
|
||||
$return_val = mmcache_get( md5( $this->identifier . $key ) );
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function do_remove( $key )
|
||||
{
|
||||
mmcache_rm( md5( $this->identifier . $key ) );
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Cache Abstraction]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Core Module
|
||||
| > Module written by Brandon Farber
|
||||
| > Date started: Friday 19th May 2006 17:33
|
||||
|
|
||||
| > Module Version Number: 1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Cache Object Core
|
||||
* -- XCache Cache Storage
|
||||
*
|
||||
* Basic Usage Examples
|
||||
* <code>
|
||||
* $cache = new cache_lib( 'identifier' );
|
||||
* Update:
|
||||
* $db->do_put( 'key', 'value' [, 'ttl'] );
|
||||
* Remove
|
||||
* $db->do_remove( 'key' );
|
||||
* Retrieve
|
||||
* $db->do_get( 'key' );
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage Cache Abstraction
|
||||
* @author Brandon Mecham
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class cache_lib
|
||||
{
|
||||
var $identifier;
|
||||
var $crashed = 0;
|
||||
|
||||
|
||||
function cache_lib( $identifier='' )
|
||||
{
|
||||
if( !function_exists('xcache_get') )
|
||||
{
|
||||
$this->crashed = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !$identifier )
|
||||
{
|
||||
$this->identifier = md5( uniqid( rand(), TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
}
|
||||
|
||||
unset( $identifier );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function do_put( $key, $value, $ttl=0 )
|
||||
{
|
||||
$ttl = $ttl > 0 ? intval($ttl) : '';
|
||||
|
||||
if( $ttl )
|
||||
{
|
||||
xcache_set( md5( $this->identifier . $key ),
|
||||
$value,
|
||||
$ttl );
|
||||
}
|
||||
else
|
||||
{
|
||||
xcache_set( md5( $this->identifier . $key ),
|
||||
$value );
|
||||
}
|
||||
}
|
||||
|
||||
function do_get( $key )
|
||||
{
|
||||
$return_val = "";
|
||||
|
||||
if( xcache_isset( md5( $this->identifier . $key ) ) )
|
||||
{
|
||||
$return_val = xcache_get( md5( $this->identifier . $key ) );
|
||||
}
|
||||
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function do_remove( $key )
|
||||
{
|
||||
xcache_unset( md5( $this->identifier . $key ) );
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,137 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power Dynamic v1.0.0
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2004 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
| INVISION POWER DYNAMIC IS NOT FREE SOFTWARE!
|
||||
| http://www.invisionpower.com/dynamic/
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Id$
|
||||
| > $Revision: 128 $
|
||||
| > $Date: 2006-01-20 12:46:26 +0000 (Fri, 20 Jan 2006) $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > CAPTCHA ANTI-SPAM CLASS
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Thursday 2 February (11:08)
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* CAPTCHA CLASS
|
||||
* ipsclass dependent method of showing an anti-spam image
|
||||
*
|
||||
* This creates a unique MD5 hash and stores it in the DB with
|
||||
* an 8 character string of 0-9a-z
|
||||
*
|
||||
* <code>
|
||||
* CREATE TABLE captcha (
|
||||
* captcha_unique_id VARCHAR(32) NOT NULL default '',
|
||||
* captcha_string VARCHAR(100) NOT NULL default '',
|
||||
* captcha_ipaddress VARCHAR(16) NOT NULL default '',
|
||||
* captcha_date INT(10) NOT NULL default '',
|
||||
* PRIMARY KEY (captcha_unique_id )
|
||||
* );
|
||||
* </code>
|
||||
* @package IPDYNAMIC
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class class_captcha
|
||||
{
|
||||
/**
|
||||
* Global IPS class array
|
||||
* @var object
|
||||
*/
|
||||
var $ipsclass;
|
||||
|
||||
/**
|
||||
* Captcha plug in class
|
||||
* @var string
|
||||
*/
|
||||
var $_plugInClass = '';
|
||||
|
||||
/**
|
||||
* Return an error if GD is not installed?
|
||||
* My most verbose string name. I'm so proud.
|
||||
* @var boolean
|
||||
*/
|
||||
var $show_error_gd_img = FALSE;
|
||||
|
||||
/**
|
||||
* Error string
|
||||
* @var string
|
||||
*/
|
||||
var $error_string = '';
|
||||
|
||||
/**
|
||||
* Constructor bah to PHP 4
|
||||
*
|
||||
* @param object IPSClass object
|
||||
* @param string Captcha plug-in to use
|
||||
*/
|
||||
function class_captcha( $ipsclass, $plugin )
|
||||
{
|
||||
$this->ipsclass =& $ipsclass;
|
||||
$plugin = $this->ipsclass->txt_alphanumerical_clean( $plugin );
|
||||
|
||||
if ( ! file_exists( KERNEL_PATH . 'class_captcha_plugin/' . $plugin . '.php' ) )
|
||||
{
|
||||
$plugin = 'default';
|
||||
}
|
||||
|
||||
require_once( KERNEL_PATH . 'class_captcha_plugin/' . $plugin . '.php' );
|
||||
$this->_plugInClass = new captchaPlugIn( $ipsclass );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Initializes captcha session and returns the template bit
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initializes captcha session
|
||||
* Clears out "dead" entries, adds new row and returns
|
||||
* template bit
|
||||
*
|
||||
* @return string HTML Template bit
|
||||
*/
|
||||
function getTemplate()
|
||||
{
|
||||
return $this->_plugInClass->getTemplate();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Captcha validate
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Show the captcha bot image
|
||||
*
|
||||
* @return boolean
|
||||
* @since 1.0
|
||||
*/
|
||||
function validate()
|
||||
{
|
||||
return $this->_plugInClass->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch Plug In Class Handle
|
||||
*
|
||||
* If you need it...
|
||||
*/
|
||||
function fetchPlugInClassHandle()
|
||||
{
|
||||
return $this->_plugInClass;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,375 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power KERNEL
|
||||
| Invision Power Board
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2006 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
| INVISION POWER BOARD IS NOT FREE SOFTWARE!
|
||||
| http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Communication Class: Allows data to be sent via HTTP:POST
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Friday 6th January 2006 (12:24)
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Communication
|
||||
*
|
||||
* Class to send data via HTTP:POST and return data
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Communication
|
||||
*
|
||||
* Wrapper for getting file contents
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_communication
|
||||
{
|
||||
/**
|
||||
* Use sockets flag
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $use_sockets = 0;
|
||||
|
||||
/**
|
||||
* Error array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $errors = array();
|
||||
|
||||
/**
|
||||
* Key prefix
|
||||
* Prefix to identify communication strings
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $key_prefix = '__xsx__';
|
||||
|
||||
/**#@+
|
||||
* Set Authentication
|
||||
*
|
||||
* @var strings
|
||||
*/
|
||||
var $auth_req = 0;
|
||||
var $auth_user;
|
||||
var $auth_pass;
|
||||
/**#@-*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Constructor
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_communication()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// RECEIVE DATA
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Receive data from the "send" function
|
||||
*
|
||||
* @param array Array of fields to return
|
||||
* @return array Array of fields
|
||||
*/
|
||||
function communication_receive_data( $return_fields=array() )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$return_array = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Get data...
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $_REQUEST as $k => $v )
|
||||
{
|
||||
if ( strstr( $k, $this->key_prefix ) )
|
||||
{
|
||||
$k = str_replace( $this->key_prefix, '', $k );
|
||||
|
||||
$return_array[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_filter_fields( $return_array );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SEND DATA
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Send the data
|
||||
*
|
||||
* @param string URI to post to
|
||||
* @param array Arry of post fields
|
||||
* @return string File data
|
||||
*/
|
||||
function communication_send_data( $file_location='', $post_array=array() )
|
||||
{
|
||||
if ( ! is_array( $post_array ) OR ! count( $post_array ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! $file_location )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $this->_post_data( $file_location, $post_array );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Filter off fields
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Filter out fields (optional)
|
||||
*
|
||||
* @access private
|
||||
* @param array Array of fields to return
|
||||
* @return array Array of fields
|
||||
*/
|
||||
function _filter_fields( $in_fields=array(), $out_fields=array() )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$return_array = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Check
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! is_array( $in_fields ) or ! count( $in_fields ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! is_array( $out_fields ) or ! count( $out_fields ) )
|
||||
{
|
||||
return $in_fields;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Get data...
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $out_fields as $k => $type )
|
||||
{
|
||||
if ( $in_fields[ $k ] )
|
||||
{
|
||||
switch ( $type )
|
||||
{
|
||||
default:
|
||||
case 'string':
|
||||
case 'text':
|
||||
$return_array[ $k ] = trim( $in_fields[ $k ] );
|
||||
break;
|
||||
case 'int':
|
||||
case 'integar':
|
||||
$return_array[ $k ] = intval( $in_fields[ $k ] );
|
||||
break;
|
||||
case 'float':
|
||||
case 'floatval':
|
||||
$return_array[ $k ] = floatval( $in_fields[ $k ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return_array;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SEND DATA
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Get file contents (with sockets)
|
||||
*
|
||||
* @access private
|
||||
* @param string URI to post to
|
||||
* @param array Arry of post fields
|
||||
* @return string File data
|
||||
*/
|
||||
function _post_data( $file_location, $post_array )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$data = null;
|
||||
$fsocket_timeout = 10;
|
||||
$post_back = array();
|
||||
|
||||
//-------------------------------
|
||||
// Fix up post string
|
||||
//-------------------------------
|
||||
|
||||
foreach ( $post_array as $key => $val )
|
||||
{
|
||||
$post_back[] = $this->key_prefix . $key . '=' . urlencode($val);
|
||||
}
|
||||
|
||||
$post_back_str = implode('&', $post_back);
|
||||
|
||||
//-------------------------------
|
||||
// Parse URL
|
||||
//-------------------------------
|
||||
|
||||
$url_parts = parse_url($file_location);
|
||||
|
||||
if ( ! $url_parts['host'] )
|
||||
{
|
||||
$this->errors[] = "No host found in the URL '$file_location'!";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Finalize
|
||||
//-------------------------------
|
||||
|
||||
$host = $url_parts['host'];
|
||||
$port = ( isset($url_parts['port']) ) ? $url_parts['port'] : 80;
|
||||
|
||||
//-------------------------------
|
||||
// Tidy up path
|
||||
//-------------------------------
|
||||
|
||||
if ( ! empty( $url_parts["path"] ) )
|
||||
{
|
||||
$path = $url_parts["path"];
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = "/";
|
||||
}
|
||||
|
||||
if ( ! empty( $url_parts["query"] ) )
|
||||
{
|
||||
$path .= "?" . $url_parts["query"];
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Try CURL first...
|
||||
//-------------------------------
|
||||
|
||||
if ( function_exists("curl_init") AND function_exists("curl_exec") )
|
||||
{
|
||||
if ( $sock = curl_init() )
|
||||
{
|
||||
curl_setopt( $sock, CURLOPT_URL , $file_location );
|
||||
curl_setopt( $sock, CURLOPT_TIMEOUT , 15 );
|
||||
curl_setopt( $sock, CURLOPT_POST , TRUE );
|
||||
curl_setopt( $sock, CURLOPT_POSTFIELDS , $post_back_str );
|
||||
curl_setopt( $sock, CURLOPT_POSTFIELDSIZE , 0);
|
||||
curl_setopt( $sock, CURLOPT_RETURNTRANSFER , TRUE );
|
||||
|
||||
$result = curl_exec($sock);
|
||||
|
||||
curl_close($sock);
|
||||
|
||||
return $result ? $result : FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ( ! $fp = @fsockopen( $host, $port, $errno, $errstr, $fsocket_timeout ) )
|
||||
{
|
||||
$this->errors[] = "CONNECTION REFUSED FROM $host";
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$final_carriage = "";
|
||||
|
||||
if ( ! $this->auth_req )
|
||||
{
|
||||
$final_carriage = "\r\n";
|
||||
}
|
||||
|
||||
$header = "POST $path HTTP/1.0\r\n";
|
||||
$header .= "Host: $host\r\n";
|
||||
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
$header .= "Content-Length: " . strlen($post_back_str) . "\r\n{$final_carriage}";
|
||||
|
||||
if ( ! fputs( $fp, $header . $post_back_str ) )
|
||||
{
|
||||
$this->errors[] = "Unable to send request to $host!";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( $this->auth_req )
|
||||
{
|
||||
if( $this->auth_user && $this->auth_pass )
|
||||
{
|
||||
$header = "Authorization: Basic ".base64_encode("{$this->auth_user}:{$this->auth_pass}")."\r\n\r\n";
|
||||
|
||||
if ( ! fputs( $fp, $header ) )
|
||||
{
|
||||
$this->errors[] = "Authorization Failed!";
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@stream_set_timeout($fp, $fsocket_timeout);
|
||||
|
||||
$status = @socket_get_status($fp);
|
||||
|
||||
while( ! feof($fp) && ! $status['timed_out'] )
|
||||
{
|
||||
$data .= fgets ($fp,8192);
|
||||
$status = socket_get_status($fp);
|
||||
}
|
||||
|
||||
fclose ($fp);
|
||||
|
||||
//-------------------------------
|
||||
// Strip headers
|
||||
//-------------------------------
|
||||
|
||||
$tmp = split("\r\n\r\n", $data, 2);
|
||||
$data = $tmp[1];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,321 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
| Licence Info: http://www.invisionboard.com/?license
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2005-10-10 14:03:20 +0100 (Mon, 10 Oct 2005) $
|
||||
| > $Revision: 22 $
|
||||
| > $Author: matt $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Converge methods (KERNEL)
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: 15th March 2004
|
||||
|
|
||||
| > Module Version Number: 1.0.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Converge
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
/**
|
||||
* Converge Class
|
||||
*
|
||||
* Methods and functions for handling converge authentication,
|
||||
* password generation and update methods
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_converge
|
||||
{
|
||||
/**
|
||||
* Current DB connection, passed by reference
|
||||
*
|
||||
* @var Database object
|
||||
* @todo Use ipsclass?
|
||||
*/
|
||||
var $current_db = "";
|
||||
|
||||
/**
|
||||
* Converge member array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $member = array();
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// CONSTRUCTOR
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Constructor, accepts database object
|
||||
*
|
||||
* @param object Database object
|
||||
*/
|
||||
|
||||
function class_converge(&$DB)
|
||||
{
|
||||
$this->current_db = $DB;
|
||||
|
||||
// Temp code!
|
||||
$this->converge_db = $DB;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Test for converge row
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Checks for a DB row that matches $email
|
||||
*
|
||||
* @param string Email address
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function converge_check_for_member_by_email( $email )
|
||||
{
|
||||
$test = $this->converge_db->simple_exec_query( array( 'select' => 'converge_id', 'from' => 'members_converge', 'where' => "converge_email='$email'" ) );
|
||||
|
||||
if ( $test['converge_id'] )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Update converge row (password)
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Updates member's converge DB row password
|
||||
*
|
||||
* @param string MD5 hash of new password
|
||||
* @param string Email address
|
||||
*/
|
||||
|
||||
function converge_update_password( $new_md5_pass, $email )
|
||||
{
|
||||
if ( ! $email or ! $new_md5_pass )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( $email != $this->member['converge_email'] )
|
||||
{
|
||||
$temp_member = $this->converge_db->simple_exec_query( array( 'select' => '*', 'from' => 'members_converge', 'where' => "converge_email='$email'" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp_member = $this->member;
|
||||
}
|
||||
|
||||
$new_pass = md5( md5( $temp_member['converge_pass_salt'] ) . $new_md5_pass );
|
||||
|
||||
$this->converge_db->do_update( 'members_converge', array( 'converge_pass_hash' => $new_pass ), 'converge_id='.$temp_member['converge_id'] );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Update converge row
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Updates member's converge DB row email address
|
||||
*
|
||||
* @param string Current email address
|
||||
* @param string New email address
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function converge_update_member($curr_email, $new_email)
|
||||
{
|
||||
if ( ! $curr_email or ! $new_email )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! $this->member['converge_id'] )
|
||||
{
|
||||
$this->converge_load_member( $curr_email );
|
||||
|
||||
if ( ! $this->member['converge_id'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
$this->converge_db->do_update( 'members_converge', array( 'converge_email' => $new_email ), 'converge_id='.$this->member['converge_id'] );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Get converge row
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Load converge DB row by email address
|
||||
*
|
||||
* @param string Current email address
|
||||
*/
|
||||
|
||||
function converge_load_member($email)
|
||||
{
|
||||
if ( ! $email )
|
||||
{
|
||||
$this->member = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->member = $this->converge_db->simple_exec_query( array( 'select' => '*', 'from' => 'members_converge', 'where' => "converge_email='$email'" ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Get converge row (based on ID)
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Load converge DB row by converge (member) ID
|
||||
*
|
||||
* @param integar Member ID
|
||||
*/
|
||||
|
||||
function converge_load_member_by_id($id)
|
||||
{
|
||||
$id = intval($id);
|
||||
|
||||
if ( ! $id )
|
||||
{
|
||||
$this->member = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->member = $this->converge_db->simple_exec_query( array( 'select' => '*', 'from' => 'members_converge', 'where' => "converge_id='$id'" ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Authenticate password
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Check supplied password with converge DB row
|
||||
*
|
||||
* @param string MD5 of entered password
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function converge_authenticate_member( $md5_once_password )
|
||||
{
|
||||
if ( ! $this->member['converge_pass_hash'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( $this->member['converge_pass_hash'] == $this->generate_compiled_passhash( $this->member['converge_pass_salt'], $md5_once_password ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Generate password
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Generates a compiled passhash
|
||||
*
|
||||
* Returns a new MD5 hash of the supplied salt and MD5 hash of the password
|
||||
*
|
||||
* @param string User's salt (5 random chars)
|
||||
* @param string User's MD5 hash of their password
|
||||
* @return string MD5 hash of compiled salted password
|
||||
*/
|
||||
|
||||
function generate_compiled_passhash($salt, $md5_once_password)
|
||||
{
|
||||
return md5( md5( $salt ) . $md5_once_password );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Generate SALT
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Generates a password salt
|
||||
*
|
||||
* Returns n length string of any char except backslash
|
||||
*
|
||||
* @param integer Length of desired salt, 5 by default
|
||||
* @return string n character random string
|
||||
*/
|
||||
|
||||
function generate_password_salt($len=5)
|
||||
{
|
||||
$salt = '';
|
||||
|
||||
//srand( (double)microtime() * 1000000 );
|
||||
// PHP 4.3 is now required ^ not needed
|
||||
|
||||
for ( $i = 0; $i < $len; $i++ )
|
||||
{
|
||||
$num = rand(33, 126);
|
||||
|
||||
if ( $num == '92' )
|
||||
{
|
||||
$num = 93;
|
||||
}
|
||||
|
||||
$salt .= chr( $num );
|
||||
}
|
||||
|
||||
return $salt;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Generate auto log in key (MD5 hash of random 60 char string
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Generates a log in key
|
||||
*
|
||||
* @param integer Length of desired random chars to MD5
|
||||
* @return string MD5 hash of random characters
|
||||
*/
|
||||
|
||||
function generate_auto_log_in_key($len=60)
|
||||
{
|
||||
$pass = $this->generate_password_salt( $len );
|
||||
|
||||
return md5($pass);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,137 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2004 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
| INVISION POWER BOARD IS NOT FREE SOFTWARE!
|
||||
| http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > CONVERT CHAR SET FUNCTIONS (Simple, light parser)
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Friday 2nd December 2005 (10:18)
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper class for converting character sets. This is to keep a consistent
|
||||
* interface even if we decide to change the actual engine.
|
||||
*
|
||||
* EXAMPLE: Converting text from one char set to another
|
||||
* <code>
|
||||
* $convert = new class_convert_charset();
|
||||
* $converted_text = $convert->convert_charset( $string, $string_char_set, $destination_char_set );
|
||||
* print $converted_text;
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 3.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
/**
|
||||
* RSS class for creation and extraction of RSS feeds.
|
||||
*
|
||||
* Does what it says on the tin.
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 3.0
|
||||
*/
|
||||
class class_convert_charset
|
||||
{
|
||||
/**
|
||||
* IPSCLASS object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
var $ipsclass;
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Convert charset
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Converts a text string from its current charset to a destination charset
|
||||
* As above
|
||||
*
|
||||
* @param string Text string
|
||||
* @param string Text string char set (original)
|
||||
* @param string Desired character set (destination)
|
||||
* @return string
|
||||
*/
|
||||
function convert_charset( $string, $string_char_set, $destination_char_set='UTF-8' )
|
||||
{
|
||||
$string_char_set = strtolower($string_char_set);
|
||||
$t = $string;
|
||||
|
||||
//-----------------------------------------
|
||||
// Did we pass a destination?
|
||||
//-----------------------------------------
|
||||
|
||||
$destination_char_set = strtolower($destination_char_set);
|
||||
|
||||
//-----------------------------------------
|
||||
// Not the same?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $destination_char_set == $string_char_set )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !$string_char_set )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !$t OR $t == '' )
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Do the convert - internally..
|
||||
//-----------------------------------------
|
||||
|
||||
/*if ( function_exists( 'mb_convert_encoding' ) )
|
||||
{
|
||||
$text = mb_convert_encoding( $string, $destination_char_set, $string_char_set );
|
||||
}
|
||||
else if ( function_exists( 'recode_string' ) )
|
||||
{
|
||||
$text = recode_string( $string_char_set.'..'.$destination_char_set, $string );
|
||||
}
|
||||
else if ( function_exists( 'iconv' ) )
|
||||
{
|
||||
$text = iconv( $string_char_set, $destination_char_set.'//TRANSLIT', $string);
|
||||
}
|
||||
else
|
||||
{*/
|
||||
require_once( IPS_CLASSES_PATH . '/i18n/convertcharset/ConvertCharset.class.php' );
|
||||
$convert = new ConvertCharset();
|
||||
$text = $convert->Convert($string, $string_char_set, $destination_char_set, false );
|
||||
//}
|
||||
|
||||
return $text ? $text : $t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [DB Abstraction]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > MySQL Driver Module
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: Monday 28th February 2005 16:46
|
||||
|
|
||||
| > Module Version Number: 2.1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Database Object Driver
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage DatabaseAbstraction
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gateway for mysql/mysqli client
|
||||
*
|
||||
*/
|
||||
|
||||
//define( 'FORCE_MYSQL_ONLY', 1 );
|
||||
|
||||
//-----------------------------------------
|
||||
// Define KERNEL_PATH if not
|
||||
// defined - i.e. installation
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! defined('KERNEL_PATH') )
|
||||
{
|
||||
if( defined('INS_KERNEL_PATH') )
|
||||
{
|
||||
define( 'KERNEL_PATH', INS_KERNEL_PATH );
|
||||
}
|
||||
else
|
||||
{
|
||||
define( 'KERNEL_PATH', str_replace( "//", "/", str_replace( "\\", "/", dirname( __FILE__ ) ) ) . "/" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// MySQLi and PHP 5.0.5 don't get along well
|
||||
//-----------------------------------------
|
||||
|
||||
$versions = explode( ".", phpversion() );
|
||||
|
||||
if( $versions[0] == 5 AND $versions[1] == 0 AND $versions[2] == 5 )
|
||||
{
|
||||
define( 'FORCE_MYSQL_ONLY', 1 );
|
||||
}
|
||||
|
||||
if ( extension_loaded('mysqli') AND ! defined( 'FORCE_MYSQL_ONLY' ) )
|
||||
{
|
||||
require( KERNEL_PATH."class_db_mysqli_client.php" );
|
||||
}
|
||||
else
|
||||
{
|
||||
require( KERNEL_PATH."class_db_mysql_client.php" );
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Clean up
|
||||
//-----------------------------------------
|
||||
|
||||
unset( $versions );
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,452 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel Module
|
||||
| Invision Power Board
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2005 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Difference Engine.
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Thursday 10th February 2005 (10:47)
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Differences class
|
||||
*
|
||||
* Get file differences
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Differences class
|
||||
*
|
||||
* Get file differences
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_difference
|
||||
{
|
||||
# Globals
|
||||
|
||||
/**
|
||||
* Shell command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $diff_command = 'diff';
|
||||
|
||||
/**
|
||||
* Type of diff to use
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $method = 'exec';
|
||||
|
||||
/**
|
||||
* Differences found?
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $diff_found = 0;
|
||||
|
||||
/**
|
||||
* Post process DIFF result?
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $post_process = 1;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Constructor
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_difference()
|
||||
{
|
||||
//-------------------------------
|
||||
// Server?
|
||||
//-------------------------------
|
||||
|
||||
if ( (substr(PHP_OS, 0, 3) == 'WIN') OR ( ! function_exists('exec') ) )
|
||||
{
|
||||
$this->method = 'CGI';
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Produce difference output
|
||||
// //@header("Content-type: text/plain"); print_r($diff_res_array); exit();
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Wrapper function to get differences
|
||||
*
|
||||
* @return string Diff data
|
||||
*/
|
||||
function get_differences( $str1, $str2 )
|
||||
{
|
||||
$this->diff_found = 0;
|
||||
|
||||
$str1 = $this->_diff_tag_space($str1);
|
||||
$str2 = $this->_diff_tag_space($str2);
|
||||
$str1_lines = $this->_diff_explode_string_into_words($str1);
|
||||
$str2_lines = $this->_diff_explode_string_into_words($str2);
|
||||
|
||||
if ( $this->method == 'CGI' )
|
||||
{
|
||||
$diff_res = $this->_get_cgi_diff( implode( chr(10), $str1_lines ).chr(10), implode( chr(10), $str2_lines ).chr(10) );
|
||||
}
|
||||
else if ( $this->method == 'PHP' )
|
||||
{
|
||||
$diff_res = $this->_get_php_diff( implode( chr(10), $str1_lines ).chr(10), implode( chr(10), $str2_lines ).chr(10) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$diff_res = $this->_get_exec_diff( implode( chr(10), $str1_lines ).chr(10), implode( chr(10), $str2_lines ).chr(10) );
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Post process?
|
||||
//-------------------------------
|
||||
|
||||
if ( $this->post_process )
|
||||
{
|
||||
if ( is_array($diff_res) )
|
||||
{
|
||||
reset($diff_res);
|
||||
$c = 0;
|
||||
$diff_res_array = array();
|
||||
|
||||
foreach( $diff_res as $l_val )
|
||||
{
|
||||
if ( intval($l_val) )
|
||||
{
|
||||
$c = intval($l_val);
|
||||
$diff_res_array[$c]['changeInfo'] = $l_val;
|
||||
}
|
||||
|
||||
if (substr($l_val,0,1) == '<')
|
||||
{
|
||||
$diff_res_array[$c]['old'][] = substr($l_val,2);
|
||||
}
|
||||
|
||||
if (substr($l_val,0,1) == '>')
|
||||
{
|
||||
$diff_res_array[$c]['new'][] = substr($l_val,2);
|
||||
}
|
||||
}
|
||||
|
||||
$out_str = '';
|
||||
$clr_buffer = '';
|
||||
|
||||
for ( $a = -1; $a < count($str1_lines); $a++ )
|
||||
{
|
||||
if ( is_array( $diff_res_array[$a+1] ) )
|
||||
{
|
||||
if ( strstr( $diff_res_array[$a+1]['changeInfo'], 'a') )
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
$clr_buffer .= htmlspecialchars($str1_lines[$a]).' ';
|
||||
}
|
||||
|
||||
$out_str .= $clr_buffer;
|
||||
$clr_buffer = '';
|
||||
|
||||
if (is_array($diff_res_array[$a+1]['old']))
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
$out_str.='<del style="-ips-match:1">'.htmlspecialchars(implode(' ',$diff_res_array[$a+1]['old'])).'</del> ';
|
||||
}
|
||||
|
||||
if (is_array($diff_res_array[$a+1]['new']))
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
$out_str.='<ins style="-ips-match:1">'.htmlspecialchars(implode(' ',$diff_res_array[$a+1]['new'])).'</ins> ';
|
||||
}
|
||||
|
||||
$cip = explode(',',$diff_res_array[$a+1]['changeInfo']);
|
||||
|
||||
if ( ! strcmp( $cip[0], $a + 1 ) )
|
||||
{
|
||||
$new_line = intval($cip[1])-1;
|
||||
|
||||
if ( $new_line > $a )
|
||||
{
|
||||
$a = $new_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$clr_buffer .= htmlspecialchars($str1_lines[$a]).' ';
|
||||
}
|
||||
}
|
||||
|
||||
$out_str .= $clr_buffer;
|
||||
|
||||
$out_str = str_replace(' ',chr(10),$out_str);
|
||||
|
||||
$out_str = $this->_diff_tag_space($out_str,1);
|
||||
|
||||
return $out_str;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $diff_res;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Adds space character after HTML tags
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Adds space character after HTML tags
|
||||
*
|
||||
* @return string Converted string
|
||||
*/
|
||||
function _diff_tag_space( $str, $rev=0 )
|
||||
{
|
||||
if ( $rev )
|
||||
{
|
||||
return str_replace(' <','<',str_replace('> ','>',$str) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return str_replace('<',' <',str_replace('>','> ',$str) );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Explodes input string into words
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Explodes input string into words
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function _diff_explode_string_into_words( $str )
|
||||
{
|
||||
$str_array = $this->_explode_trim( chr(10), $str );
|
||||
$out_array = array();
|
||||
|
||||
reset($str_array);
|
||||
|
||||
foreach( $str_array as $low )
|
||||
{
|
||||
$all_words = $this->_explode_trim( ' ', $low, 1 );
|
||||
$out_array = array_merge($out_array, $all_words);
|
||||
$out_array[] = '';
|
||||
$out_array[] = '';
|
||||
}
|
||||
|
||||
return $out_array;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Explode into array and trim
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Explode into array and trim
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function _explode_trim( $delim, $str, $remove_blank=0 )
|
||||
{
|
||||
$tmp = explode( $delim, trim($str) );
|
||||
$final = array();
|
||||
|
||||
foreach( $tmp as $i )
|
||||
{
|
||||
if ( $remove_blank AND ( $i === '' OR $i === NULL ) ) //!$i AND $i !== 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$final[] = trim($i);
|
||||
}
|
||||
}
|
||||
|
||||
return $final;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Produce differences using PHP
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Produce differences using PHP
|
||||
*
|
||||
* @param string comapre string 1
|
||||
* @param string comapre string 2
|
||||
* @return string
|
||||
*/
|
||||
function _get_php_diff( $str1 , $str2 )
|
||||
{
|
||||
$str1 = explode( "\n", str_replace( "\r\n", "\n", $str1 ) );
|
||||
$str2 = explode( "\n", str_replace( "\r\n", "\n", $str2 ) );
|
||||
|
||||
include_once KERNEL_PATH.'PEAR/Text/Diff.php';
|
||||
include_once KERNEL_PATH.'PEAR/Text/Diff/Renderer.php';
|
||||
include_once KERNEL_PATH.'PEAR/Text/Diff/Renderer/inline.php';
|
||||
|
||||
$diff = new Text_Diff( $str1,$str2 );
|
||||
|
||||
$renderer = new Text_Diff_Renderer_inline();
|
||||
|
||||
$result = $renderer->render($diff);
|
||||
|
||||
# Inline formatting adjustments
|
||||
$result = htmlspecialchars( $result );
|
||||
|
||||
$result = str_replace( "<ins>", '<ins style="-ips-match:1">', $result );
|
||||
$result = str_replace( "<del>", '<del style="-ips-match:1">', $result );
|
||||
$result = preg_replace( "#</(ins|del)>#", "</\\1>", $result );
|
||||
|
||||
# Got a match?
|
||||
if ( strstr( $result, 'style="-ips-match:1"' ) )
|
||||
{
|
||||
$this->diff_found = 1;
|
||||
}
|
||||
|
||||
# No post processing please
|
||||
$this->post_process = 0;
|
||||
|
||||
# Convert lines to a space, and two spaces to a single line
|
||||
$result = str_replace(' ', chr(10), str_replace( "\n", " ", $result ) );
|
||||
$result = $this->_diff_tag_space($result,1);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Produce differences using unix
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Produce differences using unix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function _get_exec_diff( $str1, $str2 )
|
||||
{
|
||||
//-------------------------------
|
||||
// Write the tmp files
|
||||
//-------------------------------
|
||||
|
||||
$file1 = ROOT_PATH.'uploads/'.time().'-1';
|
||||
$file2 = ROOT_PATH.'uploads/'.time().'-2';
|
||||
|
||||
if ( $FH1 = @fopen( $file1, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH1, $str1, strlen($str1) );
|
||||
@fclose( $FH1 );
|
||||
}
|
||||
|
||||
if ( $FH2 = @fopen( $file2, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH2, $str2, strlen($str2) );
|
||||
@fclose( $FH2 );
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Check
|
||||
//-------------------------------
|
||||
|
||||
if ( file_exists( $file1 ) and file_exists( $file2 ) )
|
||||
{
|
||||
exec( $this->diff_command.' '.$file1.' '.$file2, $result );
|
||||
|
||||
@unlink( $file1 );
|
||||
@unlink( $file2 );
|
||||
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Error, files not written to disk";
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Produce differences using unix
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Produce differences using CGI
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function _get_cgi_diff( $str1, $str2 )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Load file management class
|
||||
//-----------------------------------------
|
||||
|
||||
require_once( IPS_CLASSES_PATH.'/class_file_management.php' );
|
||||
$this->class_file_management = new class_file_management();
|
||||
$this->class_file_management->use_sockets = $this->ipsclass->vars['enable_sockets'];
|
||||
|
||||
//-------------------------------
|
||||
// Write the tmp files
|
||||
//-------------------------------
|
||||
|
||||
$file1 = 'tmp-1';
|
||||
$file2 = 'tmp-2';
|
||||
|
||||
if ( $FH1 = @fopen( ROOT_PATH.'uploads/'.$file1, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH1, $str1, strlen($str1) );
|
||||
@fclose( $FH1 );
|
||||
}
|
||||
|
||||
if ( $FH2 = @fopen( ROOT_PATH.'uploads/'.$file2, 'w' ) )
|
||||
{
|
||||
@fwrite( $FH2, $str2, strlen($str2) );
|
||||
@fclose( $FH2 );
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Check
|
||||
//-------------------------------
|
||||
|
||||
if ( file_exists( ROOT_PATH.'uploads/'.$file1 ) AND file_exists( ROOT_PATH.'uploads/'.$file2 ) )
|
||||
{
|
||||
$result = $this->class_file_management->get_file_contents( $this->ipsclass->vars['base_url']."/".CP_DIRECTORY."/".IPS_CGI_DIRECTORY."/cgi_getdifference.cgi" );
|
||||
|
||||
@unlink( ROOT_PATH.'uploads/'.$file1 );
|
||||
@unlink( ROOT_PATH.'uploads/'.$file2 );
|
||||
|
||||
return explode( "\n", $result );
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Error, files not written to disk";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -1,975 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Email Functions]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Core Module
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: Tuesday 1st March 2005 (11:52)
|
||||
|
|
||||
| > Module Version Number: 2.1.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Email
|
||||
*
|
||||
* This class contains all generic PHP mail and SMTP functions
|
||||
* as well as specific functions for IPB emails
|
||||
*
|
||||
* Example usage:
|
||||
* <code>
|
||||
* $email = new class_email();
|
||||
* $email->email_init();
|
||||
* $email->to = 'user@invisionboard.com';
|
||||
* $email->from = 'from@user.com';
|
||||
* $email->subject = 'Test Email';
|
||||
* $email->message = 'Hello there!';
|
||||
* $email->send_mail();
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Email Class
|
||||
*
|
||||
* Methods and functions for handling emails
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
* @todo Separate out IPB content and leave a pure
|
||||
* email class.
|
||||
*/
|
||||
class class_email
|
||||
{
|
||||
/**
|
||||
* From email address
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $from = "";
|
||||
|
||||
/**
|
||||
* From email address
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $from_display = "";
|
||||
|
||||
/**
|
||||
* To email address
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $to = "";
|
||||
|
||||
/**
|
||||
* Email subject
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $subject = "";
|
||||
|
||||
/**
|
||||
* Email message contents
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $message = "";
|
||||
|
||||
/**
|
||||
* Plain text message contents
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $pt_message = "";
|
||||
|
||||
/**
|
||||
* Attachments: Parts
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $parts = array();
|
||||
|
||||
/**
|
||||
* BCC Email addresses
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $bcc = array();
|
||||
|
||||
/**
|
||||
* Email headers
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $mail_headers = array();
|
||||
|
||||
/**
|
||||
* Header EOL
|
||||
* RFC specs state \r\n
|
||||
* However most servers support \n
|
||||
* @var string
|
||||
*/
|
||||
var $header_eol = "\n";
|
||||
|
||||
/**
|
||||
* Attachments: Multi-part
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $multipart = "";
|
||||
|
||||
/**
|
||||
* Attachments: Boundry
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $boundry = "----=_NextPart_000_0022_01C1BD6C.D0C0F9F0";
|
||||
|
||||
/**
|
||||
* HTML email flag
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $html_email = 0;
|
||||
|
||||
/**
|
||||
* Email character set
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $char_set = 'utf-8';
|
||||
|
||||
/**
|
||||
* SMTP:
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
var $smtp_fp = null;
|
||||
|
||||
/**
|
||||
* SMTP: Message
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $smtp_msg = "";
|
||||
|
||||
/**
|
||||
* SMTP: Port
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $smtp_port = 25;
|
||||
|
||||
/**
|
||||
* SMTP: Host
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $smtp_host = "localhost";
|
||||
|
||||
/**
|
||||
* SMTP: Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $smtp_user = "";
|
||||
|
||||
/**
|
||||
* SMTP: Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $smtp_pass = "";
|
||||
|
||||
/**
|
||||
* SMTP: Return code
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $smtp_code = "";
|
||||
|
||||
/**
|
||||
* SMTP: Wrap email addresses in brackets flag
|
||||
*
|
||||
* @var integer boolean
|
||||
*/
|
||||
var $wrap_brackets = 0;
|
||||
|
||||
/**
|
||||
* Default email method (mail or smtp)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $mail_method = 'mail';
|
||||
|
||||
/**
|
||||
* Dump email to flat file for testing
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $temp_dump = 0;
|
||||
|
||||
/**
|
||||
* Error message
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $error_msg;
|
||||
|
||||
/**
|
||||
* Error description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $error_help;
|
||||
|
||||
/**
|
||||
* Error flag
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $error;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// CONSTRUCTOR
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_email()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// ADD ATTACHMENT
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Add an attachment to the current email
|
||||
*
|
||||
* @param string File data
|
||||
* @param string File name
|
||||
* @param string File type (MIME)
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function add_attachment($data = "", $name = "", $ctype='application/octet-stream')
|
||||
{
|
||||
$this->parts[] = array( 'ctype' => $ctype,
|
||||
'data' => $data,
|
||||
'encode' => 'base64',
|
||||
'name' => $name
|
||||
);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// BUILD HEADERS
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Build the email headers (MIME, Charset, From, BCC, To, Subject, etc)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function build_headers()
|
||||
{
|
||||
$extra_headers = array();
|
||||
$extra_header_rfc = "";
|
||||
|
||||
//-----------------------------------------
|
||||
// HTML (hitmuhl)
|
||||
// If we're sending HTML messages, then
|
||||
// we'll add the plain text message along with
|
||||
// it for non HTML browsers
|
||||
//-----------------------------------------
|
||||
|
||||
$this->pt_message = $this->message;
|
||||
$this->pt_message = str_replace( "<br />", "\n", $this->pt_message );
|
||||
$this->pt_message = str_replace( "<br>" , "\n", $this->pt_message );
|
||||
$this->pt_message = strip_tags( $this->pt_message );
|
||||
|
||||
$this->pt_message = html_entity_decode( $this->pt_message, ENT_QUOTES );
|
||||
$this->pt_message = str_replace( '\', '\\', $this->pt_message );
|
||||
$this->pt_message = str_replace( '$', '$', $this->pt_message );
|
||||
|
||||
// Now put & back...
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Start mail headers
|
||||
//-----------------------------------------
|
||||
|
||||
$this->mail_headers['MIME-Version'] = "1.0";
|
||||
|
||||
//-----------------------------------------
|
||||
// From and to...
|
||||
//-----------------------------------------
|
||||
|
||||
if( $this->from_display )
|
||||
{
|
||||
$this->mail_headers['From'] = '"' . $this->from_display . '" <' . $this->from . '>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->mail_headers['From'] = '<' . $this->from . '>';
|
||||
}
|
||||
|
||||
if ( $this->mail_method != 'smtp' )
|
||||
{
|
||||
if ( count( $this->bcc ) > 1 )
|
||||
{
|
||||
$this->mail_headers['Bcc'] = implode( "," , $this->bcc );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this->to )
|
||||
{
|
||||
$this->mail_headers['To'] = $this->to;
|
||||
}
|
||||
|
||||
$this->mail_headers['Subject'] = $this->subject;
|
||||
}
|
||||
|
||||
$this->mail_headers['Return-Path'] = $this->from;
|
||||
$this->mail_headers['X-Priority'] = "3";
|
||||
$this->mail_headers['X-Mailer'] = "IPS PHP Mailer";
|
||||
|
||||
//-----------------------------------------
|
||||
// Attachments?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( count ($this->parts) > 0 )
|
||||
{
|
||||
if ( ! $this->html_email )
|
||||
{
|
||||
$extra_headers[0]['Content-Type'] = "multipart/mixed;\n\tboundary=\"".$this->boundry."\"";
|
||||
|
||||
$extra_headers[0]['notencode'] = "\n\nThis is a MIME encoded message.\n\n--".$this->boundry."\n";
|
||||
|
||||
$extra_headers[1]['Content-Type'] = "text/plain;\n\tcharset=\"".$this->char_set."\"";
|
||||
#$extra_headers[1]['Content-Transfer-Encoding'] = "quoted-printable";
|
||||
|
||||
$extra_headers[1]['notencode'] = "\n\n".$this->message."\n\n--".$this->boundry;
|
||||
}
|
||||
else
|
||||
{
|
||||
$extra_headers[0]['Content-Type'] = "multipart/mixed;\n\tboundary=\"".$this->boundry."\"";
|
||||
|
||||
$extra_headers[0]['notencode'] = "\n\nThis is a MIME encoded message.\n\n--".$this->boundry."\n";
|
||||
|
||||
$extra_headers[1]['Content-Type'] = "text/html;\n\tcharset=\"".$this->char_set."\"";
|
||||
#$extra_headers[1]['Content-Transfer-Encoding'] = "quoted-printable";
|
||||
|
||||
$extra_headers[1]['notencode'] = "\n\n".$this->message."\n\n--".$this->boundry;
|
||||
}
|
||||
|
||||
$extra_headers[2]['notencode'] = $this->build_multipart();
|
||||
|
||||
reset($extra_headers);
|
||||
|
||||
foreach( $extra_headers as $subset => $the_header )
|
||||
{
|
||||
foreach( $the_header as $k => $v )
|
||||
{
|
||||
if( $k == 'notencode' )
|
||||
{
|
||||
$extra_headers_rfc .= $v;
|
||||
}
|
||||
else
|
||||
{
|
||||
$v = $this->encode_headers( array( 'v' => $v ) );
|
||||
|
||||
$extra_headers_rfc .= $k.': '.$v['v'].$this->header_eol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->message = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------
|
||||
// HTML (hitmuhl) ?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $this->html_email )
|
||||
{
|
||||
$extra_headers[0]['Content-Type'] = "multipart/alternative;\n\tboundary=\"".$this->boundry."\"";
|
||||
|
||||
$extra_headers[0]['notencode'] = "\n\nThis is a MIME encoded message.\n\n--".$this->boundry."\n";
|
||||
|
||||
$extra_headers[1]['Content-Type'] = "text/html;\n\tcharset=\"".$this->char_set."\"";
|
||||
#$extra_headers[1]['Content-Transfer-Encoding'] = "quoted-printable";
|
||||
|
||||
$extra_headers[1]['notencode'] = "\n\n".$this->message."\n\n--".$this->boundry."\n";
|
||||
|
||||
$extra_headers[2]['Content-Type'] = "text/plain;\n\tcharset=\"".$this->char_set."\"";
|
||||
#$extra_headers[2]['Content-Transfer-Encoding'] = "quoted-printable";
|
||||
|
||||
$extra_headers[2]['notencode'] = "\n\n".$this->pt_message."\n\n";
|
||||
|
||||
reset($extra_headers);
|
||||
|
||||
foreach( $extra_headers as $subset => $the_header )
|
||||
{
|
||||
foreach( $the_header as $k => $v )
|
||||
{
|
||||
if( $k == 'notencode' )
|
||||
{
|
||||
$extra_headers_rfc .= $v;
|
||||
}
|
||||
else
|
||||
{
|
||||
$v = $this->encode_headers( array( 'v' => $v ) );
|
||||
|
||||
$extra_headers_rfc .= $k.': '.$v['v'].$this->header_eol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->message = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->mail_headers['Content-type'] = 'text/plain; charset="'.$this->char_set.'"';
|
||||
}
|
||||
}
|
||||
|
||||
$this->encode_headers();
|
||||
|
||||
foreach( $this->mail_headers as $k => $v )
|
||||
{
|
||||
$this->rfc_headers .= $k.": ".$v.$this->header_eol;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Attachments extra?
|
||||
//-----------------------------------------
|
||||
|
||||
if( $extra_headers_rfc )
|
||||
{
|
||||
$this->rfc_headers .= $extra_headers_rfc;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// BUILD MULTIPART
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Build the multipart headers for the email
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function build_multipart()
|
||||
{
|
||||
$multipart = "";
|
||||
|
||||
for ($i = sizeof($this->parts) - 1 ; $i >= 0 ; $i--)
|
||||
{
|
||||
$multipart .= $this->header_eol . $this->encode_attachment($this->parts[$i]) . "--" . $this->boundry;
|
||||
}
|
||||
|
||||
return $multipart . "--\n";
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Send_mail:
|
||||
// Physically sends the email
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Send the mail (mail must be built by this point)
|
||||
*
|
||||
* @return boolean On error
|
||||
*/
|
||||
|
||||
function send_mail()
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Wipe ya face
|
||||
//-----------------------------------------
|
||||
|
||||
$this->to = preg_replace( "/[ \t]+/" , "" , $this->to );
|
||||
$this->from = preg_replace( "/[ \t]+/" , "" , $this->from );
|
||||
|
||||
$this->to = preg_replace( "/,,/" , "," , $this->to );
|
||||
$this->from = preg_replace( "/,,/" , "," , $this->from );
|
||||
|
||||
$this->to = preg_replace( "#\#\[\]'\"\(\):;/\$!£%\^&\*\{\}#" , "", $this->to );
|
||||
$this->from = preg_replace( "#\#\[\]'\"\(\):;/\$!£%\^&\*\{\}#" , "", $this->from);
|
||||
|
||||
//-----------------------------------------
|
||||
// Build headers
|
||||
//-----------------------------------------
|
||||
|
||||
$this->build_headers();
|
||||
|
||||
if( $this->mail_method != 'smtp' )
|
||||
{
|
||||
$subject = $this->encode_headers( array( 'Subject' => $this->subject ) );
|
||||
|
||||
$this->subject = $subject['Subject'];
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Lets go..
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ($this->from) and ($this->subject) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Tmp dump? (Testing)
|
||||
//-----------------------------------------
|
||||
|
||||
if ($this->temp_dump == 1)
|
||||
{
|
||||
$blah = $this->subject."\n------------\n".$this->rfc_headers."\n\n".$this->message;
|
||||
|
||||
if( !is_dir( $this->root_path . '/_mail' ) )
|
||||
{
|
||||
@mkdir( $this->root_path . '/_mail' );
|
||||
@chmod( $this->root_path . '/_mail', 0777 );
|
||||
}
|
||||
|
||||
$pathy = str_replace( '//', '/', $this->root_path . '/_mail/' . date("M-j-Y,hi-A") . str_replace( '@', '+', $this->to ) . '.php' );
|
||||
$fh = @fopen( $pathy, 'w' );
|
||||
@fputs( $fh, $blah, strlen($blah) );
|
||||
@fclose( $fh );
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------
|
||||
// PHP MAIL()
|
||||
//-----------------------------------------
|
||||
|
||||
if ($this->mail_method != 'smtp')
|
||||
{
|
||||
if ( ! @mail( $this->to, $this->subject, $this->message, $this->rfc_headers, $this->extra_opts ) )
|
||||
{
|
||||
# Try without args for safe mode peeps
|
||||
if ( ! @mail( $this->to, $this->subject, $this->message, $this->rfc_headers ) )
|
||||
{
|
||||
$this->fatal_error("Could not send the email", "Failed at 'mail' command");
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------
|
||||
// SMTP
|
||||
//-----------------------------------------
|
||||
else
|
||||
{
|
||||
$this->smtp_send_mail();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->fatal_error("From or subject empty");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->to = "";
|
||||
$this->from = "";
|
||||
$this->from_display = "";
|
||||
$this->message = "";
|
||||
$this->pt_message = "";
|
||||
$this->subject = "";
|
||||
$this->mail_headers = array();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SMTP: Get line
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* SMTP: Get next line
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function smtp_get_line()
|
||||
{
|
||||
$this->smtp_msg = "";
|
||||
|
||||
while ( $line = fgets( $this->smtp_fp, 515 ) )
|
||||
{
|
||||
$this->smtp_msg .= $line;
|
||||
|
||||
if ( substr($line, 3, 1) == " " )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SMTP Send CMD
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* SMTP: Send command
|
||||
*
|
||||
* @param string SMTP command
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function smtp_send_cmd($cmd)
|
||||
{
|
||||
$this->smtp_msg = "";
|
||||
$this->smtp_code = "";
|
||||
|
||||
fputs( $this->smtp_fp, $cmd."\r\n" );
|
||||
|
||||
$this->smtp_get_line();
|
||||
|
||||
$this->smtp_code = substr( $this->smtp_msg, 0, 3 );
|
||||
|
||||
return $this->smtp_code == "" ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SMTP Error
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* SMTP: Error handler
|
||||
*
|
||||
* @param string SMTP error
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function smtp_error($err = "")
|
||||
{
|
||||
$this->smtp_msg = $err;
|
||||
$this->fatal_error( $err );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SMTP: Encode newlines
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Encode data and make it safe for SMTP transport
|
||||
*
|
||||
* @param string Raw Data
|
||||
* @return string CRLF Encoded Data
|
||||
*/
|
||||
|
||||
function smtp_crlf_encode($data)
|
||||
{
|
||||
$data .= "\n";
|
||||
$data = str_replace( "\n", "\r\n", str_replace( "\r", "", $data ) );
|
||||
$data = str_replace( "\n.\r\n" , "\n. \r\n", $data );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SMTP send mail
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* SMTP: Sends the SMTP email
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function smtp_send_mail()
|
||||
{
|
||||
$this->smtp_fp = @fsockopen( $this->smtp_host, intval($this->smtp_port), $errno, $errstr, 30 );
|
||||
|
||||
if ( ! $this->smtp_fp )
|
||||
{
|
||||
$this->smtp_error("Could not open a socket to the SMTP server");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->smtp_get_line();
|
||||
|
||||
$this->smtp_code = substr( $this->smtp_msg, 0, 3 );
|
||||
|
||||
if ( $this->smtp_code == 220 )
|
||||
{
|
||||
$data = $this->smtp_crlf_encode( $this->mail_headers."\n" . $this->message);
|
||||
|
||||
//-----------------------------------------
|
||||
// HELO!, er... HELLO!
|
||||
//-----------------------------------------
|
||||
|
||||
$this->smtp_send_cmd("HELO ".$this->smtp_host);
|
||||
|
||||
if ( $this->smtp_code != 250 )
|
||||
{
|
||||
$this->smtp_send_cmd("EHLO ".$this->smtp_host);
|
||||
|
||||
if ( $this->smtp_code != 250 )
|
||||
{
|
||||
$this->smtp_error("HELO,EHLO");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Do you like my user!
|
||||
//-----------------------------------------
|
||||
|
||||
if ($this->smtp_user and $this->smtp_pass)
|
||||
{
|
||||
$this->smtp_send_cmd("AUTH LOGIN");
|
||||
|
||||
if ( $this->smtp_code == 334 )
|
||||
{
|
||||
$this->smtp_send_cmd( base64_encode($this->smtp_user) );
|
||||
|
||||
if ( $this->smtp_code != 334 )
|
||||
{
|
||||
$this->smtp_error("Username not accepted from the server");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->smtp_send_cmd( base64_encode($this->smtp_pass) );
|
||||
|
||||
if ( $this->smtp_code != 235 )
|
||||
{
|
||||
$this->smtp_error("Password not accepted from the server");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->smtp_error("This server does not support authorisation");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// We're from MARS!
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $this->wrap_brackets )
|
||||
{
|
||||
if ( ! preg_match( "/^</", $this->from ) )
|
||||
{
|
||||
$this->from = "<".$this->from.">";
|
||||
}
|
||||
}
|
||||
|
||||
$this->smtp_send_cmd("MAIL FROM:".$this->from);
|
||||
|
||||
if ( $this->smtp_code != 250 )
|
||||
{
|
||||
$this->smtp_error();
|
||||
return;
|
||||
}
|
||||
|
||||
$to_arry = array( $this->to );
|
||||
|
||||
if ( count( $this->bcc ) > 0 )
|
||||
{
|
||||
foreach ($this->bcc as $bcc)
|
||||
{
|
||||
if ( preg_match( "/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,4})(\]?)$/", str_replace( " ", "", $bcc ) ) )
|
||||
{
|
||||
$to_arry[] = $bcc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// You are from VENUS!
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $to_arry as $to_email )
|
||||
{
|
||||
if ( $this->wrap_brackets )
|
||||
{
|
||||
$this->smtp_send_cmd("RCPT TO:<".$to_email.">");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->smtp_send_cmd("RCPT TO:".$to_email);
|
||||
}
|
||||
|
||||
if ( $this->smtp_code != 250 )
|
||||
{
|
||||
$this->smtp_error("Incorrect email address: $to_email");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// SEND MAIL!
|
||||
//-----------------------------------------
|
||||
|
||||
$this->smtp_send_cmd("DATA");
|
||||
|
||||
if ( $this->smtp_code == 354 )
|
||||
{
|
||||
fputs( $this->smtp_fp, $data."\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->smtp_error("Error on write to SMTP server");
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// GO ON, NAFF OFF!
|
||||
//-----------------------------------------
|
||||
|
||||
$this->smtp_send_cmd(".");
|
||||
|
||||
if ( $this->smtp_code != 250 )
|
||||
{
|
||||
$this->smtp_error();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->smtp_send_cmd("quit");
|
||||
|
||||
if ( $this->smtp_code != 221 )
|
||||
{
|
||||
$this->smtp_error();
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Tubby-bye-bye!
|
||||
//-----------------------------------------
|
||||
|
||||
@fclose( $this->smtp_fp );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->smtp_error();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// FATAL ERROR : RETURN
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Fatal error handler
|
||||
*
|
||||
* @param string Error Message
|
||||
* @param string Error Help / Description
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function fatal_error($msg, $help="")
|
||||
{
|
||||
|
||||
$this->error_msg = $msg;
|
||||
$this->error_help = $help;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// ENCODE ATTACHMENT
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Encode an attachment
|
||||
*
|
||||
* @param string Raw data
|
||||
* @return string Processed data
|
||||
*/
|
||||
|
||||
function encode_attachment($part)
|
||||
{
|
||||
$msg = chunk_split(base64_encode($part['data']));
|
||||
|
||||
$headers = array();
|
||||
$header_str = "";
|
||||
|
||||
$headers['Content-Type'] = $part['ctype']. ($part['name'] ? "; name =\"".$part['name']."\"" : "");
|
||||
$headers['Content-Transfer-Encoding'] = $part['encode'];
|
||||
$headers['Content-Disposition'] = "attachment; filename=\"".$part['name']."\"";
|
||||
|
||||
$headers = $this->encode_headers( $headers );
|
||||
|
||||
foreach( $headers as $k => $v )
|
||||
{
|
||||
$header_str .= $k.': '.$v.$this->header_eol;
|
||||
}
|
||||
|
||||
$header_str .= "\n\n".$msg."\n";
|
||||
|
||||
return $header_str;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// ENCODE HEADERS - RFC2047
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function encode_headers( $headers = array() )
|
||||
{
|
||||
$enc_headers = count($headers) ? $headers : $this->mail_headers;
|
||||
|
||||
foreach( $enc_headers as $header => $value)
|
||||
{
|
||||
preg_match_all( '/(\w*[\x80-\xFF]+\w*)/', $value, $matches );
|
||||
|
||||
foreach ($matches[1] as $value)
|
||||
{
|
||||
if( $header == 'From' )
|
||||
{
|
||||
// Either sendmail or the email servers don't like 'From' encoded...let's remove the board name
|
||||
// and just move along, as email address cannot contain nasty characters themselves
|
||||
|
||||
$this->mail_headers['From'] = $this->from;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$replacement = preg_replace_callback( '/([\x80-\xFF])/', create_function( '$match', 'return "=" . strtoupper( dechex( ord( "$match[1]" ) ) );' ), $value );
|
||||
|
||||
$value = str_replace( $value, '=?' . $this->char_set . '?Q?' . $replacement . '?=', $value );
|
||||
}
|
||||
|
||||
if( !count($headers) )
|
||||
{
|
||||
$this->mail_headers[ $header ] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$enc_headers[ $header ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $enc_headers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,482 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+---------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| ========================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2004 Invision Power Services
|
||||
| http://www.invisionpower.com
|
||||
| ========================================
|
||||
+---------------------------------------------------------------------------
|
||||
| INVISION POWER BOARD IS NOT FREE SOFTWARE!
|
||||
| http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > File Management Functions
|
||||
| > Script written by Matt Mecham
|
||||
| > Date started: Tuesday 22nd February 2005 (16:55) I have cold feet
|
||||
|
|
||||
+---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class File Management
|
||||
*
|
||||
* Wrapper for getting file contents
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
if ( ! defined( 'IPS_CLASSES_PATH' ) )
|
||||
{
|
||||
/**
|
||||
* Define classes path
|
||||
*/
|
||||
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class File Management
|
||||
*
|
||||
* Wrapper for getting file contents
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_file_management
|
||||
{
|
||||
/**
|
||||
* Use sockets flag
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $use_sockets = 0;
|
||||
|
||||
/**
|
||||
* Error array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $errors = array();
|
||||
|
||||
/**
|
||||
* HTTP Status Code/Text
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $http_status_code = 0;
|
||||
var $http_status_text = "";
|
||||
|
||||
/**#@+
|
||||
* Set Authentication
|
||||
*
|
||||
* @var strings
|
||||
*/
|
||||
var $auth_req = 0;
|
||||
var $auth_user;
|
||||
var $auth_pass;
|
||||
/**#@-*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Constructor
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_file_management()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Get file contents (accepts URL or path)
|
||||
// file_get_contents() has caching issues
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get file contents (accepts URL or path)
|
||||
*
|
||||
* file_get_contents() has caching issues
|
||||
* @return string File data
|
||||
*/
|
||||
function get_file_contents( $file_location, $http_user='', $http_pass='' )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$contents = "";
|
||||
$file_location = str_replace( '&', '&', $file_location );
|
||||
|
||||
//-----------------------------------------
|
||||
// Inline user/pass?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $http_user and $http_pass )
|
||||
{
|
||||
$this->auth_req = 1;
|
||||
$this->auth_user = $http_user;
|
||||
$this->auth_pass = $http_pass;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Hello
|
||||
//-------------------------------
|
||||
|
||||
if ( ! $file_location )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! stristr( $file_location, 'http://' ) AND ! stristr( $file_location, 'https://' ) )
|
||||
{
|
||||
//-------------------------------
|
||||
// It's a path!
|
||||
//-------------------------------
|
||||
|
||||
if ( ! file_exists( $file_location ) )
|
||||
{
|
||||
$this->errors[] = "File '$file_location' does not exist, please check the path.";
|
||||
return;
|
||||
}
|
||||
|
||||
$contents = $this->get_contents_with_fopen( $file_location );
|
||||
}
|
||||
else
|
||||
{
|
||||
//-------------------------------
|
||||
// Is URL - using GET?
|
||||
//-------------------------------
|
||||
|
||||
if ( $this->use_sockets )
|
||||
{
|
||||
$contents = $this->get_contents_with_socket( $file_location );
|
||||
}
|
||||
else
|
||||
{
|
||||
$contents = $this->get_contents_with_fopen( $file_location );
|
||||
}
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// USE FOPEN TO GET TEXT
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get file contents (with PHP's fopen)
|
||||
*
|
||||
* @return string File data
|
||||
*/
|
||||
function get_contents_with_fopen( $file_location )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$buffer = "";
|
||||
|
||||
@clearstatcache();
|
||||
|
||||
if ( $FILE = fopen( $file_location, "r") )
|
||||
{
|
||||
while ( ! feof( $FILE ) )
|
||||
{
|
||||
$buffer .= fgets($FILE, 4096);
|
||||
}
|
||||
|
||||
fclose($FILE);
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// USE SOCKET TO GET TEXT
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get file contents (with sockets)
|
||||
*
|
||||
* @return string File data
|
||||
*/
|
||||
function get_contents_with_socket( $file_location )
|
||||
{
|
||||
//-------------------------------
|
||||
// INIT
|
||||
//-------------------------------
|
||||
|
||||
$data = null;
|
||||
$fsocket_timeout = 10;
|
||||
|
||||
//-------------------------------
|
||||
// Parse URL
|
||||
//-------------------------------
|
||||
|
||||
$url_parts = parse_url($file_location);
|
||||
|
||||
if ( ! $url_parts['host'] )
|
||||
{
|
||||
$this->errors[] = "No host found in the URL '$file_location'!";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Finalize
|
||||
//-------------------------------
|
||||
|
||||
$host = $url_parts['host'];
|
||||
$port = ( isset($url_parts['port']) ) ? $url_parts['port'] : ( $url_parts['scheme'] == 'https' ? 443 : 80 );
|
||||
|
||||
//-------------------------------
|
||||
// Tidy up path
|
||||
//-------------------------------
|
||||
|
||||
if ( !empty( $url_parts["path"] ) )
|
||||
{
|
||||
$path = $url_parts["path"];
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = "/";
|
||||
}
|
||||
|
||||
if ( !empty( $url_parts["query"] ) )
|
||||
{
|
||||
$path .= "?" . $url_parts["query"];
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Open connection
|
||||
//-------------------------------
|
||||
|
||||
if ( ! $fp = @fsockopen( $port == 443 ? "ssl://" . $host : $host, $port, $errno, $errstr, $fsocket_timeout ) )
|
||||
{
|
||||
$this->errors[] = "Could not establish a connection with $host";
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$final_carriage = "";
|
||||
|
||||
if ( ! $this->auth_req )
|
||||
{
|
||||
$final_carriage = "\r\n";
|
||||
}
|
||||
|
||||
if ( ! fputs( $fp, "GET $path HTTP/1.0\r\nHost:$host\r\nConnection: Keep-Alive\r\n{$final_carriage}" ) )
|
||||
{
|
||||
$this->errors[] = "Unable to send request to $host!";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( $this->auth_req )
|
||||
{
|
||||
if ( $this->auth_user && $this->auth_pass )
|
||||
{
|
||||
$header = "Authorization: Basic ".base64_encode("{$this->auth_user}:{$this->auth_pass}")."\r\n\r\n";
|
||||
|
||||
if ( ! fputs( $fp, $header ) )
|
||||
{
|
||||
$this->errors[] = "Authorization Failed!";
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@stream_set_timeout($fp, $fsocket_timeout);
|
||||
|
||||
$status = @socket_get_status($fp);
|
||||
|
||||
while( ! feof($fp) && ! $status['timed_out'] )
|
||||
{
|
||||
$data .= fgets ($fp,8192);
|
||||
$status = socket_get_status($fp);
|
||||
}
|
||||
|
||||
fclose ($fp);
|
||||
|
||||
//-------------------------------
|
||||
// Strip headers
|
||||
//-------------------------------
|
||||
|
||||
// HTTP/1.1 ### ABCD
|
||||
$this->http_status_code = substr( $data, 9, 3 );
|
||||
$this->http_status_text = substr( $data, 13, ( strpos( $data, "\r\n" ) - 13 ) );
|
||||
|
||||
$tmp = split("\r\n\r\n", $data, 2);
|
||||
$data = $tmp[1];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// USE cURL TO GET TEXT
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get file contents (with cURL)
|
||||
*
|
||||
* @return string File data
|
||||
*/
|
||||
function get_contents_with_curl( $file_location )
|
||||
{
|
||||
if ( function_exists( 'curl_init' ) AND function_exists("curl_exec") )
|
||||
{
|
||||
$ch = curl_init( $file_location );
|
||||
|
||||
curl_setopt( $ch, CURLOPT_HEADER , 0);
|
||||
curl_setopt( $ch, CURLOPT_TIMEOUT , 15 );
|
||||
curl_setopt( $ch, CURLOPT_POST , 0 );
|
||||
curl_setopt( $ch, CURLOPT_RETURNTRANSFER , 1 );
|
||||
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $data ? $data : FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// dir_copy_dir
|
||||
//
|
||||
// Copies to contents of a dir to a new dir, creating
|
||||
// destination dir if needed.
|
||||
//
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function dir_copy_dir($from_path, $to_path, $mode = 0777)
|
||||
{
|
||||
$this->errors = "";
|
||||
|
||||
//-----------------------------------------
|
||||
// Strip off trailing slashes...
|
||||
//-----------------------------------------
|
||||
|
||||
$from_path = preg_replace( "#/$#", "", $from_path);
|
||||
$to_path = preg_replace( "#/$#", "", $to_path);
|
||||
|
||||
if ( ! is_dir( $from_path ) )
|
||||
{
|
||||
$this->errors[] = "Could not locate directory '$from_path'";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! is_dir( $to_path ) )
|
||||
{
|
||||
if ( ! @mkdir( $to_path, $mode ) )
|
||||
{
|
||||
$this->errors[] = "Could not create directory '$to_path' please check the CHMOD permissions and re-try";
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@chmod( $to_path, $mode );
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_dir( $from_path ) )
|
||||
{
|
||||
$handle = opendir($from_path);
|
||||
|
||||
while ( ($file = readdir($handle)) !== false )
|
||||
{
|
||||
if ( ($file != ".") && ($file != "..") )
|
||||
{
|
||||
if ( is_dir( $from_path."/".$file ) )
|
||||
{
|
||||
$this->dir_copy_dir($from_path."/".$file, $to_path."/".$file);
|
||||
}
|
||||
|
||||
if ( is_file( $from_path."/".$file ) )
|
||||
{
|
||||
copy($from_path."/".$file, $to_path."/".$file);
|
||||
@chmod($to_path."/".$file, 0777);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
if ( ! count( $this->errors ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// dir_rm_dir
|
||||
//
|
||||
// Removes directories, if non empty, removes
|
||||
// content and directories
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function dir_rm_dir($file)
|
||||
{
|
||||
$errors = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Remove trailing slashes..
|
||||
//-----------------------------------------
|
||||
|
||||
$file = preg_replace( "#/$#", "", $file );
|
||||
|
||||
if ( file_exists($file) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Attempt CHMOD
|
||||
//-----------------------------------------
|
||||
|
||||
@chmod($file, 0777);
|
||||
|
||||
if ( is_dir($file) )
|
||||
{
|
||||
$handle = opendir($file);
|
||||
|
||||
while ( ($filename = readdir($handle)) !== false )
|
||||
{
|
||||
if ( ($filename != ".") && ($filename != "..") )
|
||||
{
|
||||
$this->dir_rm_dir($file."/".$filename);
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
|
||||
if ( ! @rmdir($file) )
|
||||
{
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! @unlink($file) )
|
||||
{
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,627 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
| Licence Info: http://www.invisionboard.com/?license
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2005-10-10 14:03:20 +0100 (Mon, 10 Oct 2005) $
|
||||
| > $Revision: 22 $
|
||||
| > $Author: matt $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > GD / IMAGE handling methods (KERNEL)
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: 2nd Feb. 2004
|
||||
|
|
||||
| > Module Version Number: 1.0.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Image Class
|
||||
*
|
||||
* This class contains all generic functions to
|
||||
* handle GD 1 & 2 thumbnail generation
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
* $image = new class_image();
|
||||
*
|
||||
* $image->in_type = 'file';
|
||||
* $image->out_type = 'file';
|
||||
* $image->in_file_dir = './uploads';
|
||||
* $image->in_file_name = 'somepicture.jpg';
|
||||
* $image->desired_width = 200;
|
||||
* $image->desired_height = 200;
|
||||
* $image->gd_version = 2;
|
||||
*
|
||||
* $return = $image->generate_thumbnail();
|
||||
*
|
||||
* print_r( $return );
|
||||
* // Prints
|
||||
* Array( thumb_width => int
|
||||
* thumb_height => int
|
||||
* thumb_location => string )
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Image Class
|
||||
*
|
||||
* Methods and functions for handling thumbnail generation
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_image
|
||||
{
|
||||
/**
|
||||
* Type of incoming data
|
||||
*
|
||||
* @var string Type
|
||||
*/
|
||||
var $in_type = 'file';
|
||||
|
||||
/**
|
||||
* Type of outgoing data
|
||||
*
|
||||
* @var string Type
|
||||
*/
|
||||
var $out_type = 'file';
|
||||
|
||||
/**
|
||||
* Save file as...
|
||||
*
|
||||
* @var string File name
|
||||
*/
|
||||
var $out_file_name = '';
|
||||
|
||||
/**
|
||||
* Save file in...
|
||||
*
|
||||
* @var string Directory
|
||||
*/
|
||||
var $out_file_dir = '';
|
||||
|
||||
/**
|
||||
* In file directory
|
||||
*
|
||||
* @var string Directory
|
||||
*/
|
||||
var $in_file_dir = '.';
|
||||
|
||||
/**
|
||||
* Name of input file name
|
||||
*
|
||||
* @var string File name
|
||||
*/
|
||||
var $in_file_name = '';
|
||||
|
||||
/**
|
||||
* Complete file name with path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $in_file_complete = '';
|
||||
|
||||
/**
|
||||
* Max. thumbnail width
|
||||
*
|
||||
* @var integer Pixels
|
||||
*/
|
||||
var $desired_width = 0;
|
||||
|
||||
/**
|
||||
* Max. thumbnail height
|
||||
*
|
||||
* @var integer Pixels
|
||||
*/
|
||||
var $desired_height = 0;
|
||||
|
||||
/**
|
||||
* GD version
|
||||
*
|
||||
* @var integer GD version
|
||||
*/
|
||||
var $gd_version = 2;
|
||||
|
||||
/**
|
||||
* Image type (PNG, JPG, GIF)
|
||||
*
|
||||
* @var string Image type
|
||||
*/
|
||||
var $image_type = '';
|
||||
|
||||
/**
|
||||
* File extension
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $file_extension = '';
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// CONSTRUCTOR
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_image()
|
||||
{
|
||||
//-----------------------------------
|
||||
// Full path?
|
||||
//-----------------------------------
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Clean paths
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Cleans up paths, generates var $in_file_complete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function clean_paths()
|
||||
{
|
||||
$this->in_file_dir = preg_replace( "#/$#", "", $this->in_file_dir );
|
||||
$this->out_file_dir = preg_replace( "#/$#", "", $this->out_file_dir );
|
||||
|
||||
if ( $this->in_file_dir and $this->in_file_name )
|
||||
{
|
||||
$this->in_file_complete = $this->in_file_dir.'/'.$this->in_file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->in_file_complete = $this->in_file_name;
|
||||
}
|
||||
|
||||
if ( ! $this->out_file_dir )
|
||||
{
|
||||
$this->out_file_dir = $this->in_file_dir;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// GENERATE THUMBNAIL
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Generates thumnbail
|
||||
*
|
||||
* @return array [ thumb_width, thumb_height, thumb_location ]
|
||||
*/
|
||||
function generate_thumbnail()
|
||||
{
|
||||
$return = array();
|
||||
$image = "";
|
||||
$thumb = "";
|
||||
|
||||
//-----------------------------------
|
||||
// Set up paths
|
||||
//-----------------------------------
|
||||
|
||||
$this->clean_paths();
|
||||
|
||||
$remap = array( 1 => 'GIF', 2 => 'JPG', 3 => 'PNG', 4 => 'SWF', 5 => 'PSD', 6 => 'BMP' );
|
||||
|
||||
if ( $this->desired_width and $this->desired_height )
|
||||
{
|
||||
//----------------------------------------------------
|
||||
// Tom Thumb!
|
||||
//----------------------------------------------------
|
||||
|
||||
$img_size = array();
|
||||
|
||||
if ( $this->in_type == 'file' )
|
||||
{
|
||||
$img_size = @GetImageSize( $this->in_file_complete );
|
||||
}
|
||||
|
||||
if ( $img_size[0] < 1 and $img_size[1] < 1 )
|
||||
{
|
||||
$img_size = array();
|
||||
$img_size[0] = $this->desired_width;
|
||||
$img_size[1] = $this->desired_height;
|
||||
|
||||
$return['thumb_width'] = $this->desired_width;
|
||||
$return['thumb_height'] = $this->desired_height;
|
||||
|
||||
if ( $this->out_type == 'file' )
|
||||
{
|
||||
$return['thumb_location'] = $this->in_file_name;
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//----------------------------------------------------
|
||||
// Show image
|
||||
//----------------------------------------------------
|
||||
|
||||
$this->show_non_gd();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
// Do we need to scale?
|
||||
//----------------------------------------------------
|
||||
|
||||
if ( ( $img_size[0] > $this->desired_width ) OR ( $img_size[1] > $this->desired_height ) )
|
||||
{
|
||||
|
||||
$im = $this->scale_image( array(
|
||||
'max_width' => $this->desired_width,
|
||||
'max_height' => $this->desired_height,
|
||||
'cur_width' => $img_size[0],
|
||||
'cur_height' => $img_size[1]
|
||||
) );
|
||||
|
||||
$return['thumb_width'] = $im['img_width'];
|
||||
$return['thumb_height'] = $im['img_height'];
|
||||
$return['original_width'] = $img_size[0];
|
||||
$return['original_height'] = $img_size[1];
|
||||
|
||||
//-----------------------------------------------
|
||||
// May as well scale properly.
|
||||
//-----------------------------------------------
|
||||
|
||||
if ( $im['img_width'] )
|
||||
{
|
||||
$this->desired_width = $im['img_width'];
|
||||
}
|
||||
|
||||
if ( $im['img_height'] )
|
||||
{
|
||||
$this->desired_height = $im['img_height'];
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
// GD functions available?
|
||||
//-----------------------------------------------
|
||||
|
||||
if ( $remap[ $img_size[2] ] == 'GIF' )
|
||||
{
|
||||
if ( function_exists( 'imagecreatefromgif') )
|
||||
{
|
||||
if ( $image = @imagecreatefromgif( $this->in_file_complete ) )
|
||||
{
|
||||
$this->image_type = 'gif';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this->out_type == 'file' )
|
||||
{
|
||||
$return['thumb_width'] = $this->desired_width;
|
||||
$return['thumb_height'] = $this->desired_height;
|
||||
$return['thumb_location'] = $this->in_file_name;
|
||||
$return['original_width'] = $img_size[0];
|
||||
$return['original_height'] = $img_size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------------
|
||||
// Show Image..
|
||||
//-----------------------------------------------
|
||||
|
||||
$this->show_non_gd();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( $remap[ $img_size[2] ] == 'PNG' )
|
||||
{
|
||||
if ( function_exists( 'imagecreatefrompng') )
|
||||
{
|
||||
if ( $image = @imagecreatefrompng( $this->in_file_complete ) )
|
||||
{
|
||||
$this->image_type = 'png';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this->out_type == 'file' )
|
||||
{
|
||||
$return['thumb_width'] = $this->desired_width;
|
||||
$return['thumb_height'] = $this->desired_height;
|
||||
$return['thumb_location'] = $this->in_file_name;
|
||||
$return['original_width'] = $img_size[0];
|
||||
$return['original_height'] = $img_size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------------
|
||||
// Show Image..
|
||||
//-----------------------------------------------
|
||||
|
||||
$this->show_non_gd();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( $remap[ $img_size[2] ] == 'JPG' )
|
||||
{
|
||||
if ( function_exists( 'imagecreatefromjpeg') )
|
||||
{
|
||||
if ( $image = @imagecreatefromjpeg( $this->in_file_complete ) )
|
||||
{
|
||||
$this->image_type = 'jpg';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this->out_type == 'file' )
|
||||
{
|
||||
$return['thumb_width'] = $this->desired_width;
|
||||
$return['thumb_height'] = $this->desired_height;
|
||||
$return['thumb_location'] = $this->in_file_name;
|
||||
$return['original_width'] = $img_size[0];
|
||||
$return['original_height'] = $img_size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------------
|
||||
// Show Image..
|
||||
//-----------------------------------------------
|
||||
|
||||
$this->show_non_gd();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
// Did we get a return from imagecreatefrom?
|
||||
//----------------------------------------------------
|
||||
|
||||
if ( $image )
|
||||
{
|
||||
if ( $this->gd_version == 1 )
|
||||
{
|
||||
$thumb = @imagecreate( $im['img_width'], $im['img_height'] );
|
||||
@imagecopyresized( $thumb, $image, 0, 0, 0, 0, $im['img_width'], $im['img_height'], $img_size[0], $img_size[1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$thumb = @imagecreatetruecolor( $im['img_width'], $im['img_height'] );
|
||||
|
||||
if( $this->image_type == 'png' OR $this->image_type == 'gif' )
|
||||
{
|
||||
@imagealphablending( $thumb, FALSE );
|
||||
@imagesavealpha( $thumb, TRUE );
|
||||
|
||||
$transparent = @imagecolorallocatealpha($thumb, 255, 255, 255, 127);
|
||||
@imagefilledrectangle($thumb, 0, 0, $im['img_width'], $im['img_height'], $transparent);
|
||||
}
|
||||
|
||||
@imagecopyresampled($thumb, $image, 0, 0, 0, 0, $im['img_width'], $im['img_height'], $img_size[0], $img_size[1] );
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
// Saving?
|
||||
//-----------------------------------------------
|
||||
|
||||
if ( $this->out_type == 'file' )
|
||||
{
|
||||
if ( ! $this->out_file_name )
|
||||
{
|
||||
//-----------------------------------------------
|
||||
// Remove file extension...
|
||||
//-----------------------------------------------
|
||||
|
||||
$this->out_file_name = preg_replace( "/^(.*)\..+?$/", "\\1", $this->in_file_name ) . '_thumb';
|
||||
}
|
||||
|
||||
if ( function_exists( 'imagepng' ) AND ($this->image_type == 'png' OR $this->image_type == 'gif') )
|
||||
{
|
||||
$this->file_extension = 'png';
|
||||
@imagepng( $thumb, $this->out_file_dir."/".$this->out_file_name.'.png' );
|
||||
@chmod( $this->out_file_dir."/".$this->out_file_name.'.png', 0777 );
|
||||
@imagedestroy( $thumb );
|
||||
@imagedestroy( $image );
|
||||
$return['thumb_location'] = $this->out_file_name.'.png';
|
||||
return $return;
|
||||
}
|
||||
else if ( function_exists( 'imagejpeg' ) )
|
||||
{
|
||||
$this->file_extension = 'jpg';
|
||||
@imagejpeg( $thumb, $this->out_file_dir."/".$this->out_file_name.'.jpg' );
|
||||
@chmod( $this->out_file_dir."/".$this->out_file_name.'.jpg', 0777 );
|
||||
@imagedestroy( $thumb );
|
||||
@imagedestroy( $image );
|
||||
$return['thumb_location'] = $this->out_file_name.'.jpg';
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--------------------------------------
|
||||
// Can't save...
|
||||
//--------------------------------------
|
||||
|
||||
$return['thumb_width'] = $this->desired_width;
|
||||
$return['thumb_height'] = $this->desired_height;
|
||||
$return['thumb_location'] = $this->in_file_name;
|
||||
$return['original_width'] = $img_size[0];
|
||||
$return['original_height'] = $img_size[1];
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------------
|
||||
// Show image
|
||||
//-----------------------------------------------
|
||||
|
||||
$this->show_image( $thumb, $this->image_type );
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//----------------------------------------------------
|
||||
// Could not GD, return..
|
||||
//----------------------------------------------------
|
||||
|
||||
if ( $this->out_type == 'file' )
|
||||
{
|
||||
$return['thumb_width'] = $this->desired_width;
|
||||
$return['thumb_height'] = $this->desired_height;
|
||||
$return['thumb_location'] = $this->in_file_name;
|
||||
$return['original_width'] = $img_size[0];
|
||||
$return['original_height'] = $img_size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------------
|
||||
// Show Image..
|
||||
//-----------------------------------------------
|
||||
|
||||
$this->show_non_gd();
|
||||
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
// No need to scale..
|
||||
//----------------------------------------------------
|
||||
else
|
||||
{
|
||||
if ( $this->out_type == 'file' )
|
||||
{
|
||||
//$return['thumb_location'] = $this->in_file_name;
|
||||
$return['thumb_width'] = $img_size[0];
|
||||
$return['thumb_height'] = $img_size[1];
|
||||
$return['original_width'] = $img_size[0];
|
||||
$return['original_height'] = $img_size[1];
|
||||
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------------
|
||||
// Show Image..
|
||||
//-----------------------------------------------
|
||||
|
||||
$this->show_non_gd();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Show GD image
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Show GD image
|
||||
*
|
||||
* @param string Thumbnail data
|
||||
* @param string Thumbnail type (gif, png, jpg)
|
||||
* @return void
|
||||
*/
|
||||
function show_image( $thumb, $type )
|
||||
{
|
||||
flush();
|
||||
|
||||
if ( $type == 'gif' )
|
||||
{
|
||||
@header('Content-type: image/gif');
|
||||
}
|
||||
else if ( $type == 'png' )
|
||||
{
|
||||
@header('Content-Type: image/png' );
|
||||
}
|
||||
else
|
||||
{
|
||||
@header('Content-Type: image/jpeg' );
|
||||
}
|
||||
|
||||
print $thumb;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Show non GD image
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Show a NON GD image
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function show_non_gd()
|
||||
{
|
||||
$file_extension = preg_replace( ".*\.(\w+)$", "\\1", $this->in_file_name );
|
||||
$file_extension = strtolower( $file_extension );
|
||||
$file_extension = $file_extension == 'jpeg' ? 'jpg' : $file_extension;
|
||||
|
||||
if ( strstr( ' gif jpg png ', ' '.$file_extension.' ' ) )
|
||||
{
|
||||
if ( $data = @file_get_contents( $this->in_file_complete ) )
|
||||
{
|
||||
$this->show_image( $data, $file_extension );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return scaled down image
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Scale an image
|
||||
*
|
||||
* @param array [ cur_height, cur_width, max_width, max_height ]
|
||||
* @return array [ img_height, img_width ]
|
||||
*/
|
||||
function scale_image($arg)
|
||||
{
|
||||
// max_width, max_height, cur_width, cur_height
|
||||
|
||||
$ret = array(
|
||||
'img_width' => $arg['cur_width'],
|
||||
'img_height' => $arg['cur_height']
|
||||
);
|
||||
|
||||
if ( $arg['cur_width'] > $arg['max_width'] )
|
||||
{
|
||||
$ret['img_width'] = $arg['max_width'];
|
||||
$ret['img_height'] = ceil( ( $arg['cur_height'] * ( ( $arg['max_width'] * 100 ) / $arg['cur_width'] ) ) / 100 );
|
||||
$arg['cur_height'] = $ret['img_height'];
|
||||
$arg['cur_width'] = $ret['img_width'];
|
||||
}
|
||||
|
||||
if ( $arg['cur_height'] > $arg['max_height'] )
|
||||
{
|
||||
$ret['img_height'] = $arg['max_height'];
|
||||
$ret['img_width'] = ceil( ( $arg['cur_width'] * ( ( $arg['max_height'] * 100 ) / $arg['cur_height'] ) ) / 100 );
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,396 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [Application Profiling]
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Application Profiling
|
||||
| > Module written by Brandon Farber
|
||||
| > Date started: Monday 28th February 2005 16:46
|
||||
|
|
||||
| > Module Version Number: 1.0.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Application Profiling Layer [PHP5]
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage ApplicationProfiling
|
||||
* @author Brandon Farber
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gateway for application profiling
|
||||
*
|
||||
* $a = new class_profiling();
|
||||
* $a->output_results( true, false );
|
||||
*/
|
||||
|
||||
//-----------------------------------------
|
||||
// Define KERNEL_PATH if not
|
||||
// defined - i.e. installation
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! defined('KERNEL_PATH') )
|
||||
{
|
||||
if( defined('INS_KERNEL_PATH') )
|
||||
{
|
||||
define( 'KERNEL_PATH', INS_KERNEL_PATH );
|
||||
}
|
||||
else
|
||||
{
|
||||
define( 'KERNEL_PATH', str_replace( "//", "/", str_replace( "\\", "/", dirname( __FILE__ ) ) ) . "/" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Define ROOT_PATH if not
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! defined('ROOT_PATH') )
|
||||
{
|
||||
$path = str_replace( "//", "/", str_replace( "\\", "/", dirname( __FILE__ ) ) );
|
||||
$path_bits = explode( "/", $path );
|
||||
array_pop( $path_bits );
|
||||
|
||||
define( 'ROOT_PATH', implode( "/", $path_bits ) . "/" );
|
||||
}
|
||||
|
||||
|
||||
class class_profiling
|
||||
{
|
||||
var $start_time = array();
|
||||
var $end_time = array();
|
||||
var $running_time = array();
|
||||
|
||||
var $start_memory = array();
|
||||
var $end_memory = array();
|
||||
|
||||
var $descriptions = array();
|
||||
|
||||
var $timer_stack = array();
|
||||
var $internal_count = array();
|
||||
var $stack_trace = null;
|
||||
|
||||
var $cur_timer = null;
|
||||
var $init_time = 0;
|
||||
|
||||
var $init_memory = 0;
|
||||
var $total_memory = 0;
|
||||
var $peak_memory = 0;
|
||||
|
||||
|
||||
function __construct( $start_apd = false )
|
||||
{
|
||||
$this->start_time = array();
|
||||
$this->end_time = array();
|
||||
$this->running_time = array();
|
||||
|
||||
$this->start_memory = array();
|
||||
$this->end_memory = array();
|
||||
|
||||
$this->descriptions = array();
|
||||
|
||||
$this->timer_stack = array();
|
||||
$this->internal_count = array();
|
||||
$this->stack_trace = "Profiling Class Initialized\n";
|
||||
|
||||
$this->cur_timer = null;
|
||||
$this->init_time = $this->get_micro_seconds();
|
||||
|
||||
$this->init_memory = $this->get_current_memory();
|
||||
$this->total_memory = $this->init_memory;
|
||||
$this->peak_memory = $this->init_memory;
|
||||
|
||||
if( $start_apd == true && function_exists( 'apd_set_pprof_trace' ) )
|
||||
{
|
||||
apd_set_pprof_trace();
|
||||
}
|
||||
|
||||
$this->start_session( 'Overall' );
|
||||
}
|
||||
|
||||
|
||||
function start_session( $name, $desc='' )
|
||||
{
|
||||
$x = array_push( $this->timer_stack, $this->cur_timer );
|
||||
|
||||
if( isset($this->timer_stack[ $x - 1 ]) )
|
||||
{
|
||||
$this->_suspend_timer( $this->timer_stack[ $x - 1 ] );
|
||||
}
|
||||
|
||||
$this->start_time[ $name ] = $this->get_micro_seconds();
|
||||
$this->start_memory[ $name ] = $this->get_current_memory();
|
||||
|
||||
$this->cur_timer = $name;
|
||||
|
||||
$this->descriptions[ $name ] = $desc;
|
||||
|
||||
if( array_key_exists( $name, $this->internal_count ) )
|
||||
{
|
||||
$this->internal_count[ $name ]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->internal_count[ $name ] = 1;
|
||||
}
|
||||
|
||||
$this->stack_trace .= "Started Session '{$name}'\n";
|
||||
|
||||
$backtrace = debug_backtrace();
|
||||
|
||||
if( is_array($backtrace) AND count($backtrace) )
|
||||
{
|
||||
$cnt = 0;
|
||||
|
||||
foreach( array_reverse( $backtrace ) as $trace )
|
||||
{
|
||||
$cnt++;
|
||||
|
||||
$this->stack_trace .= "\t{$cnt}. Function '{$trace['function']}' in {$trace['file']} (line {$trace['line']})\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function stop_session( $name )
|
||||
{
|
||||
$this->end_time[ $name ] = $this->get_micro_seconds();
|
||||
$this->end_memory[ $name ] = $this->get_current_memory();
|
||||
|
||||
if( !array_key_exists( $name, $this->running_time ) )
|
||||
{
|
||||
$this->running_time[ $name ] = $this->get_elapsed_time( $name );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->running_time[ $name ] += $this->get_elapsed_time( $name );
|
||||
}
|
||||
|
||||
$this->cur_timer = array_pop( $this->timer_stack );
|
||||
|
||||
$this->stack_trace .= "Stopped Session '{$name}'\n";
|
||||
|
||||
if( isset($this->cur_timer) )
|
||||
{
|
||||
$this->_resume_timer( $this->cur_timer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function get_elapsed_time( $name )
|
||||
{
|
||||
if( !array_key_exists( $name, $this->start_time ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( array_key_exists( $name, $this->end_time ) )
|
||||
{
|
||||
return ( $this->end_time[ $name ] - $this->start_time[ $name ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( $this->get_micro_seconds() - $this->start_time[ $name ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_total_time()
|
||||
{
|
||||
return ( $this->get_micro_seconds() - $this->init_time );
|
||||
}
|
||||
|
||||
|
||||
function get_peak_memory()
|
||||
{
|
||||
if( function_exists( 'memory_get_peak_usage' ) )
|
||||
{
|
||||
$this->peak_memory = memory_get_peak_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( count( $this->start_memory ) )
|
||||
{
|
||||
foreach( $this->start_memory as $mem_entry )
|
||||
{
|
||||
if( $mem_entry > $this->peak_memory )
|
||||
{
|
||||
$this->peak_memory = $mem_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( count( $this->end_memory ) )
|
||||
{
|
||||
foreach( $this->end_memory as $mem_entry )
|
||||
{
|
||||
if( $mem_entry > $this->peak_memory )
|
||||
{
|
||||
$this->peak_memory = $mem_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->peak_memory;
|
||||
}
|
||||
|
||||
|
||||
function _resume_timer( $name )
|
||||
{
|
||||
$this->stack_trace .= "Resumed Session '{$name}'\n";
|
||||
|
||||
$this->start_time[ $name ] = $this->get_micro_seconds();
|
||||
}
|
||||
|
||||
|
||||
function _suspend_timer( $name )
|
||||
{
|
||||
$this->stack_trace .= "Suspended Session '{$name}'\n";
|
||||
|
||||
$this->end_time[ $name ] = $this->get_micro_seconds();
|
||||
|
||||
if( !array_key_exists( $name, $this->running_time ) )
|
||||
{
|
||||
$this->running_time[ $name ] = $this->get_elapsed_time( $name );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->running_time[ $name ] += $this->get_elapsed_time( $name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function get_micro_seconds()
|
||||
{
|
||||
$tmp = explode( " ", microtime() );
|
||||
|
||||
return ( $tmp[0] + $tmp[1] );
|
||||
}
|
||||
|
||||
|
||||
function get_current_memory()
|
||||
{
|
||||
if( ! function_exists( 'memory_get_usage' ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return memory_get_usage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function format_memory( $val=0 )
|
||||
{
|
||||
if( $val >= 1048576 )
|
||||
{
|
||||
return ( round( ( $val / 1048576 * 100 ), 2 ) / 100 ) . 'MB';
|
||||
}
|
||||
else if( $val >= 1024 )
|
||||
{
|
||||
return ( round( ( $val / 1024 * 100 ), 2 ) / 100 ) . 'KB';
|
||||
}
|
||||
else
|
||||
{
|
||||
return intval( $val ) . 'b';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function output_results( $display_backtrace=true, $log=false )
|
||||
{
|
||||
$this->stop_session( 'Overall' );
|
||||
$this->total_memory = $this->get_current_memory();
|
||||
|
||||
$timed_total = 0;
|
||||
$percent_total = 0;
|
||||
$output = null;
|
||||
|
||||
$overall_time = $this->get_total_time();
|
||||
$overall_memory = $this->get_peak_memory();
|
||||
|
||||
if( $log == false )
|
||||
{
|
||||
print "<pre>\n";
|
||||
}
|
||||
|
||||
ksort($this->descriptions);
|
||||
|
||||
$output = "============================================================================\n";
|
||||
$output .= " PROFILER OUTPUT\n";
|
||||
$output .= "============================================================================\n";
|
||||
$output .= "Calls Time Memory Routine\n";
|
||||
$output .= "----------------------------------------------------------------------------\n";
|
||||
|
||||
foreach( $this->descriptions as $key => $val )
|
||||
{
|
||||
$this_total = $this->running_time[$key];
|
||||
$this_count = $this->internal_count[$key];
|
||||
$this_percent = ( $this_total / $overall_time ) * 100;
|
||||
$this_memory = $this->format_memory( $this->end_memory[ $key ] - $this->start_memory[ $key ] );
|
||||
|
||||
$timed_total += $this_total;
|
||||
$percent_total += $this_percent;
|
||||
$mem_total += $this->end_memory[ $key ] - $this->start_memory[ $key ];
|
||||
|
||||
$output .= sprintf( "%3d %3.4f ms (%3.2f %%) %s %s\n", $this_count, $this_total * 1000, $this_percent, $this_memory, $key);
|
||||
}
|
||||
|
||||
$output .= "\n";
|
||||
|
||||
$missed_time = $overall_time - $timed_total;
|
||||
$missed_percent = ( $missed_time / $overall_time ) * 100;
|
||||
$percent_total += $missed_percent;
|
||||
$missed_memory = $this->format_memory( $this->total_memory - $this->init_memory - $mem_total );
|
||||
|
||||
$output .= sprintf( " %3.4f ms (%3.2f %%) %s %s\n", $missed_time * 1000, $missed_percent, $missed_memory, 'Leaked' );
|
||||
|
||||
$output .= "============================================================================\n";
|
||||
$output .= "Start Memory: " . $this->format_memory( $this->init_memory ) . "\n";
|
||||
$output .= "Total Memory: " . $this->format_memory( $this->total_memory ) . "\n";
|
||||
$output .= "Peak Memory: " . $this->format_memory( $this->peak_memory ) . "\n";
|
||||
$output .= "============================================================================\n";
|
||||
|
||||
$output .= sprintf( " %3.4f ms (%3.2f %%) %s %s\n", $timed_total * 1000, $pecent_total, $this->format_memory( $this->total_memory ), 'OVERALL TIME' );
|
||||
|
||||
$output .= "============================================================================\n";
|
||||
|
||||
if( $display_backtrace == true )
|
||||
{
|
||||
$output .= "Backtrace\n";
|
||||
$output .= $this->stack_trace;
|
||||
}
|
||||
|
||||
if( $log == false )
|
||||
{
|
||||
print $output . '</pre>';
|
||||
}
|
||||
else
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,636 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
| Licence Info: http://www.invisionboard.com/?license
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2005-10-10 14:03:20 +0100 (Mon, 10 Oct 2005) $
|
||||
| > $Revision: 22 $
|
||||
| > $Author: matt $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > Template Engine module (KERNEL)
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: 5th January 2004
|
||||
|
|
||||
| > Module Version Number: 1.0.0
|
||||
+--------------------------------------------------------------------------
|
||||
| New template module to build, rebuild and generate caches of templates
|
||||
| which include the new IPB HTML Logic system.
|
||||
|
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: Template Engine
|
||||
*
|
||||
* This class contains all generic functions to handle
|
||||
* converting HTML logic to PHP code and vice-versa
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
* <if="$bf.vars['threaded_per_page'] == 10">
|
||||
* html here
|
||||
* </if>
|
||||
* <else if="ibf.vars['threaded_per_page'] >= 100 or some_var == 'this'">
|
||||
* html here
|
||||
* </if>
|
||||
* <else if="show['this'] > 100">
|
||||
* html here
|
||||
* </if>
|
||||
* <else>
|
||||
* html here
|
||||
* </else>
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Template Engine
|
||||
*
|
||||
* Methods and functions for handling file uploads
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_template
|
||||
{
|
||||
/**
|
||||
* Root path
|
||||
*
|
||||
* @var string File Path
|
||||
*/
|
||||
var $root_path = './';
|
||||
|
||||
/**
|
||||
* Cache directory
|
||||
*
|
||||
* @var string Directory
|
||||
*/
|
||||
var $cache_dir = 'skin_cache';
|
||||
|
||||
/**
|
||||
* Cache ID
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $cache_id = '1';
|
||||
|
||||
/**
|
||||
* Database ID
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $database_id = '1';
|
||||
|
||||
/**
|
||||
* Cache path
|
||||
*
|
||||
* @var string File Path
|
||||
*/
|
||||
var $cache_path = '';
|
||||
|
||||
function class_template()
|
||||
{
|
||||
$this->cache_path = $this->root_path . $this->cache_dir . '/cacheid_' . $this->cache_id;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Convert HTML to PHP cache file
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Wrapper function to convert HTML logic to PHP code
|
||||
*
|
||||
* @param string Function name (eg: show_active_users)
|
||||
* @param string Function data (The input variables)
|
||||
* @param string Function HTML (The actual HTML)
|
||||
* @param string Function description (Not used in IPB)
|
||||
* @return string Converted HTML code as a PHP function
|
||||
*/
|
||||
|
||||
function convert_html_to_php($func_name, $func_data, $func_html, $func_desc="")
|
||||
{
|
||||
//-------------------------------
|
||||
// Make sure we have ="" on each
|
||||
// func data
|
||||
//-------------------------------
|
||||
|
||||
$func_data = preg_replace( "#".'\$'."(\w+)(,|$)#i", "\$\\1=\"\"\\2", str_replace( " ", "", $func_data ) );
|
||||
|
||||
$top = "//===========================================================================\n".
|
||||
"// <ips:{$func_name}:desc:{$func_desc}>\n".
|
||||
"//===========================================================================\n";
|
||||
|
||||
$start = "function {$func_name}($func_data) {\n\$IPBHTML = \"\";\n//--starthtml--//\n";
|
||||
$middle = $this->build_section_html_to_php($func_html);
|
||||
$end = "\n//--endhtml--//\nreturn \$IPBHTML;\n}\n";
|
||||
|
||||
return $top.$start.$middle.$end;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Alias: Convert PHP to HTML
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Wrapper function to convert PHP to HTML logic
|
||||
*
|
||||
* @param string PHP Code
|
||||
* @return string Converted PHP code as HTML code
|
||||
*/
|
||||
function convert_php_to_html($php)
|
||||
{
|
||||
return $this->_convert_php_to_html($php);
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Build Section: PHP to HTML
|
||||
// - Updates HTML database with PHP cache file
|
||||
//===================================================
|
||||
|
||||
function build_section_php_to_html($php="")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Build Section: HTML to PHP
|
||||
// - Makes PHP cache of raw HTML
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Work function to convert HTML logic to PHP code
|
||||
*
|
||||
* @param string HTML logic
|
||||
* @return string PHP code block
|
||||
*/
|
||||
function build_section_html_to_php($html="")
|
||||
{
|
||||
|
||||
if ( preg_match( "#<if=[\"'].+?[\"']>#si", $html ) )
|
||||
{
|
||||
//----------------------------------------
|
||||
// Does it have logic sections?
|
||||
//----------------------------------------
|
||||
|
||||
$html = $this->_convert_html_to_php($html);
|
||||
|
||||
//----------------------------------------
|
||||
// Non-logic from top?
|
||||
//----------------------------------------
|
||||
|
||||
$html = preg_replace( "#^(.+?)(//startif)#ise", "\$this->_wrap_in_php('\\1', '\\2');", $html );
|
||||
|
||||
//----------------------------------------
|
||||
// Non-logic from between?
|
||||
//----------------------------------------
|
||||
|
||||
$html = preg_replace( "#(}//endif|}//endelse)(.+?)(//startif|//startelse|else if)#ise", "\$this->_wrap_in_php('\\2', '\\3', '\\1');", $html );
|
||||
|
||||
//$html = str_replace( "}//endif//startif", "}//endif\n//startif", $html );
|
||||
|
||||
//----------------------------------------
|
||||
// Non-logic from after? ENDELSE
|
||||
//----------------------------------------
|
||||
|
||||
if ( preg_match( "#^(.*)(}//endelse)(.+?)$#is", $html, $match ) )
|
||||
{
|
||||
if ( $match[1] and $match[2] and ( ! strstr( $match[3], "<<<EOF\n" ) ) )
|
||||
{
|
||||
$html = preg_replace( "#^(.*}//endelse)(.+?)$#ise", "\$this->_wrap_in_php('\\2', '', '\\1');", $html );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Non-logic from after? ENDIF
|
||||
//----------------------------------------
|
||||
|
||||
if ( preg_match( "#^(.*)(}//endif)(.+?)$#is", $html, $match ) )
|
||||
{
|
||||
if ( $match[1] and $match[2] and ( ! strstr( $match[3], "<<<EOF\n" ) ) )
|
||||
{
|
||||
$html = preg_replace( "#^(.*}//endif)(.+?)$#ise", "\$this->_wrap_in_php('\\2', '', '\\1');", $html );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Clean up
|
||||
//----------------------------------------
|
||||
|
||||
$html = preg_replace( "#//startelse\s+?//startelse#is", "//startelse", $html );
|
||||
}
|
||||
else
|
||||
{
|
||||
$html = $this->_wrap_in_php( $html );
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Unconvert special tags
|
||||
//----------------------------------------
|
||||
|
||||
$html = $this->unconvert_tags($html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Convert special tags into HTML safe versions
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Convert PHP tags to HTML logic safe tags
|
||||
*
|
||||
* @param string HTML/PHP data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function convert_tags($t="")
|
||||
{
|
||||
$t = preg_replace( "/{?\\\$ibforums->base_url}?/" , "{ipb.script_url}" , $t );
|
||||
$t = preg_replace( "/{?\\\$ibforums->session_id}?/" , "{ipb.session_id}" , $t );
|
||||
$t = preg_replace( "#\\\$ibforums->(member|vars|skin|lang|input)#i" , "ipb.\\1" , $t );
|
||||
|
||||
# IPB 2.1+ Kernel
|
||||
$t = preg_replace( "/{?\\\$this->ipsclass->base_url}?/" , "{ipb.script_url}" , $t );
|
||||
$t = preg_replace( "/{?\\\$this->ipsclass->session_id}?/" , "{ipb.session_id}" , $t );
|
||||
$t = preg_replace( "#\\\$this->ipsclass->(member|vars|skin|lang|input)#i" , "ipb.\\1", $t );
|
||||
|
||||
//----------------------------------------
|
||||
// Make some tags safe..
|
||||
//----------------------------------------
|
||||
|
||||
$t = preg_replace( "/\{ipb\.vars\[(['\"])?(sql_driver|sql_host|sql_database|sql_pass|sql_user|sql_port|sql_tbl_prefix|smtp_host|smtp_port|smtp_user|smtp_pass|html_dir|base_dir|upload_dir)(['\"])?\]\}/", "" , $t );
|
||||
|
||||
return $t;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Uncovert them back again
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Convert HTML tags to PHP tags
|
||||
*
|
||||
* @param string HTML/PHP data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function unconvert_tags($t="")
|
||||
{
|
||||
//----------------------------------------
|
||||
// Make some tags safe..
|
||||
//----------------------------------------
|
||||
|
||||
$t = preg_replace( "/\{ipb\.vars\[(['\"])?(sql_driver|sql_host|sql_database|sql_pass|sql_user|sql_port|sql_tbl_prefix|smtp_host|smtp_port|smtp_user|smtp_pass|html_dir|base_dir|upload_dir)(['\"])?\]\}/", "" , $t );
|
||||
|
||||
# IPB 2.1+ Kernel
|
||||
$t = preg_replace( "/{ipb\.script_url}/i" , '{$this->ipsclass->base_url}' , $t);
|
||||
$t = preg_replace( "/{ipb\.session_id}/i" , '{$this->ipsclass->session_id}', $t);
|
||||
$t = preg_replace( "#ipb\.(member|vars|skin|lang|input)#i", '$this->ipsclass->\\1' , $t );
|
||||
|
||||
return $t;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Wrap HTML into PHP
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Wrap PHP code in HEREDOC tags
|
||||
*
|
||||
* @param string Main HTML code
|
||||
* @param string After Code
|
||||
* @param string Before Code
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _wrap_in_php( $html, $after="", $before="" )
|
||||
{
|
||||
$html = $this->_trim_newlines($this->_trim_slashes($html));
|
||||
|
||||
$before = $this->_trim_slashes($before);
|
||||
$after = $this->_trim_slashes($after);
|
||||
|
||||
if ( ! strstr( $before, "\n" ) )
|
||||
{
|
||||
$before .= "\n";
|
||||
}
|
||||
|
||||
if ( ! trim($html) )
|
||||
{
|
||||
return $before.$html.$after;
|
||||
}
|
||||
|
||||
return $before."\n\$IPBHTML .= <<<EOF\n$html\nEOF;\n".$after;
|
||||
}
|
||||
|
||||
|
||||
//===================================================
|
||||
// Convert: HTML Logic to PHP logic
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Convert HTML tags to PHP tags
|
||||
*
|
||||
* @param string HTML/PHP data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _convert_html_to_php($html)
|
||||
{
|
||||
$html = $this->_trim_slashes($html);
|
||||
$html = preg_replace( "#(?:\s+?)?<if=[\"'](.+?)[\"']>(.+?)</if>#ise" , "\$this->_statement_if('\\1', '\\2')" , $html );
|
||||
$html = preg_replace( "#(?:\s+?)?<else if=[\"'](.+?)[\"']>(.+?)</if>#ise", "\$this->_statement_elseif('\\1', '\\2')", $html );
|
||||
$html = preg_replace( "#(?:\s+?)?<else>(.+?)</else>#ise" , "\$this->_statement_else('\\1')" , $html );
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Convert: PHP logic to HTML logic
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Convert PHP tags to HTML tags
|
||||
*
|
||||
* @param string PHP data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _convert_php_to_html($php)
|
||||
{
|
||||
$php = preg_replace( "#else if\s+?\((.+?)\)\s+?{(.+?)}//endif(\n)?#ise" , "\$this->_reverse_if('\\1', '\\2', 'else if')", $php );
|
||||
$php = preg_replace( "#//startif\nif\s+?\((.+?)\)\s+?{(.+?)}//endif(\n)?#ise", "\$this->_reverse_if('\\1', '\\2', 'if')" , $php );
|
||||
$php = preg_replace( "#else\s+?{(.+?)}//endelse(\n)?#ise" , "\$this->_reverse_else( '\\1' )" , $php );
|
||||
|
||||
//----------------------------------------
|
||||
// Parse raw sections
|
||||
//----------------------------------------
|
||||
|
||||
$php = $this->_reverse_ipbhtml($php);
|
||||
|
||||
//----------------------------------------
|
||||
// Convert ipb-htmllogic tags
|
||||
//----------------------------------------
|
||||
|
||||
//$php = preg_replace( "#//start-htmllogic#i" , "<ipb-htmllogic>", $php );
|
||||
//$php = preg_replace( "#//end-htmllogic#i", "</ipb-htmllogic>" , $php );
|
||||
|
||||
//----------------------------------------
|
||||
// Remove start ifs
|
||||
//----------------------------------------
|
||||
|
||||
$php = str_replace( "//startif\n" , "\n", $php );
|
||||
$php = str_replace( "//startelse\n", "\n", $php );
|
||||
|
||||
//----------------------------------------
|
||||
// Remove extra spaces
|
||||
//----------------------------------------
|
||||
|
||||
$php = preg_replace( "#(</if>|</else>)\s+?(<if|<else)#is", "\\1\n\\2", $php );
|
||||
|
||||
//----------------------------------------
|
||||
// Make safe special $Ibforums vars
|
||||
//----------------------------------------
|
||||
|
||||
$php = $this->convert_tags($php);
|
||||
|
||||
return $php;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Reverse: PHP IF to HTML IF
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Reverse the IF tag
|
||||
*
|
||||
* @param string PHP Variables / Operators
|
||||
* @param string PHP data
|
||||
* @param string Tag start
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _reverse_if( $code, $php, $start='if' )
|
||||
{
|
||||
$code = $this->_trim_slashes(trim($code));
|
||||
$code = preg_replace( "/(^|and|or)(\s+)(.+?)(\s|$)/ise", "\$this->_reverse_prep_left('\\3', '\\1', '\\2', '\\4')", ' '.$code );
|
||||
|
||||
$php = $this->_reverse_ipbhtml($php);
|
||||
|
||||
return "<".$start."=\"".trim($code)."\">\n".$php."\n</if>\n";
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Reverse: PHP else to HTML else
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Reverse the ELSE tag
|
||||
*
|
||||
* @param string PHP Data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _reverse_else( $php )
|
||||
{
|
||||
$php = $this->_trim_slashes(trim($php));
|
||||
|
||||
$php = $this->_reverse_ipbhtml($php);
|
||||
|
||||
return "<else>\n".$php."\n</else>\n";
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Reverse: $IPBHTML to normal $HTML
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Reverse HEREDOC tags
|
||||
*
|
||||
* @param string Raw PHP Data
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _reverse_ipbhtml( $code )
|
||||
{
|
||||
$code = $this->_trim_slashes($code);
|
||||
|
||||
$code = preg_replace("/".'\$'."IPBHTML\s+?\.?=\s+?<<<EOF(.+?)EOF;\s?/si", "\\1", $code );
|
||||
|
||||
$code = trim($code);
|
||||
$code = $this->_trim_newlines($code);
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Reverse PHP IF code to HTML code
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Prepare: Reverse PHP IF code to HTML safe code
|
||||
*
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _reverse_prep_left($left, $andor="", $fs="", $ls="")
|
||||
{
|
||||
$left = trim($this->_trim_slashes($left));
|
||||
|
||||
if ( preg_match( "/".'\$'."this->ipsclass->/", $left ) )
|
||||
{
|
||||
$left = preg_replace( "/".'\$'."this->ipsclass->(.+?)$/", 'ipb.'."\\1", $left );
|
||||
}
|
||||
else
|
||||
{
|
||||
$left = str_replace( '$', '', $left );
|
||||
}
|
||||
|
||||
return $andor.$fs.$left.$ls;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Statement: Return PHP 'IF' statement
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Prepare: If code
|
||||
*
|
||||
* @param string If code
|
||||
* @param string HTML
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _statement_if( $code, $html )
|
||||
{
|
||||
$html = $this->_func_prep_html($html);
|
||||
$code = $this->_func_prep_if($code);
|
||||
|
||||
return "\n//startif\nif ( $code )\n{\n\$IPBHTML .= <<<EOF\n$html\nEOF;\n}//endif\n";
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Statement: Return PHP 'ELSE IF' statement
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Prepare: Else If code
|
||||
*
|
||||
* @param string Else If code
|
||||
* @param string HTML
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _statement_elseif( $code, $html )
|
||||
{
|
||||
$html = $this->_func_prep_html($html);
|
||||
$code = $this->_func_prep_if($code);
|
||||
|
||||
return "\nelse if ( $code )\n{\n\$IPBHTML .= <<<EOF\n$html\nEOF;\n}//endif\n";
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Statement: Return PHP 'ELSE' statement
|
||||
//===================================================
|
||||
|
||||
/**
|
||||
* Prepare: Else code
|
||||
*
|
||||
* @param string HTML
|
||||
* @return string Converted Data
|
||||
*/
|
||||
function _statement_else( $html )
|
||||
{
|
||||
$html = $this->_func_prep_html($html);
|
||||
|
||||
return "\n//startelse\nelse\n{\n\$IPBHTML .= <<<EOF\n$html\nEOF;\n}//endelse\n";
|
||||
}
|
||||
|
||||
|
||||
//===================================================
|
||||
// Strip leading newlines, etc
|
||||
//===================================================
|
||||
|
||||
function _func_prep_html($html)
|
||||
{
|
||||
$html = trim($this->_trim_slashes($html));
|
||||
|
||||
//$html = preg_replace( '/"/', '\\"', $html );
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Sort out left bit of comparison
|
||||
//===================================================
|
||||
|
||||
function _func_prep_left($left, $andor="", $fs="", $ls="")
|
||||
{
|
||||
$left = trim($this->_trim_slashes($left));
|
||||
|
||||
if ( preg_match( "/^ipb\./", $left ) )
|
||||
{
|
||||
$left = preg_replace( "/^ipb\.(.+?)$/", '$this->ipsclass->'."\\1", $left );
|
||||
}
|
||||
else
|
||||
{
|
||||
$left = '$'.$left;
|
||||
}
|
||||
|
||||
return $andor.$fs.$left.$ls;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Statement: Prep AND OR, etc
|
||||
//===================================================
|
||||
|
||||
function _func_prep_if( $code )
|
||||
{
|
||||
$code = $this->_trim_slashes($code);
|
||||
|
||||
$code = preg_replace( "/(^|and|or)(\s+)(.+?)(\s|$)/ise", "\$this->_func_prep_left('\\3', '\\1', '\\2', '\\4')", ' '.$code );
|
||||
|
||||
return trim($code);
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Remove leading and trailing newlines
|
||||
//===================================================
|
||||
|
||||
function _trim_newlines($code)
|
||||
{
|
||||
$code = preg_replace("/^\n{1,}/s", "", $code );
|
||||
$code = preg_replace("/\n{1,}$/s", "", $code );
|
||||
return $code;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Remove preg_replace/e slashes
|
||||
//===================================================
|
||||
|
||||
function _trim_slashes($code)
|
||||
{
|
||||
$code = str_replace( '\"' , '"', $code );
|
||||
$code = str_replace( "\\'", "'", $code );
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
+533
-430
File diff suppressed because it is too large.
Load diff
@@ -1,987 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
| Licence Info: http://www.invisionboard.com/?license
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2008-02-06 11:55:42 -0500 (Wed, 06 Feb 2008) $
|
||||
| > $Revision: 1184 $
|
||||
| > $Author: bfarber $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > XML-RPC handling methods (KERNEL)
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: 6th January 2006
|
||||
|
|
||||
| > Module Version Number: 1.0.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: XML_RPC Creation and Extraction Functions
|
||||
*
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
* SENDING XML-RPC Request
|
||||
* (Optional)
|
||||
* $xmlrpc->map_type_to_key['key'] = 'string';
|
||||
* $xmlrpc->map_type_to_key['key2'] = 'base64';
|
||||
* $return = $xmlrpc->xml_rpc_send( 'http://domain.com/xml-rpc_server.php', 'methodNameHere', array( 'key' => 'value', 'key2' => 'value2' ) );
|
||||
* if ( $xmlrpc->errors )
|
||||
* {
|
||||
* print_r( $xmlrpc->errors );
|
||||
* }
|
||||
*
|
||||
* Decoding XML-RPC
|
||||
* $xmlrpc->decode( $raw_xmlrpc_text );
|
||||
*
|
||||
* print_r( $xmlrpc->xmlrpc_params );
|
||||
* RETURN
|
||||
* $xmlrpc->xml_rpc_return_true();
|
||||
* </code>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage XMLHandling
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* XML Creation and Extraction Functions
|
||||
*
|
||||
* Methods and functions for handling XML documents
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @subpackage XMLHandling
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
class class_xml_rpc
|
||||
{
|
||||
/**
|
||||
* XML header
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $header = "";
|
||||
|
||||
/**
|
||||
* DOC type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $doc_type = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Error array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $errors = array();
|
||||
|
||||
/**
|
||||
* Var types
|
||||
*/
|
||||
var $var_types = array('string', 'int', 'i4', 'double', 'dateTime.iso8601', 'base64', 'boolean');
|
||||
|
||||
/**
|
||||
* Extracted xmlrpc params
|
||||
* @var array
|
||||
*/
|
||||
var $xmlrpc_params = array();
|
||||
|
||||
/**
|
||||
* Optionally map types to key
|
||||
*/
|
||||
var $map_type_to_key = array();
|
||||
|
||||
/**
|
||||
* Auth required
|
||||
*/
|
||||
var $auth_user = '';
|
||||
var $auth_pass = '';
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// CONSTRUCTOR
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_xml_rpc()
|
||||
{
|
||||
$this->header = '<?xml version="1.0" encoding="'.$this->doc_type.'"?'.'>';
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Decode an XML RPC document
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Decode an XML RPC document
|
||||
*
|
||||
* @param string XML-RPC data
|
||||
* @param array Array of fields to send (must be in key => value pairings)
|
||||
* @return void
|
||||
*/
|
||||
function xml_rpc_decode( $_xml )
|
||||
{
|
||||
$xml_parser =& new xmlrpc_parser();
|
||||
$data = $xml_parser->parse( $_xml );
|
||||
$xml_parser->destruct();
|
||||
|
||||
if ( isset( $data['methodResponse']['fault'] ) )
|
||||
{
|
||||
$tmp = $this->xml_rpc_adjust_value( $data['methodResponse']['fault']['value'] );
|
||||
$this->errors[] = $tmp['faultString'];
|
||||
}
|
||||
|
||||
$this->xmlrpc_params = $this->xml_rpc_get_params( $data );
|
||||
$this->xmlrpc_method_call = $this->xml_rpc_get_method_name( $data );
|
||||
|
||||
//-----------------------------------------
|
||||
// Debug?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( IPS_XML_RPC_DEBUG_ON )
|
||||
{
|
||||
$this->_add_debug( "DECODING XML data: " . $_xml );
|
||||
$this->_add_debug( "DECODE RESULT XML data: " . var_export( $data, TRUE ) );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust value of param
|
||||
*/
|
||||
function & xml_rpc_adjust_value( & $current_node )
|
||||
{
|
||||
if ( is_array( $current_node ) )
|
||||
{
|
||||
if ( isset($current_node['array']) )
|
||||
{
|
||||
if ( ! is_array($current_node['array']['data']) )
|
||||
{
|
||||
$temp = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp = &$current_node['array']['data']['value'];
|
||||
|
||||
if ( is_array($temp) and array_key_exists(0, $temp) )
|
||||
{
|
||||
$count = count($temp);
|
||||
|
||||
for( $n = 0 ; $n < $count ; $n++ )
|
||||
{
|
||||
$temp2[$n] = & $this->xml_rpc_adjust_value($temp[$n]);
|
||||
}
|
||||
|
||||
$temp = &$temp2;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp2 = & $this->xml_rpc_adjust_value($temp);
|
||||
$temp = array(&$temp2);
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( isset($current_node['struct']) )
|
||||
{
|
||||
if ( ! is_array($current_node['struct']) )
|
||||
{
|
||||
return array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp = &$current_node['struct']['member'];
|
||||
|
||||
if ( is_array($temp) and array_key_exists(0, $temp) )
|
||||
{
|
||||
$count = count($temp);
|
||||
|
||||
for( $n = 0 ; $n < $count ; $n++ )
|
||||
{
|
||||
$temp2[$temp[$n]['name']] = & $this->xml_rpc_adjust_value($temp[$n]['value']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp2[$temp['name']] = & $this->xml_rpc_adjust_value($temp['value']);
|
||||
}
|
||||
$temp = &$temp2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$got_it = false;
|
||||
|
||||
foreach( $this->var_types as $type )
|
||||
{
|
||||
if ( array_key_exists($type, $current_node) )
|
||||
{
|
||||
$temp = &$current_node[$type];
|
||||
$got_it = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $got_it )
|
||||
{
|
||||
$type = 'string';
|
||||
|
||||
}
|
||||
|
||||
switch ($type)
|
||||
{
|
||||
case 'int':
|
||||
case 'i4':
|
||||
case 'integer':
|
||||
case 'integar':
|
||||
$temp = (int) $temp;
|
||||
break;
|
||||
case 'string':
|
||||
$temp = (string) $temp;
|
||||
break;
|
||||
case 'double':
|
||||
$temp = (double) $temp;
|
||||
break;
|
||||
case 'boolean':
|
||||
$temp = (bool) $temp;
|
||||
break;
|
||||
case 'base64':
|
||||
$temp = trim($temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp = (string) $current_node;
|
||||
}
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the params from an XML-RPC return
|
||||
*/
|
||||
function xml_rpc_get_params( $request )
|
||||
{
|
||||
if ( isset( $request['methodCall']['params'] ) AND is_array( $request['methodCall']['params'] ) )
|
||||
{
|
||||
$temp = & $request['methodCall']['params']['param'];
|
||||
}
|
||||
else if ( isset( $request['methodResponse']['params'] ) AND is_array( $request['methodResponse']['params'] ) )
|
||||
{
|
||||
$temp = & $request['methodResponse']['params']['param'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( is_array( $temp ) and array_key_exists( 0, $temp ) )
|
||||
{
|
||||
$count = count($temp);
|
||||
|
||||
for( $n = 0 ; $n < $count ; $n++)
|
||||
{
|
||||
$temp2[$n] = & $this->xml_rpc_adjust_value($temp[$n]['value']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp2[0] = & $this->xml_rpc_adjust_value($temp['value']);
|
||||
}
|
||||
|
||||
$temp = &$temp2;
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the method name
|
||||
*/
|
||||
function xml_rpc_get_method_name( $request )
|
||||
{
|
||||
return isset( $request['methodCall']['methodName'] ) ? $request['methodCall']['methodName'] : '';
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Create and send an XML document xml_rpc_decode
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Create and send an XML document
|
||||
*
|
||||
* @param string URL to send XML-RPC data to
|
||||
* @param array Array of fields to send (must be in key => value pairings)
|
||||
* @return void
|
||||
*/
|
||||
function xml_rpc_send( $url, $method_name='', $data_array=array() )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Build RPC request
|
||||
//-----------------------------------------
|
||||
|
||||
$xmldata = $this->xml_rpc_build_document( $data_array, $method_name );
|
||||
|
||||
if ( $xmldata )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Debug?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( IPS_XML_RPC_DEBUG_ON )
|
||||
{
|
||||
$this->_add_debug( "SENDING XML data: " . $xmldata );
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Continue
|
||||
//-----------------------------------------
|
||||
|
||||
return $this->xml_rpc_post( $url, $xmldata );
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return single value
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Prints a true document and exits
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function xml_rpc_return_value( $value )
|
||||
{
|
||||
$to_print = $this->header."<methodResponse>
|
||||
<params>
|
||||
<param>
|
||||
<value>{$value}</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodResponse>";
|
||||
|
||||
@header( "Connection: close" );
|
||||
@header( "Content-length: ".strlen($to_print) );
|
||||
@header( "Content-type: text/xml" );
|
||||
@header( "Date: " . date("r") );
|
||||
print $to_print;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Creates an XML-RPC complex document
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Creates an XML-RPC complex document
|
||||
*
|
||||
* @param array Array of fields to send (must be in key => value pairings)
|
||||
* @param string Method name (optional)
|
||||
* @return string finished document
|
||||
*/
|
||||
function xml_rpc_build_document( $data_array, $method_name='' )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$xmldata = "";
|
||||
$root_tag = 'methodCall';
|
||||
|
||||
//-----------------------------------------
|
||||
// Test
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! is_array( $data_array ) or ! count( $data_array ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! $method_name )
|
||||
{
|
||||
$root_tag = 'methodResponse';
|
||||
}
|
||||
|
||||
$xmldata = $this->header . "\n";
|
||||
$xmldata .= "<".$root_tag.">\n";
|
||||
|
||||
if ( $method_name )
|
||||
{
|
||||
$xmldata .= "\t<methodName>".$method_name."</methodName>\n";
|
||||
}
|
||||
|
||||
$xmldata .= "\t<params>\n";
|
||||
$xmldata .= "\t\t<param>\n";
|
||||
$xmldata .= "\t\t\t<value>\n";
|
||||
|
||||
if ( isset( $data_array[0] ) AND is_array( $data_array[0] ) )
|
||||
{
|
||||
$xmldata .= "\t\t\t<array>\n";
|
||||
$xmldata .= "\t\t\t\t<data>\n";
|
||||
|
||||
foreach( $data_array as $k => $v )
|
||||
{
|
||||
$xmldata .= "\t\t\t\t\t<value>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t<struct>\n";
|
||||
|
||||
foreach( $v as $k2 => $v2 )
|
||||
{
|
||||
$_type = $this->map_type_to_key[ $k2 ] ? $this->map_type_to_key[ $k2 ] : $this->get_xmlrpc_string_type( $v2 );
|
||||
|
||||
$xmldata .= "\t\t\t\t\t\t\t<member>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t\t\t<name>".$k2."</name>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t\t\t<value><".$_type.">" . htmlspecialchars($v2) . "</".$_type."></value>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t\t</member>\n";
|
||||
}
|
||||
|
||||
$xmldata .= "\t\t\t\t\t\t</struct>\n";
|
||||
$xmldata .= "\t\t\t\t\t</value>\n";
|
||||
}
|
||||
|
||||
$xmldata .= "\t\t\t\t</data>\n";
|
||||
$xmldata .= "\t\t\t</array>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$xmldata .= "\t\t\t<struct>\n";
|
||||
|
||||
foreach( $data_array as $k => $v )
|
||||
{
|
||||
if ( is_array( $v ) )
|
||||
{
|
||||
$xmldata .= $this->_xml_rpc_build_document_recurse( "", $k, $v, 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$_type = isset( $this->map_type_to_key[ $k ] ) ? $this->map_type_to_key[ $k ] : $this->get_xmlrpc_string_type( $v );
|
||||
|
||||
$xmldata .= "\t\t\t\t<member>\n";
|
||||
$xmldata .= "\t\t\t\t\t<name>".$k."</name>\n";
|
||||
$xmldata .= "\t\t\t\t\t<value><".$_type.">" . htmlspecialchars($v) . "</".$_type."></value>\n";
|
||||
$xmldata .= "\t\t\t\t</member>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$xmldata .= "\t\t\t</struct>\n";
|
||||
}
|
||||
|
||||
$xmldata .= "\t\t\t</value>\n";
|
||||
$xmldata .= "\t\t</param>\n";
|
||||
$xmldata .= "\t</params>\n";
|
||||
$xmldata .= "</".$root_tag.">";
|
||||
|
||||
return $xmldata;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Creates an XML-RPC complex document
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Creates an XML-RPC complex document
|
||||
*
|
||||
* @param array Array of fields to send (must be in key => value pairings)
|
||||
* @param string Method name (optional)
|
||||
* @return string finished document
|
||||
*/
|
||||
function _xml_rpc_build_document_recurse( $xmldata, $k, $v, $depth=4 )
|
||||
{
|
||||
$xmldata .= "\t<member>\n";
|
||||
$xmldata .= "\t\t<name>".$k."</name>\n";
|
||||
$xmldata .= "\t\t<value>\n";
|
||||
$xmldata .= "\t\t\t<array>\n";
|
||||
$xmldata .= "\t\t\t\t<data>\n";
|
||||
$xmldata .= "\t\t\t\t\t<value>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t<struct>\n";
|
||||
|
||||
foreach( $v as $_k => $_v )
|
||||
{
|
||||
if ( is_array( $_v ) )
|
||||
{
|
||||
$depth++;
|
||||
$xmldata .= $this->_xml_rpc_build_document_recurse( $xmldata, $k, $v, $depth );
|
||||
}
|
||||
else
|
||||
{
|
||||
$_type = isset( $this->map_type_to_key[ $_k ] ) ? $this->map_type_to_key[ $_k ] : $this->get_xmlrpc_string_type( $_v );
|
||||
|
||||
$xmldata .= "\t\t\t\t\t\t\t<member>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t\t\t<name>".$_k."</name>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t\t\t<value><".$_type.">" . htmlspecialchars($_v) . "</".$_type."></value>\n";
|
||||
$xmldata .= "\t\t\t\t\t\t\t</member>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$xmldata .= "\t\t\t\t\t\t</struct>\n";
|
||||
$xmldata .= "\t\t\t\t\t</value>\n";
|
||||
$xmldata .= "\t\t\t\t</data>\n";
|
||||
$xmldata .= "\t\t\t</array>\n";
|
||||
$xmldata .= "\t\t</value>\n";
|
||||
$xmldata .= "\t</member>\n";
|
||||
|
||||
return $xmldata;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return True
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Prints a true document and exits
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function xml_rpc_return_true()
|
||||
{
|
||||
$to_print = $this->header."
|
||||
<methodResponse>
|
||||
<params>
|
||||
<param>
|
||||
<value><boolean>1</boolean></value>
|
||||
</param>
|
||||
</params>
|
||||
</methodResponse>";
|
||||
|
||||
@header( "Connection: close" );
|
||||
@header( "Content-length: ".strlen($to_print) );
|
||||
@header( "Content-type: text/xml" );
|
||||
@header( "Date: " . date("r") );
|
||||
print $to_print;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return Params
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Prints a document and exits
|
||||
*
|
||||
* @param array Array of params to return in key => value pairs
|
||||
* @return void
|
||||
*/
|
||||
function xml_rpc_return_params( $data_array )
|
||||
{
|
||||
$to_print = $this->xml_rpc_build_document( $data_array );
|
||||
@header( "Connection: close" );
|
||||
@header( "Content-length: ".strlen($to_print) );
|
||||
@header( "Content-type: text/xml" );
|
||||
@header( "Date: " . date("r") );
|
||||
@header( "Pragma: no-cache" );
|
||||
@header( "Cache-Control: no-cache" );
|
||||
print $to_print;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Return Error
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Prints a true document and exits
|
||||
*
|
||||
* @param int Error code
|
||||
* @param string Error Message
|
||||
* @return void
|
||||
*/
|
||||
function xml_rpc_return_error( $error_code, $error_msg )
|
||||
{
|
||||
$to_print = $this->header."
|
||||
<methodResponse>
|
||||
<fault>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>faultCode</name>
|
||||
<value>
|
||||
<int>".intval($error_code)."</int>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>faultString</name>
|
||||
<value>
|
||||
<string>".$error_msg."</string>
|
||||
</value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</fault>
|
||||
</methodResponse>";
|
||||
|
||||
@header( "Connection: close" );
|
||||
@header( "Content-length: ".strlen($to_print) );
|
||||
@header( "Content-type: text/xml" );
|
||||
@header( "Date: " . date("r") );
|
||||
print $to_print;
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Post the document
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Create and send an XML document
|
||||
*
|
||||
* @param string URL to send XML-RPC data to
|
||||
* @param array XML-RPC data
|
||||
* @return void
|
||||
*/
|
||||
function xml_rpc_post( $file_location, $xmldata='' )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$data = null;
|
||||
$fsocket_timeout = 10;
|
||||
$header = "";
|
||||
|
||||
//-----------------------------------------
|
||||
// Send it..
|
||||
//-----------------------------------------
|
||||
|
||||
$url_parts = parse_url($file_location);
|
||||
|
||||
if ( ! $url_parts['host'] )
|
||||
{
|
||||
$this->errors[] = "No host found in the URL '$file_location'!";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Finalize
|
||||
//-------------------------------
|
||||
|
||||
$host = $url_parts['host'];
|
||||
|
||||
$port = ( isset($url_parts['port']) ) ? $url_parts['port'] : ( $url_parts['scheme'] == 'https' ? 443 : 80 );
|
||||
|
||||
//-----------------------------------------
|
||||
// User and pass?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! $this->auth_user AND $url_parts['user'] )
|
||||
{
|
||||
$this->auth_user = $url_parts['user'];
|
||||
$this->auth_pass = $url_parts['pass'];
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Tidy up path
|
||||
//-------------------------------
|
||||
|
||||
if ( ! empty( $url_parts["path"] ) )
|
||||
{
|
||||
$path = $url_parts["path"];
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = "/";
|
||||
}
|
||||
|
||||
if ( ! empty( $url_parts["query"] ) )
|
||||
{
|
||||
$path .= "?" . $url_parts["query"];
|
||||
}
|
||||
|
||||
if ( ! $fp = @fsockopen( $port == 443 ? "ssl://" . $host : $host, $port, $errno, $errstr, $fsocket_timeout ) )
|
||||
{
|
||||
$this->errors[] = "CONNECTION REFUSED FROM $host";
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$header = "POST $path HTTP/1.0\r\n";
|
||||
$header .= "User-Agent: IPS XML-RPC Client Library (\$Revision: 1184 $)\r\n";
|
||||
$header .= "Host: $host\r\n";
|
||||
|
||||
if ( $this->auth_user && $this->auth_pass )
|
||||
{
|
||||
$this->_add_debug( "Authorization: Basic Performed" );
|
||||
|
||||
$header .= "Authorization: Basic ".base64_encode("{$this->auth_user}:{$this->auth_pass}")."\r\n";
|
||||
}
|
||||
|
||||
$header .= "Connection: close\r\n";
|
||||
$header .= "Content-Type: text/xml\r\n";
|
||||
$header .= "Content-Length: " . strlen($xmldata) . "\r\n\r\n";
|
||||
|
||||
if ( ! fputs( $fp, $header . $xmldata ) )
|
||||
{
|
||||
$this->errors[] = "Unable to send request to $host!";
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@stream_set_timeout($fp, $fsocket_timeout);
|
||||
|
||||
$status = @socket_get_status($fp);
|
||||
|
||||
while( ! feof($fp) && ! $status['timed_out'] )
|
||||
{
|
||||
$data .= fgets ( $fp, 8192 );
|
||||
$status = socket_get_status($fp);
|
||||
}
|
||||
|
||||
fclose ($fp);
|
||||
|
||||
//-------------------------------
|
||||
// Strip headers
|
||||
//-------------------------------
|
||||
|
||||
$tmp = split("\r\n\r\n", $data, 2);
|
||||
$data = $tmp[1];
|
||||
|
||||
//-----------------------------------------
|
||||
// Debug?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( IPS_XML_RPC_DEBUG_ON )
|
||||
{
|
||||
$this->_add_debug( "POST RESPONSE to $host{$path}: " . $data );
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Continue
|
||||
//-----------------------------------------
|
||||
|
||||
return $this->xml_rpc_decode( $data );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Get the XML-RPC string type
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Get the XML-RPC string type
|
||||
*
|
||||
* @param string String
|
||||
* @return string XML-RPC String Type
|
||||
*/
|
||||
function get_xmlrpc_string_type( $string )
|
||||
{
|
||||
$type = gettype( $string );
|
||||
|
||||
switch( $type )
|
||||
{
|
||||
default:
|
||||
case 'string':
|
||||
$type = 'string';
|
||||
break;
|
||||
case 'integer':
|
||||
$type = 'int';
|
||||
break;
|
||||
case 'double':
|
||||
$type = 'double';
|
||||
break;
|
||||
case 'null':
|
||||
case 'boolean':
|
||||
$type = 'boolean';
|
||||
break;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add debug message
|
||||
*/
|
||||
function _add_debug( $msg )
|
||||
{
|
||||
if ( IPS_XML_RPC_DEBUG_FILE AND IPS_XML_RPC_DEBUG_ON )
|
||||
{
|
||||
$full_msg = "==================================================================\n"
|
||||
. "SCRIPT NAME: " . $_SERVER["SCRIPT_NAME"] . "\n"
|
||||
. gmdate( 'r' ) . ' - ' . $_SERVER['REMOTE_ADDR'] . ' - ' . $msg . "\n"
|
||||
. "==================================================================\n";
|
||||
|
||||
if ( $FH = @fopen( IPS_XML_RPC_DEBUG_FILE, 'a+' ) )
|
||||
{
|
||||
fwrite( $FH, $full_msg, strlen( $full_msg ) );
|
||||
fclose( $FH );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class xmlrpc_parser
|
||||
{
|
||||
/**
|
||||
* Parser object
|
||||
*/
|
||||
var $parser;
|
||||
/**
|
||||
* Current document
|
||||
*/
|
||||
var $document;
|
||||
/**
|
||||
* Current tag
|
||||
*/
|
||||
var $current;
|
||||
/**
|
||||
* Parent tag
|
||||
*/
|
||||
var $parent;
|
||||
/**
|
||||
* Parents
|
||||
*/
|
||||
var $parents;
|
||||
/**
|
||||
* Last opened tag
|
||||
*/
|
||||
var $last_opened_tag;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function xmlrpc_parser( $data=null )
|
||||
{
|
||||
$this->parser = xml_parser_create();
|
||||
|
||||
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
|
||||
xml_set_object( $this->parser, $this);
|
||||
xml_set_element_handler( $this->parser, "rpc_open", "rpc_close");
|
||||
xml_set_character_data_handler($this->parser, "rpc_data");
|
||||
}
|
||||
|
||||
/**
|
||||
* Object destructor
|
||||
*/
|
||||
function destruct()
|
||||
{
|
||||
xml_parser_free( $this->parser );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the XML data
|
||||
*/
|
||||
function parse( $data )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$this->document = array();
|
||||
$this->parent = &$this->document;
|
||||
$this->parents = array();
|
||||
$this->last_opened_tag = NULL;
|
||||
|
||||
//-----------------------------------------
|
||||
// Parse
|
||||
//-----------------------------------------
|
||||
|
||||
xml_parse($this->parser, $data);
|
||||
|
||||
//-----------------------------------------
|
||||
// Return...
|
||||
//-----------------------------------------
|
||||
$tmp = $this->document;
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open handler for XML object
|
||||
*/
|
||||
function rpc_open($parser, $tag, $attributes)
|
||||
{
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$this->data = "";
|
||||
$this->last_opened_tag = $tag;
|
||||
|
||||
if ( array_key_exists( $tag, $this->parent ) )
|
||||
{
|
||||
if ( is_array( $this->parent[$tag] ) and array_key_exists( 0, $this->parent[$tag] ) )
|
||||
{
|
||||
$key = is_array( $this->parent[$tag] ) ? count( array_filter( array_keys($this->parent[$tag]), 'is_numeric' ) ) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$temp = &$this->parent[$tag];
|
||||
unset($this->parent[$tag]);
|
||||
|
||||
$this->parent[$tag][0] = &$temp;
|
||||
|
||||
if ( array_key_exists( $tag ." attr", $this->parent ) )
|
||||
{
|
||||
$temp = &$this->parent[ $tag ." attr" ];
|
||||
unset($this->parent[ $tag ." attr" ]);
|
||||
$this->parent[$tag]["0 attr"] = &$temp;
|
||||
}
|
||||
|
||||
$key = 1;
|
||||
}
|
||||
|
||||
$this->parent = &$this->parent[$tag];
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = $tag;
|
||||
}
|
||||
|
||||
if ( $attributes )
|
||||
{
|
||||
$this->parent[ $key ." attr" ] = $attributes;
|
||||
}
|
||||
|
||||
$this->parent[$key] = array();
|
||||
$this->parent = &$this->parent[$key];
|
||||
|
||||
//array_unshift($this->parents, &$this->parent);
|
||||
$this->array_unshift_ref($this->parents, $this->parent);
|
||||
}
|
||||
|
||||
function array_unshift_ref(&$array, &$value)
|
||||
{
|
||||
$return = array_unshift($array,'');
|
||||
$array[0] =& $value;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* XML data handler
|
||||
*/
|
||||
function rpc_data($parser, $data)
|
||||
{
|
||||
if ( $this->last_opened_tag != NULL )
|
||||
{
|
||||
$this->data .= $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XML close handler
|
||||
*/
|
||||
function rpc_close($parser, $tag)
|
||||
{
|
||||
if ( $this->last_opened_tag == $tag )
|
||||
{
|
||||
$this->parent = $this->data;
|
||||
$this->last_opened_tag = NULL;
|
||||
}
|
||||
|
||||
array_shift($this->parents);
|
||||
|
||||
$this->parent = &$this->parents[0];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,554 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Board
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
| Licence Info: http://www.invisionboard.com/?license
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2005-10-10 14:03:20 +0100 (Mon, 10 Oct 2005) $
|
||||
| > $Revision: 22 $
|
||||
| > $Author: matt $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > XML ARCHIVE CLASS: Handling methods (KERNEL)
|
||||
| > Module written by Matt Mecham
|
||||
| > Date started: 25th February
|
||||
|
|
||||
| > Module Version Number: 1.0.0
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* IPS Kernel Pages: XMLArchive
|
||||
*
|
||||
* This class contains all generic functions to handle
|
||||
* the creation and extraction of XML Archive documents
|
||||
* This is a proprietry technology of IPS, Inc.
|
||||
*
|
||||
* Example Usage:
|
||||
* <code>
|
||||
*
|
||||
* $xmlarchive = new class_xmlarchive();
|
||||
*
|
||||
* $xmlarchive->xml_add_file( 'some/dir/filename.html' );
|
||||
* $xmlarchive->xml_add_file_contents( $data, 'some/dir/filename.html' );
|
||||
*
|
||||
* $xmlarchive->xml_add_file( 'some/dir/filename.html', array( 'custom_tag' => $value ) );
|
||||
* $xmlarchive->xml_add_file_contents( $data, 'some/dir/filename.html', array( 'custom_tag' => $value ) );
|
||||
*
|
||||
* $xmlarchive->xml_add_directory( 'some/dir' );
|
||||
* $xmlarchive->xml_create_archive();
|
||||
*
|
||||
* $xmlarchive->xml_save( 'filename.xml' );
|
||||
* $xmlarchive->xml_save_gzip( 'filename.xml.gz' );
|
||||
*
|
||||
* $contents = $xmlarchive->xml_get_contents();
|
||||
*
|
||||
* $xmlarchive->xml_read_archive( 'filename.xml' );
|
||||
* $xmlarchive->xml_read_archive_data( $xml_data );
|
||||
* </code>
|
||||
* ERROR NUMBERS:
|
||||
* <ul>
|
||||
* <li>001: No such directory or file
|
||||
* <li>002: Not a directory
|
||||
* <li>003: Could not write archive to disk
|
||||
* <li>004: No XML document to save
|
||||
* <li>005: Could not load xml data
|
||||
* </ul>
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @copyright Invision Power Services, Inc.
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* XMLArchive Creation and Extraction Functions
|
||||
*
|
||||
* Methods and functions for handling XMLArchive documents
|
||||
*
|
||||
* @package IPS_KERNEL
|
||||
* @author Matt Mecham
|
||||
* @version 2.1
|
||||
*/
|
||||
|
||||
class class_xmlarchive
|
||||
{
|
||||
/**
|
||||
* XML content
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $xml = "";
|
||||
|
||||
/**
|
||||
* File array
|
||||
*
|
||||
* @var artay
|
||||
*/
|
||||
var $file_array = array();
|
||||
|
||||
/**
|
||||
* Error number
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $error_number = 0;
|
||||
|
||||
/**
|
||||
* Error message
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $error_message = "";
|
||||
|
||||
/**
|
||||
* Work files
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $workfiles = array();
|
||||
|
||||
/**
|
||||
* Non binary file extensions
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $non_binary = 'txt htm html xml css js cgi php php3';
|
||||
|
||||
/**
|
||||
* Strip path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $strip_path = "";
|
||||
|
||||
/**
|
||||
* Root path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $root_path = "";
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// CONSTRUCTOR
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function class_xmlarchive( $root_path="" )
|
||||
{
|
||||
$tmp = "";
|
||||
$this->root_path = $root_path;
|
||||
|
||||
//-----------------------------------
|
||||
// Get the XML class
|
||||
//-----------------------------------
|
||||
|
||||
require_once( $this->root_path.'class_xml.php' );
|
||||
|
||||
$this->xml = new class_xml();
|
||||
|
||||
$this->error_number = 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// READ Archive from disk
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Read an XML document from disk
|
||||
*
|
||||
* @param string File name
|
||||
* @return void
|
||||
*/
|
||||
function xml_read_archive( $filename )
|
||||
{
|
||||
if ( file_exists( $filename ) )
|
||||
{
|
||||
if ( strstr( $filename, '.gz' ) )
|
||||
{
|
||||
if ( $FH = @gzopen( $filename, 'r' ) )
|
||||
{
|
||||
$data = @gzread( $FH, $filename );
|
||||
@gzclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '005';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $FH = @fopen( $filename, 'r' ) )
|
||||
{
|
||||
$data = @fread( $FH, filesize( $filename ) );
|
||||
@fclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '005';
|
||||
}
|
||||
}
|
||||
|
||||
$this->xml_read_archive_data( $data );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '001';
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// READ Archive from data
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Read an XML document from passed data
|
||||
*
|
||||
* @param string Raw XML Data
|
||||
* @return void
|
||||
*/
|
||||
function xml_read_archive_data( $data )
|
||||
{
|
||||
if ( $data )
|
||||
{
|
||||
$this->xml->xml_parse_document( $data );
|
||||
|
||||
if ( is_array( $this->xml->xml_array ) )
|
||||
{
|
||||
$this->file_array = array();
|
||||
|
||||
foreach( $this->xml->xml_array['xmlarchive']['fileset']['file'] as $entry )
|
||||
{
|
||||
$this_array = array();
|
||||
|
||||
if( is_array( $entry ) )
|
||||
{
|
||||
foreach ( $entry as $k => $v )
|
||||
{
|
||||
if ( $k == 'content' )
|
||||
{
|
||||
$v['VALUE'] = base64_decode( preg_replace( "/\s/", "", $entry['content']['VALUE'] ) );
|
||||
}
|
||||
|
||||
$this_array[ $k ] = $v['VALUE'];
|
||||
}
|
||||
|
||||
$this->file_array[] = $this_array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SAVE XML to disk
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Write out the XML document as a GZIP file
|
||||
*
|
||||
* @param string FIlename
|
||||
* @return void
|
||||
*/
|
||||
function xml_save_gzip( $filename )
|
||||
{
|
||||
if ( $this->xml->xml_document )
|
||||
{
|
||||
if ( $FH = @gzopen( $filename, 'wb' ) )
|
||||
{
|
||||
@gzwrite( $FH, $this->xml->xml_document );
|
||||
@gzclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '003';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '004';
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// SAVE XML to disk
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Write out the XML document as a normal file
|
||||
*
|
||||
* @param string FIlename
|
||||
* @return void
|
||||
*/
|
||||
function xml_save( $filename )
|
||||
{
|
||||
if ( $this->xml->xml_document )
|
||||
{
|
||||
if ( $FH = @fopen( $filename, 'wb' ) )
|
||||
{
|
||||
@fwrite( $FH, $this->xml->xml_document );
|
||||
@fclose( $FH );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '003';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '004';
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// XML get contents
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Method of getting XML document from this class
|
||||
*
|
||||
* @return string XML document
|
||||
*/
|
||||
function xml_get_contents()
|
||||
{
|
||||
return $this->xml->xml_document;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Create the XML archive
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Create the XML archive
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function xml_create_archive()
|
||||
{
|
||||
$this->xml->xml_set_root( 'xmlarchive', array( 'generator' => 'IPB', 'created' => time() ) );
|
||||
$this->xml->xml_add_group( 'fileset' );
|
||||
|
||||
$entry = array();
|
||||
|
||||
foreach( $this->file_array as $f )
|
||||
{
|
||||
$content = array();
|
||||
|
||||
foreach ( $f as $k => $v )
|
||||
{
|
||||
if ( $k == 'content' )
|
||||
{
|
||||
$v = chunk_split(base64_encode($v));
|
||||
}
|
||||
|
||||
$content[] = $this->xml->xml_build_simple_tag( $k, $v );
|
||||
}
|
||||
|
||||
$entry[] = $this->xml->xml_build_entry( 'file', $content );
|
||||
}
|
||||
|
||||
$this->xml->xml_add_entry_to_group( 'fileset', $entry );
|
||||
|
||||
$this->xml->xml_format_document();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Add directory contents
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function xml_add_directory( $dir )
|
||||
{
|
||||
$this->error_number = "";
|
||||
|
||||
//-----------------------------------
|
||||
// Got dir?
|
||||
//-----------------------------------
|
||||
|
||||
if ( ! is_dir($dir) )
|
||||
{
|
||||
$this->error_number = '001';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// Populate this->workfiles
|
||||
//-----------------------------------
|
||||
|
||||
$this->workfiles = array();
|
||||
$this->_xml_get_dir_contents( $dir );
|
||||
|
||||
//-----------------------------------
|
||||
// Add them into the file array
|
||||
//-----------------------------------
|
||||
|
||||
foreach ( $this->workfiles as $f )
|
||||
{
|
||||
$this->xml_add_file( $f );
|
||||
}
|
||||
|
||||
$this->workfiles = array();
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Add File (interface to file_contents)
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function xml_add_file( $filename, $extra_tags=array() )
|
||||
{
|
||||
//-----------------------------------
|
||||
// Kill OS X hidden files
|
||||
//-----------------------------------
|
||||
|
||||
if ( preg_match( "/\.ds_store/i", $filename ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// And Windows...
|
||||
//-----------------------------------
|
||||
|
||||
if ( preg_match( "/thumbs\.db/i", $filename ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( file_exists( $filename ) )
|
||||
{
|
||||
if ( $FH = @fopen( $filename, 'rb' ) )
|
||||
{
|
||||
$data = @fread( $FH, filesize( $filename ) );
|
||||
@fclose( $FH );
|
||||
}
|
||||
|
||||
$this->xml_add_file_contents( $data, $filename, $extra_tags );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '001';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Add File Contents
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function xml_add_file_contents( $data, $filename, $extra_tags=array() )
|
||||
{
|
||||
$ext = preg_replace( "/.*\.(.+?)$/", "\\1", $filename );
|
||||
|
||||
$binary = 1;
|
||||
|
||||
//-----------------------------------
|
||||
// ASCII?
|
||||
//-----------------------------------
|
||||
|
||||
if ( strstr( ' '.$this->non_binary.' ', ' '.$ext.' ' ) )
|
||||
{
|
||||
$binary = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// Get dir / filename
|
||||
//-----------------------------------
|
||||
|
||||
$dir_path = array();
|
||||
$dir_path = explode( "/", $filename );
|
||||
|
||||
if ( count( $dir_path ) )
|
||||
{
|
||||
$real_filename = array_pop( $dir_path );
|
||||
}
|
||||
|
||||
$real_filename = $real_filename ? $real_filename : $filename;
|
||||
|
||||
$path = implode( "/", $dir_path );
|
||||
|
||||
if ( $this->strip_path )
|
||||
{
|
||||
$path = preg_replace( "#". preg_quote($this->strip_path, '#')."/?#", "", $path );
|
||||
}
|
||||
|
||||
$this_array = array(
|
||||
'filename' => $real_filename,
|
||||
'content' => $data,
|
||||
'path' => $path,
|
||||
'binary' => $binary
|
||||
);
|
||||
|
||||
foreach( $extra_tags as $k => $v )
|
||||
{
|
||||
if ( $k and ! in_array( $k, array_keys($this_array) ) )
|
||||
{
|
||||
$this_array[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
$this->file_array[] = $this_array;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// INTERNAL: Get directory contents
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
function _xml_get_dir_contents( $dir )
|
||||
{
|
||||
$dir = preg_replace( "#/$#", "", $dir );
|
||||
|
||||
if ( file_exists($dir) )
|
||||
{
|
||||
if ( is_dir($dir) )
|
||||
{
|
||||
$handle = opendir($dir);
|
||||
|
||||
while (($filename = readdir($handle)) !== false)
|
||||
{
|
||||
if (($filename != ".") && ($filename != ".."))
|
||||
{
|
||||
if ( is_dir( $dir."/".$filename ) )
|
||||
{
|
||||
//-----------------------------------
|
||||
// Recurse
|
||||
//-----------------------------------
|
||||
|
||||
$this->_xml_get_dir_contents($dir."/".$filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------
|
||||
// Add file to list
|
||||
//-----------------------------------
|
||||
|
||||
$this->workfiles[] = $dir."/".$filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '002';
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_number = '001';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
@@ -1 +1 @@
|
||||
<html>␍<head><title>Invision Power Board - Bulletin Board System</title></head>␍<body>␍<h1>403: Invision Power Board -> Forbidden</h1>␍<hr>␍You have reached this Page in error, please use␍your back button to return to Invision Board.␍<hr>␍<a href="http://anonym.to/http://www.invisionboard.com/">Invision Power Board</a>␍</body>␍</html>
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -1,116 +1,185 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| Invision Power Services Kernel [DB Tools]
|
||||
| =============================================
|
||||
| by Matthew Mecham
|
||||
| (c) 2001 - 2006 Invision Power Services, Inc.
|
||||
| http://www.invisionpower.com
|
||||
| =============================================
|
||||
| Web: http://www.invisionboard.com
|
||||
+---------------------------------------------------------------------------
|
||||
| THIS IS NOT FREE / OPEN SOURCE SOFTWARE
|
||||
+---------------------------------------------------------------------------
|
||||
| > $Date: 2007-10-18 15:47:19 -0400 (Thu, 18 Oct 2007) $
|
||||
| > $Revision: 1137 $
|
||||
| > $Author: bfarber $
|
||||
+---------------------------------------------------------------------------
|
||||
|
|
||||
| > MySQL DB Tools
|
||||
| > Module written by Remco Wilting
|
||||
| > Date started: Tuesday 1st March 2005 15:40
|
||||
|
|
||||
| > Module Version Number: 2.1.001
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* Invision Power Services
|
||||
* IP.Board v3.0.5
|
||||
* MySQL Database Diagnostic Methods
|
||||
* Last Updated: $Date: 2009-10-09 09:24:39 -0400 (Fri, 09 Oct 2009) $
|
||||
*
|
||||
* @author $Author: josh $
|
||||
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
||||
* @license http://www.iinvisionpower.com/community/board/license.html
|
||||
* @package Invision Power Services Kernel
|
||||
* @link http://www.iinvisionpower.com
|
||||
* @since Tuesday 1st March 2005 15:40
|
||||
* @version $Revision: 337 $
|
||||
*/
|
||||
|
||||
class db_tools
|
||||
{
|
||||
var $ipsclass;
|
||||
/**
|
||||
* Missing column/table/index flag
|
||||
*
|
||||
* @var boolean Table/index has issues
|
||||
* @access public
|
||||
*/
|
||||
public $has_issues = false;
|
||||
|
||||
var $has_issues = 0;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
// Constructor
|
||||
/*-------------------------------------------------------------------------*/
|
||||
function db_tools( & $ipsclass )
|
||||
{
|
||||
$this->ipsclass = & $ipsclass;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Diagnose the table indexes
|
||||
// @input sql_statements array of create table/index statements to check
|
||||
// @output array array of results ( table, index, status, message, fixsql )
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* Internal mapping - ignore me
|
||||
*
|
||||
* @var array Table/column mappings
|
||||
* @access private
|
||||
*/
|
||||
private $_mapping = array();
|
||||
|
||||
function db_index_diag( & $sql_statements )
|
||||
/**
|
||||
* Diagnose table indexes
|
||||
*
|
||||
* @access public
|
||||
* @param array Array of create table/index statements to check
|
||||
* @param array Array of issues to fix
|
||||
* @return array Array of results
|
||||
*/
|
||||
public function dbIndexDiag( $sql_statements, $issues_to_fix='' )
|
||||
{
|
||||
$indexes = array();
|
||||
$error_count = 0;
|
||||
//-----------------------------------------
|
||||
// INIT
|
||||
//-----------------------------------------
|
||||
|
||||
$indexes = array();
|
||||
$error_count = 0;
|
||||
$output = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Do we have SQL statements?
|
||||
//-----------------------------------------
|
||||
|
||||
if( is_array($sql_statements) && count($sql_statements) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Loop over our statements
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $sql_statements as $definition )
|
||||
{
|
||||
$table_name = "";
|
||||
$fields_str = "";
|
||||
$primary_key = "";
|
||||
$tablename = array();
|
||||
$fields = array();
|
||||
$final_keys = array();
|
||||
$col_definition = "";
|
||||
$colmatch = array();
|
||||
$final_primary = array();
|
||||
//-----------------------------------------
|
||||
// Some more per-statement init
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#CREATE TABLE\s+?(.+?)\s+?\(#ie", $definition, $tablename ) )
|
||||
$table_name = "";
|
||||
$fields_str = "";
|
||||
$primary_key = "";
|
||||
$tablename = array();
|
||||
$fields = array();
|
||||
$final_keys = array();
|
||||
$col_definition = "";
|
||||
$colmatch = array();
|
||||
$final_primary = array();
|
||||
|
||||
/* Remove backticks */
|
||||
$definition = str_replace( '`', '', $definition );
|
||||
|
||||
//-----------------------------------------
|
||||
// Is this a create table statement?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#CREATE\s+TABLE\s+?(.+?)\s+?\(#ie", $definition, $tablename ) )
|
||||
{
|
||||
$table_name = $tablename[1];
|
||||
if ( preg_match( "#\s+?PRIMARY\s+?KEY\s+?\((.*?)\)(?:(?:[,\s+?$])?\((.+?)\))?#is", $definition, $fields ) )
|
||||
{
|
||||
$final_primary = array();
|
||||
$tableName = $tablename[1];
|
||||
|
||||
//-----------------------------------------
|
||||
// Does the table have a primary key?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#\s+?PRIMARY\s+?KEY\s+?(?:(\w+?)\s+?)?\((.*?)\)(?:(?:[,\s+?$])?\((.+?)\))?#is", $definition, $fields ) )
|
||||
{
|
||||
$final_primary = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Did we find anything with our regex?
|
||||
//-----------------------------------------
|
||||
|
||||
if( count( $fields ) )
|
||||
{
|
||||
$primary_key = trim($fields[1]);
|
||||
//-----------------------------------------
|
||||
// Get the actual key name
|
||||
//-----------------------------------------
|
||||
|
||||
$primary_key = trim($fields[1]);
|
||||
$primary_fields = implode( ",", array_map( 'trim', explode( ",", $fields[2] ) ) );
|
||||
|
||||
//-----------------------------------------
|
||||
// Get the table definition
|
||||
//-----------------------------------------
|
||||
|
||||
$col_definition = $this->sql_strip_ticks( $definition );
|
||||
|
||||
if ( preg_match( "#^\s+?{$primary_key}\s+?(.+?)(?:[,$])#im", $col_definition, $colmatch ) )
|
||||
{
|
||||
$col_definition = trim($colmatch[1]);
|
||||
}
|
||||
$final_primary = array( $primary_key, $col_definition );
|
||||
$col_definition = $this->_sqlStripTicks( $definition );
|
||||
|
||||
//-----------------------------------------
|
||||
// This is the primary key for this table
|
||||
//-----------------------------------------
|
||||
|
||||
$final_primary = array( $primary_key ? $primary_key : $primary_fields, $primary_fields );
|
||||
}
|
||||
}
|
||||
$table_array[$i] = $table_name;
|
||||
|
||||
$table_array[$i] = $tableName;
|
||||
|
||||
//-----------------------------------------
|
||||
// We found a primary key, store it
|
||||
//-----------------------------------------
|
||||
|
||||
if ( count( $final_primary ) )
|
||||
{
|
||||
$primary_array[$i] = $final_primary;
|
||||
}
|
||||
}
|
||||
|
||||
if ( preg_match_all( "#(?<!PRIMARY)\s+?KEY\s+?(?:(\w+?)\s+?)?\((.*?)\)(?:(?:[,\s+?$])?\((.+?)\))?#is", $definition, $fields, PREG_PATTERN_ORDER ) )
|
||||
|
||||
//-----------------------------------------
|
||||
// Now find all non-primary keys
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match_all( "#(?<!PRIMARY)\s*?KEY\s+?(?:(\w+?)\s+?)?\((.+?)\)(\n|,\n)#is", $definition, $fields ) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// We got some fields!
|
||||
//-----------------------------------------
|
||||
|
||||
if( count( $fields[2] ) )
|
||||
{
|
||||
$i = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Loop over the data from the preg statement
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $fields[2] as $index_cols )
|
||||
{
|
||||
$index_cols = trim( $this->sql_strip_ticks( $index_cols ) );
|
||||
|
||||
$index_name = $fields[1][$i] ? $fields[1][$i] : $index_cols;
|
||||
|
||||
$final_keys[] = array( $index_name, implode( ",", array_map( 'trim', explode( ",", $index_cols ) ) ) );
|
||||
//-----------------------------------------
|
||||
// Get index name, column name, and store
|
||||
//-----------------------------------------
|
||||
|
||||
//$index_cols = implode( ",", array_map( 'trim', explode( ",", $this->_sqlStripTicks( preg_replace( "#\(([^\(]+?)\)#", "", $index_cols ) ) ) ) );
|
||||
$index_cols = implode( ",", array_map( 'trim', explode( ",", $this->_sqlStripTicks( $index_cols ) ) ) );
|
||||
$index_name = $fields[1][$i] ? $fields[1][$i] : $index_cols;
|
||||
|
||||
if( $index_cols != $final_primary[1] )
|
||||
{
|
||||
$final_keys[] = array( $index_name, $index_cols );
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( $table_name AND ( $primary_key OR count($final_keys) ) )
|
||||
//-----------------------------------------
|
||||
// We have some indexes for this table
|
||||
//-----------------------------------------
|
||||
|
||||
if( $tableName AND ( $primary_key OR count($final_keys) ) )
|
||||
{
|
||||
$indexes[] = array( 'table' => $table_name,
|
||||
$indexes[] = array( 'table' => $tableName,
|
||||
'primary' => $final_primary,
|
||||
'index' => $final_keys
|
||||
);
|
||||
@@ -118,106 +187,251 @@ class db_tools
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// No indexes on this table
|
||||
//-----------------------------------------
|
||||
|
||||
if( !count($indexes) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$output = array();
|
||||
//-----------------------------------------
|
||||
// Loop over the indexes
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $indexes as $data )
|
||||
{
|
||||
$table_name = str_replace( "ibf_", "", $data['table']);
|
||||
//-----------------------------------------
|
||||
// Get table schematics and clean it
|
||||
//-----------------------------------------
|
||||
|
||||
$row = $this->ipsclass->DB->sql_get_table_schematic( $table_name );
|
||||
|
||||
$tbl = $this->sql_strip_ticks( $row['Create Table'] );
|
||||
$row = ipsRegistry::DB()->getTableSchematic( $data['table'] );
|
||||
$tbl = $this->_sqlStripTicks( $row['Create Table'] );
|
||||
|
||||
//-----------------------------------------
|
||||
// Start output (one per index)
|
||||
//-----------------------------------------
|
||||
|
||||
$output[ $data['table'] ] = array( 'table' => ipsRegistry::$settings['sql_tbl_prefix'].$data['table'],
|
||||
'status' => 'ok',
|
||||
'missing' => array(),
|
||||
);
|
||||
|
||||
//-----------------------------------------
|
||||
// We had a primary key, so let's look for it
|
||||
//-----------------------------------------
|
||||
|
||||
if( isset( $data['primary'] ) && is_array($data['primary']) AND count($data['primary']) )
|
||||
{
|
||||
$index_name = $data['primary'][0];
|
||||
$column_definition = $data['primary'][1];
|
||||
$index_name = $data['primary'][0];
|
||||
$index_cols = $data['primary'][1];
|
||||
$ok = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Can we find it...?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#\s+?PRIMARY\s+?KEY\s+?\({$index_name}\)?[,\s+?$]?#is", $tbl, $match ) )
|
||||
if ( preg_match( "#\s*PRIMARY\s+?KEY\s*(\((.+?)\))?#is", $tbl, $matches ) )
|
||||
{
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'ok',
|
||||
'message' => '',
|
||||
'fixsql' => '' );
|
||||
$ok = 1;
|
||||
|
||||
//-----------------------------------------
|
||||
// It is...now is the index right (mulicolumn)?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $index_cols != $matches[2] )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Break out the real indexes and loop
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( explode( ',', $index_cols ) as $mc )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// And make sure it's in the definition
|
||||
//-----------------------------------------
|
||||
|
||||
if ( strpos( $match[2], $mc ) === false )
|
||||
{
|
||||
$query_needed = 'ALTER TABLE ' . ipsRegistry::$settings['sql_tbl_prefix'] . $data['table'] . ' DROP INDEX ' . $index_name . ', ADD INDEX ' . $index_name . ' (' . $index_cols . ')';
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// We got issues gomer!
|
||||
//-----------------------------------------
|
||||
|
||||
$this->has_issues = 1;
|
||||
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$ok = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query_needed = "ALTER TABLE ".SQL_PREFIX."$table_name CHANGE {$index_name} {$index_name} {$column_definition}, ADD PRIMARY KEY ({$index_name})";
|
||||
//-----------------------------------------
|
||||
// Generate query and set the output array
|
||||
//-----------------------------------------
|
||||
|
||||
if( !$this->ipsclass->DB->field_exists( $index_name, $table_name ) )
|
||||
{
|
||||
$query_needed = str_replace( "CHANGE {$index_name}", "ADD", $query_needed );
|
||||
}
|
||||
$query_needed = "ALTER TABLE " . ipsRegistry::$settings['sql_tbl_prefix'] . "{$data['table']} ADD PRIMARY KEY ({$index_name})";
|
||||
|
||||
$this->has_issues = 1;
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing primary key',
|
||||
'fixsql' => $query_needed );
|
||||
$error_count++;
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
$ok = 1;
|
||||
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->has_issues = 1;
|
||||
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$error_count++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Primary key is fine
|
||||
//-----------------------------------------
|
||||
|
||||
if( $ok )
|
||||
{
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Got other indexes?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( isset( $data['index'] ) && is_array( $data['index'] ) and count( $data['index'] ) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Loop over the other indexes
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $data['index'] as $indexes )
|
||||
{
|
||||
$index_name = $indexes[0];
|
||||
$index_cols = $indexes[1] ? $indexes[1] : $index_name;
|
||||
$ok = 0;
|
||||
$index_name = $indexes[0];
|
||||
$index_cols = $indexes[1] ? $indexes[1] : $index_name;
|
||||
|
||||
$ok = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Is the key there?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( preg_match( "#(?<!PRIMARY)\s+?KEY\s+?{$index_name}\s+?(\((.+?)\))?#is", $tbl, $match ) )
|
||||
if ( preg_match( "#(?<!PRIMARY)\s+?KEY\s+?{$index_name}\s+?(\((.+?)\))(\n|,\n)#is", $tbl, $match ) )
|
||||
{
|
||||
$ok = 1;
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Multi index column?
|
||||
// It is...now is the index right (mulicolumn)?
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $index_cols != $table_cols )
|
||||
if ( $index_cols != $match[2] )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Break out the real indexes and loop
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( explode( ',', $indexes[1] ) as $mc )
|
||||
{
|
||||
if ( ! strstr( $match[2], $mc ) )
|
||||
//-----------------------------------------
|
||||
// And make sure it's in the definition
|
||||
//-----------------------------------------
|
||||
|
||||
if ( strpos( $match[2], str_replace(' ', '', $mc) ) === false )
|
||||
{
|
||||
$this->has_issues = 1;
|
||||
$query_needed = 'ALTER TABLE ' . ipsRegistry::$settings['sql_tbl_prefix'] . $data['table'] . ' DROP INDEX ' . $index_name . ', ADD INDEX ' . $index_name . ' (' . $index_cols . ')';
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing field \''.$mc.'\'',
|
||||
'fixsql' => 'ALTER TABLE '.SQL_PREFIX.$table_name.' DROP INDEX '.$index_name.', ADD INDEX '.$index_name.' ('.$index_cols.')' );
|
||||
$error_count++;
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$this->has_issues = 1;
|
||||
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$ok = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing index \''.$index_name.'\'',
|
||||
'fixsql' => 'ALTER TABLE '.SQL_PREFIX.$table_name.' ADD INDEX '.$index_name.'('.$index_cols.')' );
|
||||
$error_count++;
|
||||
//-----------------------------------------
|
||||
// Generate query and set the output array
|
||||
//-----------------------------------------
|
||||
|
||||
$query_needed = 'ALTER TABLE ' . ipsRegistry::$settings['sql_tbl_prefix'] . $data['table'] . ' ADD INDEX ' . $index_name . ' (' . $index_cols . ')';
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $data['table'] OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
$ok = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$output[ $data['table'] ]['status'] = 'error';
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
$output[ $data['table'] ]['missing'][] = $index_name;
|
||||
$output[ $data['table'] ]['fixsql'][] = $query_needed;
|
||||
|
||||
$error_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// The index is ok
|
||||
//-----------------------------------------
|
||||
|
||||
if ( $ok )
|
||||
{
|
||||
$output[] = array( 'table' => SQL_PREFIX.$table_name,
|
||||
'index' => $index_name,
|
||||
'status' => 'ok',
|
||||
'message' => '',
|
||||
'fixsql' => '' );
|
||||
$output[ $data['table'] ]['index'][] = $index_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,127 +441,271 @@ class db_tools
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Diagnose the DB tables
|
||||
// @input sql_statements array of create table statements to check
|
||||
// @output array array of results ( key, table, status, message, fixsql )
|
||||
//-------------------------------------------------------------
|
||||
|
||||
function db_table_diag( & $sql_statements )
|
||||
/**
|
||||
* Diagnose table structure
|
||||
*
|
||||
* @access public
|
||||
* @param array Array of create table/index statements to check
|
||||
* @param array Array of issues to fix
|
||||
* @return array Array of results
|
||||
*/
|
||||
public function dbTableDiag( $sql_statements, $issues_to_fix='' )
|
||||
{
|
||||
$queries_needed = array();
|
||||
$tables_needed = array();
|
||||
$error_count = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Init
|
||||
//-----------------------------------------
|
||||
|
||||
$queries_needed = array();
|
||||
$tables_needed = array();
|
||||
$table_definitions = array();
|
||||
$error_count = 0;
|
||||
$_tablesFull = array();
|
||||
$_tablesAlter = array();
|
||||
|
||||
//-----------------------------------------
|
||||
// Do we have any statements?
|
||||
//-----------------------------------------
|
||||
|
||||
if( is_array( $sql_statements ) && count( $sql_statements ) )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Loop over those statements
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $sql_statements as $the_table )
|
||||
{
|
||||
$expected_columns = array();
|
||||
|
||||
if( preg_match("#CREATE TABLE\s+?(.+?)\s+?\(#ie", $the_table, $bits))
|
||||
$expected_columns = array();
|
||||
$missing_columns = array();
|
||||
|
||||
/* Remove backticks */
|
||||
$the_table = str_replace( '`', '', $the_table );
|
||||
|
||||
//-----------------------------------------
|
||||
// Is this a create table statement?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_match( "#CREATE\s+TABLE\s+?(.+?)\s+?\(#ie", $the_table, $definition ) )
|
||||
{
|
||||
$tbl_name = $bits[1];
|
||||
$tbl_name = str_replace( "ibf_", "", $tbl_name );
|
||||
$tableName = ipsRegistry::$settings['sql_tbl_prefix'] . $definition[1];
|
||||
|
||||
$table_defs[$tbl_name] = str_replace( "ibf_", SQL_PREFIX, $the_table );
|
||||
//-----------------------------------------
|
||||
// Store the entire table definition
|
||||
//-----------------------------------------
|
||||
|
||||
$table_definitions[ $tableName ] = str_replace( $definition[1], $tableName, $the_table );
|
||||
$_tablesFull[] = $tableName;
|
||||
|
||||
//-----------------------------------------
|
||||
// Get the columns
|
||||
//-----------------------------------------
|
||||
|
||||
// Get the columns and lose the first line (it's the table name)
|
||||
$columns_array = explode( "\n", $the_table );
|
||||
|
||||
//-----------------------------------------
|
||||
// Get rid of first row ("CREATE TABLE ...")
|
||||
//-----------------------------------------
|
||||
|
||||
array_shift($columns_array);
|
||||
|
||||
// Get rid of the end junk
|
||||
if ( (strpos(end($columns_array), ");") == 0) ||
|
||||
(strpos(end($columns_array), ")") == 0) ||
|
||||
(strpos(end($columns_array), ";") == 0) )
|
||||
//-----------------------------------------
|
||||
// Get rid of the junk at the end of each line
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ( strpos(end($columns_array), ");") === 0 ) OR
|
||||
( strpos(end($columns_array), ")") === 0 ) OR
|
||||
( strpos(end($columns_array), ";") === 0 ) )
|
||||
{
|
||||
array_pop($columns_array);
|
||||
}
|
||||
|
||||
|
||||
reset($columns_array);
|
||||
|
||||
//-----------------------------------------
|
||||
// Loop over each supposed "column"
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $columns_array as $col )
|
||||
{
|
||||
$temp = preg_split( "/[\s]+/" , $col );
|
||||
$col_name = trim( next( $temp ) );
|
||||
//-----------------------------------------
|
||||
// Find the column name
|
||||
//-----------------------------------------
|
||||
|
||||
if( $col_name != "PRIMARY" &&
|
||||
$col_name != "KEY" &&
|
||||
$col_name != "UNIQUE" &&
|
||||
$col_name != "" &&
|
||||
$col_name != "(" &&
|
||||
$col_name != ";" &&
|
||||
$col_name != ");" )
|
||||
$temp = preg_split( "/[\s]+/" , trim($col) );
|
||||
$columnName = $temp[0];
|
||||
|
||||
//-----------------------------------------
|
||||
// If this is a real column, map it
|
||||
//-----------------------------------------
|
||||
|
||||
if( !in_array( $columnName, array( "PRIMARY", "KEY", "UNIQUE", "", "(", ";", ");" ) ) )
|
||||
{
|
||||
$expected_columns[] = $col_name;
|
||||
$this->columns_to_defs[$tbl_name][$col_name] = trim( str_replace( ',', ';', $col ) );
|
||||
$expected_columns[] = $columnName;
|
||||
$this->_mapping[ $tableName ][ $columnName ] = trim( str_replace( ',', ';', $col ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( preg_match("#ALTER TABLE ([a-z_]*) ADD ([a-z_]*) #is", $the_table, $bits) )
|
||||
|
||||
//-----------------------------------------
|
||||
// This an alter table statement?
|
||||
//-----------------------------------------
|
||||
|
||||
elseif ( preg_match( "#ALTER\s+TABLE\s+([a-z_]*)\s+ADD\s+([a-z_]*)\s+#is", $the_table, $definition ) )
|
||||
{
|
||||
if( $bits[1] != "" &&
|
||||
$bits[2] != "" &&
|
||||
$bits[2] != 'INDEX' &&
|
||||
strpos($bits[2], 'TYPE') === false )
|
||||
//-----------------------------------------
|
||||
// If this is truly adding a new column, map it
|
||||
//-----------------------------------------
|
||||
|
||||
if( $definition[1] AND $definition[2] AND $definition[2] != 'INDEX' AND strpos($definition[2], 'TYPE') === false AND strpos($definition[2], 'ENGINE') === false )
|
||||
{
|
||||
$tbl_name = trim($bits[1]);
|
||||
$tbl_name = str_replace( "ibf_", "", $tbl_name );
|
||||
$col_name = trim($bits[2]);
|
||||
|
||||
$expected_columns[] = $col_name;
|
||||
$this->columns_to_defs[$tbl_name][$col_name] = str_replace( $bits[1], SQL_PREFIX . $tbl_name, $the_table ) . ";";
|
||||
$tableName = ipsRegistry::$settings['sql_tbl_prefix'] . trim( $definition[1] );
|
||||
$columnName = trim($definition[2]);
|
||||
$_tablesAlter[] = $tableName;
|
||||
|
||||
$expected_columns[] = $columnName;
|
||||
$this->_mapping[ $tableName ][ $columnName ] = $definition[2] . ' ' . str_replace( $definition[0], '', $the_table ) . ";";
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// We don't care about any other queries
|
||||
//-----------------------------------------
|
||||
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the current schema....
|
||||
$this->ipsclass->DB->return_die = 1;
|
||||
|
||||
if ( ! $this->ipsclass->DB->table_exists( $tbl_name ) )
|
||||
|
||||
//-----------------------------------------
|
||||
// Don't die on me sarge!
|
||||
//-----------------------------------------
|
||||
|
||||
ipsRegistry::DB()->return_die = 1;
|
||||
|
||||
$tableNoPrefix = preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $tableName );
|
||||
|
||||
//-----------------------------------------
|
||||
// If table is missing entirely, we need to build it
|
||||
//-----------------------------------------
|
||||
|
||||
if ( ! ipsRegistry::DB()->checkForTable( $tableNoPrefix ) )
|
||||
{
|
||||
$output[] = array( 'key' => $tbl_name,
|
||||
'table' => SQL_PREFIX.$tbl_name,
|
||||
'status' => 'error',
|
||||
'message' => 'missing table',
|
||||
'fixsql' => $table_defs[$tbl_name] );
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $tableNoPrefix OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $table_definitions[ $tableName ] );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$output[ $tableName ] = array( 'key' => $tableNoPrefix,
|
||||
'table' => $tableName,
|
||||
'status' => 'error_table',
|
||||
'fixsql' => array( $table_definitions[ $tableName ] )
|
||||
);
|
||||
|
||||
//-----------------------------------------
|
||||
// Increment error counter
|
||||
//-----------------------------------------
|
||||
|
||||
$error_count++;
|
||||
$this->ipsclass->DB->failed = 0;
|
||||
|
||||
//-----------------------------------------
|
||||
// Reset failed status
|
||||
//-----------------------------------------
|
||||
|
||||
ipsRegistry::DB()->failed = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Table exists...
|
||||
//-----------------------------------------
|
||||
|
||||
else
|
||||
{
|
||||
// Here we go...
|
||||
$missing = array();
|
||||
//-----------------------------------------
|
||||
// Loop over all the columns
|
||||
//-----------------------------------------
|
||||
|
||||
foreach( $expected_columns as $trymeout )
|
||||
{
|
||||
if( ! $this->ipsclass->DB->field_exists( $trymeout, $tbl_name ) )
|
||||
//-----------------------------------------
|
||||
// Does column exist?
|
||||
//-----------------------------------------
|
||||
|
||||
if( ! ipsRegistry::DB()->checkForField( $trymeout, $tableNoPrefix ) )
|
||||
{
|
||||
$missing[] = $trymeout;
|
||||
$query_needed = "ALTER TABLE " . SQL_PREFIX . $tbl_name . " ADD " . $this->columns_to_defs[$tbl_name][$trymeout];
|
||||
//-----------------------------------------
|
||||
// Missing - create "ALTER TABLE" query
|
||||
//-----------------------------------------
|
||||
|
||||
$query_needed = "ALTER TABLE " . $tableName . " ADD " . $this->_mapping[ $tableName ][ $trymeout ];
|
||||
|
||||
if( preg_match( "/auto_increment;/", $query_needed ) )
|
||||
//-----------------------------------------
|
||||
// If this is an autoincrement column, we need
|
||||
// to add the primary key, since it won't exist
|
||||
//-----------------------------------------
|
||||
|
||||
if( strpos( $query_needed, "auto_increment;" ) !== false )
|
||||
{
|
||||
//-----------------------------------------
|
||||
// Cut off the ";", add primary key bit
|
||||
//-----------------------------------------
|
||||
|
||||
$query_needed = substr( $query_needed, 0, -1 ).", ADD PRIMARY KEY( ". $trymeout . ");";
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Are we fixing now?
|
||||
//-----------------------------------------
|
||||
|
||||
if( preg_replace( '#^' . ipsRegistry::$settings['sql_tbl_prefix'] . '(.+?)#', "\\1", $issues_to_fix ) == $tableNoPrefix OR $issues_to_fix == 'all' )
|
||||
{
|
||||
ipsRegistry::DB()->query( $query_needed );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$missing_columns[] = $trymeout;
|
||||
|
||||
//-----------------------------------------
|
||||
// We only do this once
|
||||
//-----------------------------------------
|
||||
|
||||
if( !isset($output[ $tableName ]) OR !count($output[ $tableName ]) )
|
||||
{
|
||||
$output[ $tableName ] = array( 'key' => $tableNoPrefix,
|
||||
'table' => $tableName,
|
||||
'status' => 'error_column',
|
||||
);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// But with each error, add the query
|
||||
//-----------------------------------------
|
||||
|
||||
$output[ $tableName ]['fixsql'][] = $query_needed;
|
||||
|
||||
//-----------------------------------------
|
||||
// Increment error count
|
||||
//-----------------------------------------
|
||||
|
||||
$output[] = array( 'key' => $tbl_name.$trymeout,
|
||||
'table' => SQL_PREFIX.$tbl_name,
|
||||
'status' => 'error',
|
||||
'message' => 'Missing column \''.$trymeout.'\'',
|
||||
'fixsql' => $query_needed );
|
||||
$error_count++;
|
||||
}
|
||||
}
|
||||
if( !count( $missing ) )
|
||||
|
||||
//-----------------------------------------
|
||||
// If nothing was wrong, show ok message
|
||||
//-----------------------------------------
|
||||
|
||||
if( !count( $missing_columns ) )
|
||||
{
|
||||
$output[] = array( 'key' => $tbl_name,
|
||||
'table' => SQL_PREFIX.$tbl_name,
|
||||
$output[] = array( 'key' => $tableNoPrefix,
|
||||
'table' => $tableName,
|
||||
'column' => in_array( $tableName, $_tablesFull ) ? '' : $trymeout,
|
||||
'status' => 'ok',
|
||||
'message' => '',
|
||||
'fixsql' => '' );
|
||||
}
|
||||
}
|
||||
@@ -358,11 +716,14 @@ class db_tools
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// sql_strip_ticks from field names
|
||||
//-----------------------------------------
|
||||
|
||||
function sql_strip_ticks($data)
|
||||
/**
|
||||
* Remove ticks from statement
|
||||
*
|
||||
* @access private
|
||||
* @param string String
|
||||
* @return string String with ticks removed
|
||||
*/
|
||||
private function _sqlStripTicks( $data )
|
||||
{
|
||||
return str_replace( "`", "", $data );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,465 @@
|
||||
<?php
|
||||
// Copyright 2004-2008 Facebook. All Rights Reserved.
|
||||
//
|
||||
// +---------------------------------------------------------------------------+
|
||||
// | Facebook Platform PHP5 client |
|
||||
// +---------------------------------------------------------------------------+
|
||||
// | Copyright (c) 2007 Facebook, Inc. |
|
||||
// | All rights reserved. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | 1. Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | 2. Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
||||
// | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
||||
// | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
||||
// | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
||||
// | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
||||
// | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +---------------------------------------------------------------------------+
|
||||
// | For help with this library, contact developers-help@facebook.com |
|
||||
// +---------------------------------------------------------------------------+
|
||||
//
|
||||
include_once 'facebookapi_php5_restlib.php';
|
||||
|
||||
define('FACEBOOK_API_VALIDATION_ERROR', 1);
|
||||
class Facebook {
|
||||
public $api_client;
|
||||
|
||||
public $api_key;
|
||||
public $secret;
|
||||
public $generate_session_secret;
|
||||
public $session_expires;
|
||||
|
||||
public $fb_params;
|
||||
public $user;
|
||||
public $profile_user;
|
||||
public $canvas_user;
|
||||
|
||||
/*
|
||||
* Create a Facebook client like this:
|
||||
*
|
||||
* $fb = new Facebook(API_KEY, SECRET);
|
||||
*
|
||||
* This will automatically pull in any parameters, validate them against the
|
||||
* session signature, and chuck them in the public $fb_params member variable.
|
||||
*
|
||||
* @param api_key your Developer API key
|
||||
* @param secret your Developer API secret
|
||||
* @param generate_session_secret whether to automatically generate a session
|
||||
* if the user doesn't have one, but
|
||||
* there is an auth token present in the url,
|
||||
*/
|
||||
public function __construct($api_key, $secret, $generate_session_secret=false) {
|
||||
$this->api_key = $api_key;
|
||||
$this->secret = $secret;
|
||||
$this->generate_session_secret = $generate_session_secret;
|
||||
$this->api_client = new FacebookRestClient($api_key, $secret);
|
||||
|
||||
$this->validate_fb_params();
|
||||
if (isset($this->fb_params['friends'])) {
|
||||
$this->api_client->friends_list = explode(',', $this->fb_params['friends']);
|
||||
}
|
||||
if (isset($this->fb_params['added'])) {
|
||||
$this->api_client->added = $this->fb_params['added'];
|
||||
}
|
||||
if (isset($this->fb_params['canvas_user'])) {
|
||||
$this->api_client->canvas_user = $this->fb_params['canvas_user'];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates that the parameters passed in were sent from Facebook. It does so
|
||||
* by validating that the signature matches one that could only be generated
|
||||
* by using your application's secret key.
|
||||
*
|
||||
* Facebook-provided parameters will come from $_POST, $_GET, or $_COOKIE,
|
||||
* in that order. $_POST and $_GET are always more up-to-date than cookies,
|
||||
* so we prefer those if they are available.
|
||||
*
|
||||
* For nitty-gritty details of when each of these is used, check out
|
||||
* http://wiki.developers.facebook.com/index.php/Verifying_The_Signature
|
||||
*
|
||||
* @param bool resolve_auth_token convert an auth token into a session
|
||||
*/
|
||||
public function validate_fb_params($resolve_auth_token=true) {
|
||||
$this->fb_params = $this->get_valid_fb_params($_POST, 48*3600, 'fb_sig');
|
||||
|
||||
// note that with preload FQL, it's possible to receive POST params in
|
||||
// addition to GET, so use a different prefix to differentiate them
|
||||
if (!$this->fb_params) {
|
||||
$fb_params = $this->get_valid_fb_params($_GET, 48*3600, 'fb_sig');
|
||||
$fb_post_params = $this->get_valid_fb_params($_POST, 48*3600, 'fb_post_sig');
|
||||
$this->fb_params = array_merge($fb_params, $fb_post_params);
|
||||
}
|
||||
|
||||
// Okay, something came in via POST or GET
|
||||
if ($this->fb_params) {
|
||||
$user = isset($this->fb_params['user']) ?
|
||||
$this->fb_params['user'] : null;
|
||||
$this->profile_user = isset($this->fb_params['profile_user']) ?
|
||||
$this->fb_params['profile_user'] : null;
|
||||
$this->canvas_user = isset($this->fb_params['canvas_user']) ?
|
||||
$this->fb_params['canvas_user'] : null;
|
||||
|
||||
if (isset($this->fb_params['session_key'])) {
|
||||
$session_key = $this->fb_params['session_key'];
|
||||
} else if (isset($this->fb_params['profile_session_key'])) {
|
||||
$session_key = $this->fb_params['profile_session_key'];
|
||||
} else {
|
||||
$session_key = null;
|
||||
}
|
||||
$expires = isset($this->fb_params['expires']) ?
|
||||
$this->fb_params['expires'] : null;
|
||||
$this->set_user($user,
|
||||
$session_key,
|
||||
$expires);
|
||||
}
|
||||
// if no Facebook parameters were found in the GET or POST variables,
|
||||
// then fall back to cookies, which may have cached user information
|
||||
// Cookies are also used to receive session data via the Javascript API
|
||||
else if ($cookies =
|
||||
$this->get_valid_fb_params($_COOKIE, null, $this->api_key)) {
|
||||
// use $api_key . '_' as a prefix for the cookies in case there are
|
||||
// multiple facebook clients on the same domain.
|
||||
$expires = isset($cookies['expires']) ? $cookies['expires'] : null;
|
||||
$this->set_user($cookies['user'],
|
||||
$cookies['session_key'],
|
||||
$expires);
|
||||
}
|
||||
// finally, if we received no parameters, but the 'auth_token' GET var
|
||||
// is present, then we are in the middle of auth handshake,
|
||||
// so go ahead and create the session
|
||||
else if ($resolve_auth_token && isset($_GET['auth_token']) &&
|
||||
$session = $this->do_get_session($_GET['auth_token'])) {
|
||||
if ($this->generate_session_secret &&
|
||||
!empty($session['secret'])) {
|
||||
$session_secret = $session['secret'];
|
||||
}
|
||||
$this->set_user($session['uid'],
|
||||
$session['session_key'],
|
||||
$session['expires'],
|
||||
isset($session_secret) ? $session_secret : null);
|
||||
}
|
||||
|
||||
return !empty($this->fb_params);
|
||||
}
|
||||
|
||||
// Store a temporary session secret for the current session
|
||||
// for use with the JS client library
|
||||
public function promote_session() {
|
||||
try {
|
||||
$session_secret = $this->api_client->auth_promoteSession();
|
||||
if (!$this->in_fb_canvas()) {
|
||||
$this->set_cookies($this->user, $this->api_client->session_key, $this->session_expires, $session_secret);
|
||||
}
|
||||
return $session_secret;
|
||||
} catch (FacebookRestClientException $e) {
|
||||
// API_EC_PARAM means we don't have a logged in user, otherwise who
|
||||
// knows what it means, so just throw it.
|
||||
if ($e->getCode() != FacebookAPIErrorCodes::API_EC_PARAM) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function do_get_session($auth_token) {
|
||||
try {
|
||||
return $this->api_client->auth_getSession($auth_token, $this->generate_session_secret);
|
||||
} catch (FacebookRestClientException $e) {
|
||||
// API_EC_PARAM means we don't have a logged in user, otherwise who
|
||||
// knows what it means, so just throw it.
|
||||
if ($e->getCode() != FacebookAPIErrorCodes::API_EC_PARAM) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate the session currently being used, and clear any state associated with it
|
||||
public function expire_session() {
|
||||
if ($this->api_client->auth_expireSession()) {
|
||||
if (!$this->in_fb_canvas() && isset($_COOKIE[$this->api_key . '_user'])) {
|
||||
$cookies = array('user', 'session_key', 'expires', 'ss');
|
||||
foreach ($cookies as $name) {
|
||||
setcookie($this->api_key . '_' . $name, false, time() - 3600);
|
||||
unset($_COOKIE[$this->api_key . '_' . $name]);
|
||||
}
|
||||
setcookie($this->api_key, false, time() - 3600);
|
||||
unset($_COOKIE[$this->api_key]);
|
||||
}
|
||||
|
||||
// now, clear the rest of the stored state
|
||||
$this->user = 0;
|
||||
$this->api_client->session_key = 0;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function redirect($url) {
|
||||
if ($this->in_fb_canvas()) {
|
||||
echo '<fb:redirect url="' . $url . '"/>';
|
||||
} else if (preg_match('/^https?:\/\/([^\/]*\.)?facebook\.com(:\d+)?/i', $url)) {
|
||||
// make sure facebook.com url's load in the full frame so that we don't
|
||||
// get a frame within a frame.
|
||||
echo "<script type=\"text/javascript\">\ntop.location.href = \"$url\";\n</script>";
|
||||
} else {
|
||||
header('Location: ' . $url);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
public function in_frame() {
|
||||
return isset($this->fb_params['in_canvas']) || isset($this->fb_params['in_iframe']);
|
||||
}
|
||||
public function in_fb_canvas() {
|
||||
return isset($this->fb_params['in_canvas']);
|
||||
}
|
||||
|
||||
public function get_loggedin_user() {
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function get_canvas_user() {
|
||||
return $this->canvas_user;
|
||||
}
|
||||
|
||||
public function get_profile_user() {
|
||||
return $this->profile_user;
|
||||
}
|
||||
|
||||
public static function current_url() {
|
||||
return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
// require_add and require_install have been removed.
|
||||
// see http://developer.facebook.com/news.php?blog=1&story=116 for more details
|
||||
public function require_login() {
|
||||
if ($user = $this->get_loggedin_user()) {
|
||||
return $user;
|
||||
}
|
||||
$this->redirect($this->get_login_url(self::current_url(), $this->in_frame()));
|
||||
}
|
||||
|
||||
public function require_frame() {
|
||||
if (!$this->in_frame()) {
|
||||
$this->redirect($this->get_login_url(self::current_url(), true));
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_facebook_url($subdomain='www') {
|
||||
return 'http://' . $subdomain . '.new.facebook.com';
|
||||
}
|
||||
|
||||
public function get_install_url($next=null) {
|
||||
// this was renamed, keeping for compatibility's sake
|
||||
return $this->get_add_url($next);
|
||||
}
|
||||
|
||||
public function get_add_url($next=null) {
|
||||
return self::get_facebook_url().'/add.php?api_key='.$this->api_key .
|
||||
($next ? '&next=' . urlencode($next) : '');
|
||||
}
|
||||
|
||||
public function get_login_url($next, $canvas) {
|
||||
return self::get_facebook_url().'/login.php?v=1.0&api_key=' . $this->api_key .
|
||||
($next ? '&next=' . urlencode($next) : '') .
|
||||
($canvas ? '&canvas' : '');
|
||||
}
|
||||
|
||||
public function set_user($user, $session_key, $expires=null, $session_secret=null) {
|
||||
if (!$this->in_fb_canvas() && (!isset($_COOKIE[$this->api_key . '_user'])
|
||||
|| $_COOKIE[$this->api_key . '_user'] != $user)) {
|
||||
$this->set_cookies($user, $session_key, $expires, $session_secret);
|
||||
}
|
||||
$this->user = $user;
|
||||
$this->api_client->session_key = $session_key;
|
||||
$this->session_expires = $expires;
|
||||
}
|
||||
|
||||
public function set_cookies($user, $session_key, $expires=null, $session_secret=null) {
|
||||
$cookies = array();
|
||||
$cookies['user'] = $user;
|
||||
$cookies['session_key'] = $session_key;
|
||||
if ($expires != null) {
|
||||
$cookies['expires'] = $expires;
|
||||
}
|
||||
if ($session_secret != null) {
|
||||
$cookies['ss'] = $session_secret;
|
||||
}
|
||||
foreach ($cookies as $name => $val) {
|
||||
setcookie($this->api_key . '_' . $name, $val, (int)$expires);
|
||||
$_COOKIE[$this->api_key . '_' . $name] = $val;
|
||||
}
|
||||
$sig = self::generate_sig($cookies, $this->secret);
|
||||
setcookie($this->api_key, $sig, (int)$expires);
|
||||
$_COOKIE[$this->api_key] = $sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to undo the badness of magic quotes as best we can
|
||||
* @param string $val Should come directly from $_GET, $_POST, etc.
|
||||
* @return string val without added slashes
|
||||
*/
|
||||
public static function no_magic_quotes($val) {
|
||||
if (get_magic_quotes_gpc()) {
|
||||
return stripslashes($val);
|
||||
} else {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the signed parameters that were sent from Facebook. Validates the set
|
||||
* of parameters against the included signature.
|
||||
*
|
||||
* Since Facebook sends data to your callback URL via unsecured means, the
|
||||
* signature is the only way to make sure that the data actually came from
|
||||
* Facebook. So if an app receives a request at the callback URL, it should
|
||||
* always verify the signature that comes with against your own secret key.
|
||||
* Otherwise, it's possible for someone to spoof a request by
|
||||
* pretending to be someone else, i.e.:
|
||||
* www.your-callback-url.com/?fb_user=10101
|
||||
*
|
||||
* This is done automatically by verify_fb_params.
|
||||
*
|
||||
* @param assoc $params a full array of external parameters.
|
||||
* presumed $_GET, $_POST, or $_COOKIE
|
||||
* @param int $timeout number of seconds that the args are good for.
|
||||
* Specifically good for forcing cookies to expire.
|
||||
* @param string $namespace prefix string for the set of parameters we want
|
||||
* to verify. i.e., fb_sig or fb_post_sig
|
||||
*
|
||||
* @return assoc the subset of parameters containing the given prefix,
|
||||
* and also matching the signature associated with them.
|
||||
* OR an empty array if the params do not validate
|
||||
*/
|
||||
public function get_valid_fb_params($params, $timeout=null, $namespace='fb_sig') {
|
||||
$prefix = $namespace . '_';
|
||||
$prefix_len = strlen($prefix);
|
||||
$fb_params = array();
|
||||
if (empty($params)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($params as $name => $val) {
|
||||
// pull out only those parameters that match the prefix
|
||||
// note that the signature itself ($params[$namespace]) is not in the list
|
||||
if (strpos($name, $prefix) === 0) {
|
||||
$fb_params[substr($name, $prefix_len)] = self::no_magic_quotes($val);
|
||||
}
|
||||
}
|
||||
|
||||
// validate that the request hasn't expired. this is most likely
|
||||
// for params that come from $_COOKIE
|
||||
if ($timeout && (!isset($fb_params['time']) || time() - $fb_params['time'] > $timeout)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// validate that the params match the signature
|
||||
$signature = isset($params[$namespace]) ? $params[$namespace] : null;
|
||||
if (!$signature || (!$this->verify_signature($fb_params, $signature))) {
|
||||
return array();
|
||||
}
|
||||
return $fb_params;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates that a given set of parameters match their signature.
|
||||
* Parameters all match a given input prefix, such as "fb_sig".
|
||||
*
|
||||
* @param $fb_params an array of all Facebook-sent parameters,
|
||||
* not including the signature itself
|
||||
* @param $expected_sig the expected result to check against
|
||||
*/
|
||||
public function verify_signature($fb_params, $expected_sig) {
|
||||
return self::generate_sig($fb_params, $this->secret) == $expected_sig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a signature using the application secret key.
|
||||
*
|
||||
* The only two entities that know your secret key are you and Facebook,
|
||||
* according to the Terms of Service. Since nobody else can generate
|
||||
* the signature, you can rely on it to verify that the information
|
||||
* came from Facebook.
|
||||
*
|
||||
* @param $params_array an array of all Facebook-sent parameters,
|
||||
* NOT INCLUDING the signature itself
|
||||
* @param $secret your app's secret key
|
||||
*
|
||||
* @return a hash to be checked against the signature provided by Facebook
|
||||
*/
|
||||
public static function generate_sig($params_array, $secret) {
|
||||
$str = '';
|
||||
|
||||
ksort($params_array);
|
||||
// Note: make sure that the signature parameter is not already included in
|
||||
// $params_array.
|
||||
foreach ($params_array as $k=>$v) {
|
||||
$str .= "$k=$v";
|
||||
}
|
||||
$str .= $secret;
|
||||
|
||||
return md5($str);
|
||||
}
|
||||
|
||||
public function encode_validationError($summary, $message) {
|
||||
return json_encode(
|
||||
array('errorCode' => FACEBOOK_API_VALIDATION_ERROR,
|
||||
'errorTitle' => $summary,
|
||||
'errorMessage' => $message));
|
||||
}
|
||||
|
||||
public function encode_multiFeedStory($feed, $next) {
|
||||
return json_encode(
|
||||
array('method' => 'multiFeedStory',
|
||||
'content' =>
|
||||
array('next' => $next,
|
||||
'feed' => $feed)));
|
||||
}
|
||||
|
||||
public function encode_feedStory($feed, $next) {
|
||||
return json_encode(
|
||||
array('method' => 'feedStory',
|
||||
'content' =>
|
||||
array('next' => $next,
|
||||
'feed' => $feed)));
|
||||
}
|
||||
|
||||
public function create_templatizedFeedStory($title_template, $title_data=array(),
|
||||
$body_template='', $body_data = array(), $body_general=null,
|
||||
$image_1=null, $image_1_link=null,
|
||||
$image_2=null, $image_2_link=null,
|
||||
$image_3=null, $image_3_link=null,
|
||||
$image_4=null, $image_4_link=null) {
|
||||
return array('title_template'=> $title_template,
|
||||
'title_data' => $title_data,
|
||||
'body_template'=> $body_template,
|
||||
'body_data' => $body_data,
|
||||
'body_general' => $body_general,
|
||||
'image_1' => $image_1,
|
||||
'image_1_link' => $image_1_link,
|
||||
'image_2' => $image_2,
|
||||
'image_2_link' => $image_2_link,
|
||||
'image_3' => $image_3,
|
||||
'image_3_link' => $image_3_link,
|
||||
'image_4' => $image_4,
|
||||
'image_4_link' => $image_4_link);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
// Copyright 2004-2008 Facebook. All Rights Reserved.
|
||||
//
|
||||
// +---------------------------------------------------------------------------+
|
||||
// | Facebook Platform PHP5 client |
|
||||
// +---------------------------------------------------------------------------+
|
||||
// | Copyright (c) 2007 Facebook, Inc. |
|
||||
// | All rights reserved. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | 1. Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | 2. Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
||||
// | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
||||
// | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
||||
// | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
||||
// | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
||||
// | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +---------------------------------------------------------------------------+
|
||||
// | For help with this library, contact developers-help@facebook.com |
|
||||
// +---------------------------------------------------------------------------+
|
||||
//
|
||||
|
||||
/**
|
||||
* This class extends and modifies the "Facebook" class to better
|
||||
* suit desktop apps.
|
||||
*/
|
||||
class FacebookDesktop extends Facebook {
|
||||
// the application secret, which differs from the session secret
|
||||
public $app_secret;
|
||||
public $verify_sig;
|
||||
|
||||
public function __construct($api_key, $secret) {
|
||||
$this->app_secret = $secret;
|
||||
$this->verify_sig = false;
|
||||
parent::__construct($api_key, $secret);
|
||||
}
|
||||
|
||||
public function do_get_session($auth_token) {
|
||||
$this->api_client->secret = $this->app_secret;
|
||||
$this->api_client->session_key = null;
|
||||
$session_info = parent::do_get_session($auth_token);
|
||||
if (!empty($session_info['secret'])) {
|
||||
// store the session secret
|
||||
$this->set_session_secret($session_info['secret']);
|
||||
}
|
||||
return $session_info;
|
||||
}
|
||||
|
||||
public function set_session_secret($session_secret) {
|
||||
$this->secret = $session_secret;
|
||||
$this->api_client->secret = $session_secret;
|
||||
}
|
||||
|
||||
public function require_login() {
|
||||
if ($this->get_loggedin_user()) {
|
||||
try {
|
||||
// try a session-based API call to ensure that we have the correct
|
||||
// session secret
|
||||
$user = $this->api_client->users_getLoggedInUser();
|
||||
|
||||
// now that we have a valid session secret, verify the signature
|
||||
$this->verify_sig = true;
|
||||
if ($this->validate_fb_params(false)) {
|
||||
return $user;
|
||||
} else {
|
||||
// validation failed
|
||||
return null;
|
||||
}
|
||||
} catch (FacebookRestClientException $ex) {
|
||||
if (isset($_GET['auth_token'])) {
|
||||
// if we have an auth_token, use it to establish a session
|
||||
$session_info = $this->do_get_session($_GET['auth_token']);
|
||||
if ($session_info) {
|
||||
return $session_info['uid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we get here, we need to redirect the user to log in
|
||||
$this->redirect($this->get_login_url(self::current_url(), $this->in_fb_canvas()));
|
||||
}
|
||||
|
||||
public function verify_signature($fb_params, $expected_sig) {
|
||||
// we don't want to verify the signature until we have a valid
|
||||
// session secret
|
||||
if ($this->verify_sig) {
|
||||
return parent::verify_signature($fb_params, $expected_sig);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,806 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
* format. It is easy for humans to read and write. It is easy for machines
|
||||
* to parse and generate. It is based on a subset of the JavaScript
|
||||
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
||||
* This feature can also be found in Python. JSON is a text format that is
|
||||
* completely language independent but uses conventions that are familiar
|
||||
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
||||
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
||||
* ideal data-interchange language.
|
||||
*
|
||||
* This package provides a simple encoder and decoder for JSON notation. It
|
||||
* is intended for use with client-side Javascript applications that make
|
||||
* use of HTTPRequest to perform server communication functions - data can
|
||||
* be encoded into JSON notation for use in a client-side javascript, or
|
||||
* decoded from incoming Javascript requests. JSON format is native to
|
||||
* Javascript, and can be directly eval()'ed with no further parsing
|
||||
* overhead
|
||||
*
|
||||
* All strings should be in ASCII or UTF-8 format!
|
||||
*
|
||||
* LICENSE: Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met: Redistributions of source code must retain the
|
||||
* above copyright notice, this list of conditions and the following
|
||||
* disclaimer. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* @category
|
||||
* @package Services_JSON
|
||||
* @author Michal Migurski <mike-json@teczno.com>
|
||||
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
||||
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
||||
* @copyright 2005 Michal Migurski
|
||||
* @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_SLICE', 1);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_STR', 2);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_ARR', 3);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_OBJ', 4);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_CMT', 5);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* Brief example of use:
|
||||
*
|
||||
* <code>
|
||||
* // create a new instance of Services_JSON
|
||||
* $json = new Services_JSON();
|
||||
*
|
||||
* // convert a complexe value to JSON notation, and send it to the browser
|
||||
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
||||
* $output = $json->encode($value);
|
||||
*
|
||||
* print($output);
|
||||
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
||||
*
|
||||
* // accept incoming POST data, assumed to be in JSON notation
|
||||
* $input = file_get_contents('php://input', 1000000);
|
||||
* $value = $json->decode($input);
|
||||
* </code>
|
||||
*/
|
||||
class Services_JSON
|
||||
{
|
||||
/**
|
||||
* constructs a new JSON instance
|
||||
*
|
||||
* @param int $use object behavior flags; combine with boolean-OR
|
||||
*
|
||||
* possible values:
|
||||
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
||||
* "{...}" syntax creates associative arrays
|
||||
* instead of objects in decode().
|
||||
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
||||
* Values which can't be encoded (e.g. resources)
|
||||
* appear as NULL instead of throwing errors.
|
||||
* By default, a deeply-nested resource will
|
||||
* bubble up with an error, so all return values
|
||||
* from encode() should be checked with isError()
|
||||
*/
|
||||
function Services_JSON($use = 0)
|
||||
{
|
||||
$this->use = $use;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-16 char to one UTF-8 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf16 UTF-16 character
|
||||
* @return string UTF-8 character
|
||||
* @access private
|
||||
*/
|
||||
function utf162utf8($utf16)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||
}
|
||||
|
||||
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
||||
|
||||
switch(true) {
|
||||
case ((0x7F & $bytes) == $bytes):
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x7F & $bytes);
|
||||
|
||||
case (0x07FF & $bytes) == $bytes:
|
||||
// return a 2-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
|
||||
case (0xFFFF & $bytes) == $bytes:
|
||||
// return a 3-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
||||
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-8 char to one UTF-16 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf8 UTF-8 character
|
||||
* @return string UTF-16 character
|
||||
* @access private
|
||||
*/
|
||||
function utf82utf16($utf8)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
}
|
||||
|
||||
switch(strlen($utf8)) {
|
||||
case 1:
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return $utf8;
|
||||
|
||||
case 2:
|
||||
// return a UTF-16 character from a 2-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x07 & (ord($utf8{0}) >> 2))
|
||||
. chr((0xC0 & (ord($utf8{0}) << 6))
|
||||
| (0x3F & ord($utf8{1})));
|
||||
|
||||
case 3:
|
||||
// return a UTF-16 character from a 3-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr((0xF0 & (ord($utf8{0}) << 4))
|
||||
| (0x0F & (ord($utf8{1}) >> 2)))
|
||||
. chr((0xC0 & (ord($utf8{1}) << 6))
|
||||
| (0x7F & ord($utf8{2})));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function encode($var)
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case 'boolean':
|
||||
return $var ? 'true' : 'false';
|
||||
|
||||
case 'NULL':
|
||||
return 'null';
|
||||
|
||||
case 'integer':
|
||||
return (int) $var;
|
||||
|
||||
case 'double':
|
||||
case 'float':
|
||||
return (float) $var;
|
||||
|
||||
case 'string':
|
||||
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
||||
$ascii = '';
|
||||
$strlen_var = strlen($var);
|
||||
|
||||
/*
|
||||
* Iterate over every character in the string,
|
||||
* escaping with a slash or encoding to UTF-8 where necessary
|
||||
*/
|
||||
for ($c = 0; $c < $strlen_var; ++$c) {
|
||||
|
||||
$ord_var_c = ord($var{$c});
|
||||
|
||||
switch (true) {
|
||||
case $ord_var_c == 0x08:
|
||||
$ascii .= '\b';
|
||||
break;
|
||||
case $ord_var_c == 0x09:
|
||||
$ascii .= '\t';
|
||||
break;
|
||||
case $ord_var_c == 0x0A:
|
||||
$ascii .= '\n';
|
||||
break;
|
||||
case $ord_var_c == 0x0C:
|
||||
$ascii .= '\f';
|
||||
break;
|
||||
case $ord_var_c == 0x0D:
|
||||
$ascii .= '\r';
|
||||
break;
|
||||
|
||||
case $ord_var_c == 0x22:
|
||||
case $ord_var_c == 0x2F:
|
||||
case $ord_var_c == 0x5C:
|
||||
// double quote, slash, slosh
|
||||
$ascii .= '\\'.$var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
||||
// characters U-00000000 - U-0000007F (same as ASCII)
|
||||
$ascii .= $var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xE0) == 0xC0):
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
||||
$c += 1;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF0) == 0xE0):
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}));
|
||||
$c += 2;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF8) == 0xF0):
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}));
|
||||
$c += 3;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFC) == 0xF8):
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}));
|
||||
$c += 4;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFE) == 0xFC):
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}),
|
||||
ord($var{$c + 5}));
|
||||
$c += 5;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '"'.$ascii.'"';
|
||||
|
||||
case 'array':
|
||||
/*
|
||||
* As per JSON spec if any array key is not an integer
|
||||
* we must treat the the whole array as an object. We
|
||||
* also try to catch a sparsely populated associative
|
||||
* array with numeric keys here because some JS engines
|
||||
* will create an array with empty indexes up to
|
||||
* max_index which can cause memory issues and because
|
||||
* the keys, which may be relevant, will be remapped
|
||||
* otherwise.
|
||||
*
|
||||
* As per the ECMA and JSON specification an object may
|
||||
* have any string as a property. Unfortunately due to
|
||||
* a hole in the ECMA specification if the key is a
|
||||
* ECMA reserved word or starts with a digit the
|
||||
* parameter is only accessible using ECMAScript's
|
||||
* bracket notation.
|
||||
*/
|
||||
|
||||
// treat as a JSON object
|
||||
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($var),
|
||||
array_values($var));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
}
|
||||
|
||||
// treat it like a regular array
|
||||
$elements = array_map(array($this, 'encode'), $var);
|
||||
|
||||
foreach($elements as $element) {
|
||||
if(Services_JSON::isError($element)) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
return '[' . join(',', $elements) . ']';
|
||||
|
||||
case 'object':
|
||||
$vars = get_object_vars($var);
|
||||
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($vars),
|
||||
array_values($vars));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
|
||||
default:
|
||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||
? 'null'
|
||||
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* array-walking function for use in generating JSON-formatted name-value pairs
|
||||
*
|
||||
* @param string $name name of key to use
|
||||
* @param mixed $value reference to an array element to be encoded
|
||||
*
|
||||
* @return string JSON-formatted name-value pair, like '"name":value'
|
||||
* @access private
|
||||
*/
|
||||
function name_value($name, $value)
|
||||
{
|
||||
$encoded_value = $this->encode($value);
|
||||
|
||||
if(Services_JSON::isError($encoded_value)) {
|
||||
return $encoded_value;
|
||||
}
|
||||
|
||||
return $this->encode(strval($name)) . ':' . $encoded_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* reduce a string by removing leading and trailing comments and whitespace
|
||||
*
|
||||
* @param $str string string value to strip of comments and whitespace
|
||||
*
|
||||
* @return string string value stripped of comments and whitespace
|
||||
* @access private
|
||||
*/
|
||||
function reduce_string($str)
|
||||
{
|
||||
$str = preg_replace(array(
|
||||
|
||||
// eliminate single line comments in '// ...' form
|
||||
'#^\s*//(.+)$#m',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at start of string
|
||||
'#^\s*/\*(.+)\*/#Us',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at end of string
|
||||
'#/\*(.+)\*/\s*$#Us'
|
||||
|
||||
), '', $str);
|
||||
|
||||
// eliminate extraneous space
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a JSON string into appropriate variable
|
||||
*
|
||||
* @param string $str JSON-formatted string
|
||||
*
|
||||
* @return mixed number, boolean, string, array, or object
|
||||
* corresponding to given JSON input string.
|
||||
* See argument 1 to Services_JSON() above for object-output behavior.
|
||||
* Note that decode() always returns strings
|
||||
* in ASCII or UTF-8 format!
|
||||
* @access public
|
||||
*/
|
||||
function decode($str)
|
||||
{
|
||||
$str = $this->reduce_string($str);
|
||||
|
||||
switch (strtolower($str)) {
|
||||
case 'true':
|
||||
return true;
|
||||
|
||||
case 'false':
|
||||
return false;
|
||||
|
||||
case 'null':
|
||||
return null;
|
||||
|
||||
default:
|
||||
$m = array();
|
||||
|
||||
if (is_numeric($str)) {
|
||||
// Lookie-loo, it's a number
|
||||
|
||||
// This would work on its own, but I'm trying to be
|
||||
// good about returning integers where appropriate:
|
||||
// return (float)$str;
|
||||
|
||||
// Return float or int, as appropriate
|
||||
return ((float)$str == (integer)$str)
|
||||
? (integer)$str
|
||||
: (float)$str;
|
||||
|
||||
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
||||
// STRINGS RETURNED IN UTF-8 FORMAT
|
||||
$delim = substr($str, 0, 1);
|
||||
$chrs = substr($str, 1, -1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
||||
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
$ord_chrs_c = ord($chrs{$c});
|
||||
|
||||
switch (true) {
|
||||
case $substr_chrs_c_2 == '\b':
|
||||
$utf8 .= chr(0x08);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\t':
|
||||
$utf8 .= chr(0x09);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\n':
|
||||
$utf8 .= chr(0x0A);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\f':
|
||||
$utf8 .= chr(0x0C);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\r':
|
||||
$utf8 .= chr(0x0D);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case $substr_chrs_c_2 == '\\"':
|
||||
case $substr_chrs_c_2 == '\\\'':
|
||||
case $substr_chrs_c_2 == '\\\\':
|
||||
case $substr_chrs_c_2 == '\\/':
|
||||
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
||||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
||||
$utf8 .= $chrs{++$c};
|
||||
}
|
||||
break;
|
||||
|
||||
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
||||
// single, escaped unicode character
|
||||
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
||||
$utf8 .= $this->utf162utf8($utf16);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
||||
$utf8 .= $chrs{$c};
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xE0) == 0xC0:
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 2);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF0) == 0xE0:
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 3);
|
||||
$c += 2;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF8) == 0xF0:
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 4);
|
||||
$c += 3;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFC) == 0xF8:
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 5);
|
||||
$c += 4;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFE) == 0xFC:
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 6);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $utf8;
|
||||
|
||||
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
||||
// array, or object notation
|
||||
|
||||
if ($str{0} == '[') {
|
||||
$stk = array(SERVICES_JSON_IN_ARR);
|
||||
$arr = array();
|
||||
} else {
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = array();
|
||||
} else {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = new stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
||||
'where' => 0,
|
||||
'delim' => false));
|
||||
|
||||
$chrs = substr($str, 1, -1);
|
||||
$chrs = $this->reduce_string($chrs);
|
||||
|
||||
if ($chrs == '') {
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} else {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//print("\nparsing {$chrs}\n");
|
||||
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
|
||||
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
||||
// found a comma that is not inside a string, array, etc.,
|
||||
// OR we've reached the end of the character list
|
||||
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
||||
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
// we are in an array, so just push an element onto the stack
|
||||
array_push($arr, $this->decode($slice));
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
// we are in an object, so figure
|
||||
// out the property name and set an
|
||||
// element in an associative array,
|
||||
// for now
|
||||
$parts = array();
|
||||
|
||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// "name":value pair
|
||||
$key = $this->decode($parts[1]);
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// name:value pair, where name is unquoted
|
||||
$key = $parts[1];
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
||||
// found a quote, and we are not inside a string
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
|
||||
//print("Found start of string at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == $top['delim']) &&
|
||||
($top['what'] == SERVICES_JSON_IN_STR) &&
|
||||
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
||||
// found a quote, we're in a string, and it's not escaped
|
||||
// we know that it's not escaped becase there is _not_ an
|
||||
// odd number of backslashes at the end of the string so far
|
||||
array_pop($stk);
|
||||
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '[') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-bracket, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of array at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
||||
// found a right-bracket, and we're in an array
|
||||
array_pop($stk);
|
||||
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '{') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-brace, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of object at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
||||
// found a right-brace, and we're in an object
|
||||
array_pop($stk);
|
||||
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '/*') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a comment start, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
||||
$c++;
|
||||
//print("Found start of comment at {$c}\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
||||
// found a comment end, and we're in one now
|
||||
array_pop($stk);
|
||||
$c++;
|
||||
|
||||
for ($i = $top['where']; $i <= $c; ++$i)
|
||||
$chrs = substr_replace($chrs, ' ', $i, 1);
|
||||
|
||||
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this should just call PEAR::isError()
|
||||
*/
|
||||
function isError($data, $code = null)
|
||||
{
|
||||
if (class_exists('pear')) {
|
||||
return PEAR::isError($data, $code);
|
||||
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||
is_subclass_of($data, 'services_json_error'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists('PEAR_Error')) {
|
||||
|
||||
class Services_JSON_Error extends PEAR_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||
*/
|
||||
class Services_JSON_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,21 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
# In PHP 5.2 or higher we don't need to bring this in
|
||||
if (!function_exists('json_encode')) {
|
||||
require_once 'jsonwrapper_inner.php';
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
require_once 'JSON/JSON.php';
|
||||
|
||||
function json_encode($arg)
|
||||
{
|
||||
global $services_json;
|
||||
if (!isset($services_json)) {
|
||||
$services_json = new Services_JSON();
|
||||
}
|
||||
return $services_json->encode($arg);
|
||||
}
|
||||
|
||||
function json_decode($arg)
|
||||
{
|
||||
global $services_json;
|
||||
if (!isset($services_json)) {
|
||||
$services_json = new Services_JSON();
|
||||
}
|
||||
return $services_json->decode($arg);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
|
||||
$PATH_TO_CLASS = dirname(ereg_replace("\\\\", "/", __FILE__)) . "/" . "ConvertTables" . "/";
|
||||
define ("CONVERT_TABLES_DIR", $PATH_TO_CLASS);
|
||||
define ("DEBUG_MODE", 1);
|
||||
|
||||
|
||||
class ConvertCharset{
|
||||
var $RecognizedEncoding; // (boolean) This value keeps information if string contains multibyte chars.
|
||||
var $Entities; // (boolean) This value keeps information if output should be with numeric entities.
|
||||
var $FromCharset; // (string) This value keeps information about source (from) encoding
|
||||
var $ToCharset; // (string) This value keeps information about destination (to) encoding
|
||||
var $CharsetTable; // (array) This property keeps convert Table inside
|
||||
|
||||
|
||||
|
||||
function ConvertCharset ($FromCharset, $ToCharset, $TurnOnEntities = false)
|
||||
{
|
||||
|
||||
$this -> FromCharset = strtolower($FromCharset);
|
||||
$this -> ToCharset = strtolower($ToCharset);
|
||||
$this -> Entities = $TurnOnEntities;
|
||||
|
||||
|
||||
if ($this -> FromCharset == $this -> ToCharset)
|
||||
{
|
||||
print $this -> DebugOutput(1, 0, $this -> FromCharset);
|
||||
}
|
||||
if (($this -> FromCharset == $this -> ToCharset) AND ($this -> FromCharset == "utf-8"))
|
||||
{
|
||||
print $this -> DebugOutput(0, 4, $this -> FromCharset);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if ($this -> FromCharset == "utf-8")
|
||||
{
|
||||
$this -> CharsetTable = $this -> MakeConvertTable ($this -> ToCharset);
|
||||
}
|
||||
else if ($this -> ToCharset == "utf-8")
|
||||
{
|
||||
$this -> CharsetTable = $this -> MakeConvertTable ($this -> FromCharset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this -> CharsetTable = $this -> MakeConvertTable ($this -> FromCharset, $this -> ToCharset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function UnicodeEntity ($UnicodeString)
|
||||
{
|
||||
$OutString = "";
|
||||
$StringLenght = strlen ($UnicodeString);
|
||||
for ($CharPosition = 0; $CharPosition < $StringLenght; $CharPosition++)
|
||||
{
|
||||
$Char = $UnicodeString [$CharPosition];
|
||||
$AsciiChar = ord ($Char);
|
||||
|
||||
if ($AsciiChar < 128){
|
||||
$OutString .= $Char;
|
||||
}
|
||||
else if ($AsciiChar >> 5 == 6){
|
||||
$FirstByte = ($AsciiChar & 31);
|
||||
$CharPosition++;
|
||||
$Char = $UnicodeString [$CharPosition];
|
||||
$AsciiChar = ord ($Char);
|
||||
$SecondByte = ($AsciiChar & 63);
|
||||
$AsciiChar = ($FirstByte * 64) + $SecondByte;
|
||||
$Entity = sprintf ("&#%d;", $AsciiChar);
|
||||
$OutString .= $Entity;
|
||||
}
|
||||
else if ($AsciiChar >> 4 == 14){
|
||||
$FirstByte = ($AsciiChar & 31);
|
||||
$CharPosition++;
|
||||
$Char = $UnicodeString [$CharPosition];
|
||||
$AsciiChar = ord ($Char);
|
||||
$SecondByte = ($AsciiChar & 63);
|
||||
$CharPosition++;
|
||||
$Char = $UnicodeString [$CharPosition];
|
||||
$AsciiChar = ord ($Char);
|
||||
$ThidrByte = ($AsciiChar & 63);
|
||||
$AsciiChar = ((($FirstByte * 64) + $SecondByte) * 64) + $ThidrByte;
|
||||
|
||||
$Entity = sprintf ("&#%d;", $AsciiChar);
|
||||
$OutString .= $Entity;
|
||||
}
|
||||
else if ($AsciiChar >> 3 == 30){
|
||||
$FirstByte = ($AsciiChar & 31);
|
||||
$CharPosition++;
|
||||
$Char = $UnicodeString [$CharPosition];
|
||||
$AsciiChar = ord ($Char);
|
||||
$SecondByte = ($AsciiChar & 63);
|
||||
$CharPosition++;
|
||||
$Char = $UnicodeString [$CharPosition];
|
||||
$AsciiChar = ord ($Char);
|
||||
$ThidrByte = ($AsciiChar & 63);
|
||||
$CharPosition++;
|
||||
$Char = $UnicodeString [$CharPosition];
|
||||
$AsciiChar = ord ($Char);
|
||||
$FourthByte = ($AsciiChar & 63);
|
||||
$AsciiChar = ((((($FirstByte * 64) + $SecondByte) * 64) + $ThidrByte) * 64) + $FourthByte;
|
||||
|
||||
$Entity = sprintf ("&#%d;", $AsciiChar);
|
||||
$OutString .= $Entity;
|
||||
}
|
||||
}
|
||||
return $OutString;
|
||||
}
|
||||
|
||||
|
||||
function HexToUtf ($UtfCharInHex)
|
||||
{
|
||||
$OutputChar = "";
|
||||
$UtfCharInDec = hexdec($UtfCharInHex);
|
||||
if($UtfCharInDec < 128) $OutputChar .= chr($UtfCharInDec);
|
||||
else if($UtfCharInDec < 2048)$OutputChar .= chr(($UtfCharInDec >> 6) + 192) . chr(($UtfCharInDec & 63) + 128);
|
||||
else if($UtfCharInDec < 65536)$OutputChar .= chr(($UtfCharInDec >> 12) + 224) . chr((($UtfCharInDec >> 6) & 63) + 128) . chr(($UtfCharInDec & 63) + 128);
|
||||
else if($UtfCharInDec < 2097152)$OutputChar .= chr($UtfCharInDec >> 18 + 240) . chr((($UtfCharInDec >> 12) & 63) + 128) . chr(($UtfCharInDec >> 6) & 63 + 128) . chr($UtfCharInDec & 63 + 128);
|
||||
return $OutputChar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function MakeConvertTable ($FromCharset, $ToCharset = '')
|
||||
{
|
||||
$ConvertTable = array();
|
||||
for($i = 0; $i < func_num_args(); $i++)
|
||||
{
|
||||
|
||||
$FileName = func_get_arg($i);
|
||||
if (!is_file(CONVERT_TABLES_DIR . $FileName))
|
||||
{
|
||||
print $this -> DebugOutput(0, 0, CONVERT_TABLES_DIR . $FileName); //Print an error message
|
||||
exit;
|
||||
}
|
||||
$FileWithEncTabe = fopen(CONVERT_TABLES_DIR . $FileName, "r") or die(); //This die(); is just to make sure...
|
||||
while(!feof($FileWithEncTabe))
|
||||
{
|
||||
|
||||
if($OneLine = trim(fgets($FileWithEncTabe, 1024)))
|
||||
{
|
||||
|
||||
if (substr($OneLine, 0, 1) != "#")
|
||||
{
|
||||
|
||||
$HexValue = preg_split ("/[\s,]+/", $OneLine, 3); //We need only first 2 values
|
||||
|
||||
if (substr($HexValue[1], 0, 1) != "#")
|
||||
{
|
||||
$ArrayKey = strtoupper(str_replace(strtolower("0x"), "", $HexValue[1]));
|
||||
$ArrayValue = strtoupper(str_replace(strtolower("0x"), "", $HexValue[0]));
|
||||
$ConvertTable[func_get_arg($i)][$ArrayKey] = $ArrayValue;
|
||||
}
|
||||
} //if (substr($OneLine,...
|
||||
} //if($OneLine=trim(f...
|
||||
} //while(!feof($FirstFileWi...
|
||||
} //for($i = 0; $i < func_...
|
||||
|
||||
if(!is_array($ConvertTable[$FromCharset])) $ConvertTable[$FromCharset] = array();
|
||||
|
||||
if ((func_num_args() > 1) && (count($ConvertTable[$FromCharset]) == count($ConvertTable[$ToCharset])) && (count(array_diff_assoc($ConvertTable[$FromCharset], $ConvertTable[$ToCharset])) == 0))
|
||||
{
|
||||
print $this -> DebugOutput(1, 1, "$FromCharset, $ToCharset");
|
||||
}
|
||||
return $ConvertTable;
|
||||
}
|
||||
|
||||
|
||||
function Convert ($StringToChange)
|
||||
{
|
||||
if(!strlen($StringToChange)) return '';
|
||||
$StringToChange = (string)($StringToChange);
|
||||
|
||||
if($this -> FromCharset == $this -> ToCharset) return $StringToChange;
|
||||
|
||||
$NewString = "";
|
||||
|
||||
|
||||
if ($this -> FromCharset != "utf-8")
|
||||
{
|
||||
|
||||
for ($i = 0; $i < strlen($StringToChange); $i++)
|
||||
{
|
||||
$HexChar = "";
|
||||
$UnicodeHexChar = "";
|
||||
$HexChar = strtoupper(dechex(ord($StringToChange[$i])));
|
||||
if (strlen($HexChar) == 1) $HexChar = "0" . $HexChar;
|
||||
if (($this -> FromCharset == "gsm0338") && ($HexChar == '1B')){
|
||||
$i++;
|
||||
$HexChar .= strtoupper(dechex(ord($StringToChange[$i])));
|
||||
}
|
||||
if ($this -> ToCharset != "utf-8")
|
||||
{
|
||||
if (in_array($HexChar, $this -> CharsetTable[$this -> FromCharset]))
|
||||
{
|
||||
$UnicodeHexChar = array_search($HexChar, $this -> CharsetTable[$this -> FromCharset]);
|
||||
$UnicodeHexChars = explode("+", $UnicodeHexChar);
|
||||
for($UnicodeHexCharElement = 0; $UnicodeHexCharElement < count($UnicodeHexChars); $UnicodeHexCharElement++)
|
||||
{
|
||||
if (array_key_exists($UnicodeHexChars[$UnicodeHexCharElement], $this -> CharsetTable[$this -> ToCharset]))
|
||||
{
|
||||
if ($this -> Entities == true)
|
||||
{
|
||||
$NewString .= $this -> UnicodeEntity($this -> HexToUtf($UnicodeHexChars[$UnicodeHexCharElement]));
|
||||
}
|
||||
else
|
||||
{
|
||||
$NewString .= chr(hexdec($this -> CharsetTable[$this -> ToCharset][$UnicodeHexChars[$UnicodeHexCharElement]]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print $this -> DebugOutput(0, 1, $StringToChange[$i]);
|
||||
}
|
||||
} //for($UnicodeH...
|
||||
}
|
||||
else
|
||||
{
|
||||
print $this -> DebugOutput(0, 2, $StringToChange[$i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_array("$HexChar", $this -> CharsetTable[$this -> FromCharset]))
|
||||
{
|
||||
$UnicodeHexChar = array_search($HexChar, $this -> CharsetTable[$this -> FromCharset]);
|
||||
|
||||
$UnicodeHexChars = explode("+", $UnicodeHexChar);
|
||||
for($UnicodeHexCharElement = 0; $UnicodeHexCharElement < count($UnicodeHexChars); $UnicodeHexCharElement++)
|
||||
{
|
||||
if ($this -> Entities == true)
|
||||
{
|
||||
$NewString .= $this -> UnicodeEntity($this -> HexToUtf($UnicodeHexChars[$UnicodeHexCharElement]));
|
||||
}
|
||||
else
|
||||
{
|
||||
$NewString .= $this -> HexToUtf($UnicodeHexChars[$UnicodeHexCharElement]);
|
||||
}
|
||||
} // for
|
||||
}
|
||||
else
|
||||
{
|
||||
print $this -> DebugOutput(0, 2, $StringToChange[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if($this -> FromCharset == "utf-8")
|
||||
{
|
||||
$HexChar = "";
|
||||
$UnicodeHexChar = "";
|
||||
$this -> CharsetTable = $this -> MakeConvertTable ($this -> ToCharset);
|
||||
foreach ($this -> CharsetTable[$this -> ToCharset] as $UnicodeHexChar => $HexChar)
|
||||
{
|
||||
if ($this -> Entities == true){
|
||||
$EntitieOrChar = $this -> UnicodeEntity($this -> HexToUtf($UnicodeHexChar));
|
||||
}
|
||||
else
|
||||
{
|
||||
$EntitieOrChar = chr(hexdec($HexChar));
|
||||
}
|
||||
$StringToChange = str_replace($this -> HexToUtf($UnicodeHexChar), $EntitieOrChar, $StringToChange);
|
||||
}
|
||||
$NewString = $StringToChange;
|
||||
}
|
||||
|
||||
return $NewString;
|
||||
}
|
||||
|
||||
|
||||
function ConvertArray(& $array)
|
||||
{
|
||||
if (!is_array($array))
|
||||
{
|
||||
$array = $this -> Convert($array);
|
||||
return;
|
||||
}
|
||||
while(list($k, $v) = each($array))
|
||||
{
|
||||
$this -> ConvertArray($v);
|
||||
$array[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function DebugOutput ($Group, $Number, $Value = false)
|
||||
{
|
||||
$Debug[0][0] = "Error, can NOT read file: " . $Value . "<br>";
|
||||
$Debug[0][1] = "Error, can't find maching char \"" . $Value . "\" in destination encoding table!" . "<br>";
|
||||
$Debug[0][2] = "Error, can't find maching char \"" . $Value . "\" in source encoding table!" . "<br>";
|
||||
$Debug[0][3] = "Error, you did NOT set variable " . $Value . " in Convert() function." . "<br>";
|
||||
$Debug[0][4] = "You can NOT convert string from " . $Value . " to " . $Value . "!" . "<BR>";
|
||||
$Debug[1][0] = "Notice, you are trying to convert string from " . $Value . " to " . $Value . ", don't you feel it's strange? ;-)" . "<br>";
|
||||
$Debug[1][1] = "Notice, both charsets " . $Value . " are identical! Check encoding tables files." . "<br>";
|
||||
$Debug[1][2] = "Notice, there is no unicode char in the string you are trying to convert." . "<br>";
|
||||
|
||||
if (DEBUG_MODE >= $Group)
|
||||
{
|
||||
return $Debug[$Group][$Number];
|
||||
}
|
||||
} // function DebugOutput
|
||||
|
||||
} //class ends here
|
||||
?>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 3755 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user