Version 3.4.6

This commit is contained in:
Neo committed 2025-12-19 00:40:53 -08:00
1 parent e4478369d8
commit b45ea0dffb
1568 files changed
+155104 -161665

No files matched your search

+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -1,102 +1,101 @@
<?php
/**
* Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
*/
class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
{
/**
* Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator
*/
protected $ipv4;
/**
* Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator
*/
protected $ipv6;
public function __construct() {
$this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
$this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
}
public function validate($string, $config, $context) {
$length = strlen($string);
// empty hostname is OK; it's usually semantically equivalent:
// the default host as defined by a URI scheme is used:
//
// If the URI scheme defines a default for host, then that
// default applies when the host subcomponent is undefined
// or when the registered name is empty (zero length).
if ($string === '') return '';
if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
//IPv6
$ip = substr($string, 1, $length - 2);
$valid = $this->ipv6->validate($ip, $config, $context);
if ($valid === false) return false;
return '['. $valid . ']';
}
// need to do checks on unusual encodings too
$ipv4 = $this->ipv4->validate($string, $config, $context);
if ($ipv4 !== false) return $ipv4;
// A regular domain name.
// This doesn't match I18N domain names, but we don't have proper IRI support,
// so force users to insert Punycode.
// The productions describing this are:
$a = '[a-z]'; // alpha
$an = '[a-z0-9]'; // alphanum
$and = '[a-z0-9-]'; // alphanum | "-"
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
$domainlabel = "$an($and*$an)?";
// toplabel = alpha | alpha *( alphanum | "-" ) alphanum
$toplabel = "$a($and*$an)?";
// hostname = *( domainlabel "." ) toplabel [ "." ]
$uni=(IPS_DOC_CHAR_SET=="UTF-8")?"u":"";
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i".$uni, $string)) {
return $string;
}
// If we have Net_IDNA2 support, we can support IRIs by
// punycoding them. (This is the most portable thing to do,
// since otherwise we have to assume browsers support
if ($config->get('Core.EnableIDNA')) {
$idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true));
// we need to encode each period separately
$parts = explode('.', $string);
try {
$new_parts = array();
foreach ($parts as $part) {
$encodable = false;
for ($i = 0, $c = strlen($part); $i < $c; $i++) {
if (ord($part[$i]) > 0x7a) {
$encodable = true;
break;
}
}
if (!$encodable) {
$new_parts[] = $part;
} else {
$new_parts[] = $idna->encode($part);
}
}
$string = implode('.', $new_parts);
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
return $string;
}
} catch (Exception $e) {
// XXX error reporting
}
}
return false;
}
}
// vim: et sw=4 sts=4
<?php
/**
* Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
*/
class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
{
/**
* Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator
*/
protected $ipv4;
/**
* Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator
*/
protected $ipv6;
public function __construct() {
$this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
$this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
}
public function validate($string, $config, $context) {
$length = strlen($string);
// empty hostname is OK; it's usually semantically equivalent:
// the default host as defined by a URI scheme is used:
//
// If the URI scheme defines a default for host, then that
// default applies when the host subcomponent is undefined
// or when the registered name is empty (zero length).
if ($string === '') return '';
if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
//IPv6
$ip = substr($string, 1, $length - 2);
$valid = $this->ipv6->validate($ip, $config, $context);
if ($valid === false) return false;
return '['. $valid . ']';
}
// need to do checks on unusual encodings too
$ipv4 = $this->ipv4->validate($string, $config, $context);
if ($ipv4 !== false) return $ipv4;
// A regular domain name.
// This doesn't match I18N domain names, but we don't have proper IRI support,
// so force users to insert Punycode.
// The productions describing this are:
$a = '[a-z]'; // alpha
$an = '[a-z0-9]'; // alphanum
$and = '[a-z0-9-]'; // alphanum | "-"
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
$domainlabel = "$an($and*$an)?";
// toplabel = alpha | alpha *( alphanum | "-" ) alphanum
$toplabel = "$a($and*$an)?";
// hostname = *( domainlabel "." ) toplabel [ "." ]
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
return $string;
}
// If we have Net_IDNA2 support, we can support IRIs by
// punycoding them. (This is the most portable thing to do,
// since otherwise we have to assume browsers support
if ($config->get('Core.EnableIDNA')) {
$idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true));
// we need to encode each period separately
$parts = explode('.', $string);
try {
$new_parts = array();
foreach ($parts as $part) {
$encodable = false;
for ($i = 0, $c = strlen($part); $i < $c; $i++) {
if (ord($part[$i]) > 0x7a) {
$encodable = true;
break;
}
}
if (!$encodable) {
$new_parts[] = $part;
} else {
$new_parts[] = $idna->encode($part);
}
}
$string = implode('.', $new_parts);
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
return $string;
}
} catch (Exception $e) {
// XXX error reporting
}
}
return false;
}
}
// vim: et sw=4 sts=4
@@ -333,7 +333,7 @@ class HTMLPurifier_Encoder
/**
* Converts a string to UTF-8 based on configuration.
*/
public static function convertToUTF8($str, $config, $context) {
public static function convertToUTF8($str, $config, $context) {
$encoding = $config->get('Core.Encoding');
if ($encoding === 'utf-8') return $str;
static $iconv = null;
@@ -355,6 +355,10 @@ class HTMLPurifier_Encoder
$str = utf8_encode($str);
return $str;
}
else
{
return IPSText::convertCharsets( $str, $encoding );
}
trigger_error('Encoding not supported, please install iconv', E_USER_ERROR);
}
@@ -1,99 +1,122 @@
<?php
/**
* Injector that converts http, https and ftp text URLs to actual links.
*/
class HTMLPurifier_Injector_Linkify extends HTMLPurifier_Injector
{
public $name = 'Linkify';
public $needed = array('a' => array('href'));
public function handleText(&$token) {
if (!$this->allowsElement('a')) return;
if (strpos($token->data, '://') === false) {
// our really quick heuristic failed, abort
// this may not work so well if we want to match things like
// "google.com", but then again, most people don't
return;
}
//print $token->data;
// there is/are URL(s). Let's split the string:
// Note: this regex is extremely permissive
//$bits = preg_split('#((?:https?|ftp)://[^\s\'"<>()]+)#S', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE);
/* MODIFIED April 26, 2013
@link http://community.invisionpower.com/resources/bugs.html/_/ip-board/links-being-corrupted-or-malformed-in-board-and-nexus-r41993
Test case:
http://invisionpower.com,
http://invisionpower.com.
http://invisionpower.com
https://invisionpower.com
https://blah.gov/blah-blah.as
http://en.wikipedia.org/wiki/Chi_(mythology)
(http://google.com)
*/
$uni=(IPS_DOC_CHAR_SET=="UTF-8")?"u":"";
preg_match_all( "#(.*?)(\()?((?:http|ftp|https):\/\/[\p{L}\-_]+(?:\.[\p{L}\-_]+)?(?:[\p{L}\-\.,\(\)@?^=%&amp;:\/~\+\#]*[\p{L}\-\@?^=%&amp;\/~\+\#]))(.*?)$#ims" . $uni, $token->data, $matches );
//print_r($matches);exit;
//$token = array();
// $i = index
// $c = count
// $l = is link
/*for ($i = 0, $c = count($bits), $l = false; $i < $c; $i++, $l = !$l) {
if (!$l) {
if ($bits[$i] === '') continue;
$token[] = new HTMLPurifier_Token_Text($bits[$i]);
} else {
$token[] = new HTMLPurifier_Token_Start('a', array('href' => $bits[$i]));
$token[] = new HTMLPurifier_Token_Text($bits[$i]);
$token[] = new HTMLPurifier_Token_End('a');
}
}*/
if( is_array($matches) AND count($matches) )
{
$token = array();//by denchu 06062013
foreach( $matches[0] as $k => $match )
{
if( !$matches[3][$k] )
{
$token[] = new HTMLPurifier_Token_Text($token->data);
}
else
{
if( $matches[1][$k] )
{
$token[] = new HTMLPurifier_Token_Text($matches[1][$k]);
}
if( $matches[2][$k] )
{
$token[] = new HTMLPurifier_Token_Text($matches[2][$k]);
}
if( !$matches[2][$k] AND $matches[4][$k] == ')' )
{
$matches[3][$k] .= ')';
unset($matches[4][$k]);
}
$token[] = new HTMLPurifier_Token_Start('a', array('href' => $matches[3][$k]));
$token[] = new HTMLPurifier_Token_Text($matches[3][$k]);
$token[] = new HTMLPurifier_Token_End('a');
if( $matches[4][$k] )
{
$token[] = new HTMLPurifier_Token_Text($matches[4][$k]);
}
}
}
}
//print_r($token);exit;
}
}
// vim: et sw=4 sts=4
<?php
/**
* Injector that converts http, https and ftp text URLs to actual links.
*/
class HTMLPurifier_Injector_Linkify extends HTMLPurifier_Injector
{
public $name = 'Linkify';
public $needed = array('a' => array('href'));
public function handleText(&$token) {
if (!$this->allowsElement('a')) return;
//var_dump( $token->data ); exit;
if (strpos($token->data, '://') === false) {
// our really quick heuristic failed, abort
// this may not work so well if we want to match things like
// "google.com", but then again, most people don't
return;
}
//print $token->data;
// there is/are URL(s). Let's split the string:
// Note: this regex is extremely permissive
//$bits = preg_split('#((?:https?|ftp)://[^\s\'"<>()]+)#S', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE);
/* MODIFIED April 26, 2013
@link http://community.invisionpower.com/resources/bugs.html/_/ip-board/links-being-corrupted-or-malformed-in-board-and-nexus-r41993
Test case:
http://invisionpower.com,
http://invisionpower.com.
http://invisionpower.com
https://invisionpower.com
https://blah.gov/blah-blah.as
http://en.wikipedia.org/wiki/Chi_(mythology)
http://en.wikipedia.org/wiki/Assassin's_Creed
(http://google.com)
*/
preg_match_all( "#(.*?)(\()?((?:http|ftp|https):\/\/[\w\-_]+(?:\.[\w\-_]+)?(?:[\w\-\.,\'\(\)@?^=%&amp;:/~\+\#]*[\w\-\@?^=%&amp;/~\+\#]))(.*)(?(?=\S+)\S+)(.*)$#ims", $token->data, $matches );
//$token = array();
// $i = index
// $c = count
// $l = is link
/*for ($i = 0, $c = count($bits), $l = false; $i < $c; $i++, $l = !$l) {
if (!$l) {
if ($bits[$i] === '') continue;
$token[] = new HTMLPurifier_Token_Text($bits[$i]);
} else {
$token[] = new HTMLPurifier_Token_Start('a', array('href' => $bits[$i]));
$token[] = new HTMLPurifier_Token_Text($bits[$i]);
$token[] = new HTMLPurifier_Token_End('a');
}
}*/
if( is_array($matches[0]) AND count($matches[0]) )
{
$token = array();
foreach( $matches[0] as $k => $match )
{
if( !$matches[3][$k] )
{
$token[] = new HTMLPurifier_Token_Text($token->data);
}
else
{
if( $matches[1][$k] )
{
$token[] = new HTMLPurifier_Token_Text($matches[1][$k]);
}
if( $matches[2][$k] )
{
$token[] = new HTMLPurifier_Token_Text($matches[2][$k]);
}
if( !$matches[2][$k] AND !in_array( $matches[4][$k], array( '!', '.', ',' ) ) AND strpos( $matches[4][$k], ' ' ) === false AND ! preg_match( "#(\r|\n|\r\n)#i", $matches[4][$k] ) )
{
$matches[3][$k] .= $matches[4][$k];
unset($matches[4][$k]);
}
$token[] = new HTMLPurifier_Token_Start('a', array('href' => str_replace( '\'', '%27', $matches[3][$k] )));
$token[] = new HTMLPurifier_Token_Text($matches[3][$k]);
$token[] = new HTMLPurifier_Token_End('a');
if( $matches[4][$k] )
{
// Let's do some testing. We may need to recurse in on this line for extra links.
$test = explode( ' ', $matches[4][$k] );
foreach( $test AS $v )
{
if ( strpos( $v, 'http' ) !== false OR strpos( $v, 'https' ) !== false OR strpos( $v, 'ftp' ) !== false )
{
$token[] = new HTMLPurifier_Token_Start('a', array('href' => str_replace( '\'', '%27', $v )));
$token[] = new HTMLPurifier_Token_Text($v);
$token[] = new HTMLPurifier_Token_End('a');
$token[] = new HTMLPurifier_Token_Text(' '); // Because we exploded the text, spaces were lost. Re-add them.
}
else
{
$token[] = new HTMLPurifier_Token_Text($v);
$token[] = new HTMLPurifier_Token_Text(' '); // Because we exploded the text, spaces were lost. Re-add them.
}
}
//$token[] = new HTMLPurifier_Token_Text($matches[4][$k]);
}
if( $matches[5][$k] )
{
$token[] = new HTMLPurifier_Token_Text( $matches[5][$k] );
}
}
}
}
}
}
// vim: et sw=4 sts=4
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+426 -426
View File
@@ -1,427 +1,427 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* AJAX input parsing and handling
* Last Updated: $Date: 2012-08-28 17:56:22 -0400 (Tue, 28 Aug 2012) $
* </pre>
*
* @author $Author: bfarber $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 11296 $
*/
class classAjax
{
/**
* XML output
*
* @var string Output
*/
public $xml_output;
/**
* XML Header
*
* @var string XML doctype
*/
public $xml_header;
/**
* Character sets
*
* @var array Charsets supported by html_entity_decode
*/
protected $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
*
* @return @e 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, array( $this, 'arrayWalkConvert' ) );
//-----------------------------------------
// Using this code allows characters that ARE supported
// within the character set to be recoded properly, instead
// of as HTML entities when submitted via AJAX. The problem is,
// any characters NOT supported in the charset are corrupted. :-\
//-----------------------------------------
//array_walk_recursive( $_POST, create_function( '&$value, $key', '$value = IPSText::convertCharsets( IPSText::convertUnicode($value, true), "utf-8", "' . IPS_DOC_CHAR_SET . '" );' ) );
// 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);' ) );
}
/**
* Callback to convert unicode and charset for AJAX requests
*
* @param mixed Value
* @param string Key
* @return @e void
*/
public function arrayWalkConvert( &$value, $key )
{
if( is_string( $value ) )
{
$value = IPSText::convertCharsets( IPSText::convertUnicode( $value ), "utf-8", IPS_DOC_CHAR_SET );
}
}
/**
* Normalize the character set of incoming AJAX data and optionally parse the value through the parseCleanValue routine
*
* @param string Raw input string
* @param boolean Run through parse_incoming routine
* @see IPSText::parseCleanValue
* @return @e string
*/
public function convertAndMakeSafe( $value, $parse_incoming=true )
{
$value = rawurldecode( $value );
//-----------------------------------------
// \ char is passed as %5C so it won't be double
// escaped if magic quotes is on - do it manually
// @link http://community.invisionpower.com/tracker/issue-24971-status-update-issue/
//-----------------------------------------
if( IPS_MAGIC_QUOTES )
{
$value = str_replace( "\\", "\\\\", $value );
}
$value = $this->convertUnicode( $value );
$value = $this->convertHtmlEntities( $value );
if( $parse_incoming )
{
$value = IPSText::parseCleanValue( $value );
}
return $value;
}
/**
* Remove hook comments and parse replacements
*
* @param string Output data
* @return @e string
*/
public function cleanOutput( $string )
{
if ( ! IN_ACP )
{
$string = preg_replace( '#<!--hook\.([^\>]+?)-->#', '', $string );
}
$string = ipsRegistry::getClass('output')->replaceMacros( $string );
return $string;
}
/**
* Print a generic error message
*
* @return @e void
*/
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 XML result
*
* @param mixed Value to send
* @return @e void
*/
public function returnNull( $val=0 )
{
@header( "Content-type: text/xml" );
$this->printNocacheHeaders();
$val = $this->parseAndCleanHooks( $val );
print $this->xml_header . "\r\n<null>{$val}</null>";
exit();
}
/**
* Return a string
*
* @param string String to output
* @return @e void
*/
public function returnString( $string )
{
@header( "Content-type: text/plain;charset=" . IPS_DOC_CHAR_SET );
$this->printNocacheHeaders();
echo $this->parseAndCleanHooks( $string );
exit();
}
/**
* Return a JSON error message
*
* @param string Error message
* @param string Content-type header to send
* @return @e void
*/
public function returnJsonError( $message, $header="application/json" )
{
/* Just alias it... */
$this->returnJsonArray( array( 'error' => $message ), false, $header );
}
/**
* Return a JSON object
*
* @param array Array of key => value fields
* @param boolean Clean the data (used when passing HTML)
* @param string Optional content-type header string (default application/json)
* @param array Optional array (0 => template group, 1 => bit name) to pass JSON into a custom skin method
* @return @e void
*/
public function returnJsonArray( $json=array(), $cleanData=false, $header="application/json", $templateWrapper=array() )
{
@header( "Content-type: " . $header . ";charset=" . IPS_DOC_CHAR_SET );
$this->printNocacheHeaders();
/* Always return as UTF-8 */
array_walk_recursive( $json, array( 'IPSText', 'arrayWalkCallbackConvert' ) );
if ( $cleanData )
{
array_walk_recursive( $json, array( $this, 'cleanHtml' ) );
}
$result = json_encode( $json );
$result = IPSText::convertCharsets($result, "UTF-8", IPS_DOC_CHAR_SET);
/* Print via a wrapper? */
if ( is_array( $templateWrapper ) AND count( $templateWrapper ) )
{
print ipsRegistry::getClass('output')->getTemplate( $templateWrapper[0] )->$templateWrapper[1]( $result );
}
else
{
print $result;
}
exit();
}
/**
* Return HTML content
*
* @param string HTML to output
* @param boolean Force returned output to UTF-8
* @return @e void
*/
public function returnHtml( $string, $returnAsUtf8=false )
{
if ( $string )
{
$this->cleanHtml( $string );
}
/* Always return as UTF-8 */
if ( $returnAsUtf8 )
{
$string = IPSText::convertCharsets( $string, IPS_DOC_CHAR_SET, "UTF-8" );
}
@header( "Content-type: text/html;charset=" . IPS_DOC_CHAR_SET );
$this->printNocacheHeaders();
print $string;
exit();
}
/**
* Execute template hooks and remove hook comments
*
* @param string $string
* @return @e string
*/
public function parseAndCleanHooks( $string )
{
$string = ipsRegistry::getClass('output')->templateHooks( $string );
$string = preg_replace( '#<!--hook\.([^\>]+?)-->#', '', $string );
return $string;
}
/**
* Print 200 OK and nocache headers
*
* @return @e void
*/
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
*
* @deprecated This function no longer does anything
* @param string Input to convert
* @return @e string
*/
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
*
* @param string Input to convert
* @return @e string
*/
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( "&amp;#", "&#", $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;
}
/**
* Formats an HTML string for output. Fixes some browser-specific bugs, parses replacements and executes hooks
*
* @param string $string
* @param string Array key (only necessary when executed from an array_walk callback)
* @return @e string
*/
public function cleanHtml( &$string, $key='' )
{
/* Is it really a string? */
if ( is_string($string) )
{
// Fix IE bugs
$string = str_ireplace( "&sect", "&amp;sect", $string );
if ( strtolower( IPS_DOC_CHAR_SET ) == 'iso-8859-1' )
{
$string = str_replace( "ì", "&#8220;", $string );
$string = str_replace( "î", "&#8221;", $string );
}
// Other stuff
$string = ipsRegistry::getClass('output')->replaceMacros( $string );
$string = $this->parseAndCleanHooks( $string );
}
return $string;
}
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.6
* AJAX input parsing and handling
* Last Updated: $Date: 2012-08-28 17:56:22 -0400 (Tue, 28 Aug 2012) $
* </pre>
*
* @author $Author: bfarber $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 11296 $
*/
class classAjax
{
/**
* XML output
*
* @var string Output
*/
public $xml_output;
/**
* XML Header
*
* @var string XML doctype
*/
public $xml_header;
/**
* Character sets
*
* @var array Charsets supported by html_entity_decode
*/
protected $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
*
* @return @e 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, array( $this, 'arrayWalkConvert' ) );
//-----------------------------------------
// Using this code allows characters that ARE supported
// within the character set to be recoded properly, instead
// of as HTML entities when submitted via AJAX. The problem is,
// any characters NOT supported in the charset are corrupted. :-\
//-----------------------------------------
//array_walk_recursive( $_POST, create_function( '&$value, $key', '$value = IPSText::convertCharsets( IPSText::convertUnicode($value, true), "utf-8", "' . IPS_DOC_CHAR_SET . '" );' ) );
// 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);' ) );
}
/**
* Callback to convert unicode and charset for AJAX requests
*
* @param mixed Value
* @param string Key
* @return @e void
*/
public function arrayWalkConvert( &$value, $key )
{
if( is_string( $value ) )
{
$value = IPSText::convertCharsets( IPSText::convertUnicode( $value ), "utf-8", IPS_DOC_CHAR_SET );
}
}
/**
* Normalize the character set of incoming AJAX data and optionally parse the value through the parseCleanValue routine
*
* @param string Raw input string
* @param boolean Run through parse_incoming routine
* @see IPSText::parseCleanValue
* @return @e string
*/
public function convertAndMakeSafe( $value, $parse_incoming=true )
{
$value = rawurldecode( $value );
//-----------------------------------------
// \ char is passed as %5C so it won't be double
// escaped if magic quotes is on - do it manually
// @link http://community.invisionpower.com/tracker/issue-24971-status-update-issue/
//-----------------------------------------
if( IPS_MAGIC_QUOTES )
{
$value = str_replace( "\\", "\\\\", $value );
}
$value = $this->convertUnicode( $value );
$value = $this->convertHtmlEntities( $value );
if( $parse_incoming )
{
$value = IPSText::parseCleanValue( $value );
}
return $value;
}
/**
* Remove hook comments and parse replacements
*
* @param string Output data
* @return @e string
*/
public function cleanOutput( $string )
{
if ( ! IN_ACP )
{
$string = preg_replace( '#<!--hook\.([^\>]+?)-->#', '', $string );
}
$string = ipsRegistry::getClass('output')->replaceMacros( $string );
return $string;
}
/**
* Print a generic error message
*
* @return @e void
*/
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>You must be logged in to access this feature</message></error>\r\n";
$this->xml_output .= "</errors>";
print $this->xml_output;
exit();
}
/**
* Return a NULL XML result
*
* @param mixed Value to send
* @return @e void
*/
public function returnNull( $val=0 )
{
@header( "Content-type: text/xml" );
$this->printNocacheHeaders();
$val = $this->parseAndCleanHooks( $val );
print $this->xml_header . "\r\n<null>{$val}</null>";
exit();
}
/**
* Return a string
*
* @param string String to output
* @return @e void
*/
public function returnString( $string )
{
@header( "Content-type: text/plain;charset=" . IPS_DOC_CHAR_SET );
$this->printNocacheHeaders();
echo $this->parseAndCleanHooks( $string );
exit();
}
/**
* Return a JSON error message
*
* @param string Error message
* @param string Content-type header to send
* @return @e void
*/
public function returnJsonError( $message, $header="application/json" )
{
/* Just alias it... */
$this->returnJsonArray( array( 'error' => $message ), false, $header );
}
/**
* Return a JSON object
*
* @param array Array of key => value fields
* @param boolean Clean the data (used when passing HTML)
* @param string Optional content-type header string (default application/json)
* @param array Optional array (0 => template group, 1 => bit name) to pass JSON into a custom skin method
* @return @e void
*/
public function returnJsonArray( $json=array(), $cleanData=false, $header="application/json", $templateWrapper=array() )
{
@header( "Content-type: " . $header . ";charset=" . IPS_DOC_CHAR_SET );
$this->printNocacheHeaders();
/* Always return as UTF-8 */
array_walk_recursive( $json, array( 'IPSText', 'arrayWalkCallbackConvert' ) );
if ( $cleanData )
{
array_walk_recursive( $json, array( $this, 'cleanHtml' ) );
}
$result = json_encode( $json );
$result = IPSText::convertCharsets($result, "UTF-8", IPS_DOC_CHAR_SET);
/* Print via a wrapper? */
if ( is_array( $templateWrapper ) AND count( $templateWrapper ) )
{
print ipsRegistry::getClass('output')->getTemplate( $templateWrapper[0] )->$templateWrapper[1]( $result );
}
else
{
print $result;
}
exit();
}
/**
* Return HTML content
*
* @param string HTML to output
* @param boolean Force returned output to UTF-8
* @return @e void
*/
public function returnHtml( $string, $returnAsUtf8=false )
{
if ( $string )
{
$this->cleanHtml( $string );
}
/* Always return as UTF-8 */
if ( $returnAsUtf8 )
{
$string = IPSText::convertCharsets( $string, IPS_DOC_CHAR_SET, "UTF-8" );
}
@header( "Content-type: text/html;charset=" . IPS_DOC_CHAR_SET );
$this->printNocacheHeaders();
print $string;
exit();
}
/**
* Execute template hooks and remove hook comments
*
* @param string $string
* @return @e string
*/
public function parseAndCleanHooks( $string )
{
$string = ipsRegistry::getClass('output')->templateHooks( $string );
$string = preg_replace( '#<!--hook\.([^\>]+?)-->#', '', $string );
return $string;
}
/**
* Print 200 OK and nocache headers
*
* @return @e void
*/
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
*
* @deprecated This function no longer does anything
* @param string Input to convert
* @return @e string
*/
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
*
* @param string Input to convert
* @return @e string
*/
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( "&amp;#", "&#", $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;
}
/**
* Formats an HTML string for output. Fixes some browser-specific bugs, parses replacements and executes hooks
*
* @param string $string
* @param string Array key (only necessary when executed from an array_walk callback)
* @return @e string
*/
public function cleanHtml( &$string, $key='' )
{
/* Is it really a string? */
if ( is_string($string) )
{
// Fix IE bugs
$string = str_ireplace( "&sect", "&amp;sect", $string );
if ( strtolower( IPS_DOC_CHAR_SET ) == 'iso-8859-1' )
{
$string = str_replace( "ì", "&#8220;", $string );
$string = str_replace( "î", "&#8221;", $string );
}
// Other stuff
$string = ipsRegistry::getClass('output')->replaceMacros( $string );
$string = $this->parseAndCleanHooks( $string );
}
return $string;
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* This class can act as an API server, handling API requests
* Last Updated: $Date: 2012-12-27 11:37:49 -0500 (Thu, 27 Dec 2012) $
* </pre>
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* 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: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* 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: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* 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: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* 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: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* 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: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* 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: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
+101 -101
View File
@@ -1,102 +1,102 @@
<?php
/**
* @file classCaptcha.php Provides methods to handle CAPTCHA abstraction - easily create, check and display CAPTHCA images
*~TERABYTE_DOC_READY~
* $Copyright: (c) 2001 - 2011 Invision Power Services, Inc.$
* $License: http://www.invisionpower.com/company/standards.php#license$
* $Author: bfarber $
* @since Friday 19th May 2006 17:33
* $LastChangedDate: 2012-02-10 20:05:52 -0500 (Fri, 10 Feb 2012) $
* @version v3.4.5
* $Revision: 10288 $
*/
/**
*
* @class classCaptcha
* @brief Provides methods to handle CAPTCHA abstraction - easily create, check and display CAPTHCA images
*
*/
class classCaptcha
{
/**
* Registry Object
*
* @var object
*/
public $registry;
/**
* Settings array
*
* @var array
*/
public $settings;
/**
* Object that stored the plug in class
*
* @var $_plugInClass
*/
protected $_plugInClass;
/**
* Constructor
*
* @param object $registry Registry Object
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
$this->registry = $registry;
$this->settings =& $this->registry->fetchSettings();
$plugin = $this->settings['bot_antispam_type'];
if ( ! is_file( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' ) )
{
$plugin = 'default';
}
require_once( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' );/*noLibHook*/
$this->_plugInClass = new captchaPlugIn( $registry );
}
/**
* Magic __call method
*
* @param string $method Method name
* @param mixed $arguments Method arguments
* @return @e 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
*
* @param string $name Property name
* @return @e mixed
*/
public function __get( $name )
{
if ( property_exists( $this->_plugInClass, $name ) )
{
return $this->_plugInClass->$name;
}
else
{
trigger_error( $name . " не существует", E_USER_ERROR );
}
}
<?php
/**
* @file classCaptcha.php Provides methods to handle CAPTCHA abstraction - easily create, check and display CAPTHCA images
*~TERABYTE_DOC_READY~
* $Copyright: (c) 2001 - 2011 Invision Power Services, Inc.$
* $License: http://www.invisionpower.com/company/standards.php#license$
* $Author: bfarber $
* @since Friday 19th May 2006 17:33
* $LastChangedDate: 2012-02-10 20:05:52 -0500 (Fri, 10 Feb 2012) $
* @version v3.4.6
* $Revision: 10288 $
*/
/**
*
* @class classCaptcha
* @brief Provides methods to handle CAPTCHA abstraction - easily create, check and display CAPTHCA images
*
*/
class classCaptcha
{
/**
* Registry Object
*
* @var object
*/
public $registry;
/**
* Settings array
*
* @var array
*/
public $settings;
/**
* Object that stored the plug in class
*
* @var $_plugInClass
*/
protected $_plugInClass;
/**
* Constructor
*
* @param object $registry Registry Object
* @return @e void
*/
public function __construct( ipsRegistry $registry )
{
$this->registry = $registry;
$this->settings =& $this->registry->fetchSettings();
$plugin = $this->settings['bot_antispam_type'];
if ( ! is_file( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' ) )
{
$plugin = 'default';
}
require_once( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' );/*noLibHook*/
$this->_plugInClass = new captchaPlugIn( $registry );
}
/**
* Magic __call method
*
* @param string $method Method name
* @param mixed $arguments Method arguments
* @return @e mixed
*/
public function __call( $method, $arguments )
{
if ( method_exists( $this->_plugInClass, $method ) )
{
return $this->_plugInClass->$method( $arguments );
}
else
{
trigger_error( $method . " does not exist", E_USER_ERROR );
}
}
/**
* Magic __get method
*
* @param string $name Property name
* @return @e mixed
*/
public function __get( $name )
{
if ( property_exists( $this->_plugInClass, $name ) )
{
return $this->_plugInClass->$name;
}
else
{
trigger_error( $name . " does not exist", E_USER_ERROR );
}
}
}
@@ -7,7 +7,7 @@
* $Author: bfarber $
* @since Friday 19th May 2006 17:33
* $LastChangedDate: 2012-02-10 20:05:52 -0500 (Fri, 10 Feb 2012) $
* @version v3.4.5
* @version v3.4.6
* $Revision: 10288 $
*/
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -47,11 +47,11 @@ define("RECAPTCHA_VERIFY_SERVER", "http://www.google.com");
*~TERABYTE_DOC_READY~
* $Copyright: (c) 2001 - 2011 Invision Power Services, Inc.$
* $License: http://www.invisionpower.com/company/standards.php#license$
* $Author: mark $
* $Author: rashbrook $
* @since Friday 19th May 2006 17:33
* $LastChangedDate: 2013-02-11 12:32:07 -0500 (Mon, 11 Feb 2013) $
* @version v3.4.5
* $Revision: 11975 $
* $LastChangedDate: 2013-10-16 19:11:24 -0400 (Wed, 16 Oct 2013) $
* @version v3.4.6
* $Revision: 12381 $
*/
/**
@@ -158,9 +158,9 @@ class captchaPlugin
};
</script>";
$html .= '<script type="text/javascript" src="'. $server . '/challenge?k=' . $this->public_key . '"></script>
$html .= '<script type="text/javascript" src="'. $server . '/challenge?k=' . $this->public_key . '&hl=' . $this->settings['recaptcha_language'] . '"></script>
<noscript>
<iframe src="'. $server . '/noscript?k=' . $this->public_key . '" height="300" width="500" frameborder="0"></iframe><br/>
<iframe src="'. $server . '/noscript?k=' . $this->public_key . '&hl=' . $this->settings['recaptcha_language'] . '" height="300" width="500" frameborder="0"></iframe><br/>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript>';
@@ -192,7 +192,15 @@ class captchaPlugin
$captcha_unique_id = $_REQUEST['recaptcha_challenge_field'];
$captcha_input = $_REQUEST['recaptcha_response_field'];
//-----------------------------------------
// Path disclosure prevention
//-----------------------------------------
if ( is_array( $captcha_input ) )
{
return false;
}
if ( $captcha_input == null || strlen($captcha_input) == 0 || $captcha_unique_id == null || strlen($captcha_unique_id) == 0)
{
return false;
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Character set conversion library
* Last Updated: $Date: 2012-12-07 14:02:27 -0500 (Fri, 07 Dec 2012) $
* </pre>
File diff suppressed because it is too large. Load diff
+2035 -2035
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* MySQL Database Driver :: Further loads mysql or mysqli client appropriately
* Last Updated: $Date: 2012-09-17 11:58:03 -0400 (Mon, 17 Sep 2012) $
* </pre>
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+435 -435
View File
@@ -1,436 +1,436 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* Compare and highlight differences between two strings or files
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Thursday 10th February 2005 (10:47)
* @version $Revision: 10721 $
*/
if ( ! defined( 'IPS_CLASSES_PATH' ) )
{
/**
* Define classes path
*/
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
}
class classDifference
{
/**
* Shell command
*
* @var string
*/
public $diff_command = 'diff';
/**
* Type of diff to use
*
* @var string [EXEC, PHP]
*/
public $method = 'EXEC';
/**
* Differences found?
*
* @var integer
*/
public $diff_found = 0;
/**
* Post process DIFF result?
*
* @var integer
*/
public $post_process = 1;
/**
* Constructor
*
* @return @e void
*/
public function __construct()
{
//-------------------------------
// Server?
//-------------------------------
if( strpos( strtolower( PHP_OS ), 'win' ) === 0 OR ( ! function_exists('exec') ) )
{
$this->method = 'PHP';
}
}
/**
* Retrieve a text string showing the differences between the two supplied strings
*
* @param string Original string
* @param string New string
* @param string Inline or unified report (only supported by PHP method)
* @return @e string
*/
public function getDifferences( $str1, $str2, $method='inline' )
{
$this->diff_found = 0;
if ( $this->method != 'PHP' )
{
$str1 = $this->_diffTagSpace($str1);
$str2 = $this->_diffTagSpace($str2);
$str1_lines = $this->_diffExplodeStringIntoWords($str1);
$str2_lines = $this->_diffExplodeStringIntoWords($str2);
}
if ( $this->method == 'PHP' )
{
$diff_res = $this->_getPhpDiff( $str1, $str2, $method );
}
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
*
* @param string String
* @param integer [Optional][0=reverse, 1=normal]
* @return @e string
*/
protected function _diffTagSpace( $str, $rev=0 )
{
if ( $rev )
{
return str_replace(' &lt;','&lt;',str_replace('&gt; ','&gt;',$str) );
}
else
{
return str_replace('<',' <',str_replace('>','> ',$str) );
}
}
/**
* Explodes input string into words
*
* @access protected
* @param string Input string
* @return @e array
*/
protected 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
*
* @param string Delimiter
* @param string String to check
* @param integer [Optional] Remove blank lines
* @return @e array
*/
protected 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
*
* @param string comapre string 1
* @param string comapre string 2
* @return @e string
*/
protected function _getPhpDiff( $str1 , $str2, $method='inline' )
{
$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/' );/*noLibHook*/
/* OMG.. too many PHP 5 errors under strict standards */
$oldReportLevel = error_reporting( 0 );
error_reporting( $oldReportLevel ^ E_STRICT );
require_once 'Text/Diff.php';/*noLibHook*/
require_once 'Text/Diff/Renderer.php';/*noLibHook*/
$diff = new Text_Diff( 'auto', array( $str1, $str2 ) );
if ( $method == 'inline' )
{
require_once 'Text/Diff/Renderer/inline.php';/*noLibHook*/
$renderer = new Text_Diff_Renderer_inline();
}
else
{
require_once 'Text/Diff/Renderer/unified.php';/*noLibHook*/
$renderer = new Text_Diff_Renderer_unified();
$renderer->_leading_context_lines = 10000;
$renderer->_trailing_context_lines = 10000;
}
$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
*
* @param string comapre string 1
* @param string comapre string 2
* @return @e string
*/
protected 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 ( is_file( $file1 ) and is_file( $file2 ) )
{
exec( $this->diff_command.' '.$file1.' '.$file2, $result );
@unlink( $file1 );
@unlink( $file2 );
return $result;
}
else
{
return "Ошибка, файлы не были записаны на диск";
}
}
/**
* Format differences for output (common)
*
* @param string Differences report
* @param string Format method (inline|unified)
* @param bool Wrap in pre tags (true) or nl2br for output (false)
* @return @e string
*/
public function formatDifferenceReport( $result, $method='inline', $pre=true )
{
if( $result )
{
if( $method == 'unified' )
{
$result = str_replace( array( "\r\n", "\r" ), "\n", $result );
$result = preg_replace( '#(^|\n)(\-|\+)([^\n]+?)\n#', "\n\\1\\2\\3\n\n", $result );
$result = htmlspecialchars( $result );
$result = preg_replace( '#^@@([^@]+?)@@#m', '', $result );
$result = preg_replace( '#(^|\n)\-([^\n]+?)\n#', "\\1<del>\\2</del>\n", $result );
$result = preg_replace( '#(^|\n)\+([^\n]+?)\n#', "\\1<ins>\\2</ins>\n", $result );
$result = str_replace( "</ins>\n\n", "</ins>\n", $result );
$result = str_replace( "</del>\n", '</del>', $result );
$result = str_replace( "\n\n<ins>", "\n<ins>", $result );
$result = str_replace( "\n\n<del>", "\n<del>", $result );
$result = str_replace( "\n+\n", "\n\n", $result );
$result = str_replace( "\n-\n", "\n\n", $result );
if( $pre )
{
$result = '<pre>' . $result . '</pre>';
}
else
{
$result = str_replace( "\t", "&nbsp; &nbsp; ", $result );
$result = str_replace( ' ', '&nbsp;', $result );
$result = nl2br( $result );
}
}
else
{
$result = str_replace( "\n", "<br>", $result );
$result = str_replace( "&gt;&lt;", "&gt;\n&lt;", $result );
$result = preg_replace( "#(?<!(\<del|\<ins)) {1}(?!:style)#i", "&nbsp;", $result );
if( $pre )
{
$result = '<pre>' . $result . '</pre>';
}
else
{
$result = str_replace( "\t", "&nbsp; &nbsp; ", $result );
$result = str_replace( ' ', '&nbsp;', $result );
$result = nl2br( $result );
}
}
}
return $result;
}
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.6
* Compare and highlight differences between two strings or files
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Thursday 10th February 2005 (10:47)
* @version $Revision: 10721 $
*/
if ( ! defined( 'IPS_CLASSES_PATH' ) )
{
/**
* Define classes path
*/
define( 'IPS_CLASSES_PATH', dirname(__FILE__) );
}
class classDifference
{
/**
* Shell command
*
* @var string
*/
public $diff_command = 'diff';
/**
* Type of diff to use
*
* @var string [EXEC, PHP]
*/
public $method = 'EXEC';
/**
* Differences found?
*
* @var integer
*/
public $diff_found = 0;
/**
* Post process DIFF result?
*
* @var integer
*/
public $post_process = 1;
/**
* Constructor
*
* @return @e void
*/
public function __construct()
{
//-------------------------------
// Server?
//-------------------------------
if( strpos( strtolower( PHP_OS ), 'win' ) === 0 OR ( ! function_exists('exec') ) )
{
$this->method = 'PHP';
}
}
/**
* Retrieve a text string showing the differences between the two supplied strings
*
* @param string Original string
* @param string New string
* @param string Inline or unified report (only supported by PHP method)
* @return @e string
*/
public function getDifferences( $str1, $str2, $method='inline' )
{
$this->diff_found = 0;
if ( $this->method != 'PHP' )
{
$str1 = $this->_diffTagSpace($str1);
$str2 = $this->_diffTagSpace($str2);
$str1_lines = $this->_diffExplodeStringIntoWords($str1);
$str2_lines = $this->_diffExplodeStringIntoWords($str2);
}
if ( $this->method == 'PHP' )
{
$diff_res = $this->_getPhpDiff( $str1, $str2, $method );
}
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
*
* @param string String
* @param integer [Optional][0=reverse, 1=normal]
* @return @e string
*/
protected function _diffTagSpace( $str, $rev=0 )
{
if ( $rev )
{
return str_replace(' &lt;','&lt;',str_replace('&gt; ','&gt;',$str) );
}
else
{
return str_replace('<',' <',str_replace('>','> ',$str) );
}
}
/**
* Explodes input string into words
*
* @access protected
* @param string Input string
* @return @e array
*/
protected 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
*
* @param string Delimiter
* @param string String to check
* @param integer [Optional] Remove blank lines
* @return @e array
*/
protected 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
*
* @param string comapre string 1
* @param string comapre string 2
* @return @e string
*/
protected function _getPhpDiff( $str1 , $str2, $method='inline' )
{
$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/' );/*noLibHook*/
/* OMG.. too many PHP 5 errors under strict standards */
$oldReportLevel = error_reporting( 0 );
error_reporting( $oldReportLevel ^ E_STRICT );
require_once 'Text/Diff.php';/*noLibHook*/
require_once 'Text/Diff/Renderer.php';/*noLibHook*/
$diff = new Text_Diff( 'auto', array( $str1, $str2 ) );
if ( $method == 'inline' )
{
require_once 'Text/Diff/Renderer/inline.php';/*noLibHook*/
$renderer = new Text_Diff_Renderer_inline();
}
else
{
require_once 'Text/Diff/Renderer/unified.php';/*noLibHook*/
$renderer = new Text_Diff_Renderer_unified();
$renderer->_leading_context_lines = 10000;
$renderer->_trailing_context_lines = 10000;
}
$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
*
* @param string comapre string 1
* @param string comapre string 2
* @return @e string
*/
protected 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 ( is_file( $file1 ) and is_file( $file2 ) )
{
exec( $this->diff_command.' '.$file1.' '.$file2, $result );
@unlink( $file1 );
@unlink( $file2 );
return $result;
}
else
{
return "Error, files not written to disk";
}
}
/**
* Format differences for output (common)
*
* @param string Differences report
* @param string Format method (inline|unified)
* @param bool Wrap in pre tags (true) or nl2br for output (false)
* @return @e string
*/
public function formatDifferenceReport( $result, $method='inline', $pre=true )
{
if( $result )
{
if( $method == 'unified' )
{
$result = str_replace( array( "\r\n", "\r" ), "\n", $result );
$result = preg_replace( '#(^|\n)(\-|\+)([^\n]+?)\n#', "\n\\1\\2\\3\n\n", $result );
$result = htmlspecialchars( $result );
$result = preg_replace( '#^@@([^@]+?)@@#m', '', $result );
$result = preg_replace( '#(^|\n)\-([^\n]+?)\n#', "\\1<del>\\2</del>\n", $result );
$result = preg_replace( '#(^|\n)\+([^\n]+?)\n#', "\\1<ins>\\2</ins>\n", $result );
$result = str_replace( "</ins>\n\n", "</ins>\n", $result );
$result = str_replace( "</del>\n", '</del>', $result );
$result = str_replace( "\n\n<ins>", "\n<ins>", $result );
$result = str_replace( "\n\n<del>", "\n<del>", $result );
$result = str_replace( "\n+\n", "\n\n", $result );
$result = str_replace( "\n-\n", "\n\n", $result );
if( $pre )
{
$result = '<pre>' . $result . '</pre>';
}
else
{
$result = str_replace( "\t", "&nbsp; &nbsp; ", $result );
$result = str_replace( ' ', '&nbsp;', $result );
$result = nl2br( $result );
}
}
else
{
$result = str_replace( "\n", "<br>", $result );
$result = str_replace( "&gt;&lt;", "&gt;\n&lt;", $result );
$result = preg_replace( "#(?<!(\<del|\<ins)) {1}(?!:style)#i", "&nbsp;", $result );
if( $pre )
{
$result = '<pre>' . $result . '</pre>';
}
else
{
$result = str_replace( "\t", "&nbsp; &nbsp; ", $result );
$result = str_replace( ' ', '&nbsp;', $result );
$result = nl2br( $result );
}
}
}
return $result;
}
}
+3 -3
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Send email using php mail() or SMTP
* Last Updated: $Date: 2012-11-12 11:43:40 -0500 (Mon, 12 Nov 2012) $
* </pre>
@@ -672,7 +672,7 @@ class classEmail implements interfaceEmail
if( !is_dir( $this->temp_dump_path ) )
{
$this->_fatalError( "Включена отладка, но путь отладки не существует и не может быть создан" );
$this->_fatalError( "Debugging enabled, but debug path does not exist and cannot be created" );
return false;
}
@@ -703,7 +703,7 @@ class classEmail implements interfaceEmail
{
if ( ! @mail( $this->to, $this->subject, $this->message, $this->rfc_headers ) )
{
$this->_fatalError( "Невозможно отправить сообщение", "Ошибка функции 'mail'" );
$this->_fatalError( "Could not send the email", "Failed at 'mail' command" );
}
}
}
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -2,7 +2,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* FTP Class
* Last Updated: $Date: 2013-02-06 10:51:28 -0500 (Wed, 06 Feb 2013) $ BY $Author: mark $
* </pre>
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Image Handler: create thumbnails, apply watermarks and copyright tests, save or display final image
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Image Handler: GD2 Library
* Last Updated: $Date: 2013-02-06 19:48:42 -0500 (Wed, 06 Feb 2013) $
* </pre>
+13 -11
View File
@@ -3,19 +3,19 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Image Handler: ImageMagick Library
* Last Updated: $Date: 2013-02-20 19:45:47 -0500 (Wed, 20 Feb 2013) $
* Last Updated: $Date: 2013-08-05 19:04:11 -0400 (Mon, 05 Aug 2013) $
* </pre>
*
* @author $Author: bfarber $
* @author $Author: AndyMillne $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Monday 5th May 2008 14:00
* @version $Revision: 12007 $
* @version $Revision: 12329 $
*
* ImageMagick Example
* <code>
@@ -26,12 +26,12 @@
* '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
@@ -133,6 +133,8 @@ class classImageImagemagick extends classImage implements interfaceImage
@unlink( $this->temp_file );
}
@copy( $this->image_full, $this->temp_file );
//---------------------------------------------------------
// Get image extension
//---------------------------------------------------------
@@ -193,7 +195,7 @@ class classImageImagemagick extends classImage implements interfaceImage
//$ratioOrig = 1;
}
if ( $width / $height > $ratioOrig )
if ( $width / $height > $ratioOrig )
{
$nheight = $width / $ratioOrig;
$nwidth = $width;
@@ -229,7 +231,7 @@ class classImageImagemagick extends classImage implements interfaceImage
* @return @e array
*/
public function crop( $x1, $y1, $width, $height )
{
{
$this->_cropX = $x1;
$this->_cropY = $y1;
@@ -268,7 +270,7 @@ class classImageImagemagick extends classImage implements interfaceImage
if( ! is_array($new_dims) OR !count($new_dims) OR !$new_dims['img_width'] )
{
if( ! $this->force_resize )
{
{
return array( 'originalWidth' => $this->orig_dimensions['width'],
'originalHeight' => $this->orig_dimensions['height'],
'newWidth' => $this->orig_dimensions['width'],
@@ -503,7 +505,7 @@ class classImageImagemagick extends classImage implements interfaceImage
}
else
{
return false;
return false;
}
}
@@ -596,7 +598,7 @@ class classImageImagemagick extends classImage implements interfaceImage
}
else
{
return false;
return false;
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Three Way Merge Class
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $ BY $author$
* </pre>
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Template Parser : Converts HTML "logic" into PHP code
* Last Updated: $Date: 2012-10-18 10:27:08 -0400 (Thu, 18 Oct 2012) $
* </pre>
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* Upload handler : Handles $_FILES and checks for security
* Last Updated: $Date: 2013-02-19 06:02:12 -0500 (Tue, 19 Feb 2013) $
* </pre>
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* XML Handler: Rewritten for PHP5
* By Matt Mecham
* Last Updated: $Date: 2012-07-27 11:43:25 -0400 (Fri, 27 Jul 2012) $
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* XML Archive Hanlder: Can create XML Archives (gzips) of multiple files, binary and ascii
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -8,7 +8,7 @@
* $Author: AndyMillne $
* @since Tuesday 1st March 2005 15:40
* $LastChangedDate: 2013-05-07 11:14:15 -0400 (Tue, 07 May 2013) $
* @version v3.4.5
* @version v3.4.6
* $Revision: 12235 $
*/
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -3,7 +3,7 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.5
* IP.Board v3.4.6
* 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: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com/">IP.Board</a>
IP.Board
</body>
</html>
+1 -1
View File
@@ -5,6 +5,6 @@
<hr>
You have reached this page in error, please use your back button to return to the forum.
<hr>
<a href="http://www.invisionpower.com">IP.Board</a>
IP.Board
</body>
</html>
@@ -1,799 +0,0 @@
<?php
/**
* The default Cache Lifetime (in seconds).
*/
define("OAUTH2_DEFAULT_EXPIRES_IN", 3600*60*60*24);
/**
* The default Base domain for the Cookie.
*/
define("OAUTH2_DEFAULT_BASE_DOMAIN", '');
/**
* OAuth2.0 draft v10 client-side implementation.
*
* @author Originally written by Naitik Shah <naitik@facebook.com>.
* @author Update to draft v10 by Edison Wong <hswong3i@pantarei-design.com>.
*
* @sa <a href="https://github.com/facebook/php-sdk">Facebook PHP SDK</a>.
*/
abstract class OAuth2Client {
/**
* Array of persistent variables stored.
*/
protected $conf = array();
/**
* Returns a persistent variable.
*
* To avoid problems, always use lower case for persistent variable names.
*
* @param $name
* The name of the variable to return.
* @param $default
* The default value to use if this variable has never been set.
*
* @return
* The value of the variable.
*/
public function getVariable($name, $default = NULL) {
return isset($this->conf[$name]) ? $this->conf[$name] : $default;
}
/**
* Sets a persistent variable.
*
* To avoid problems, always use lower case for persistent variable names.
*
* @param $name
* The name of the variable to set.
* @param $value
* The value to set.
*/
public function setVariable($name, $value) {
$this->conf[$name] = $value;
return $this;
}
// Stuff that should get overridden by subclasses.
//
// I don't want to make these abstract, because then subclasses would have
// to implement all of them, which is too much work.
//
// So they're just stubs. Override the ones you need.
/**
* Initialize a Drupal OAuth2.0 Application.
*
* @param $config
* An associative array as below:
* - base_uri: The base URI for the OAuth2.0 endpoints.
* - code: (optional) The authorization code.
* - username: (optional) The username.
* - password: (optional) The password.
* - client_id: (optional) The application ID.
* - client_secret: (optional) The application secret.
* - authorize_uri: (optional) The end-user authorization endpoint URI.
* - access_token_uri: (optional) The token endpoint URI.
* - services_uri: (optional) The services endpoint URI.
* - cookie_support: (optional) TRUE to enable cookie support.
* - base_domain: (optional) The domain for the cookie.
* - file_upload_support: (optional) TRUE if file uploads are enabled.
*/
public function __construct($config = array()) {
// We must set base_uri first.
$this->setVariable('base_uri', $config['base_uri']);
unset($config['base_uri']);
// Use predefined OAuth2.0 params, or get it from $_REQUEST.
foreach (array('code', 'username', 'password') as $name) {
if (isset($config[$name]))
$this->setVariable($name, $config[$name]);
else if (isset($_REQUEST[$name]) && !empty($_REQUEST[$name]))
$this->setVariable($name, $_REQUEST[$name]);
unset($config[$name]);
}
// Endpoint URIs.
foreach (array('authorize_uri', 'access_token_uri', 'services_uri') as $name) {
if (isset($config[$name]))
if (substr($config[$name], 0, 4) == "http")
$this->setVariable($name, $config[$name]);
else
$this->setVariable($name, $this->getVariable('base_uri') . $config[$name]);
unset($config[$name]);
}
// Other else configurations.
foreach ($config as $name => $value) {
$this->setVariable($name, $value);
}
}
/**
* Try to get session object from custom method.
*
* By default we generate session object based on access_token response, or
* if it is provided from server with $_REQUEST. For sure, if it is provided
* by server it should follow our session object format.
*
* Session object provided by server can ensure the correct expires and
* base_domain setup as predefined in server, also you may get more useful
* information for custom functionality, too. BTW, this may require for
* additional remote call overhead.
*
* You may wish to override this function with your custom version due to
* your own server-side implementation.
*
* @param $access_token
* (optional) A valid access token in associative array as below:
* - access_token: A valid access_token generated by OAuth2.0
* authorization endpoint.
* - expires_in: (optional) A valid expires_in generated by OAuth2.0
* authorization endpoint.
* - refresh_token: (optional) A valid refresh_token generated by OAuth2.0
* authorization endpoint.
* - scope: (optional) A valid scope generated by OAuth2.0
* authorization endpoint.
*
* @return
* A valid session object in associative array for setup cookie, and
* NULL if not able to generate it with custom method.
*/
protected function getSessionObject($access_token = NULL) {
$session = NULL;
// Try generate local version of session cookie.
if (!empty($access_token) && isset($access_token['access_token'])) {
$session['access_token'] = $access_token['access_token'];
$session['base_domain'] = $this->getVariable('base_domain', OAUTH2_DEFAULT_BASE_DOMAIN);
$session['expires'] = isset($access_token['expires_in']) ? time() + $access_token['expires_in'] : time() + $this->getVariable('expires_in', OAUTH2_DEFAULT_EXPIRES_IN);
$session['refresh_token'] = isset($access_token['refresh_token']) ? $access_token['refresh_token'] : '';
$session['scope'] = isset($access_token['scope']) ? $access_token['scope'] : '';
$session['secret'] = md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
// Provide our own signature.
$sig = self::generateSignature(
$session,
$this->getVariable('client_secret')
);
$session['sig'] = $sig;
}
// Try loading session from $_REQUEST.
if (!$session && isset($_REQUEST['session'])) {
$session = json_decode(
get_magic_quotes_gpc()
? stripslashes($_REQUEST['session'])
: $_REQUEST['session'],
TRUE
);
}
return $session;
}
/**
* Make an API call.
*
* Support both OAuth2.0 or normal GET/POST API call, with relative
* or absolute URI.
*
* If no valid OAuth2.0 access token found in session object, this function
* will automatically switch as normal remote API call without "oauth_token"
* parameter.
*
* Assume server reply in JSON object and always decode during return. If
* you hope to issue a raw query, please use makeRequest().
*
* @param $path
* The target path, relative to base_path/service_uri or an absolute URI.
* @param $method
* (optional) The HTTP method (default 'GET').
* @param $params
* (optional The GET/POST parameters.
*
* @return
* The JSON decoded response object.
*
* @throws OAuth2Exception
*/
public function api($path, $method = 'GET', $params = array()) {
if (is_array($method) && empty($params)) {
$params = $method;
$method = 'GET';
}
// json_encode all params values that are not strings.
foreach ($params as $key => $value) {
if (!is_string($value)) {
$params[$key] = json_encode($value);
}
}
$result = json_decode($this->makeOAuth2Request(
$this->getUri($path),
$method,
$params
), TRUE);
// Results are returned, errors are thrown.
if (is_array($result) && isset($result['error'])) {
$e = new OAuth2Exception($result);
switch ($e->getType()) {
// OAuth 2.0 Draft 10 style.
case 'invalid_token':
$this->setSession(NULL);
default:
$this->setSession(NULL);
}
throw $e;
}
return $result;
}
// End stuff that should get overridden.
/**
* Default options for cURL.
*/
public static $CURL_OPTS = array(
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => TRUE,
CURLOPT_TIMEOUT => 60,
CURLOPT_USERAGENT => 'oauth2-draft-v10',
CURLOPT_HTTPHEADER => array("Accept: application/json"),
);
/**
* Set the Session.
*
* @param $session
* (optional) The session object to be set. NULL if hope to frush existing
* session object.
* @param $write_cookie
* (optional) TRUE if a cookie should be written. This value is ignored
* if cookie support has been disabled.
*
* @return
* The current OAuth2.0 client-side instance.
*/
public function setSession($session = NULL, $write_cookie = TRUE) {
$this->setVariable('_session', $this->validateSessionObject($session));
$this->setVariable('_session_loaded', TRUE);
if ($write_cookie) {
$this->setCookieFromSession($this->getVariable('_session'));
}
return $this;
}
/**
* Get the session object.
*
* This will automatically look for a signed session via custom method,
* OAuth2.0 grant type with authorization_code, OAuth2.0 grant type with
* password, or cookie that we had already setup.
*
* @return
* The valid session object with OAuth2.0 infomration, and NULL if not
* able to discover any cases.
*/
public function getSession() {
if (!$this->getVariable('_session_loaded')) {
$session = NULL;
$write_cookie = TRUE;
// Try obtain login session by custom method.
// $session = $this->getSessionObject(NULL);
// $session = $this->validateSessionObject($session);
// grant_type == authorization_code.
if (!$session && $this->getVariable('code')) {
$access_token = $this->getAccessTokenFromAuthorizationCode($this->getVariable('code'));
$session = $this->getSessionObject($access_token);
$session = $this->validateSessionObject($session);
}
// grant_type == password.
if (!$session && $this->getVariable('username') && $this->getVariable('password')) {
$access_token = $this->getAccessTokenFromPassword($this->getVariable('username'), $this->getVariable('password'));
$session = $this->getSessionObject($access_token);
$session = $this->validateSessionObject($session);
}
// Try loading session from cookie if necessary.
if (!$session && $this->getVariable('cookie_support')) {
$cookie_name = $this->getSessionCookieName();
if (isset($_COOKIE[$cookie_name])) {
$session = array();
parse_str(trim(
get_magic_quotes_gpc()
? stripslashes($_COOKIE[$cookie_name])
: $_COOKIE[$cookie_name],
'"'
), $session);
$session = $this->validateSessionObject($session);
// Write only if we need to delete a invalid session cookie.
$write_cookie = empty($session);
}
}
$this->setSession($session, $write_cookie);
}
return $this->getVariable('_session');
}
/**
* Gets an OAuth2.0 access token from session.
*
* This will trigger getSession() and so we MUST initialize with required
* configuration.
*
* @return
* The valid OAuth2.0 access token, and NULL if not exists in session.
*/
public function getAccessToken() {
$session = $this->getSession();
return isset($session['access_token']) ? $session['access_token'] : NULL;
}
/**
* Get access token from OAuth2.0 token endpoint with authorization code.
*
* This function will only be activated if both access token URI, client
* identifier and client secret are setup correctly.
*
* @param $code
* Authorization code issued by authorization server's authorization
* endpoint.
*
* @return
* A valid OAuth2.0 JSON decoded access token in associative array, and
* NULL if not enough parameters or JSON decode failed.
*/
private function getAccessTokenFromAuthorizationCode($code) {
if ($this->getVariable('access_token_uri') && $this->getVariable('client_id') && $this->getVariable('client_secret')) {
$result = json_decode($this->makeRequest(
$this->getVariable('access_token_uri'),
'POST',
array(
'grant_type' => 'authorization_code',
'client_id' => $this->getVariable('client_id'),
'client_secret' => $this->getVariable('client_secret'),
'code' => $code,
'redirect_uri' => $this->getVariable( 'authorize_callback_uri') //$this->getCurrentUri(),
)
), TRUE);
return $result;
}
return NULL;
}
/**
* Get access token from OAuth2.0 token endpoint with basic user
* credentials.
*
* This function will only be activated if both username and password
* are setup correctly.
*
* @param $username
* Username to be check with.
* @param $password
* Password to be check with.
*
* @return
* A valid OAuth2.0 JSON decoded access token in associative array, and
* NULL if not enough parameters or JSON decode failed.
*/
private function getAccessTokenFromPassword($username, $password) {
if ($this->getVariable('access_token_uri') && $this->getVariable('client_id') && $this->getVariable('client_secret')) {
return json_decode($this->makeRequest(
$this->getVariable('access_token_uri'),
'POST',
array(
'grant_type' => 'password',
'client_id' => $this->getVariable('client_id'),
'client_secret' => $this->getVariable('client_secret'),
'username' => $username,
'password' => $password,
)
), TRUE);
}
return NULL;
}
/**
* Make an OAuth2.0 Request.
*
* Automatically append "oauth_token" in query parameters if not yet
* exists and able to discover a valid access token from session. Otherwise
* just ignore setup with "oauth_token" and handle the API call AS-IS, and
* so may issue a plain API call without OAuth2.0 protection.
*
* @param $path
* The target path, relative to base_path/service_uri or an absolute URI.
* @param $method
* (optional) The HTTP method (default 'GET').
* @param $params
* (optional The GET/POST parameters.
*
* @return
* The JSON decoded response object.
*
* @throws OAuth2Exception
*/
protected function makeOAuth2Request($path, $method = 'GET', $params = array()) {
if ((!isset($params['oauth_token']) || empty($params['oauth_token'])) && $oauth_token = $this->getAccessToken()) {
$params['oauth_token'] = $oauth_token;
}
return $this->makeRequest($path, $method, $params);
}
/**
* Makes an HTTP request.
*
* This method can be overriden by subclasses if developers want to do
* fancier things or use something other than cURL to make the request.
*
* @param $path
* The target path, relative to base_path/service_uri or an absolute URI.
* @param $method
* (optional) The HTTP method (default 'GET').
* @param $params
* (optional The GET/POST parameters.
* @param $ch
* (optional) An initialized curl handle
*
* @return
* The JSON decoded response object.
*/
protected function makeRequest($path, $method = 'GET', $params = array(), $ch = NULL) {
if (!$ch)
$ch = curl_init();
$opts = self::$CURL_OPTS;
if ($params) {
switch ($method) {
case 'GET':
$path .= '?' . http_build_query($params, NULL, '&');
break;
// Method override as we always do a POST.
default:
if ($this->getVariable('file_upload_support')) {
$opts[CURLOPT_POSTFIELDS] = $params;
}
else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, NULL, '&');
}
}
}
$opts[CURLOPT_URL] = $path;
// Disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
// for 2 seconds if the server does not support this header.
if (isset($opts[CURLOPT_HTTPHEADER])) {
$existing_headers = $opts[CURLOPT_HTTPHEADER];
$existing_headers[] = 'Expect:';
$opts[CURLOPT_HTTPHEADER] = $existing_headers;
}
else {
$opts[CURLOPT_HTTPHEADER] = array('Expect:');
}
curl_setopt_array($ch, $opts);
$result = curl_exec($ch);
if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT
error_log('Invalid or no certificate authority found, using bundled information');
curl_setopt($ch, CURLOPT_CAINFO,
dirname(__FILE__) . '/fb_ca_chain_bundle.crt');
$result = curl_exec($ch);
}
if ($result === FALSE) {
$e = new OAuth2Exception(array(
'code' => curl_errno($ch),
'message' => curl_error($ch),
));
curl_close($ch);
throw $e;
}
curl_close($ch);
// Split the HTTP response into header and body.
list($headers, $body) = explode("\r\n\r\n", $result);
$headers = explode("\r\n", $headers);
// We catch HTTP/1.1 4xx or HTTP/1.1 5xx error response.
if (strpos($headers[0], 'HTTP/1.1 4') !== FALSE || strpos($headers[0], 'HTTP/1.1 5') !== FALSE) {
$result = array(
'code' => 0,
'message' => '',
);
if (preg_match('/^HTTP\/1.1 ([0-9]{3,3}) (.*)$/', $headers[0], $matches)) {
$result['code'] = $matches[1];
$result['message'] = $matches[2];
}
// In case retrun with WWW-Authenticate replace the description.
foreach ($headers as $header) {
if (preg_match("/^WWW-Authenticate:.*error='(.*)'/", $header, $matches)) {
$result['error'] = $matches[1];
}
}
return json_encode($result);
}
return $body;
}
/**
* The name of the cookie that contains the session object.
*
* @return
* The cookie name.
*/
private function getSessionCookieName() {
return 'oauth2_' . $this->getVariable('client_id');
}
/**
* Set a JS Cookie based on the _passed in_ session.
*
* It does not use the currently stored session - you need to explicitly
* pass it in.
*
* @param $session
* The session to use for setting the cookie.
*/
protected function setCookieFromSession($session = NULL) {
if (!$this->getVariable('cookie_support'))
return;
$cookie_name = $this->getSessionCookieName();
$value = 'deleted';
$expires = time() - 3600;
$base_domain = $this->getVariable('base_domain', OAUTH2_DEFAULT_BASE_DOMAIN);
if ($session) {
$value = '"' . http_build_query($session, NULL, '&') . '"';
$base_domain = isset($session['base_domain']) ? $session['base_domain'] : $base_domain;
$expires = isset($session['expires']) ? $session['expires'] : time() + $this->getVariable('expires_in', OAUTH2_DEFAULT_EXPIRES_IN);
}
// Prepend dot if a domain is found.
if ($base_domain)
$base_domain = '.' . $base_domain;
// If an existing cookie is not set, we dont need to delete it.
if ($value == 'deleted' && empty($_COOKIE[$cookie_name]))
return;
if (headers_sent())
error_log('Could not set cookie. Headers already sent.');
else
setcookie($cookie_name, $value, $expires, '/', $base_domain);
}
/**
* Validates a session_version = 3 style session object.
*
* @param $session
* The session object.
*
* @return
* The session object if it validates, NULL otherwise.
*/
protected function validateSessionObject($session) {
// Make sure some essential fields exist.
if (is_array($session) && isset($session['access_token']) && isset($session['sig'])) {
// Validate the signature.
$session_without_sig = $session;
unset($session_without_sig['sig']);
$expected_sig = self::generateSignature(
$session_without_sig,
$this->getVariable('client_secret')
);
if ($session['sig'] != $expected_sig) {
error_log('Got invalid session signature in cookie.');
$session = NULL;
}
}
else {
$session = NULL;
}
return $session;
}
/**
* Since $_SERVER['REQUEST_URI'] is only available on Apache, we
* generate an equivalent using other environment variables.
*/
function getRequestUri() {
if (isset($_SERVER['REQUEST_URI'])) {
$uri = $_SERVER['REQUEST_URI'];
}
else {
if (isset($_SERVER['argv'])) {
$uri = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['argv'][0];
}
elseif (isset($_SERVER['QUERY_STRING'])) {
$uri = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
}
else {
$uri = $_SERVER['SCRIPT_NAME'];
}
}
// Prevent multiple slashes to avoid cross site requests via the Form API.
$uri = '/' . ltrim($uri, '/');
return $uri;
}
/**
* Returns the Current URL.
*
* @return
* The current URL.
*/
protected function getCurrentUri() {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'
? 'https://'
: 'http://';
$current_uri = $protocol . $_SERVER['HTTP_HOST'] . $this->getRequestUri();
$parts = parse_url($current_uri);
$query = '';
if (!empty($parts['query'])) {
$params = array();
parse_str($parts['query'], $params);
$params = array_filter($params);
if (!empty($params)) {
$query = '?' . http_build_query($params, NULL, '&');
}
}
// Use port if non default.
$port = isset($parts['port']) &&
(($protocol === 'http://' && $parts['port'] !== 80) || ($protocol === 'https://' && $parts['port'] !== 443))
? ':' . $parts['port'] : '';
// Rebuild.
return $protocol . $parts['host'] . $port . $parts['path'] . $query;
}
/**
* Build the URL for given path and parameters.
*
* @param $path
* (optional) The path.
* @param $params
* (optional) The query parameters in associative array.
*
* @return
* The URL for the given parameters.
*/
protected function getUri($path = '', $params = array()) {
$url = $this->getVariable('services_uri') ? $this->getVariable('services_uri') : $this->getVariable('base_uri');
if (!empty($path))
if (substr($path, 0, 4) == "http")
$url = $path;
else
$url = rtrim($url, '/') . '/' . ltrim($path, '/');
if (!empty($params))
$url .= '?' . http_build_query($params, NULL, '&');
return $url;
}
/**
* Generate a signature for the given params and secret.
*
* @param $params
* The parameters to sign.
* @param $secret
* The secret to sign with.
*
* @return
* The generated signature
*/
protected function generateSignature($params, $secret) {
// Work with sorted data.
ksort($params);
// Generate the base string.
$base_string = '';
foreach ($params as $key => $value) {
$base_string .= $key . '=' . $value;
}
$base_string .= $secret;
return md5($base_string);
}
}
class OAuth2Exception extends Exception {
/**
* The result from the API server that represents the exception information.
*/
protected $result;
/**
* Make a new API Exception with the given result.
*
* @param $result
* The result from the API server.
*/
public function __construct($result) {
$this->result = $result;
$code = isset($result['code']) ? $result['code'] : 0;
if (isset($result['error'])) {
// OAuth 2.0 Draft 10 style
$message = $result['error'];
}
elseif (isset($result['message'])) {
// cURL style
$message = $result['message'];
}
else {
$message = 'Unknown Error. Check getResult()';
}
parent::__construct($message, $code);
}
/**
* Return the associated result object returned by the API server.
*
* @returns
* The result from the API server.
*/
public function getResult() {
return $this->result;
}
/**
* Returns the associated type for the error. This will default to
* 'Exception' when a type is not available.
*
* @return
* The type for the error.
*/
public function getType() {
if (isset($this->result['error'])) {
$message = $this->result['error'];
if (is_string($message)) {
// OAuth 2.0 Draft 10 style
return $message;
}
}
return 'Exception';
}
/**
* To make debugging easier.
*
* @returns
* The string representation of the error.
*/
public function __toString() {
$str = $this->getType() . ': ';
if ($this->code != 0) {
$str .= $this->code . ': ';
}
return $str . $this->message;
}
}
@@ -1,802 +0,0 @@
<?php
/**
* The default Cache Lifetime (in seconds).
*/
define("OAUTH2_DEFAULT_EXPIRES_IN", 3600*60*60*24);
/**
* The default Base domain for the Cookie.
*/
define("OAUTH2_DEFAULT_BASE_DOMAIN", '');
/**
* OAuth2.0 draft v10 client-side implementation.
*
* @author Originally written by Naitik Shah <naitik@facebook.com>.
* @author Update to draft v10 by Edison Wong <hswong3i@pantarei-design.com>.
*
* @sa <a href="https://github.com/facebook/php-sdk">Facebook PHP SDK</a>.
*/
abstract class OAuth2Client {
/**
* Array of persistent variables stored.
*/
protected $conf = array();
/**
* Returns a persistent variable.
*
* To avoid problems, always use lower case for persistent variable names.
*
* @param $name
* The name of the variable to return.
* @param $default
* The default value to use if this variable has never been set.
*
* @return
* The value of the variable.
*/
public function getVariable($name, $default = NULL) {
return isset($this->conf[$name]) ? $this->conf[$name] : $default;
}
/**
* Sets a persistent variable.
*
* To avoid problems, always use lower case for persistent variable names.
*
* @param $name
* The name of the variable to set.
* @param $value
* The value to set.
*/
public function setVariable($name, $value) {
$this->conf[$name] = $value;
return $this;
}
// Stuff that should get overridden by subclasses.
//
// I don't want to make these abstract, because then subclasses would have
// to implement all of them, which is too much work.
//
// So they're just stubs. Override the ones you need.
/**
* Initialize a Drupal OAuth2.0 Application.
*
* @param $config
* An associative array as below:
* - base_uri: The base URI for the OAuth2.0 endpoints.
* - code: (optional) The authorization code.
* - username: (optional) The username.
* - password: (optional) The password.
* - client_id: (optional) The application ID.
* - client_secret: (optional) The application secret.
* - authorize_uri: (optional) The end-user authorization endpoint URI.
* - access_token_uri: (optional) The token endpoint URI.
* - services_uri: (optional) The services endpoint URI.
* - cookie_support: (optional) TRUE to enable cookie support.
* - base_domain: (optional) The domain for the cookie.
* - file_upload_support: (optional) TRUE if file uploads are enabled.
*/
public function __construct($config = array()) {
// We must set base_uri first.
$this->setVariable('base_uri', $config['base_uri']);
unset($config['base_uri']);
// Use predefined OAuth2.0 params, or get it from $_REQUEST.
foreach (array('code', 'username', 'password') as $name) {
if (isset($config[$name]))
$this->setVariable($name, $config[$name]);
else if (isset($_REQUEST[$name]) && !empty($_REQUEST[$name]))
$this->setVariable($name, $_REQUEST[$name]);
unset($config[$name]);
}
// Endpoint URIs.
foreach (array('authorize_uri', 'access_token_uri', 'services_uri') as $name) {
if (isset($config[$name]))
if (substr($config[$name], 0, 4) == "http")
$this->setVariable($name, $config[$name]);
else
$this->setVariable($name, $this->getVariable('base_uri') . $config[$name]);
unset($config[$name]);
}
// Other else configurations.
foreach ($config as $name => $value) {
$this->setVariable($name, $value);
}
}
/**
* Try to get session object from custom method.
*
* By default we generate session object based on access_token response, or
* if it is provided from server with $_REQUEST. For sure, if it is provided
* by server it should follow our session object format.
*
* Session object provided by server can ensure the correct expires and
* base_domain setup as predefined in server, also you may get more useful
* information for custom functionality, too. BTW, this may require for
* additional remote call overhead.
*
* You may wish to override this function with your custom version due to
* your own server-side implementation.
*
* @param $access_token
* (optional) A valid access token in associative array as below:
* - access_token: A valid access_token generated by OAuth2.0
* authorization endpoint.
* - expires_in: (optional) A valid expires_in generated by OAuth2.0
* authorization endpoint.
* - refresh_token: (optional) A valid refresh_token generated by OAuth2.0
* authorization endpoint.
* - scope: (optional) A valid scope generated by OAuth2.0
* authorization endpoint.
*
* @return
* A valid session object in associative array for setup cookie, and
* NULL if not able to generate it with custom method.
*/
protected function getSessionObject($access_token = NULL) {
$session = NULL;
// Try generate local version of session cookie.
if (!empty($access_token) && isset($access_token['access_token'])) {
$session['access_token'] = $access_token['access_token'];
$session['base_domain'] = $this->getVariable('base_domain', OAUTH2_DEFAULT_BASE_DOMAIN);
$session['expires'] = isset($access_token['expires_in']) ? time() + $access_token['expires_in'] : time() + $this->getVariable('expires_in', OAUTH2_DEFAULT_EXPIRES_IN);
$session['refresh_token'] = isset($access_token['refresh_token']) ? $access_token['refresh_token'] : '';
$session['scope'] = isset($access_token['scope']) ? $access_token['scope'] : '';
$session['secret'] = md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
// Provide our own signature.
$sig = self::generateSignature(
$session,
$this->getVariable('client_secret')
);
$session['sig'] = $sig;
}
// Try loading session from $_REQUEST.
if (!$session && isset($_REQUEST['session'])) {
$session = json_decode(
get_magic_quotes_gpc()
? stripslashes($_REQUEST['session'])
: $_REQUEST['session'],
TRUE
);
}
return $session;
}
/**
* Make an API call.
*
* Support both OAuth2.0 or normal GET/POST API call, with relative
* or absolute URI.
*
* If no valid OAuth2.0 access token found in session object, this function
* will automatically switch as normal remote API call without "oauth_token"
* parameter.
*
* Assume server reply in JSON object and always decode during return. If
* you hope to issue a raw query, please use makeRequest().
*
* @param $path
* The target path, relative to base_path/service_uri or an absolute URI.
* @param $method
* (optional) The HTTP method (default 'GET').
* @param $params
* (optional The GET/POST parameters.
*
* @return
* The JSON decoded response object.
*
* @throws OAuth2Exception
*/
public function api($path, $method = 'GET', $params = array()) {
if (is_array($method) && empty($params)) {
$params = $method;
$method = 'GET';
}
// json_encode all params values that are not strings.
foreach ($params as $key => $value) {
if (!is_string($value)) {
$params[$key] = json_encode($value);
}
}
$result = json_decode($this->makeOAuth2Request(
$this->getUri($path),
$method,
$params
), TRUE);
// Results are returned, errors are thrown.
if (is_array($result) && isset($result['error'])) {
$e = new OAuth2Exception($result);
switch ($e->getType()) {
// OAuth 2.0 Draft 10 style.
case 'invalid_token':
$this->setSession(NULL);
default:
$this->setSession(NULL);
}
throw $e;
}
return $result;
}
// End stuff that should get overridden.
/**
* Default options for cURL.
*/
public static $CURL_OPTS = array(
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => TRUE,
CURLOPT_TIMEOUT => 60,
CURLOPT_USERAGENT => 'oauth2-draft-v10',
CURLOPT_HTTPHEADER => array("Accept: application/json"),
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => FALSE
);
/**
* Set the Session.
*
* @param $session
* (optional) The session object to be set. NULL if hope to frush existing
* session object.
* @param $write_cookie
* (optional) TRUE if a cookie should be written. This value is ignored
* if cookie support has been disabled.
*
* @return
* The current OAuth2.0 client-side instance.
*/
public function setSession($session = NULL, $write_cookie = TRUE) {
$this->setVariable('_session', $this->validateSessionObject($session));
$this->setVariable('_session_loaded', TRUE);
if ($write_cookie) {
$this->setCookieFromSession($this->getVariable('_session'));
}
return $this;
}
/**
* Get the session object.
*
* This will automatically look for a signed session via custom method,
* OAuth2.0 grant type with authorization_code, OAuth2.0 grant type with
* password, or cookie that we had already setup.
*
* @return
* The valid session object with OAuth2.0 infomration, and NULL if not
* able to discover any cases.
*/
public function getSession() {
if (!$this->getVariable('_session_loaded')) {
$session = NULL;
$write_cookie = TRUE;
// Try obtain login session by custom method.
// $session = $this->getSessionObject(NULL);
// $session = $this->validateSessionObject($session);
// grant_type == authorization_code.
if (!$session && $this->getVariable('code')) {
$access_token = $this->getAccessTokenFromAuthorizationCode($this->getVariable('code'));
$session = $this->getSessionObject($access_token);
$session = $this->validateSessionObject($session);
}
// grant_type == password.
if (!$session && $this->getVariable('username') && $this->getVariable('password')) {
$access_token = $this->getAccessTokenFromPassword($this->getVariable('username'), $this->getVariable('password'));
$session = $this->getSessionObject($access_token);
$session = $this->validateSessionObject($session);
}
// Try loading session from cookie if necessary.
if (!$session && $this->getVariable('cookie_support')) {
$cookie_name = $this->getSessionCookieName();
if (isset($_COOKIE[$cookie_name])) {
$session = array();
parse_str(trim(
get_magic_quotes_gpc()
? stripslashes($_COOKIE[$cookie_name])
: $_COOKIE[$cookie_name],
'"'
), $session);
$session = $this->validateSessionObject($session);
// Write only if we need to delete a invalid session cookie.
$write_cookie = empty($session);
}
}
$this->setSession($session, $write_cookie);
}
return $this->getVariable('_session');
}
/**
* Gets an OAuth2.0 access token from session.
*
* This will trigger getSession() and so we MUST initialize with required
* configuration.
*
* @return
* The valid OAuth2.0 access token, and NULL if not exists in session.
*/
public function getAccessToken() {
$session = $this->getSession();
return isset($session['access_token']) ? $session['access_token'] : NULL;
}
/**
* Get access token from OAuth2.0 token endpoint with authorization code.
*
* This function will only be activated if both access token URI, client
* identifier and client secret are setup correctly.
*
* @param $code
* Authorization code issued by authorization server's authorization
* endpoint.
*
* @return
* A valid OAuth2.0 JSON decoded access token in associative array, and
* NULL if not enough parameters or JSON decode failed.
*/
private function getAccessTokenFromAuthorizationCode($code) {
if ($this->getVariable('access_token_uri') && $this->getVariable('client_id') && $this->getVariable('client_secret')) {
$result = json_decode($this->makeRequest(
$this->getVariable('access_token_uri'),
'POST',
array(
'grant_type' => 'authorization_code',
'client_id' => $this->getVariable('client_id'),
'client_secret' => $this->getVariable('client_secret'),
'code' => $code,
'redirect_uri' => $this->getVariable( 'authorize_callback_uri') //$this->getCurrentUri(),
)
), TRUE);
return $result;
}
return NULL;
}
/**
* Get access token from OAuth2.0 token endpoint with basic user
* credentials.
*
* This function will only be activated if both username and password
* are setup correctly.
*
* @param $username
* Username to be check with.
* @param $password
* Password to be check with.
*
* @return
* A valid OAuth2.0 JSON decoded access token in associative array, and
* NULL if not enough parameters or JSON decode failed.
*/
private function getAccessTokenFromPassword($username, $password) {
if ($this->getVariable('access_token_uri') && $this->getVariable('client_id') && $this->getVariable('client_secret')) {
return json_decode($this->makeRequest(
$this->getVariable('access_token_uri'),
'POST',
array(
'grant_type' => 'password',
'client_id' => $this->getVariable('client_id'),
'client_secret' => $this->getVariable('client_secret'),
'username' => $username,
'password' => $password,
)
), TRUE);
}
return NULL;
}
/**
* Make an OAuth2.0 Request.
*
* Automatically append "oauth_token" in query parameters if not yet
* exists and able to discover a valid access token from session. Otherwise
* just ignore setup with "oauth_token" and handle the API call AS-IS, and
* so may issue a plain API call without OAuth2.0 protection.
*
* @param $path
* The target path, relative to base_path/service_uri or an absolute URI.
* @param $method
* (optional) The HTTP method (default 'GET').
* @param $params
* (optional The GET/POST parameters.
*
* @return
* The JSON decoded response object.
*
* @throws OAuth2Exception
*/
protected function makeOAuth2Request($path, $method = 'GET', $params = array()) {
if ((!isset($params['oauth_token']) || empty($params['oauth_token'])) && $oauth_token = $this->getAccessToken()) {
$params['oauth_token'] = $oauth_token;
}
return $this->makeRequest($path, $method, $params);
}
/**
* Makes an HTTP request.
*
* This method can be overriden by subclasses if developers want to do
* fancier things or use something other than cURL to make the request.
*
* @param $path
* The target path, relative to base_path/service_uri or an absolute URI.
* @param $method
* (optional) The HTTP method (default 'GET').
* @param $params
* (optional The GET/POST parameters.
* @param $ch
* (optional) An initialized curl handle
*
* @return
* The JSON decoded response object.
*/
protected function makeRequest($path, $method = 'GET', $params = array(), $ch = NULL) {
if (!$ch)
$ch = curl_init();
$opts = self::$CURL_OPTS;
if ($params) {
switch ($method) {
case 'GET':
$path .= '?' . http_build_query($params, NULL, '&');
break;
// Method override as we always do a POST.
default:
if ($this->getVariable('file_upload_support')) {
$opts[CURLOPT_POSTFIELDS] = $params;
}
else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, NULL, '&');
}
}
}
$opts[CURLOPT_URL] = $path;
// Disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
// for 2 seconds if the server does not support this header.
if (isset($opts[CURLOPT_HTTPHEADER])) {
$existing_headers = $opts[CURLOPT_HTTPHEADER];
$existing_headers[] = 'Expect:';
$opts[CURLOPT_HTTPHEADER] = $existing_headers;
}
else {
$opts[CURLOPT_HTTPHEADER] = array('Expect:');
}
curl_setopt_array($ch, $opts);
$result = curl_exec($ch);
if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT
error_log('Invalid or no certificate authority found, using bundled information');
curl_setopt($ch, CURLOPT_CAINFO,
dirname(__FILE__) . '/fb_ca_chain_bundle.crt');
$result = curl_exec($ch);
}
if ($result === FALSE) {
$e = new OAuth2Exception(array(
'code' => curl_errno($ch),
'message' => curl_error($ch),
));
curl_close($ch);
throw $e;
}
curl_close($ch);
// Split the HTTP response into header and body.
list($headers, $body) = explode("\r\n\r\n", $result);
$headers = explode("\r\n", $headers);
// We catch HTTP/1.1 4xx or HTTP/1.1 5xx error response.
if (strpos($headers[0], 'HTTP/1.1 4') !== FALSE || strpos($headers[0], 'HTTP/1.1 5') !== FALSE) {
$result = array(
'code' => 0,
'message' => '',
);
if (preg_match('/^HTTP\/1.1 ([0-9]{3,3}) (.*)$/', $headers[0], $matches)) {
$result['code'] = $matches[1];
$result['message'] = $matches[2];
}
// In case retrun with WWW-Authenticate replace the description.
foreach ($headers as $header) {
if (preg_match("/^WWW-Authenticate:.*error='(.*)'/", $header, $matches)) {
$result['error'] = $matches[1];
}
}
return json_encode($result);
}
return $body;
}
/**
* The name of the cookie that contains the session object.
*
* @return
* The cookie name.
*/
private function getSessionCookieName() {
return 'oauth2_' . $this->getVariable('client_id');
}
/**
* Set a JS Cookie based on the _passed in_ session.
*
* It does not use the currently stored session - you need to explicitly
* pass it in.
*
* @param $session
* The session to use for setting the cookie.
*/
protected function setCookieFromSession($session = NULL) {
if (!$this->getVariable('cookie_support'))
return;
$cookie_name = $this->getSessionCookieName();
$value = 'deleted';
$expires = time() - 3600;
$base_domain = $this->getVariable('base_domain', OAUTH2_DEFAULT_BASE_DOMAIN);
if ($session) {
$value = '"' . http_build_query($session, NULL, '&') . '"';
$base_domain = isset($session['base_domain']) ? $session['base_domain'] : $base_domain;
$expires = isset($session['expires']) ? $session['expires'] : time() + $this->getVariable('expires_in', OAUTH2_DEFAULT_EXPIRES_IN);
}
// Prepend dot if a domain is found.
if ($base_domain)
$base_domain = '.' . $base_domain;
// If an existing cookie is not set, we dont need to delete it.
if ($value == 'deleted' && empty($_COOKIE[$cookie_name]))
return;
if (headers_sent())
error_log('Could not set cookie. Headers already sent.');
else
setcookie($cookie_name, $value, $expires, '/', $base_domain);
}
/**
* Validates a session_version = 3 style session object.
*
* @param $session
* The session object.
*
* @return
* The session object if it validates, NULL otherwise.
*/
protected function validateSessionObject($session) {
// Make sure some essential fields exist.
if (is_array($session) && isset($session['access_token']) && isset($session['sig'])) {
// Validate the signature.
$session_without_sig = $session;
unset($session_without_sig['sig']);
$expected_sig = self::generateSignature(
$session_without_sig,
$this->getVariable('client_secret')
);
if ($session['sig'] != $expected_sig) {
error_log('Got invalid session signature in cookie.');
$session = NULL;
}
}
else {
$session = NULL;
}
return $session;
}
/**
* Since $_SERVER['REQUEST_URI'] is only available on Apache, we
* generate an equivalent using other environment variables.
*/
function getRequestUri() {
if (isset($_SERVER['REQUEST_URI'])) {
$uri = $_SERVER['REQUEST_URI'];
}
else {
if (isset($_SERVER['argv'])) {
$uri = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['argv'][0];
}
elseif (isset($_SERVER['QUERY_STRING'])) {
$uri = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
}
else {
$uri = $_SERVER['SCRIPT_NAME'];
}
}
// Prevent multiple slashes to avoid cross site requests via the Form API.
$uri = '/' . ltrim($uri, '/');
return $uri;
}
/**
* Returns the Current URL.
*
* @return
* The current URL.
*/
protected function getCurrentUri() {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'
? 'https://'
: 'http://';
$current_uri = $protocol . $_SERVER['HTTP_HOST'] . $this->getRequestUri();
$parts = parse_url($current_uri);
$query = '';
if (!empty($parts['query'])) {
$params = array();
parse_str($parts['query'], $params);
$params = array_filter($params);
if (!empty($params)) {
$query = '?' . http_build_query($params, NULL, '&');
}
}
// Use port if non default.
$port = isset($parts['port']) &&
(($protocol === 'http://' && $parts['port'] !== 80) || ($protocol === 'https://' && $parts['port'] !== 443))
? ':' . $parts['port'] : '';
// Rebuild.
return $protocol . $parts['host'] . $port . $parts['path'] . $query;
}
/**
* Build the URL for given path and parameters.
*
* @param $path
* (optional) The path.
* @param $params
* (optional) The query parameters in associative array.
*
* @return
* The URL for the given parameters.
*/
protected function getUri($path = '', $params = array()) {
$url = $this->getVariable('services_uri') ? $this->getVariable('services_uri') : $this->getVariable('base_uri');
if (!empty($path))
if (substr($path, 0, 4) == "http")
$url = $path;
else
$url = rtrim($url, '/') . '/' . ltrim($path, '/');
if (!empty($params))
$url .= '?' . http_build_query($params, NULL, '&');
return $url;
}
/**
* Generate a signature for the given params and secret.
*
* @param $params
* The parameters to sign.
* @param $secret
* The secret to sign with.
*
* @return
* The generated signature
*/
protected function generateSignature($params, $secret) {
// Work with sorted data.
ksort($params);
// Generate the base string.
$base_string = '';
foreach ($params as $key => $value) {
$base_string .= $key . '=' . $value;
}
$base_string .= $secret;
return md5($base_string);
}
}
class OAuth2Exception extends Exception {
/**
* The result from the API server that represents the exception information.
*/
protected $result;
/**
* Make a new API Exception with the given result.
*
* @param $result
* The result from the API server.
*/
public function __construct($result) {
$this->result = $result;
$code = isset($result['code']) ? $result['code'] : 0;
if (isset($result['error'])) {
// OAuth 2.0 Draft 10 style
$message = $result['error'];
}
elseif (isset($result['message'])) {
// cURL style
$message = $result['message'];
}
else {
$message = 'Unknown Error. Check getResult()';
}
parent::__construct($message, $code);
}
/**
* Return the associated result object returned by the API server.
*
* @returns
* The result from the API server.
*/
public function getResult() {
return $this->result;
}
/**
* Returns the associated type for the error. This will default to
* 'Exception' when a type is not available.
*
* @return
* The type for the error.
*/
public function getType() {
if (isset($this->result['error'])) {
$message = $this->result['error'];
if (is_string($message)) {
// OAuth 2.0 Draft 10 style
return $message;
}
}
return 'Exception';
}
/**
* To make debugging easier.
*
* @returns
* The string representation of the error.
*/
public function __toString() {
$str = $this->getType() . ': ';
if ($this->code != 0) {
$str .= $this->code . ': ';
}
return $str . $this->message;
}
}
-105
View File
@@ -1,105 +0,0 @@
<?php
require_once( dirname(__FILE__) . '/OAuth2Client.php' );
class vkClient extends OAuth2Client
{
private $_allowed_scopes = array(
'notify', // Пользователь разрешил отправлять ему уведомления.
'friends', // Доступ к друзьям.
'photos', // Доступ к фотографиям.
'audio', // Доступ к аудиозаписям.
'video', // Доступ к видеозаписям.
'notes', // Доступ заметкам пользователя.
'pages', // Доступ к wiki-страницам.
'offers', // Доступ к предложениям (устаревшие методы).
'questions', // Доступ к вопросам (устаревшие методы).
'wall', // Доступ к обычным и расширенным методам работы со стеной.
'messages', // (для Standalone-приложений) Доступ к расширенным методам работы с сообщениями.
'offline', // Доступ к API в любое время со стороннего сервера.
);
public function __construct($config = array())
{
$configured_scopes = array( 'offline' );
if ( isset($config['scope']) )
{
$config_scopes = array_map( 'trim', explode(',', $config['scope']) );
foreach( $config_scopes as $scope )
{
if ( in_array( $scope, $this->_allowed_scopes ) )
{
$configured_scopes[] = $scope;
}
}
unset( $config['scope'] );
}
$this->setVariable( 'scope', implode(',', $configured_scopes) );
parent::__construct($config);
}
/**
* Получение ссылки на авторизацию
*
* @link http://vk.com/developers.php?o=-1&p=%C0%E2%F2%EE%F0%E8%E7%E0%F6%E8%FF%20%F1%E0%E9%F2%EE%E2
*/
public function getAuthorizeUrl($params = array())
{
$params = array_merge(
array(
'client_id' => $this->getVariable('client_id'),
// здесь возможно нужен urlencode + уникальный ключ пользователя
'redirect_uri' => $this->getVariable('authorize_callback_uri'),
'response_type' => ( $this->getVariable('logintype') == 'client' ) ? 'token' : 'code',
'scope' => $this->getVariable( 'scope' ),
), $params);
return $this->getUri( $this->getVariable('authorize_uri'), $params);
}
/**
* Авторизационный сервер vkontakte нам какбы отвечает
* {"access_token":"533bacf01e11f55b536a565b57531ac114461ae8736d6506a3", "expires_in":43200, "user_id":6492}
*
* @link http://vk.com/developers.php?o=-1&p=%C0%E2%F2%EE%F0%E8%E7%E0%F6%E8%FF%20%F1%E0%E9%F2%EE%E2
*/
protected function getSessionObject($access_token = NULL)
{
$session = NULL;
// Готовим данные для куки
if (!empty($access_token) && isset($access_token['access_token'])) {
$session['access_token'] = $access_token['access_token'];
$session['expires'] = ( isset($access_token['expires_in']) && $access_token['expires_in'] ) ? time() + $access_token['expires_in'] : time() + $this->getVariable('expires_in', OAUTH2_DEFAULT_EXPIRES_IN);
$session['refresh_token'] = isset($access_token['refresh_token']) ? $access_token['refresh_token'] : '';
$session['user_id'] = isset($access_token['user_id']) ? $access_token['user_id'] : 0;
$sig = self::generateSignature(
$session,
$this->getVariable('client_secret')
);
$session['sig'] = $sig;
}
return $session;
}
/**
* У vkontakte вместо oauth_token имеем access_token
*
* @link http://vk.com/developers.php?o=-1&p=%C2%FB%EF%EE%EB%ED%E5%ED%E8%E5%20%E7%E0%EF%F0%EE%F1%EE%E2%20%EA%20API
*/
protected function makeOAuth2Request($path, $method = 'GET', $params = array())
{
if ((!isset($params['access_token']) || empty($params['access_token'])) && $oauth_token = $this->getAccessToken())
{
$params['access_token'] = $oauth_token;
}
return $this->makeRequest($path, $method, $params);
}
}