Version 3.4.5

This commit is contained in:
Neo committed 2025-12-19 00:38:12 -08:00
1 parent fb6b5baabc
commit e4478369d8
1360 files changed
+228921 -179445

No files matched your search

@@ -1,101 +1,102 @@
<?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
<?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
@@ -26,7 +26,7 @@ class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform
$scheme = $url->getSchemeObj($config, $context);
if ($scheme->browsable && !$url->isBenign($config, $context)) {
$attr['target'] = 'blank';
$attr['target'] = '_blank';
}
return $attr;
@@ -1,46 +1,99 @@
<?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;
}
// 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);
$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');
}
}
}
}
// 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;
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
@@ -3901,4 +3901,3 @@ class HTML5TreeConstructer {
return $this->dom;
}
}
?>
+49 -24
View File
@@ -48,7 +48,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version CVS: $Id: mime.php 8229 2011-03-31 10:17:44Z ips_terabyte $
* @version CVS: $Id: mime.php 11977 2013-02-12 11:06:34Z mark $
* @link http://pear.php.net/package/Mail_mime
*
* This class is based on HTML Mime Mail class from
@@ -63,7 +63,7 @@
*
* This package depends on PEAR to raise errors.
*/
require_once 'PEAR.php';/*noLibHook*/
require_once 'PEAR.php';
/**
* require Mail_mimePart
@@ -72,7 +72,7 @@ require_once 'PEAR.php';/*noLibHook*/
* create all the different parts a mail can
* consist of.
*/
require_once 'Mail/mimePart.php';/*noLibHook*/
require_once 'Mail/mimePart.php';
/**
@@ -245,7 +245,7 @@ class Mail_mime
}
} else {
$cont = $this->_file2str($data);
if (PEAR::isError($cont)) {
if ($this->_isError($cont)) {
return $cont;
}
if (!$append) {
@@ -286,7 +286,7 @@ class Mail_mime
$this->_htmlbody = $data;
} else {
$cont = $this->_file2str($data);
if (PEAR::isError($cont)) {
if ($this->_isError($cont)) {
return $cont;
}
$this->_htmlbody = $cont;
@@ -336,7 +336,7 @@ class Mail_mime
$filedata = null;
$bodyfile = $file;
} else {
if (PEAR::isError($filedata = $this->_file2str($file))) {
if ($this->_isError($filedata = $this->_file2str($file))) {
return $filedata;
}
}
@@ -387,6 +387,8 @@ class Mail_mime
* @param string $description Content-Description header
* @param string $h_charset The character set of the headers e.g. filename
* If not specified, $charset will be used
* @param array $add_headers Additional part headers. Array keys can be in form
* of <header_name>:<parameter_name>
*
* @return mixed True on success or PEAR_Error object
* @access public
@@ -403,7 +405,8 @@ class Mail_mime
$n_encoding = null,
$f_encoding = null,
$description = '',
$h_charset = null
$h_charset = null,
$add_headers = array()
) {
$bodyfile = null;
@@ -413,12 +416,12 @@ class Mail_mime
$filedata = null;
$bodyfile = $file;
} else {
if (PEAR::isError($filedata = $this->_file2str($file))) {
if ($this->_isError($filedata = $this->_file2str($file))) {
return $filedata;
}
}
// Force the name the user supplied, otherwise use $file
$filename = ($name ? $name : $file);
$filename = ($name ? $name : $this->_basename($file));
} else {
$filedata = $file;
$filename = $name;
@@ -429,7 +432,6 @@ class Mail_mime
$err = PEAR::raiseError($msg);
return $err;
}
$filename = $this->_basename($filename);
$this->_parts[] = array(
'body' => $filedata,
@@ -442,6 +444,7 @@ class Mail_mime
'location' => $location,
'disposition' => $disposition,
'description' => $description,
'add_headers' => $add_headers,
'name_encoding' => $n_encoding,
'filename_encoding' => $f_encoding,
'headers_charset' => $h_charset,
@@ -458,7 +461,7 @@ class Mail_mime
* @return string Contents of $file_name
* @access private
*/
function &_file2str($file_name)
function _file2str($file_name)
{
// Check state of file and raise an error properly
if (!file_exists($file_name)) {
@@ -497,7 +500,7 @@ class Mail_mime
* @return object The text mimePart object
* @access private
*/
function &_addTextPart(&$obj, $text)
function _addTextPart(&$obj, $text)
{
$params['content_type'] = 'text/plain';
$params['encoding'] = $this->_build_params['text_encoding'];
@@ -523,7 +526,7 @@ class Mail_mime
* @return object The html mimePart object
* @access private
*/
function &_addHtmlPart(&$obj)
function _addHtmlPart(&$obj)
{
$params['content_type'] = 'text/html';
$params['encoding'] = $this->_build_params['html_encoding'];
@@ -547,7 +550,7 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
function &_addMixedPart()
function _addMixedPart()
{
$params = array();
$params['content_type'] = 'multipart/mixed';
@@ -569,7 +572,7 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
function &_addAlternativePart(&$obj)
function _addAlternativePart(&$obj)
{
$params['content_type'] = 'multipart/alternative';
$params['eol'] = $this->_build_params['eol'];
@@ -593,7 +596,7 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
function &_addRelatedPart(&$obj)
function _addRelatedPart(&$obj)
{
$params['content_type'] = 'multipart/related';
$params['eol'] = $this->_build_params['eol'];
@@ -616,7 +619,7 @@ class Mail_mime
* @return object The image mimePart object
* @access private
*/
function &_addHtmlImagePart(&$obj, $value)
function _addHtmlImagePart(&$obj, $value)
{
$params['content_type'] = $value['c_type'];
$params['encoding'] = 'base64';
@@ -647,7 +650,7 @@ class Mail_mime
* @return object The image mimePart object
* @access private
*/
function &_addAttachmentPart(&$obj, $value)
function _addAttachmentPart(&$obj, $value)
{
$params['eol'] = $this->_build_params['eol'];
$params['filename'] = $value['name'];
@@ -680,6 +683,9 @@ class Mail_mime
if (!empty($value['description'])) {
$params['description'] = $value['description'];
}
if (is_array($value['add_headers'])) {
$params['headers'] = $value['add_headers'];
}
$ret = $obj->addSubpart($value['body'], $params);
return $ret;
@@ -712,7 +718,7 @@ class Mail_mime
$body = $this->get($params);
if (PEAR::isError($body)) {
if ($this->_isError($body)) {
return $body;
}
@@ -1013,7 +1019,7 @@ class Mail_mime
if ($filename) {
// Append mimePart message headers and body into file
$headers = $message->encodeToFile($filename, $boundary, $skip_head);
if (PEAR::isError($headers)) {
if ($this->_isError($headers)) {
return $headers;
}
$this->_headers = array_merge($this->_headers, $headers);
@@ -1021,7 +1027,7 @@ class Mail_mime
return $ret;
} else {
$output = $message->encode($boundary, $skip_head);
if (PEAR::isError($output)) {
if ($this->_isError($output)) {
return $output;
}
$this->_headers = array_merge($this->_headers, $output['headers']);
@@ -1142,8 +1148,8 @@ class Mail_mime
? $this->_build_params['eol'] : "\r\n";
// add parameters
$token_regexp = '#([^\x21,\x23-\x27,\x2A,\x2B,\x2D'
. ',\x2E,\x30-\x39,\x41-\x5A,\x5E-\x7E])#';
$token_regexp = '#([^\x21\x23-\x27\x2A\x2B\x2D'
. '\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#';
if (is_array($params)) {
foreach ($params as $name => $value) {
if ($name == 'boundary') {
@@ -1319,7 +1325,8 @@ class Mail_mime
*/
function encodeHeader($name, $value, $charset, $encoding)
{
return Mail_mimePart::encodeHeader(
$mime_part = new Mail_mimePart;
return $mime_part->encodeHeader(
$name, $value, $charset, $encoding, $this->_build_params['eol']
);
}
@@ -1465,4 +1472,22 @@ class Mail_mime
}
}
/**
* PEAR::isError wrapper
*
* @param mixed $data Object
*
* @return bool True if object is an instance of PEAR_Error
* @access private
*/
function _isError($data)
{
// PEAR::isError() is not PHP 5.4 compatible (see Bug #19473)
if (is_object($data) && is_a($data, 'PEAR_Error')) {
return true;
}
return false;
}
} // End of class
+1 -1
View File
@@ -52,7 +52,7 @@
* @author Sean Coates <sean@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version CVS: $Id: mimeDecode.php 10914 2012-06-12 14:14:49Z bfarber $
* @version CVS: $Id: mimeDecode.php 10705 2012-05-08 15:35:49Z mark $
* @link http://pear.php.net/package/Mail_mime
*/
+80 -23
View File
@@ -48,7 +48,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version CVS: $Id: mimePart.php 8229 2011-03-31 10:17:44Z ips_terabyte $
* @version CVS: $Id: mimePart.php 11977 2013-02-12 11:06:34Z mark $
* @link http://pear.php.net/package/Mail_mime
*/
@@ -131,6 +131,7 @@ class Mail_mimePart
*/
var $_eol = "\r\n";
/**
* Constructor.
*
@@ -144,7 +145,7 @@ class Mail_mimePart
* charset - Content character set
* cid - Content ID to apply
* disposition - Content disposition, inline or attachment
* dfilename - Filename parameter for content disposition
* filename - Filename parameter for content disposition
* description - Content description
* name_encoding - Encoding of the attachment name (Content-Type)
* By default filenames are encoded using RFC2231
@@ -155,6 +156,8 @@ class Mail_mimePart
* headers_charset - Charset of the headers e.g. filename, description.
* If not set, 'charset' will be used
* eol - End of line sequence. Default: "\r\n"
* headers - Hash array with additional part headers. Array keys can be
* in form of <header_name>:<parameter_name>
* body_file - Location of file with part's body (instead of $body)
*
* @access public
@@ -167,6 +170,11 @@ class Mail_mimePart
$this->_eol = MAIL_MIMEPART_CRLF;
}
// Additional part headers
if (!empty($params['headers']) && is_array($params['headers'])) {
$headers = $params['headers'];
}
foreach ($params as $key => $value) {
switch ($key) {
case 'encoding':
@@ -185,6 +193,11 @@ class Mail_mimePart
case 'body_file':
$this->_body_file = $value;
break;
// for backward compatibility
case 'dfilename':
$params['filename'] = $value;
break;
}
}
@@ -210,13 +223,17 @@ class Mail_mimePart
$params['headers_charset'] = $params['charset'];
}
}
// header values encoding parameters
$h_charset = !empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII';
$h_language = !empty($params['language']) ? $params['language'] : null;
$h_encoding = !empty($params['name_encoding']) ? $params['name_encoding'] : null;
if (!empty($params['filename'])) {
$headers['Content-Type'] .= ';' . $this->_eol;
$headers['Content-Type'] .= $this->_buildHeaderParam(
'name', $params['filename'],
!empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII',
!empty($params['language']) ? $params['language'] : null,
!empty($params['name_encoding']) ? $params['name_encoding'] : null
'name', $params['filename'], $h_charset, $h_language, $h_encoding
);
}
@@ -226,23 +243,41 @@ class Mail_mimePart
if (!empty($params['filename'])) {
$headers['Content-Disposition'] .= ';' . $this->_eol;
$headers['Content-Disposition'] .= $this->_buildHeaderParam(
'filename', $params['filename'],
!empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII',
!empty($params['language']) ? $params['language'] : null,
'filename', $params['filename'], $h_charset, $h_language,
!empty($params['filename_encoding']) ? $params['filename_encoding'] : null
);
}
// add attachment size
$size = $this->_body_file ? filesize($this->_body_file) : strlen($body);
if ($size) {
$headers['Content-Disposition'] .= ';' . $this->_eol . ' size=' . $size;
}
}
if (!empty($params['description'])) {
$headers['Content-Description'] = $this->encodeHeader(
'Content-Description', $params['description'],
!empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII',
!empty($params['name_encoding']) ? $params['name_encoding'] : 'quoted-printable',
'Content-Description', $params['description'], $h_charset, $h_encoding,
$this->_eol
);
}
// Search and add existing headers' parameters
foreach ($headers as $key => $value) {
$items = explode(':', $key);
if (count($items) == 2) {
$header = $items[0];
$param = $items[1];
if (isset($headers[$header])) {
$headers[$header] .= ';' . $this->_eol;
}
$headers[$header] .= $this->_buildHeaderParam(
$param, $value, $h_charset, $h_language, $h_encoding
);
unset($headers[$key]);
}
}
// Default encoding
if (!isset($this->_encoding)) {
$this->_encoding = '7bit';
@@ -280,7 +315,7 @@ class Mail_mimePart
for ($i = 0; $i < count($this->_subparts); $i++) {
$encoded['body'] .= '--' . $boundary . $eol;
$tmp = $this->_subparts[$i]->encode();
if (PEAR::isError($tmp)) {
if ($this->_isError($tmp)) {
return $tmp;
}
foreach ($tmp['headers'] as $key => $value) {
@@ -303,7 +338,7 @@ class Mail_mimePart
@ini_set('magic_quotes_runtime', $magic_quote_setting);
}
if (PEAR::isError($body)) {
if ($this->_isError($body)) {
return $body;
}
$encoded['body'] = $body;
@@ -355,7 +390,7 @@ class Mail_mimePart
@ini_set('magic_quotes_runtime', $magic_quote_setting);
}
return PEAR::isError($res) ? $res : $this->_headers;
return $this->_isError($res) ? $res : $this->_headers;
}
/**
@@ -390,7 +425,7 @@ class Mail_mimePart
for ($i = 0; $i < count($this->_subparts); $i++) {
fwrite($fh, $f_eol . '--' . $boundary . $eol);
$res = $this->_subparts[$i]->_encodePartToFile($fh);
if (PEAR::isError($res)) {
if ($this->_isError($res)) {
return $res;
}
$f_eol = $eol;
@@ -405,7 +440,7 @@ class Mail_mimePart
$res = $this->_getEncodedDataFromFile(
$this->_body_file, $this->_encoding, $fh
);
if (PEAR::isError($res)) {
if ($this->_isError($res)) {
return $res;
}
}
@@ -633,8 +668,8 @@ class Mail_mimePart
// RFC 2045:
// value needs encoding if contains non-ASCII chars or is longer than 78 chars
if (!preg_match('#[^\x20-\x7E]#', $value)) {
$token_regexp = '#([^\x21,\x23-\x27,\x2A,\x2B,\x2D'
. ',\x2E,\x30-\x39,\x41-\x5A,\x5E-\x7E])#';
$token_regexp = '#([^\x21\x23-\x27\x2A\x2B\x2D'
. '\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#';
if (!preg_match($token_regexp, $value)) {
// token
if (strlen($name) + strlen($value) + 3 <= $maxLength) {
@@ -656,7 +691,7 @@ class Mail_mimePart
// RFC2231:
$encValue = preg_replace_callback(
'/([^\x21,\x23,\x24,\x26,\x2B,\x2D,\x2E,\x30-\x39,\x41-\x5A,\x5E-\x7E])/',
'/([^\x21\x23\x24\x26\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E])/',
array($this, '_encodeReplaceCallback'), $value
);
$value = "$charset'$language'$encValue";
@@ -780,6 +815,7 @@ class Mail_mimePart
'from', 'to', 'cc', 'bcc', 'sender', 'reply-to',
'resent-from', 'resent-to', 'resent-cc', 'resent-bcc',
'resent-sender', 'resent-reply-to',
'mail-reply-to', 'mail-followup-to',
'return-receipt-to', 'disposition-notification-to',
);
$other_headers = array(
@@ -800,6 +836,9 @@ class Mail_mimePart
// Structured header (make sure addr-spec inside is not encoded)
if (!empty($separator)) {
// Simple e-mail address regexp
$email_regexp = '([^\s<]+|("[^\r\n"]+"))@\S+';
$parts = Mail_mimePart::_explodeQuotedString($separator, $value);
$value = '';
@@ -817,12 +856,12 @@ class Mail_mimePart
}
// let's find phrase (name) and/or addr-spec
if (preg_match('/^<\S+@\S+>$/', $part)) {
if (preg_match('/^<' . $email_regexp . '>$/', $part)) {
$value .= $part;
} else if (preg_match('/^\S+@\S+$/', $part)) {
} else if (preg_match('/^' . $email_regexp . '$/', $part)) {
// address without brackets and without name
$value .= $part;
} else if (preg_match('/<*\S+@\S+>*$/', $part, $matches)) {
} else if (preg_match('/<*' . $email_regexp . '>*$/', $part, $matches)) {
// address with name (handle name)
$address = $matches[0];
$word = str_replace($address, '', $part);
@@ -1187,4 +1226,22 @@ class Mail_mimePart
return sprintf('%%%02X', ord($matches[1]));
}
/**
* PEAR::isError wrapper
*
* @param mixed $data Object
*
* @return bool True if object is an instance of PEAR_Error
* @access private
*/
function _isError($data)
{
// PEAR::isError() is not PHP 5.4 compatible (see Bug #19473)
if (is_object($data) && is_a($data, 'PEAR_Error')) {
return true;
}
return false;
}
} // End of class
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,4 @@
<?php
class Net_IDNA2_Exception extends Exception
{
}
@@ -0,0 +1,6 @@
<?php
require_once 'Net/IDNA2/Exception.php';
class Net_IDNA2_Exception_Nameprep extends Net_IDNA2_Exception
{
}
@@ -0,0 +1,146 @@
<?php
header( 'Content-Type: text/html; charset=UTF-8' );
require 'Net/IDNA.php';
$idn = Net_IDNA::getInstance();
if (isset($_REQUEST['encode'])) {
$decoded = isset($_REQUEST['decoded'])? $_REQUEST['decoded'] : '';
try {
$encoded = $idn->encode($decoded);
}
catch (Exception $e) {
/* just swallow */
}
}
if (isset($_REQUEST['decode'])) {
$encoded = isset($_REQUEST['encoded'])? $_REQUEST['encoded'] : '';
try {
$decoded = $idn->decode($encoded);
}
catch (Exception $e) {
/* just swallow */
}
}
if (!isset($encoded)) {
$encoded = '';
}
if (!isset($decoded)) {
$decoded = '';
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Punycode Converter</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css">
body
{
font-family: Helvetica, Arial, sans-serif;
font-size: 10pt;
background: rgb( 255, 255, 255 );
}
#centered
{
text-align: center;
vertical-align: middle;
}
#round
{
background-color: rgb( 240, 240, 240 );
border: 1px solid black;
text-align: center;
vertical-align: middle;
padding: 4px;
}
#subhead
{
font-size: 8pt;
}
</style>
</head>
<body>
<table width="780" border="0" cellpadding="0" cellspacing="0">
<tr>
<td id="centered">
<div id="round">
<strong>IDNA Converter</strong><br />
<span id="subhead">
See <a href="http://faqs.org/rfcs/rfc3490.html" title="IDNA" target="_blank">RFC3490</a>,
<a href="http://faqs.org/rfcs/rfc3491.html" title="Nameprep, a Stringprep profile" target="_blank">RFC3491</a>,
<a href="http://faqs.org/rfcs/rfc3492.html" title="Punycode" target="_blank">RFC3492</a> and
<a href="http://faqs.org/rfcs/rfc3454.html" title="Stringprep" target="_blank">RFC3454</a><br />
</span>
<br />
This converter allows you to transfer domain names between the encoded (Punycode) notation and the
decoded (UTF-8) notation.<br />
Just enter the domain name in the respective field and click on the button right beside it to have
it converted. Please be aware, that you might even enter complete domain names (like j&#xFC;rgen-m&#xFC;ller.de),
but without the protocol (<strong>DO NOT</strong> enter http://m&#xFC;ller.de) or an email address.<br />
Since the underlying library is still buggy, we cannot guarantee its usefulness and correctness. You should
always doublecheck the results given here by converting them back to the original form.<br />
Any productive use is discouraged and prone to fail.<br />
<br />
Make sure, that your browser is capable of the <strong>UTF-8</strong> character encoding.<br />
<br />
<table border="0" cellpadding="2" cellspacing="2" align="center">
<tr>
<td class="thead" align="left">Original</td>
<td class="thead" align="right">Punycode</td>
</tr>
<tr>
<td>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="GET">
<input type="text" name="decoded" value="<?php echo $decoded; ?>" size="24" maxlength="255" />
<input type="submit" name="encode" value="Encode &gt;&gt;" />
</form>
</td>
<td>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="GET">
<input type="submit" name="decode" value="&lt;&lt; Decode" />
<input type="text" name="encoded" value="<?php echo $encoded; ?>" size="24" maxlength="255" />
</form>
</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,32 @@
<?php
if (!defined('PHPUnit2_MAIN_METHOD')) {
define('PHPUnit2_MAIN_METHOD', 'Net_IDNA2_AllTests::main');
}
require_once 'PHPUnit2/TextUI/TestRunner.php';
require_once 'Net_IDNA2Test.php';
require_once 'draft-josefsson-idn-test-vectors.php';
class Net_IDNA2_AllTests
{
public static function main()
{
PHPUnit2_TextUI_TestRunner::run(self::suite());
}
public static function suite()
{
$suite = new PHPUnit2_Framework_TestSuite('PEAR - Net_IDNA2');
$suite->addTestSuite('Net_IDNA2Test');
$suite->addTestSuite('draft-josefsson-idn-test-vectors');
return $suite;
}
}
if (PHPUnit2_MAIN_METHOD == 'Net_IDNA2_AllTests::main') {
Net_IDNA2_AllTests::main();
}
@@ -0,0 +1,68 @@
<?php
require_once 'Net/IDNA2.php';
require_once 'PHPUnit2/Framework/TestCase.php';
class Net_IDNA2Test extends PHPUnit2_Framework_TestCase
{
/**
* Initialise tests
*
* @return void
*/
public function setUp()
{
$this->idn = new Net_IDNA2();
}
/**
* Test if a complete URL consisting also of port-number etc. will be decoded just fine, test 1
*
* @return void
*/
public function testShouldDecodePortNumbersFragmentsAndUrisCorrectly1()
{
$result = $this->idn->decode('http://www.xn--ml-6kctd8d6a.org:8080/test.php?arg1=1&arg2=2#fragment');
$this->assertSame("http://www.\xD0\xB5\xD1\x85\xD0\xB0m\xD1\x80l\xD0\xB5.org:8080/test.php?arg1=1&arg2=2#fragment", $result);
}
/**
* Test if a complete URL consisting also of port-number etc. will be decoded just fine, test 2
*
* @return void
*/
public function testShouldDecodePortNumbersFragmentsAndUrisCorrectly2()
{
$result = $this->idn->decode('http://xn--tst-qla.example.com:8080/test.php?arg1=1&arg2=2#fragment');
$this->assertSame("http://täst.example.com:8080/test.php?arg1=1&arg2=2#fragment", $result);
}
/**
* Test encoding of German letter Eszett according to the original standard (IDNA2003)
*
* @return void
*/
public function testEncodingForGermanEszettUsingIDNA2003()
{
// make sure to use 2003-encoding
$this->idn->setParams('version', '2003');
$result = $this->idn->encode('http://www.straße.example.com/');
$this->assertSame("http://www.strasse.example.com/", $result);
}
/**
* Test encoding of German letter Eszett according to the "new" standard (IDNA2005/IDNAbis)
*
* @return void
*/
public function testEncodingForGermanEszettUsingIDNA2008()
{
// make sure to use 2008-encoding
$this->idn->setParams('version', '2008');
$result = $this->idn->encode('http://www.straße.example.com/');
// switch back for other testcases
$this->idn->setParams('version', '2003');
$this->assertSame("http://www.xn--strae-oqa.example.com/", $result);
}
}
+426 -422
View File
@@ -1,423 +1,427 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* AJAX input parsing and handling
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 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: 10914 $
*/
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='' )
{
// 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.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;
}
}
+5 -5
View File
@@ -3,9 +3,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class can act as an API server, handling API requests
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-12-27 11:37:49 -0500 (Thu, 27 Dec 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -15,7 +15,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 6th January 2006 (12:24)
* @version $Revision: 10914 $
* @version $Revision: 11758 $
*
* Examples of sending and receiving API data
* <code>
@@ -557,7 +557,7 @@ class classApiServer
*/
protected function _encodeBase64Array( $array )
{
return base64_encode( serialize( $array ) );
return base64_encode( json_encode( $array ) );
}
/**
@@ -577,7 +577,7 @@ class classApiServer
* @link http://community.invisionpower.com/tracker/issue-18676-xml-rpcapiserver-params-not-unserialized/
* base64 data types are properly base-64 decoded in the XML-RPC library now, so it is redundant to do so here now
*/
return unserialize( $data );
return json_decode( $data, true );
}
else
{
+3 -3
View File
@@ -3,10 +3,10 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class acts as a cache layer, allowing you to store and retrieve data in
* external cache sources such as memcache or APC
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -16,7 +16,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
* Basic Usage Examples
* <code>
+3 -3
View File
@@ -3,10 +3,10 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class acts as a cache layer, allowing you to store and retrieve data in
* external cache sources such as memcache or APC
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -16,7 +16,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
* Basic Usage Examples
* <code>
+3 -3
View File
@@ -3,10 +3,10 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class acts as a cache layer, allowing you to store and retrieve data in
* external cache sources such as memcache or APC
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -16,7 +16,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
* Basic Usage Examples
* <code>
+3 -3
View File
@@ -3,10 +3,10 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class acts as a cache layer, allowing you to store and retrieve data in
* external cache sources such as memcache or APC
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -16,7 +16,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
* Basic Usage Examples
* <code>
+3 -3
View File
@@ -3,10 +3,10 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class acts as a cache layer, allowing you to store and retrieve data in
* external cache sources such as memcache or APC
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -16,7 +16,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
* Basic Usage Examples
* <code>
+3 -3
View File
@@ -3,10 +3,10 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class acts as a cache layer, allowing you to store and retrieve data in
* external cache sources such as memcache or APC
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -16,7 +16,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
* Basic Usage Examples
* <code>
+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.3.4
* $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 );
}
}
<?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 );
}
}
}
@@ -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.3.4
* @version v3.4.5
* $Revision: 10288 $
*/
@@ -0,0 +1,262 @@
<?php
/**
* The KeyCAPTCHA server URL's
*/
if ( !class_exists('KeyCAPTCHA_CLASS') )
{
class KeyCAPTCHA_CLASS
{
private $c_kc_keyword = "accept";
private $p_kc_visitor_ip = "";
private $p_kc_session_id = "";
private $p_kc_web_server_sign = "";
private $p_kc_web_server_sign2 = "";
private $p_kc_js_code = "";
private $p_kc_private_key = "";
private $p_kc_userID = 0;
public function get_web_server_sign($use_visitor_ip = 0)
{
return md5($this->p_kc_session_id . (($use_visitor_ip) ? ($this->p_kc_visitor_ip) :("")) . $this->p_kc_private_key);
}
function __construct($a_private_key='')
{
if ( $a_private_key != '' ) {
$set = explode("0",trim($a_private_key),2);
if (sizeof($set)>1){
$this->p_kc_private_key = trim($set[0]);
$this->p_kc_userID = (int)$set[1];
$this->p_kc_js_code =
"<!-- KeyCAPTCHA code (www.keycaptcha.com)-->
<script type=\"text/javascript\">
var s_s_c_user_id = '".$this->p_kc_userID."';
var s_s_c_session_id = '#KC_SESSION_ID#';
var s_s_c_captcha_field_id = 'capcode';
var s_s_c_submit_button_id = 'submit,Submit';
var s_s_c_web_server_sign = '#KC_WSIGN#';
var s_s_c_web_server_sign2 = '#KC_WSIGN2#';
</script>
<script type=\"text/javascript\" src=\"http://backs.keycaptcha.com/swfs/cap.js\"></script>
<!-- end of KeyCAPTCHA code-->";
}
}
$this->p_kc_session_id = uniqid() . '-1.0.0.033';
$this->p_kc_visitor_ip = $_SERVER["REMOTE_ADDR"];
}
function http_get($path)
{
$arr = parse_url($path);
$host = $arr['host'];
$page = $arr['path'];
if ( $page=='' ) {
$page='/';
}
if ( isset( $arr['query'] ) ) {
$page.='?'.$arr['query'];
}
$errno = 0;
$errstr = '';
$fp = fsockopen ($host, 80, $errno, $errstr, 30);
if (!$fp){ return ""; }
$request = "GET $page HTTP/1.0\r\n";
$request .= "Host: $host\r\n";
$request .= "Connection: close\r\n";
$request .= "Cache-Control: no-store, no-cache\r\n";
$request .= "Pragma: no-cache\r\n";
$request .= "User-Agent: KeyCAPTCHA\r\n";
$request .= "\r\n";
fwrite ($fp,$request);
$out = '';
while (!feof($fp)) $out .= fgets($fp, 250);
fclose($fp);
$ov = explode("close\r\n\r\n", $out);
return $ov[1];
}
public function check_result($response)
{
$kc_vars = explode("|", $response);
if ( count( $kc_vars ) < 4 )
{
return false;
}
if ($kc_vars[0] == md5($this->c_kc_keyword . $kc_vars[1] . $this->p_kc_private_key . $kc_vars[2]))
{
if (stripos($kc_vars[2], "http://") !== 0)
{
$kc_current_time = time();
$kc_var_time = split('[/ :]', $kc_vars[2]);
$kc_submit_time = gmmktime($kc_var_time[3], $kc_var_time[4], $kc_var_time[5], $kc_var_time[1], $kc_var_time[2], $kc_var_time[0]);
if (($kc_current_time - $kc_submit_time) < 15)
{
return true;
}
}
else
{
if ($this->http_get($kc_vars[2]) == "1")
{
return true;
}
}
}
return false;
}
public function render_js ()
{
if ( isset($_SERVER['HTTPS']) && ( $_SERVER['HTTPS'] == 'on' ) )
{
$this->p_kc_js_code = str_replace ("http://","https://", $this->p_kc_js_code);
}
$this->p_kc_js_code = str_replace ("#KC_SESSION_ID#", $this->p_kc_session_id, $this->p_kc_js_code);
$this->p_kc_js_code = str_replace ("#KC_WSIGN#", $this->get_web_server_sign(1), $this->p_kc_js_code);
$this->p_kc_js_code = str_replace ("#KC_WSIGN2#", $this->get_web_server_sign(), $this->p_kc_js_code);
return $this->p_kc_js_code;
}
}
}
class captchaPlugin
{
/**
* Registry object
*
* @access protected
* @var object
*/
public $registry;
/**
* Database object
*
* @access protected
* @var object
*/
public $DB;
/**
* Settings object
*
* @access protected
* @var object
*/
public $settings;
/**
* Request object
*
* @access protected
* @var object
*/
public $request;
/**
* Language object
*
* @access protected
* @var object
*/
public $lang;
/**
* Member object
*
* @access protected
* @var object
*/
public $member;
/**
* Member data object
*
* @access protected
* @var object
*/
public $memberData;
/**
* Error code from KeyCAPTCHA
*
* @access protected
* @var string
*/
public $error;
/**
* Constructor
*
* @access public
* @param object Registry Object
* @return void
*/
public function __construct( ipsRegistry $registry )
{
$this->registry = $registry;
$this->DB = $this->registry->DB();
$this->settings =& $this->registry->fetchSettings();
$this->request =& $this->registry->fetchRequest();
$this->lang = $this->registry->getClass('class_localization');
$this->member = $this->registry->member();
$this->memberData =& $this->registry->member()->fetchMemberData();
}
/**
* Gets the challenge HTML (javascript and non-javascript version).
* This is called from the browser, and the resulting KeyCAPTCHA HTML widget
* is embedded within the HTML form it was called from.
*
* @access public
* @return string Form HTML to display
*/
public function getTemplate()
{
$private_key = $this->settings['keycaptcha_privatekey'];
if ( ! $private_key )
{
return '';
}
$kc_o = new KeyCAPTCHA_CLASS($private_key );
return $this->registry->output->getTemplate('global_other')->captchaKeycaptcha( '<input type="hidden" id="capcode" name="capcode">'.$kc_o->render_js() );
}
/**
* Validate the input code
*
* @access public
* @return boolean Validation successful
* @since 1.0
*/
public function validate()
{
$private_key = $this->settings['keycaptcha_privatekey'];
if ( ! $private_key )
{
return '';
}
$capcode = $_REQUEST['capcode'];
$kc_o = new KeyCAPTCHA_CLASS( $private_key );
if (! $kc_o->check_result($capcode) ) {
return false;
}
return true;
}
}
@@ -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: bfarber $
* $Author: mark $
* @since Friday 19th May 2006 17:33
* $LastChangedDate: 2012-02-10 20:05:52 -0500 (Fri, 10 Feb 2012) $
* @version v3.3.4
* $Revision: 10288 $
* $LastChangedDate: 2013-02-11 12:32:07 -0500 (Mon, 11 Feb 2013) $
* @version v3.4.5
* $Revision: 11975 $
*/
/**
@@ -118,7 +118,7 @@ class captchaPlugin
/* Settings */
$this->public_key = trim( $this->settings['recaptcha_public_key'] );
$this->private_key = trim( $this->settings['recaptcha_private_key'] );
$this->useSSL = $this->settings['logins_over_https'];
$this->useSSL = ( $this->settings['logins_over_https'] or $this->registry->output->isHTTPS );
}
/**
@@ -153,7 +153,8 @@ class captchaPlugin
$html .= "<script type='text/javascript'>
var RecaptchaOptions = {
lang : '{$this->settings['recaptcha_language']}',
theme : '{$this->settings['recaptcha_theme']}'
theme : '{$this->settings['recaptcha_theme']}',
tabindex: 49
};
</script>";
+17 -9
View File
@@ -3,9 +3,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* Character set conversion library
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-12-07 14:02:27 -0500 (Fri, 07 Dec 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -17,7 +17,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 2nd December 2005 10:18
* @version $Revision: 10914 $
* @version $Revision: 11687 $
* @version 1.0 2004-07-27 00:37
* @link http://www.unicode.org Unicode Homepage
* @link http://www.mikkom.pl My Homepage
@@ -234,17 +234,25 @@ class classConvertCharset
*/
if ($string_char_set != "utf-8")
{
/* Cache the conversion table to prevent rebuilding on every request */
static $charsetTables = array();
/**
* Now build table with both charsets for encoding change.
*/
if ($destination_char_set != "utf-8")
{
$charsetTable = $this->_makeConversionTable( $string_char_set, $destination_char_set );
}
else
if( !$charsetTables[ $string_char_set ] )
{
$charsetTable = $this->_makeConversionTable( $string_char_set );
if ($destination_char_set != "utf-8")
{
$charsetTables[ $string_char_set ] = $this->_makeConversionTable( $string_char_set, $destination_char_set );
}
else
{
$charsetTables[ $string_char_set ] = $this->_makeConversionTable( $string_char_set );
}
}
$charsetTable = $charsetTables[ $string_char_set ];
if( !count($charsetTable) )
{
File diff suppressed because it is too large. Load diff
+2035 -1932
View File
File diff suppressed because it is too large. Load diff
+142 -15
View File
@@ -3,26 +3,29 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* MySQL Database Driver :: Further loads mysql or mysqli client appropriately
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-09-17 11:58:03 -0400 (Mon, 17 Sep 2012) $
* </pre>
*
* @author $Author: bfarber $
* @author $Author: mark $
* @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 28th February 2005 16:46
* @version $Revision: 10914 $
* @version $Revision: 11341 $
*/
/**
* 1 = Replace into
* 2 = Insert into...on duplicate key update
*/
define( 'REPLACE_TYPE', 2 );
if( !defined('REPLACE_TYPE') )
{
define( 'REPLACE_TYPE', 2 );
}
/**
* Handle base class definitions
@@ -112,23 +115,141 @@ abstract class db_main_mysql extends dbMain
* @param string [Optional] Where clause
* @param boolean [Optional] Run on shutdown
* @param boolean [Optional] $set is already pre-formatted
* @param array [Optional] Joined table data
* @return @e resource
*/
public function update( $table, $set, $where='', $shutdown=false, $preformatted=false, $debug=false )
public function update( $table, $set, $where='', $shutdown=false, $preformatted=false, $add_join=array() )
{
//-----------------------------------------
// Form query
// Normal
//-----------------------------------------
if ( empty( $add_join ) )
{
/* Compile the update clause */
$dba = $preformatted ? $set : $this->compileUpdateString( $set );
/* Put it together */
$query = "UPDATE " . $this->obj['sql_tbl_prefix'] . $table . " SET " . $dba;
/* Add in a where clause if necessary (we don't want to something silly like delete all the tickets...) */
if ( $where )
{
$query .= " WHERE " . $where;
}
}
//-----------------------------------------
// With joins
//-----------------------------------------
else
{
//-----------------------------------------
// OK, here we go...
//-----------------------------------------
$dba = $preformatted ? $set : $this->compileUpdateString( $set );
$from_array = array();
$joinleft_array = array();
$where_array = array();
$final_from = array();
$from_array[] = $table;
$hasLeft = false;
$hasInner = false;
$query = "UPDATE " . $this->obj['sql_tbl_prefix'] . $table . " SET " . $dba;
if ( $where )
{
$where_array[] = $where;
}
if ( $where )
{
$query .= " WHERE " . $where;
}
//-----------------------------------------
// Loop through JOINs and sort info
//-----------------------------------------
if ( is_array( $add_join ) and count( $add_join ) )
{
foreach( $add_join as $join )
{
if ( ! is_array( $join ) )
{
continue;
}
if ( empty($join['type']) OR $join['type'] == 'left' )
{
$hasLeft = true;
# Join is left or not specified (assume left)
$tmp = " LEFT JOIN ";
foreach( $join['from'] as $tbl => $alias )
{
$tmp .= $this->obj['sql_tbl_prefix'].$tbl.' '.$alias;
}
if ( $join['where'] )
{
$tmp .= " ON ( ".$join['where']." ) ";
}
$joinleft_array[] = $tmp;
unset( $tmp );
}
else if ( $join['type'] == 'inner' )
{
$hasInner = true;
# Join is inline
$from_array[] = $join['from'];
if ( $join['where'] )
{
$where_array[] = $join['where'];
}
}
else
{
# Not using any other type of join
}
}
}
//-----------------------------------------
// Build it..
//-----------------------------------------
foreach( $from_array as $i )
{
foreach( $i as $tbl => $alias )
{
$final_from[] = $this->obj['sql_tbl_prefix'] . $tbl . ' ' . $alias;
}
}
#http://bugs.mysql.com/bug.php?id=37925
$table = ( $hasLeft === true && $hasInner === true ) ? '(' . implode( ",", $final_from ) . ')' : implode( ",", $final_from );
$where = implode( " AND " , $where_array );
$join = implode( "\n" , $joinleft_array );
$query = "UPDATE {$table}";
if ( $join )
{
$query .= " " . $join . " ";
}
$query .= "SET " . ( $preformatted ? $set : $this->compileUpdateString( $set ) );
if ( $where != "" )
{
$query .= " WHERE " . $where;
}
}
//-----------------------------------------
// Run
//-----------------------------------------
return $this->_determineShutdownAndRun( $query, $shutdown );
}
@@ -1021,11 +1142,17 @@ abstract class db_main_mysql extends dbMain
* @param string [Optional] Where clause
* @param array [Optional] Joined table data
* @param boolean Calculate total rows too
* @param array [Optional] Force index
* @return @e void
*/
protected function _buildSelect( $get, $table, $where, $add_join=array(), $calcRows=FALSE )
protected function _buildSelect( $get, $table, $where, $add_join=array(), $calcRows=FALSE, $forceIndex=array() )
{
$_calcRows = ( $calcRows === TRUE ) ? 'SQL_CALC_FOUND_ROWS ' : '';
if ( !empty( $forceIndex ) )
{
$table .= ' FORCE INDEX('. implode( ',', array_map( create_function( '$v', 'return $v == \'PRIMARY\' ? $v : "'.$this->fieldNameEncapsulate.'{$v}'.$this->fieldNameEncapsulate.'";' ), $forceIndex ) ) .')';
}
if( !count($add_join) )
{
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.3.4
* Compare and highlight differences between two strings or files
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 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: 10914 $
*/
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;
}
<?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;
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+11 -5
View File
@@ -2,9 +2,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* FTP Class
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $ BY $Author: bfarber $
* Last Updated: $Date: 2013-02-06 10:51:28 -0500 (Wed, 06 Feb 2013) $ BY $Author: mark $
* </pre>
*
* @author Mark Wade
@@ -12,7 +12,7 @@
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @link http://www.invisionpower.com
* @version $Rev: 10914 $
* @version $Rev: 11945 $
*
*/
@@ -68,7 +68,7 @@ class classFtp
}
/* Connect */
if ( !( $this->stream = ftp_connect( $host, $port, $timeout ) ) )
if ( !( $this->stream = @ftp_connect( $host, $port, $timeout ) ) )
{
throw new Exception( 'CONNECT_FAIL' );
}
@@ -123,7 +123,13 @@ class classFtp
{
if ( $dir == '..' )
{
$currentDir = @ftp_pwd( $this->stream );
$chdir = @ftp_cdup( $this->stream );
if ( $currentDir === @ftp_pwd( $this->stream ) )
{
$chdir = false;
}
}
elseif ( substr( $dir, 0, 1 ) !== '/' )
{
@@ -139,7 +145,7 @@ class classFtp
{
throw new Exception( 'CHDIR_FAILED' );
}
$this->directory = $dir;
$this->directory = @ftp_pwd( $this->stream );
}
/**
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -3,9 +3,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* Image Handler: create thumbnails, apply watermarks and copyright tests, save or display final image
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -15,7 +15,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Monday 5th May 2008 14:00
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
* GD Example
* <code>
+38 -9
View File
@@ -3,9 +3,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* Image Handler: GD2 Library
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2013-02-06 19:48:42 -0500 (Wed, 06 Feb 2013) $
* </pre>
*
* @author $Author: bfarber $
@@ -15,7 +15,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Monday 5th May 2008 14:00
* @version $Revision: 10914 $
* @version $Revision: 11951 $
*
* GD Example
* <code>
@@ -251,9 +251,9 @@ class classImageGd extends classImage implements interfaceImage
*/
public function resizeImage( $width, $height, $secondPass=false, $returnIfUnnecessary=false, $canvas=array() )
{
//---------------------------------------------------------
// Get proportionate dimensions and store
//---------------------------------------------------------
//---------------------------------------------------------
// Get proportionate dimensions and store
//---------------------------------------------------------
$dst_x = 0;
$dst_y = 0;
@@ -261,12 +261,22 @@ class classImageGd extends classImage implements interfaceImage
if ( ! $secondPass )
{
$new_dims = $this->_getResizeDimensions( $width, $height );
if( !$new_dims['img_width'] )
{
$new_dims = array(
'img_width' => $this->cur_dimensions['width'],
'img_height' => $this->cur_dimensions['height'],
'cur_width' => $this->cur_dimensions['width'],
'cur_height' => $this->cur_dimensions['height'],
);
}
/* Canvas? */
if ( is_array( $canvas ) && count( $canvas ) )
{
$storedNewDims = $new_dims;
$new_dims = array( 'img_width' => $canvas[0], 'img_height' => $canvas[1] );
$new_dims = array( 'img_width' => $canvas[0], 'img_height' => $canvas[1], 'cur_width' => $new_dims['cur_width'] ? $new_dims['cur_width'] : $this->cur_dimensions['width'], 'cur_height' => $new_dims['cur_height'] ? $new_dims['cur_height'] : $this->cur_dimensions['height'] );
if ( $storedNewDims['img_width'] < $canvas[0] )
{
@@ -284,7 +294,26 @@ class classImageGd extends classImage implements interfaceImage
$new_dims['img_width'] = $width;
$new_dims['img_height'] = $height;
}
//---------------------------------------------------------
// If new image is same size as original, just return original
// This preserves GIF animation and allows images not to be "compressed" unnecessarily
//---------------------------------------------------------
if ( $returnIfUnnecessary AND ! $this->force_resize )
{
if ( ( $this->orig_dimensions['width'] <= $width ) AND ( $this->orig_dimensions['height'] <= $height ) )
{
return array(
'originalWidth' => $this->orig_dimensions['width'],
'originalHeight' => $this->orig_dimensions['height'],
'newWidth' => $this->orig_dimensions['width'],
'newHeight' => $this->orig_dimensions['height'],
'noResize' => true
);
}
}
if( ! is_array($new_dims) OR !count($new_dims) OR !$new_dims['img_width'] )
{
if( ! $this->force_resize )
@@ -655,7 +684,7 @@ class classImageGd extends classImage implements interfaceImage
}
else
{
@imagecopymerge( $this->image, $mark, $locate_x, $locate_y, 0, 0, $img_info[0], $img_info[1], $opacity );
@imagecopymerge( $this->image, $mark, $locate_x, $locate_y, 0, 0, $img_info[0], $img_info[1], intval($opacity) );
}
//---------------------------------------------------------
+6 -6
View File
@@ -3,9 +3,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* Image Handler: ImageMagick Library
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2013-02-20 19:45:47 -0500 (Wed, 20 Feb 2013) $
* </pre>
*
* @author $Author: bfarber $
@@ -15,7 +15,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Monday 5th May 2008 14:00
* @version $Revision: 10914 $
* @version $Revision: 12007 $
*
* ImageMagick Example
* <code>
@@ -318,15 +318,15 @@ class classImageImagemagick extends classImage implements interfaceImage
$border = array( 0, 0 );
$borderStmt = '';
/* Figure out border */
/* Figure out border - round/str_replace are to ensure locales do not result in "39,5x0" */
if ( $new_dims['img_width'] < $width )
{
$border[0] = ( $width - $new_dims['img_width'] ) / 2;
$border[0] = round( str_replace( ',', '.', ( $width - $new_dims['img_width'] ) / 2 ) );
}
if ( $new_dims['img_height'] < $height )
{
$border[1] = ( $height - $new_dims['img_height'] ) / 2;
$border[1] = round( str_replace( ',', '.', ( $height - $new_dims['img_height'] ) / 2 ) );
}
if ( count( $border ) )
+3 -3
View File
@@ -2,9 +2,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* Three Way Merge Class
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $ BY $author$
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $ BY $author$
* </pre>
*
* @author Matt Mecham
@@ -12,7 +12,7 @@
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @link http://www.invisionpower.com
* @version $Rev: 10914 $
* @version $Rev: 10721 $
*
*/
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -3,9 +3,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* Template Parser : Converts HTML "logic" into PHP code
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-10-18 10:27:08 -0400 (Thu, 18 Oct 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -15,7 +15,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Wednesday 23rd February 2005 13:53
* @version $Revision: 10914 $
* @version $Revision: 11481 $
*
*/
@@ -174,9 +174,9 @@ class classTemplate
//-----------------------------------------
$this->_skinGroup = preg_replace( '#^(.*)_\d+?$#', "\\1", $full_class_name );
$final_content = $this->_returnFunctionData( $data );
//-----------------------------------------
// Function Hooks
//------------------------------------------
@@ -236,7 +236,7 @@ EOF;
// Remove PHP tags
//-----------------------------------------
$data = preg_replace( "#<".'\?php\n+?(.*)\n+?\?>#is', "\\1", $data );
$data = preg_replace( "#<".'\?php\n+?(.*)\n+?(\?>|$)#is', "\\1", $data );
//-----------------------------------------
// Pick through and get all function names
@@ -1455,7 +1455,7 @@ EOF;
//$_false = trim( $_false );
$php_statement = "{$hook_pre_startif}\" . (($statement) ? (\"{$hook_post_startif}{$_true}{$hook_pre_endif}\") : (\"{$hook_pre_else}{$_false}{$hook_post_else}\")) . \"{$hook_post_endif}";
$template = substr_replace( $template, $php_statement, $found_if, $found_end_if + strlen($tag_end_if) - $found_if);
$found_end_if = $found_if + strlen($php_statement) - 1;
+5 -5
View File
@@ -3,19 +3,19 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* Upload handler : Handles $_FILES and checks for security
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2013-02-19 06:02:12 -0500 (Tue, 19 Feb 2013) $
* </pre>
*
* @author $Author: bfarber $
* @author $Author: mmecham $
* @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 15th March 2004
* @version $Revision: 10914 $
* @version $Revision: 12001 $
*
*
* Example Usage:
@@ -472,7 +472,7 @@ class classUpload
return false;
}
# Thanks to Nicolas Grekas from comments at www.splitbrain.org for helping to identify all vulnerable HTML tags
else if( preg_match( '#<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy#si', $file_check ) )
else if( preg_match( '#(<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy)(\s|=|>)#si', $file_check ) )
{
@unlink( $this->saved_upload_name );
$this->error_no = 5;
+10 -8
View File
@@ -3,20 +3,20 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* XML Handler: Rewritten for PHP5
* By Matt Mecham
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-07-27 11:43:25 -0400 (Fri, 27 Jul 2012) $
* </pre>
*
* @author $Author: bfarber $
* @author $Author: mark $
* @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 25th February 2004
* @version $Revision: 10914 $
* @version $Revision: 11149 $
*
*
* Example Usage:
@@ -225,11 +225,12 @@ class classXML
* @param string Name of tag to create
* @param string [Name of parent tag (optional)]
* @param array [Attributes]
* @param string [Namespace URI]
* @return @e void
*/
public function addElement( $tag, $parentTag='', $attributes=array() )
public function addElement( $tag, $parentTag='', $attributes=array(), $namespaceUri='' )
{
$this->_domObjects[ $tag ] = $this->_node( $parentTag )->appendChild( new DOMElement( $tag ) );
$this->_domObjects[ $tag ] = $this->_node( $parentTag )->appendChild( new DOMElement( $tag, '', $namespaceUri ) );
$this->addAttributes( $tag, $attributes );
}
@@ -243,9 +244,10 @@ class classXML
* @param string Name of parent tag
* @param mixed Tag wrapper
* @param array Array of data to add
* @param string [Namespace URI]
* @return @e void
*/
public function addElementAsRecord( $parentTag, $tag, $data )
public function addElementAsRecord( $parentTag, $tag, $data, $namespaceUri='' )
{
/* A little set up if you please... */
$_tag = $tag;
@@ -257,7 +259,7 @@ class classXML
$_tag_attr = $tag[1];
}
$record = $this->_node( $parentTag )->appendChild( new DOMElement( $_tag ) );
$record = $this->_node( $parentTag )->appendChild( new DOMElement( $_tag, ( is_array( $data ) ? NULL : $data ), $namespaceUri ) );
if ( is_array( $_tag_attr ) AND count( $_tag_attr ) )
{
+3 -3
View File
@@ -3,9 +3,9 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* XML Archive Hanlder: Can create XML Archives (gzips) of multiple files, binary and ascii
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -15,7 +15,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since 25th February 2004
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
*
* Example Usage:
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+18 -13
View File
@@ -5,11 +5,11 @@
*~TERABYTE_DOC_READY~
* $Copyright: (c) 2001 - 2011 Invision Power Services, Inc.$
* $License: http://www.invisionpower.com/company/standards.php#license$
* $Author: bfarber $
* $Author: AndyMillne $
* @since Tuesday 1st March 2005 15:40
* $LastChangedDate: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* @version v3.3.4
* $Revision: 10914 $
* $LastChangedDate: 2013-05-07 11:14:15 -0400 (Tue, 07 May 2013) $
* @version v3.4.5
* $Revision: 12235 $
*/
/**
@@ -89,7 +89,7 @@ class db_tools
$final_primary = array();
/* Remove backticks */
$definition = str_replace( '`', '', $definition );
$definition = $this->_sqlStripTicks( $definition );
$definition = preg_replace( "#CREATE\s+TABLE\s+IF\s+NOT\s+EXISTS\s+#i", "CREATE TABLE ", $definition );
@@ -141,7 +141,7 @@ class db_tools
// Now find all non-primary keys
//-----------------------------------------
if ( preg_match_all( "#\s+?(UNIQUE KEY|KEY|INDEX|UNIQUE)\s+?(?:(\w+?)\s+?)?\(\s*(.+?)\s*\)(\n|,\n)#is", $definition, $fields ) )
if ( preg_match_all( "#\s+?(UNIQUE KEY|KEY|INDEX|UNIQUE)\s+?(?:(\w+?)\s+?)?\(\s*(.+?)\s*\)(?:\s+using (?:btree|hash))?(\n|,\n)#is", $definition, $fields ) )
{
//-----------------------------------------
// We got some fields!
@@ -209,8 +209,10 @@ class db_tools
// Get table schematics and clean it
//-----------------------------------------
$row = ipsRegistry::DB()->getTableSchematic( $data['table'] );
$tbl = $this->_sqlStripTicks( $row['Create Table'] );
$row = ipsRegistry::DB()->getTableSchematic( $data['table'] );
$tbl = $this->_sqlStripTicks( $row['Create Table'] );
$tbl = preg_replace( "#(USING BTREE|USING HASH)#i", "", $tbl );
//-----------------------------------------
// Start output (one per index)
@@ -357,7 +359,7 @@ class db_tools
$ok = 0;
/* MySql seems to name multi-column indexes by the first field name regardless of what KEY NAME you specify. I know, nice isn't it. */
if ( strstr( $index_cols, ',' ) AND ! preg_match( "#\n\s*?(?:UNIQUE KEY|KEY|INDEX|UNIQUE)\s+?{$_checkName}\s+?(\(\s*(.+?)\s*\))(\n|,\n)#is", $tbl, $match ) )
if ( strstr( $index_cols, ',' ) AND ! preg_match( "#\n\s*?(?:UNIQUE KEY|KEY|INDEX|UNIQUE)\s+?{$_checkName}\s+?(\(\s*(.+?)\s*\))(?:\s+using (?:btree|hash))?(\s|,\s)#is", $tbl, $match ) )
{
list( $_checkName, ) = explode( ',', $index_cols );
@@ -372,7 +374,7 @@ class db_tools
// Is the key there?
//-----------------------------------------
if ( preg_match( "#\n\s*?(?:UNIQUE KEY|KEY|INDEX|UNIQUE)\s+?{$_checkName}\s+?(\(\s*(.+?)\s*\))(\n|,\n)#is", $tbl, $match ) )
if ( preg_match( "#\n\s*?(?:UNIQUE KEY|KEY|INDEX|UNIQUE)\s+?{$_checkName}\s+?(\(\s*(.+?)\s*\))(?:\s+using (?:btree|hash))?(\s|,\s)#is", $tbl, $match ) )
{
$ok = 1;
@@ -524,7 +526,7 @@ class db_tools
$missing_columns = array();
/* Remove backticks */
$the_table = str_replace( '`', '', $the_table );
$the_table = $this->_sqlStripTicks( $the_table );
$the_table = preg_replace( "#CREATE\s+TABLE\s+IF\s+NOT\s+EXISTS\s+#i", "CREATE TABLE ", $the_table );
@@ -780,7 +782,7 @@ class db_tools
}
/**
* Remove ticks from statement
* Remove ticks and double quotes from statement
*
* @param string $data String to clean
* @return @e string
@@ -792,6 +794,9 @@ class db_tools
*/
protected function _sqlStripTicks( $data )
{
return str_replace( "`", "", $data );
$data = str_replace( '`', '', $data );
$data = str_replace( '"', '', $data );
return $data;
}
}
+1 -1
View File
@@ -15,7 +15,7 @@
* under the License.
*/
require_once "base_facebook.php";/*noLibHook*/
require_once( IPS_KERNEL_PATH . 'facebook/base_facebook.php' );/*noLibHook*/
/**
* Extends the BaseFacebook class with the intent of using
@@ -3,10 +3,10 @@
/**
* <pre>
* Invision Power Services
* IP.Board v3.3.4
* IP.Board v3.4.5
* This class acts as a cache layer, allowing you to store and retrieve data in
* external cache sources such as memcache or APC
* Last Updated: $Date: 2012-06-12 10:14:49 -0400 (Tue, 12 Jun 2012) $
* Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
* </pre>
*
* @author $Author: bfarber $
@@ -16,7 +16,7 @@
* @subpackage Kernel
* @link http://www.invisionpower.com
* @since Friday 19th May 2006 17:33
* @version $Revision: 10914 $
* @version $Revision: 10721 $
*
*/
+2 -2
View File
@@ -26,7 +26,7 @@ class TwitterOAuth {
/* Contains the last API call */
public $last_api_call;
/* Set up the API root URL */
public $host = "https://api.twitter.com/1/";
public $host = "https://api.twitter.com/1.1/";
/* Set timeout default */
public $timeout = 30;
/* Set connect timeout */
@@ -259,7 +259,7 @@ class TwitterOAuth {
$path = "/";
}
$header = "$method {$path} HTTP/1.0\r\n";
$header = "$method {$path} HTTP/1.1\r\n";
$header .= "User-Agent: Twitter\r\n";
$header .= "Host: " . str_replace( array( 'http://', 'https://', 'ssl://' ), '', $host ) . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
@@ -0,0 +1,799 @@
<?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;
}
}
@@ -0,0 +1,802 @@
<?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
@@ -0,0 +1,105 @@
<?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);
}
}