first commit

This commit is contained in:
alazhar
2020-01-02 22:20:31 +07:00
commit 10eb3340ad
5753 changed files with 631345 additions and 0 deletions

View File

@ -0,0 +1,815 @@
<?php
/**
* @version $Id: JSON.php 1812 2013-01-14 18:45:06Z lefteris.kavadas $
* @package K2
* @author JoomlaWorks http://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die;
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Converts to and from JSON format.
*
* JSON (JavaScript Object Notation) is a lightweight data-interchange
* format. It is easy for humans to read and write. It is easy for machines
* to parse and generate. It is based on a subset of the JavaScript
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
* This feature can also be found in Python. JSON is a text format that is
* completely language independent but uses conventions that are familiar
* to programmers of the C-family of languages, including C, C++, C#, Java,
* JavaScript, Perl, TCL, and many others. These properties make JSON an
* ideal data-interchange language.
*
* This package provides a simple encoder and decoder for JSON notation. It
* is intended for use with client-side Javascript applications that make
* use of HTTPRequest to perform server communication functions - data can
* be encoded into JSON notation for use in a client-side javascript, or
* decoded from incoming Javascript requests. JSON format is native to
* Javascript, and can be directly eval()'ed with no further parsing
* overhead
*
* All strings should be in ASCII or UTF-8 format!
*
* LICENSE: Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met: Redistributions of source code must retain the
* above copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* @category
* @package Services_JSON
* @author Michal Migurski <mike-json@teczno.com>
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
* @copyright 2005 Michal Migurski
* @version CVS: $Id: JSON.php 1812 2013-01-14 18:45:06Z lefteris.kavadas $
* @license http://www.opensource.org/licenses/bsd-license.php
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
*/
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
if(!defined('SERVICES_JSON_SLICE')) define('SERVICES_JSON_SLICE', 1);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
if(!defined('SERVICES_JSON_IN_STR')) define('SERVICES_JSON_IN_STR', 2);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
if(!defined('SERVICES_JSON_IN_ARR')) define('SERVICES_JSON_IN_ARR', 3);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
if(!defined('SERVICES_JSON_IN_OBJ')) define('SERVICES_JSON_IN_OBJ', 4);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
if(!defined('SERVICES_JSON_IN_CMT')) define('SERVICES_JSON_IN_CMT', 5);
/**
* Behavior switch for Services_JSON::decode()
*/
if(!defined('SERVICES_JSON_LOOSE_TYPE')) define('SERVICES_JSON_LOOSE_TYPE', 16);
/**
* Behavior switch for Services_JSON::decode()
*/
if(!defined('SERVICES_JSON_SUPPRESS_ERRORS')) define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
/**
* Converts to and from JSON format.
*
* Brief example of use:
*
* <code>
* // create a new instance of Services_JSON
* $json = new Services_JSON();
*
* // convert a complexe value to JSON notation, and send it to the browser
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
* $output = $json->encode($value);
*
* print($output);
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
*
* // accept incoming POST data, assumed to be in JSON notation
* $input = file_get_contents('php://input', 1000000);
* $value = $json->decode($input);
* </code>
*/
if(!class_exists('Services_JSON')){
class Services_JSON
{
/**
* constructs a new JSON instance
*
* @param int $use object behavior flags; combine with boolean-OR
*
* possible values:
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
* "{...}" syntax creates associative arrays
* instead of objects in decode().
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
* Values which can't be encoded (e.g. resources)
* appear as NULL instead of throwing errors.
* By default, a deeply-nested resource will
* bubble up with an error, so all return values
* from encode() should be checked with isError()
*/
function Services_JSON($use = 0)
{
$this->use = $use;
}
/**
* convert a string from one UTF-16 char to one UTF-8 char
*
* Normally should be handled by mb_convert_encoding, but
* provides a slower PHP-only method for installations
* that lack the multibye string extension.
*
* @param string $utf16 UTF-16 character
* @return string UTF-8 character
* @access private
*/
function utf162utf8($utf16)
{
// oh please oh please oh please oh please oh please
if(function_exists('mb_convert_encoding')) {
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
}
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
switch(true) {
case ((0x7F & $bytes) == $bytes):
// this case should never be reached, because we are in ASCII range
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0x7F & $bytes);
case (0x07FF & $bytes) == $bytes:
// return a 2-byte UTF-8 character
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0xC0 | (($bytes >> 6) & 0x1F))
. chr(0x80 | ($bytes & 0x3F));
case (0xFFFF & $bytes) == $bytes:
// return a 3-byte UTF-8 character
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0xE0 | (($bytes >> 12) & 0x0F))
. chr(0x80 | (($bytes >> 6) & 0x3F))
. chr(0x80 | ($bytes & 0x3F));
}
// ignoring UTF-32 for now, sorry
return '';
}
/**
* convert a string from one UTF-8 char to one UTF-16 char
*
* Normally should be handled by mb_convert_encoding, but
* provides a slower PHP-only method for installations
* that lack the multibye string extension.
*
* @param string $utf8 UTF-8 character
* @return string UTF-16 character
* @access private
*/
function utf82utf16($utf8)
{
// oh please oh please oh please oh please oh please
if(function_exists('mb_convert_encoding')) {
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
}
switch(strlen($utf8)) {
case 1:
// this case should never be reached, because we are in ASCII range
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return $utf8;
case 2:
// return a UTF-16 character from a 2-byte UTF-8 char
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0x07 & (ord($utf8{0}) >> 2))
. chr((0xC0 & (ord($utf8{0}) << 6))
| (0x3F & ord($utf8{1})));
case 3:
// return a UTF-16 character from a 3-byte UTF-8 char
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr((0xF0 & (ord($utf8{0}) << 4))
| (0x0F & (ord($utf8{1}) >> 2)))
. chr((0xC0 & (ord($utf8{1}) << 6))
| (0x7F & ord($utf8{2})));
}
// ignoring UTF-32 for now, sorry
return '';
}
/**
* encodes an arbitrary variable into JSON format
*
* @param mixed $var any number, boolean, string, array, or object to be encoded.
* see argument 1 to Services_JSON() above for array-parsing behavior.
* if var is a strng, note that encode() always expects it
* to be in ASCII or UTF-8 format!
*
* @return mixed JSON string representation of input var or an error if a problem occurs
* @access public
*/
function encode($var)
{
switch (gettype($var)) {
case 'boolean':
return $var ? 'true' : 'false';
case 'NULL':
return 'null';
case 'integer':
return (int) $var;
case 'double':
case 'float':
return (float) $var;
case 'string':
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
$ascii = '';
$strlen_var = strlen($var);
/*
* Iterate over every character in the string,
* escaping with a slash or encoding to UTF-8 where necessary
*/
for ($c = 0; $c < $strlen_var; ++$c) {
$ord_var_c = ord($var{$c});
switch (true) {
case $ord_var_c == 0x08:
$ascii .= '\b';
break;
case $ord_var_c == 0x09:
$ascii .= '\t';
break;
case $ord_var_c == 0x0A:
$ascii .= '\n';
break;
case $ord_var_c == 0x0C:
$ascii .= '\f';
break;
case $ord_var_c == 0x0D:
$ascii .= '\r';
break;
case $ord_var_c == 0x22:
case $ord_var_c == 0x2F:
case $ord_var_c == 0x5C:
// double quote, slash, slosh
$ascii .= '\\'.$var{$c};
break;
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
// characters U-00000000 - U-0000007F (same as ASCII)
$ascii .= $var{$c};
break;
case (($ord_var_c & 0xE0) == 0xC0):
// characters U-00000080 - U-000007FF, mask 110XXXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
$c += 1;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xF0) == 0xE0):
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}));
$c += 2;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xF8) == 0xF0):
// characters U-00010000 - U-001FFFFF, mask 11110XXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}),
ord($var{$c + 3}));
$c += 3;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xFC) == 0xF8):
// characters U-00200000 - U-03FFFFFF, mask 111110XX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}),
ord($var{$c + 3}),
ord($var{$c + 4}));
$c += 4;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xFE) == 0xFC):
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}),
ord($var{$c + 3}),
ord($var{$c + 4}),
ord($var{$c + 5}));
$c += 5;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
}
}
return '"'.$ascii.'"';
case 'array':
/*
* As per JSON spec if any array key is not an integer
* we must treat the the whole array as an object. We
* also try to catch a sparsely populated associative
* array with numeric keys here because some JS engines
* will create an array with empty indexes up to
* max_index which can cause memory issues and because
* the keys, which may be relevant, will be remapped
* otherwise.
*
* As per the ECMA and JSON specification an object may
* have any string as a property. Unfortunately due to
* a hole in the ECMA specification if the key is a
* ECMA reserved word or starts with a digit the
* parameter is only accessible using ECMAScript's
* bracket notation.
*/
// treat as a JSON object
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
$properties = array_map(array($this, 'name_value'),
array_keys($var),
array_values($var));
foreach($properties as $property) {
if(Services_JSON::isError($property)) {
return $property;
}
}
return '{' . join(',', $properties) . '}';
}
// treat it like a regular array
$elements = array_map(array($this, 'encode'), $var);
foreach($elements as $element) {
if(Services_JSON::isError($element)) {
return $element;
}
}
return '[' . join(',', $elements) . ']';
case 'object':
$vars = get_object_vars($var);
$properties = array_map(array($this, 'name_value'),
array_keys($vars),
array_values($vars));
foreach($properties as $property) {
if(Services_JSON::isError($property)) {
return $property;
}
}
return '{' . join(',', $properties) . '}';
default:
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
? 'null'
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
}
}
/**
* array-walking function for use in generating JSON-formatted name-value pairs
*
* @param string $name name of key to use
* @param mixed $value reference to an array element to be encoded
*
* @return string JSON-formatted name-value pair, like '"name":value'
* @access private
*/
function name_value($name, $value)
{
$encoded_value = $this->encode($value);
if(Services_JSON::isError($encoded_value)) {
return $encoded_value;
}
return $this->encode(strval($name)) . ':' . $encoded_value;
}
/**
* reduce a string by removing leading and trailing comments and whitespace
*
* @param $str string string value to strip of comments and whitespace
*
* @return string string value stripped of comments and whitespace
* @access private
*/
function reduce_string($str)
{
$str = preg_replace(array(
// eliminate single line comments in '// ...' form
'#^\s*//(.+)$#m',
// eliminate multi-line comments in '/* ... */' form, at start of string
'#^\s*/\*(.+)\*/#Us',
// eliminate multi-line comments in '/* ... */' form, at end of string
'#/\*(.+)\*/\s*$#Us'
), '', $str);
// eliminate extraneous space
return trim($str);
}
/**
* decodes a JSON string into appropriate variable
*
* @param string $str JSON-formatted string
*
* @return mixed number, boolean, string, array, or object
* corresponding to given JSON input string.
* See argument 1 to Services_JSON() above for object-output behavior.
* Note that decode() always returns strings
* in ASCII or UTF-8 format!
* @access public
*/
function decode($str)
{
$str = $this->reduce_string($str);
switch (strtolower($str)) {
case 'true':
return true;
case 'false':
return false;
case 'null':
return null;
default:
$m = array();
if (is_numeric($str)) {
// Lookie-loo, it's a number
// This would work on its own, but I'm trying to be
// good about returning integers where appropriate:
// return (float)$str;
// Return float or int, as appropriate
return ((float)$str == (integer)$str)
? (integer)$str
: (float)$str;
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
// STRINGS RETURNED IN UTF-8 FORMAT
$delim = substr($str, 0, 1);
$chrs = substr($str, 1, -1);
$utf8 = '';
$strlen_chrs = strlen($chrs);
for ($c = 0; $c < $strlen_chrs; ++$c) {
$substr_chrs_c_2 = substr($chrs, $c, 2);
$ord_chrs_c = ord($chrs{$c});
switch (true) {
case $substr_chrs_c_2 == '\b':
$utf8 .= chr(0x08);
++$c;
break;
case $substr_chrs_c_2 == '\t':
$utf8 .= chr(0x09);
++$c;
break;
case $substr_chrs_c_2 == '\n':
$utf8 .= chr(0x0A);
++$c;
break;
case $substr_chrs_c_2 == '\f':
$utf8 .= chr(0x0C);
++$c;
break;
case $substr_chrs_c_2 == '\r':
$utf8 .= chr(0x0D);
++$c;
break;
case $substr_chrs_c_2 == '\\"':
case $substr_chrs_c_2 == '\\\'':
case $substr_chrs_c_2 == '\\\\':
case $substr_chrs_c_2 == '\\/':
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
$utf8 .= $chrs{++$c};
}
break;
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
// single, escaped unicode character
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
. chr(hexdec(substr($chrs, ($c + 4), 2)));
$utf8 .= $this->utf162utf8($utf16);
$c += 5;
break;
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
$utf8 .= $chrs{$c};
break;
case ($ord_chrs_c & 0xE0) == 0xC0:
// characters U-00000080 - U-000007FF, mask 110XXXXX
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 2);
++$c;
break;
case ($ord_chrs_c & 0xF0) == 0xE0:
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 3);
$c += 2;
break;
case ($ord_chrs_c & 0xF8) == 0xF0:
// characters U-00010000 - U-001FFFFF, mask 11110XXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 4);
$c += 3;
break;
case ($ord_chrs_c & 0xFC) == 0xF8:
// characters U-00200000 - U-03FFFFFF, mask 111110XX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 5);
$c += 4;
break;
case ($ord_chrs_c & 0xFE) == 0xFC:
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 6);
$c += 5;
break;
}
}
return $utf8;
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
// array, or object notation
if ($str{0} == '[') {
$stk = array(SERVICES_JSON_IN_ARR);
$arr = array();
} else {
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
$stk = array(SERVICES_JSON_IN_OBJ);
$obj = array();
} else {
$stk = array(SERVICES_JSON_IN_OBJ);
$obj = new stdClass();
}
}
array_push($stk, array('what' => SERVICES_JSON_SLICE,
'where' => 0,
'delim' => false));
$chrs = substr($str, 1, -1);
$chrs = $this->reduce_string($chrs);
if ($chrs == '') {
if (reset($stk) == SERVICES_JSON_IN_ARR) {
return $arr;
} else {
return $obj;
}
}
//print("\nparsing {$chrs}\n");
$strlen_chrs = strlen($chrs);
for ($c = 0; $c <= $strlen_chrs; ++$c) {
$top = end($stk);
$substr_chrs_c_2 = substr($chrs, $c, 2);
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
// found a comma that is not inside a string, array, etc.,
// OR we've reached the end of the character list
$slice = substr($chrs, $top['where'], ($c - $top['where']));
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
if (reset($stk) == SERVICES_JSON_IN_ARR) {
// we are in an array, so just push an element onto the stack
array_push($arr, $this->decode($slice));
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
// we are in an object, so figure
// out the property name and set an
// element in an associative array,
// for now
$parts = array();
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
// "name":value pair
$key = $this->decode($parts[1]);
$val = $this->decode($parts[2]);
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
$obj[$key] = $val;
} else {
$obj->$key = $val;
}
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
// name:value pair, where name is unquoted
$key = $parts[1];
$val = $this->decode($parts[2]);
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
$obj[$key] = $val;
} else {
$obj->$key = $val;
}
}
}
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
// found a quote, and we are not inside a string
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
//print("Found start of string at {$c}\n");
} elseif (($chrs{$c} == $top['delim']) &&
($top['what'] == SERVICES_JSON_IN_STR) &&
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
// found a quote, we're in a string, and it's not escaped
// we know that it's not escaped becase there is _not_ an
// odd number of backslashes at the end of the string so far
array_pop($stk);
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
} elseif (($chrs{$c} == '[') &&
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
// found a left-bracket, and we are in an array, object, or slice
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
//print("Found start of array at {$c}\n");
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
// found a right-bracket, and we're in an array
array_pop($stk);
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
} elseif (($chrs{$c} == '{') &&
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
// found a left-brace, and we are in an array, object, or slice
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
//print("Found start of object at {$c}\n");
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
// found a right-brace, and we're in an object
array_pop($stk);
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
} elseif (($substr_chrs_c_2 == '/*') &&
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
// found a comment start, and we are in an array, object, or slice
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
$c++;
//print("Found start of comment at {$c}\n");
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
// found a comment end, and we're in one now
array_pop($stk);
$c++;
for ($i = $top['where']; $i <= $c; ++$i)
$chrs = substr_replace($chrs, ' ', $i, 1);
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
}
}
if (reset($stk) == SERVICES_JSON_IN_ARR) {
return $arr;
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
return $obj;
}
}
}
}
/**
* @todo Ultimately, this should just call PEAR::isError()
*/
function isError($data, $code = null)
{
if (class_exists('pear')) {
return PEAR::isError($data, $code);
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
is_subclass_of($data, 'services_json_error'))) {
return true;
}
return false;
}
}
}
if (!class_exists('Services_JSON_Error')) {
if (class_exists('PEAR_Error')) {
class Services_JSON_Error extends PEAR_Error
{
function Services_JSON_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
}
}
} else {
/**
* @todo Ultimately, this class shall be descended from PEAR_Error
*/
class Services_JSON_Error
{
function Services_JSON_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
}
}
}
}

View File

@ -0,0 +1,536 @@
<?php
/**
* @version $Id: akismet.class.php 1994 2013-07-04 17:25:25Z lefteris.kavadas $
* @package K2
* @author JoomlaWorks http://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die ;
/**
* Akismet anti-comment spam service
*
* The class in this package allows use of the {@link http://akismet.com Akismet} anti-comment spam service in any PHP5 application.
*
* This service performs a number of checks on submitted data and returns whether or not the data is likely to be spam.
*
* Please note that in order to use this class, you must have a vaild {@link http://wordpress.com/api-keys/ WordPress API key}. They are free for non/small-profit types and getting one will only take a couple of minutes.
*
* For commercial use, please {@link http://akismet.com/commercial/ visit the Akismet commercial licensing page}.
*
* Please be aware that this class is PHP5 only. Attempts to run it under PHP4 will most likely fail.
*
* See the Akismet class documentation page linked to below for usage information.
*
* @package akismet
* @author Alex Potsides, {@link http://www.achingbrain.net http://www.achingbrain.net}
* @version 0.5
* @copyright Alex Potsides, {@link http://www.achingbrain.net http://www.achingbrain.net}
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
/**
* The Akismet PHP5 Class
*
* This class takes the functionality from the Akismet WordPress plugin written by {@link http://photomatt.net/ Matt Mullenweg} and allows it to be integrated into any PHP5 application or website.
*
* The original plugin is {@link http://akismet.com/download/ available on the Akismet website}.
*
* <code>
* $akismet = new Akismet('http://www.example.com/blog/', 'aoeu1aoue');
* $akismet->setCommentAuthor($name);
* $akismet->setCommentAuthorEmail($email);
* $akismet->setCommentAuthorURL($url);
* $akismet->setCommentContent($comment);
* $akismet->setPermalink('http://www.example.com/blog/alex/someurl/');
*
* if($akismet->isCommentSpam())
* // store the comment but mark it as spam (in case of a mis-diagnosis)
* else
* // store the comment normally
* </code>
*
* Optionally you may wish to check if your WordPress API key is valid as in the example below.
*
* <code>
* $akismet = new Akismet('http://www.example.com/blog/', 'aoeu1aoue');
*
* if($akismet->isKeyValid()) {
* // api key is okay
* } else {
* // api key is invalid
* }
* </code>
*
* @package akismet
* @name Akismet
* @version 0.5
* @author Alex Potsides
* @link http://www.achingbrain.net/
*/
class Akismet
{
private $version = '0.5';
private $wordPressAPIKey;
private $blogURL;
private $comment;
private $apiPort;
private $akismetServer;
private $akismetVersion;
private $requestFactory;
// This prevents some potentially sensitive information from being sent accross the wire.
private $ignore = array(
'HTTP_COOKIE',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED_HOST',
'HTTP_MAX_FORWARDS',
'HTTP_X_FORWARDED_SERVER',
'REDIRECT_STATUS',
'SERVER_PORT',
'PATH',
'DOCUMENT_ROOT',
'SERVER_ADMIN',
'QUERY_STRING',
'PHP_SELF'
);
/**
* @param string $blogURL The URL of your blog.
* @param string $wordPressAPIKey WordPress API key.
*/
public function __construct($blogURL, $wordPressAPIKey)
{
$this->blogURL = $blogURL;
$this->wordPressAPIKey = $wordPressAPIKey;
// Set some default values
$this->apiPort = 80;
$this->akismetServer = 'rest.akismet.com';
$this->akismetVersion = '1.1';
$this->requestFactory = new SocketWriteReadFactory();
// Start to populate the comment data
$this->comment['blog'] = $blogURL;
if (isset($_SERVER['HTTP_USER_AGENT']))
{
$this->comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
}
if (isset($_SERVER['HTTP_REFERER']))
{
$this->comment['referrer'] = $_SERVER['HTTP_REFERER'];
}
/*
* This is necessary if the server PHP5 is running on has been set up to run PHP4 and
* PHP5 concurently and is actually running through a separate proxy al a these instructions:
* http://www.schlitt.info/applications/blog/archives/83_How_to_run_PHP4_and_PHP_5_parallel.html
* and http://wiki.coggeshall.org/37.html
* Otherwise the user_ip appears as the IP address of the PHP4 server passing the requests to the
* PHP5 one...
*/
if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR'))
{
$this->comment['user_ip'] = $_SERVER['REMOTE_ADDR'];
}
else
{
$this->comment['user_ip'] = getenv('HTTP_X_FORWARDED_FOR');
}
}
/**
* Makes a request to the Akismet service to see if the API key passed to the constructor is valid.
*
* Use this method if you suspect your API key is invalid.
*
* @return bool True is if the key is valid, false if not.
*/
public function isKeyValid()
{
// Check to see if the key is valid
$response = $this->sendRequest('key='.$this->wordPressAPIKey.'&blog='.$this->blogURL, $this->akismetServer, '/'.$this->akismetVersion.'/verify-key');
return $response[1] == 'valid';
}
// makes a request to the Akismet service
private function sendRequest($request, $host, $path)
{
$http_request = "POST ".$path." HTTP/1.0\r\n";
$http_request .= "Host: ".$host."\r\n";
$http_request .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";
$http_request .= "Content-Length: ".strlen($request)."\r\n";
$http_request .= "User-Agent: Akismet PHP5 Class ".$this->version." | Akismet/1.11\r\n";
$http_request .= "\r\n";
$http_request .= $request;
$requestSender = $this->requestFactory->createRequestSender();
$response = $requestSender->send($host, $this->apiPort, $http_request);
return explode("\r\n\r\n", $response, 2);
}
// Formats the data for transmission
private function getQueryString()
{
foreach ($_SERVER as $key => $value)
{
if (!in_array($key, $this->ignore))
{
if ($key == 'REMOTE_ADDR')
{
$this->comment[$key] = $this->comment['user_ip'];
}
else
{
$this->comment[$key] = $value;
}
}
}
$query_string = '';
foreach ($this->comment as $key => $data)
{
if (!is_array($data))
{
$query_string .= $key.'='.urlencode(stripslashes($data)).'&';
}
}
return $query_string;
}
/**
* Tests for spam.
*
* Uses the web service provided by {@link http://www.akismet.com Akismet} to see whether or not the submitted comment is spam. Returns a boolean value.
*
* @return bool True if the comment is spam, false if not
* @throws Will throw an exception if the API key passed to the constructor is invalid.
*/
public function isCommentSpam()
{
$response = $this->sendRequest($this->getQueryString(), $this->wordPressAPIKey.'.rest.akismet.com', '/'.$this->akismetVersion.'/comment-check');
if ($response[1] == 'invalid' && !$this->isKeyValid())
{
throw new exception('The Wordpress API key passed to the Akismet constructor is invalid. Please obtain a valid one from http://wordpress.com/api-keys/');
}
return ($response[1] == 'true');
}
/**
* Submit spam that is incorrectly tagged as ham.
*
* Using this function will make you a good citizen as it helps Akismet to learn from its mistakes. This will improve the service for everybody.
*/
public function submitSpam()
{
$this->sendRequest($this->getQueryString(), $this->wordPressAPIKey.'.'.$this->akismetServer, '/'.$this->akismetVersion.'/submit-spam');
}
/**
* Submit ham that is incorrectly tagged as spam.
*
* Using this function will make you a good citizen as it helps Akismet to learn from its mistakes. This will improve the service for everybody.
*/
public function submitHam()
{
$this->sendRequest($this->getQueryString(), $this->wordPressAPIKey.'.'.$this->akismetServer, '/'.$this->akismetVersion.'/submit-ham');
}
/**
* To override the user IP address when submitting spam/ham later on
*
* @param string $userip An IP address. Optional.
*/
public function setUserIP($userip)
{
$this->comment['user_ip'] = $userip;
}
/**
* To override the referring page when submitting spam/ham later on
*
* @param string $referrer The referring page. Optional.
*/
public function setReferrer($referrer)
{
$this->comment['referrer'] = $referrer;
}
/**
* A permanent URL referencing the blog post the comment was submitted to.
*
* @param string $permalink The URL. Optional.
*/
public function setPermalink($permalink)
{
$this->comment['permalink'] = $permalink;
}
/**
* The type of comment being submitted.
*
* May be blank, comment, trackback, pingback, or a made up value like "registration" or "wiki".
*/
public function setCommentType($commentType)
{
$this->comment['comment_type'] = $commentType;
}
/**
* The name that the author submitted with the comment.
*/
public function setCommentAuthor($commentAuthor)
{
$this->comment['comment_author'] = $commentAuthor;
}
/**
* The email address that the author submitted with the comment.
*
* The address is assumed to be valid.
*/
public function setCommentAuthorEmail($authorEmail)
{
$this->comment['comment_author_email'] = $authorEmail;
}
/**
* The URL that the author submitted with the comment.
*/
public function setCommentAuthorURL($authorURL)
{
$this->comment['comment_author_url'] = $authorURL;
}
/**
* The comment's body text.
*/
public function setCommentContent($commentBody)
{
$this->comment['comment_content'] = $commentBody;
}
/**
* Lets you override the user agent used to submit the comment.
* you may wish to do this when submitting ham/spam.
* Defaults to $_SERVER['HTTP_USER_AGENT']
*/
public function setCommentUserAgent($userAgent)
{
$this->comment['user_agent'] = $userAgent;
}
/**
* Defaults to 80
*/
public function setAPIPort($apiPort)
{
$this->apiPort = $apiPort;
}
/**
* Defaults to rest.akismet.com
*/
public function setAkismetServer($akismetServer)
{
$this->akismetServer = $akismetServer;
}
/**
* Defaults to '1.1'
*
* @param string $akismetVersion
*/
public function setAkismetVersion($akismetVersion)
{
$this->akismetVersion = $akismetVersion;
}
/**
* Used by unit tests to mock transport layer
*
* @param AkismetRequestFactory $requestFactory
*/
public function setRequestFactory($requestFactory)
{
$this->requestFactory = $requestFactory;
}
}
/**
* Used internally by Akismet
*
* This class is used by Akismet to do the actual sending and receiving of data. It opens a connection to a remote host, sends some data and the reads the response and makes it available to the calling program.
*
* The code that makes up this class originates in the Akismet WordPress plugin, which is {@link http://akismet.com/download/ available on the Akismet website}.
*
* N.B. It is not necessary to call this class directly to use the Akismet class.
*
* @package akismet
* @name SocketWriteRead
* @version 0.5
* @author Alex Potsides
* @link http://www.achingbrain.net/
*/
class SocketWriteRead implements AkismetRequestSender
{
private $response;
private $errorNumber;
private $errorString;
public function __construct()
{
$this->errorNumber = 0;
$this->errorString = '';
}
/**
* Sends the data to the remote host.
*
* @param string $host The host to send/receive data.
* @param int $port The port on the remote host.
* @param string $request The data to send.
* @param int $responseLength The amount of data to read. Defaults to 1160 bytes.
* @throws An exception is thrown if a connection cannot be made to the remote host.
* @returns The server response
*/
public function send($host, $port, $request, $responseLength = 1160)
{
$response = '';
$fs = fsockopen($host, $port, $this->errorNumber, $this->errorString, 3);
if ($this->errorNumber != 0)
{
throw new Exception('Error connecting to host: '.$host.' Error number: '.$this->errorNumber.' Error message: '.$this->errorString);
}
if ($fs !== false)
{
@fwrite($fs, $request);
while (!feof($fs))
{
$response .= fgets($fs, $responseLength);
}
fclose($fs);
}
return $response;
}
/**
* Returns the server response text
*
* @return string
*/
public function getResponse()
{
return $this->response;
}
/**
* Returns the error number
*
* If there was no error, 0 will be returned.
*
* @return int
*/
public function getErrorNumner()
{
return $this->errorNumber;
}
/**
* Returns the error string
*
* If there was no error, an empty string will be returned.
*
* @return string
*/
public function getErrorString()
{
return $this->errorString;
}
}
/**
* Used internally by the Akismet class and to mock the Akismet anti spam service in
* the unit tests.
*
* N.B. It is not necessary to call this class directly to use the Akismet class.
*
* @package akismet
* @name SocketWriteReadFactory
* @version 0.5
* @author Alex Potsides
* @link http://www.achingbrain.net/
*/
class SocketWriteReadFactory implements AkismetRequestFactory
{
public function createRequestSender()
{
return new SocketWriteRead();
}
}
/**
* Used internally by the Akismet class and to mock the Akismet anti spam service in
* the unit tests.
*
* N.B. It is not necessary to implement this class to use the Akismet class.
*
* @package akismet
* @name AkismetRequestSender
* @version 0.5
* @author Alex Potsides
* @link http://www.achingbrain.net/
*/
interface AkismetRequestSender
{
/**
* Sends the data to the remote host.
*
* @param string $host The host to send/receive data.
* @param int $port The port on the remote host.
* @param string $request The data to send.
* @param int $responseLength The amount of data to read. Defaults to 1160 bytes.
* @throws An exception is thrown if a connection cannot be made to the remote host.
* @returns The server response
*/
public function send($host, $port, $request, $responseLength = 1160);
}
/**
* Used internally by the Akismet class and to mock the Akismet anti spam service in
* the unit tests.
*
* N.B. It is not necessary to implement this class to use the Akismet class.
*
* @package akismet
* @name AkismetRequestFactory
* @version 0.5
* @author Alex Potsides
* @link http://www.achingbrain.net/
*/
interface AkismetRequestFactory
{
public function createRequestSender();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
<?php
/**
* @version $Id: elFinderConnector.class.php 1812 2013-01-14 18:45:06Z lefteris.kavadas $
* @package K2
* @author JoomlaWorks http://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die;
/**
* Default elFinder connector
*
* @author Dmitry (dio) Levashov
**/
class elFinderConnector {
/**
* elFinder instance
*
* @var elFinder
**/
protected $elFinder;
/**
* Options
*
* @var aray
**/
protected $options = array();
/**
* undocumented class variable
*
* @var string
**/
protected $header = 'Content-Type: application/json';
/**
* Constructor
*
* @return void
* @author Dmitry (dio) Levashov
**/
public function __construct($elFinder, $debug=false) {
$this->elFinder = $elFinder;
if ($debug) {
$this->header = 'Content-Type: text/html; charset=utf-8';
}
}
/**
* Execute elFinder command and output result
*
* @return void
* @author Dmitry (dio) Levashov
**/
public function run() {
$isPost = $_SERVER["REQUEST_METHOD"] == 'POST';
$src = $_SERVER["REQUEST_METHOD"] == 'POST' ? $_POST : $_GET;
$cmd = isset($src['cmd']) ? $src['cmd'] : '';
$args = array();
if (!function_exists('json_encode')) {
$error = $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_JSON);
$this->output(array('error' => '{"error":["'.implode('","', $error).'"]}', 'raw' => true));
}
if (!$this->elFinder->loaded()) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors));
}
// telepat_mode: on
if (!$cmd && $isPost) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html'));
}
// telepat_mode: off
if (!$this->elFinder->commandExists($cmd)) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)));
}
// collect required arguments to exec command
foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) {
$arg = $name == 'FILES'
? $_FILES
: (isset($src[$name]) ? $src[$name] : '');
if (!is_array($arg)) {
$arg = trim($arg);
}
if ($req && (!isset($arg) || $arg === '')) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
}
$args[$name] = $arg;
}
$args['debug'] = isset($src['debug']) ? !!$src['debug'] : false;
$this->output($this->elFinder->exec($cmd, $args));
}
/**
* Output json
*
* @param array data to output
* @return void
* @author Dmitry (dio) Levashov
**/
protected function output(array $data) {
$header = isset($data['header']) ? $data['header'] : $this->header;
unset($data['header']);
if ($header) {
if (is_array($header)) {
foreach ($header as $h) {
header($h);
}
} else {
header($header);
}
}
if (isset($data['pointer'])) {
rewind($data['pointer']);
fpassthru($data['pointer']);
if (!empty($data['volume'])) {
$data['volume']->close($data['pointer'], $data['info']['hash']);
}
exit();
} else {
if (!empty($data['raw']) && !empty($data['error'])) {
exit($data['error']);
} else {
exit(json_encode($data));
}
}
}
}// END class

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,845 @@
<?php
/**
* @version $Id: elFinderVolumeLocalFileSystem.class.php 1989 2013-07-04 13:52:28Z lefteris.kavadas $
* @package K2
* @author JoomlaWorks http://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die;
/**
* elFinder driver for local filesystem.
*
* @author Dmitry (dio) Levashov
* @author Troex Nevelin
**/
class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
/**
* Driver id
* Must be started from letter and contains [a-z0-9]
* Used as part of volume id
*
* @var string
**/
protected $driverId = 'l';
/**
* Required to count total archive files size
*
* @var int
**/
protected $archiveSize = 0;
/**
* Constructor
* Extend options with required fields
*
* @return void
* @author Dmitry (dio) Levashov
**/
public function __construct() {
$this->options['alias'] = ''; // alias to replace root dir name
$this->options['dirMode'] = 0755; // new dirs mode
$this->options['fileMode'] = 0644; // new files mode
$this->options['quarantine'] = '.quarantine'; // quarantine folder name - required to check archive (must be hidden)
$this->options['maxArcFilesSize'] = 0; // max allowed archive files size (0 - no limit)
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Configure after successfull mount.
*
* @return void
* @author Dmitry (dio) Levashov
**/
protected function configure() {
$this->aroot = realpath($this->root);
$root = $this->stat($this->root);
if ($this->options['quarantine']) {
$this->attributes[] = array(
'pattern' => '~^'.preg_quote(DIRECTORY_SEPARATOR.$this->options['quarantine']).'$~',
'read' => false,
'write' => false,
'locked' => true,
'hidden' => true
);
}
// chek thumbnails path
if ($this->options['tmbPath']) {
$this->options['tmbPath'] = strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false
// tmb path set as dirname under root dir
? $this->root.DIRECTORY_SEPARATOR.$this->options['tmbPath']
// tmb path as full path
: $this->_normpath($this->options['tmbPath']);
}
parent::configure();
// if no thumbnails url - try detect it
if ($root['read'] && !$this->tmbURL && $this->URL) {
if (strpos($this->tmbPath, $this->root) === 0) {
$this->tmbURL = $this->URL.str_replace(DIRECTORY_SEPARATOR, '/', substr($this->tmbPath, strlen($this->root)+1));
if (preg_match("|[^/?&=]$|", $this->tmbURL)) {
$this->tmbURL .= '/';
}
}
}
// check quarantine dir
if (!empty($this->options['quarantine'])) {
$this->quarantine = $this->root.DIRECTORY_SEPARATOR.$this->options['quarantine'];
if ((!is_dir($this->quarantine) && !$this->_mkdir($this->root, $this->options['quarantine'])) || !is_writable($this->quarantine)) {
$this->archivers['extract'] = array();
$this->disabled[] = 'extract';
}
} else {
$this->archivers['extract'] = array();
$this->disabled[] = 'extract';
}
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/*********************** paths/urls *************************/
/**
* Return parent directory path
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _dirname($path) {
return dirname($path);
}
/**
* Return file name
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _basename($path) {
return basename($path);
}
/**
* Join dir name and file name and retur full path
*
* @param string $dir
* @param string $name
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _joinPath($dir, $name) {
return $dir.DIRECTORY_SEPARATOR.$name;
}
/**
* Return normalized path, this works the same as os.path.normpath() in Python
*
* @param string $path path
* @return string
* @author Troex Nevelin
**/
protected function _normpath($path) {
if (empty($path)) {
return '.';
}
if (strpos($path, '/') === 0) {
$initial_slashes = true;
} else {
$initial_slashes = false;
}
if (($initial_slashes)
&& (strpos($path, '//') === 0)
&& (strpos($path, '///') === false)) {
$initial_slashes = 2;
}
$initial_slashes = (int) $initial_slashes;
$comps = explode('/', $path);
$new_comps = array();
foreach ($comps as $comp) {
if (in_array($comp, array('', '.'))) {
continue;
}
if (($comp != '..')
|| (!$initial_slashes && !$new_comps)
|| ($new_comps && (end($new_comps) == '..'))) {
array_push($new_comps, $comp);
} elseif ($new_comps) {
array_pop($new_comps);
}
}
$comps = $new_comps;
$path = implode('/', $comps);
if ($initial_slashes) {
$path = str_repeat('/', $initial_slashes) . $path;
}
return $path ? $path : '.';
}
/**
* Return file path related to root dir
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _relpath($path) {
return $path == $this->root ? '' : substr($path, strlen($this->root)+1);
}
/**
* Convert path related to root dir into real path
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _abspath($path) {
return $path == DIRECTORY_SEPARATOR ? $this->root : $this->root.DIRECTORY_SEPARATOR.$path;
}
/**
* Return fake path started from root dir
*
* @param string $path file path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _path($path) {
return $this->rootName.($path == $this->root ? '' : $this->separator.$this->_relpath($path));
}
/**
* Return true if $path is children of $parent
*
* @param string $path path to check
* @param string $parent parent path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _inpath($path, $parent) {
return $path == $parent || strpos($path, $parent.DIRECTORY_SEPARATOR) === 0;
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
* - (int) size file size in b. required
* - (int) ts file modification time in unix time. required
* - (string) mime mimetype. required for folders, others - optionally
* - (bool) read read permissions. required
* - (bool) write write permissions. required
* - (bool) locked is object locked. optionally
* - (bool) hidden is object hidden. optionally
* - (string) alias for symlinks - link target path relative to root path. optionally
* - (string) target for symlinks - link target path. optionally
*
* If file does not exists - returns empty array or false.
*
* @param string $path file path
* @return array|false
* @author Dmitry (dio) Levashov
**/
protected function _stat($path) {
$stat = array();
if (!file_exists($path)) {
return $stat;
}
if ($path != $this->root && is_link($path)) {
if (($target = $this->readlink($path)) == false
|| $target == $path) {
$stat['mime'] = 'symlink-broken';
$stat['read'] = false;
$stat['write'] = false;
$stat['size'] = 0;
return $stat;
}
$stat['alias'] = $this->_path($target);
$stat['target'] = $target;
$path = $target;
$lstat = lstat($path);
$size = $lstat['size'];
} else {
$size = @filesize($path);
}
$dir = is_dir($path);
$stat['mime'] = $dir ? 'directory' : $this->mimetype($path);
$stat['ts'] = filemtime($path);
$stat['read'] = is_readable($path);
$stat['write'] = is_writable($path);
if ($stat['read']) {
$stat['size'] = $dir ? 0 : $size;
}
return $stat;
}
/**
* Return true if path is dir and has at least one childs directory
*
* @param string $path dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _subdirs($path) {
if (($dir = dir($path))) {
$dir = dir($path);
while (($entry = $dir->read()) !== false) {
$p = $dir->path.DIRECTORY_SEPARATOR.$entry;
if ($entry != '.' && $entry != '..' && is_dir($p) && !$this->attr($p, 'hidden')) {
$dir->close();
return true;
}
}
$dir->close();
}
return false;
}
/**
* Return object width and height
* Ususaly used for images, but can be realize for video etc...
*
* @param string $path file path
* @param string $mime file mime type
* @return string
* @author Dmitry (dio) Levashov
**/
protected function _dimensions($path, $mime) {
clearstatcache();
return strpos($mime, 'image') === 0 && ($s = @getimagesize($path)) !== false
? $s[0].'x'.$s[1]
: false;
}
/******************** file/dir content *********************/
/**
* Return symlink target file
*
* @param string $path link path
* @return string
* @author Dmitry (dio) Levashov
**/
protected function readlink($path) {
if (!($target = @readlink($path))) {
return false;
}
if (substr($target, 0, 1) != DIRECTORY_SEPARATOR) {
$target = dirname($path).DIRECTORY_SEPARATOR.$target;
}
$atarget = realpath($target);
if (!$atarget) {
return false;
}
$root = $this->root;
$aroot = $this->aroot;
if ($this->_inpath($atarget, $this->aroot)) {
return $this->_normpath($this->root.DIRECTORY_SEPARATOR.substr($atarget, strlen($this->aroot)+1));
}
return false;
}
/**
* Return files list in directory.
*
* @param string $path dir path
* @return array
* @author Dmitry (dio) Levashov
**/
protected function _scandir($path) {
$files = array();
foreach (scandir($path) as $name) {
if ($name != '.' && $name != '..') {
$files[] = $path.DIRECTORY_SEPARATOR.$name;
}
}
return $files;
}
/**
* Open file and return file pointer
*
* @param string $path file path
* @param bool $write open file for writing
* @return resource|false
* @author Dmitry (dio) Levashov
**/
protected function _fopen($path, $mode='rb') {
return @fopen($path, 'r');
}
/**
* Close opened file
*
* @param resource $fp file pointer
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _fclose($fp, $path='') {
return @fclose($fp);
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed
*
* @param string $path parent dir path
* @param string $name new directory name
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _mkdir($path, $name) {
$path = $path.DIRECTORY_SEPARATOR.$name;
if (@mkdir($path)) {
@chmod($path, $this->options['dirMode']);
return $path;
}
return false;
}
/**
* Create file and return it's path or false on failed
*
* @param string $path parent dir path
* @param string $name new file name
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _mkfile($path, $name) {
$path = $path.DIRECTORY_SEPARATOR.$name;
if (($fp = @fopen($path, 'w'))) {
@fclose($fp);
@chmod($path, $this->options['fileMode']);
return $path;
}
return false;
}
/**
* Create symlink
*
* @param string $source file to link to
* @param string $targetDir folder to create link in
* @param string $name symlink name
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _symlink($source, $targetDir, $name) {
return @symlink($source, $targetDir.DIRECTORY_SEPARATOR.$name);
}
/**
* Copy file into another file
*
* @param string $source source file path
* @param string $targetDir target directory path
* @param string $name new file name
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _copy($source, $targetDir, $name) {
return copy($source, $targetDir.DIRECTORY_SEPARATOR.$name);
}
/**
* Move file into another parent dir.
* Return new file path or false.
*
* @param string $source source file path
* @param string $target target dir path
* @param string $name file name
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function _move($source, $targetDir, $name) {
$target = $targetDir.DIRECTORY_SEPARATOR.$name;
return @rename($source, $target) ? $target : false;
}
/**
* Remove file
*
* @param string $path file path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _unlink($path) {
return @unlink($path);
}
/**
* Remove dir
*
* @param string $path dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _rmdir($path) {
return @rmdir($path);
}
/**
* Create new file and write into it from file pointer.
* Return new file path or false on error.
*
* @param resource $fp file pointer
* @param string $dir target dir path
* @param string $name file name
* @return bool|string
* @author Dmitry (dio) Levashov
**/
protected function _save($fp, $dir, $name, $mime, $w, $h) {
$path = $dir.DIRECTORY_SEPARATOR.$name;
if (!($target = @fopen($path, 'wb'))) {
return false;
}
while (!feof($fp)) {
fwrite($target, fread($fp, 8192));
}
fclose($target);
@chmod($path, $this->options['fileMode']);
clearstatcache();
return $path;
}
/**
* Get file contents
*
* @param string $path file path
* @return string|false
* @author Dmitry (dio) Levashov
**/
protected function _getContents($path) {
return file_get_contents($path);
}
/**
* Write a string to a file
*
* @param string $path file path
* @param string $content new file content
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _filePutContents($path, $content) {
if (@file_put_contents($path, $content, LOCK_EX) !== false) {
clearstatcache();
return true;
}
return false;
}
/**
* Detect available archivers
*
* @return void
**/
protected function _checkArchivers() {
if (!function_exists('exec')) {
$this->options['archivers'] = $this->options['archive'] = array();
return;
}
$arcs = array(
'create' => array(),
'extract' => array()
);
//exec('tar --version', $o, $ctar);
$this->procExec('tar --version', $o, $ctar);
if ($ctar == 0) {
$arcs['create']['application/x-tar'] = array('cmd' => 'tar', 'argc' => '-cf', 'ext' => 'tar');
$arcs['extract']['application/x-tar'] = array('cmd' => 'tar', 'argc' => '-xf', 'ext' => 'tar');
//$test = exec('gzip --version', $o, $c);
unset($o);
$test = $this->procExec('gzip --version', $o, $c);
if ($c == 0) {
$arcs['create']['application/x-gzip'] = array('cmd' => 'tar', 'argc' => '-czf', 'ext' => 'tgz');
$arcs['extract']['application/x-gzip'] = array('cmd' => 'tar', 'argc' => '-xzf', 'ext' => 'tgz');
}
unset($o);
//$test = exec('bzip2 --version', $o, $c);
$test = $this->procExec('bzip2 --version', $o, $c);
if ($c == 0) {
$arcs['create']['application/x-bzip2'] = array('cmd' => 'tar', 'argc' => '-cjf', 'ext' => 'tbz');
$arcs['extract']['application/x-bzip2'] = array('cmd' => 'tar', 'argc' => '-xjf', 'ext' => 'tbz');
}
}
unset($o);
//exec('zip --version', $o, $c);
$this->procExec('zip -v', $o, $c);
if ($c == 0) {
$arcs['create']['application/zip'] = array('cmd' => 'zip', 'argc' => '-r9', 'ext' => 'zip');
}
unset($o);
$this->procExec('unzip --help', $o, $c);
if ($c == 0) {
$arcs['extract']['application/zip'] = array('cmd' => 'unzip', 'argc' => '', 'ext' => 'zip');
}
unset($o);
//exec('rar --version', $o, $c);
$this->procExec('rar --version', $o, $c);
if ($c == 0 || $c == 7) {
$arcs['create']['application/x-rar'] = array('cmd' => 'rar', 'argc' => 'a -inul', 'ext' => 'rar');
$arcs['extract']['application/x-rar'] = array('cmd' => 'rar', 'argc' => 'x -y', 'ext' => 'rar');
} else {
unset($o);
//$test = exec('unrar', $o, $c);
$test = $this->procExec('unrar', $o, $c);
if ($c==0 || $c == 7) {
$arcs['extract']['application/x-rar'] = array('cmd' => 'unrar', 'argc' => 'x -y', 'ext' => 'rar');
}
}
unset($o);
//exec('7za --help', $o, $c);
$this->procExec('7za --help', $o, $c);
if ($c == 0) {
$arcs['create']['application/x-7z-compressed'] = array('cmd' => '7za', 'argc' => 'a', 'ext' => '7z');
$arcs['extract']['application/x-7z-compressed'] = array('cmd' => '7za', 'argc' => 'e -y', 'ext' => '7z');
if (empty($arcs['create']['application/x-gzip'])) {
$arcs['create']['application/x-gzip'] = array('cmd' => '7za', 'argc' => 'a -tgzip', 'ext' => 'tar.gz');
}
if (empty($arcs['extract']['application/x-gzip'])) {
$arcs['extract']['application/x-gzip'] = array('cmd' => '7za', 'argc' => 'e -tgzip -y', 'ext' => 'tar.gz');
}
if (empty($arcs['create']['application/x-bzip2'])) {
$arcs['create']['application/x-bzip2'] = array('cmd' => '7za', 'argc' => 'a -tbzip2', 'ext' => 'tar.bz');
}
if (empty($arcs['extract']['application/x-bzip2'])) {
$arcs['extract']['application/x-bzip2'] = array('cmd' => '7za', 'argc' => 'a -tbzip2 -y', 'ext' => 'tar.bz');
}
if (empty($arcs['create']['application/zip'])) {
$arcs['create']['application/zip'] = array('cmd' => '7za', 'argc' => 'a -tzip -l', 'ext' => 'zip');
}
if (empty($arcs['extract']['application/zip'])) {
$arcs['extract']['application/zip'] = array('cmd' => '7za', 'argc' => 'e -tzip -y', 'ext' => 'zip');
}
if (empty($arcs['create']['application/x-tar'])) {
$arcs['create']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'a -ttar -l', 'ext' => 'tar');
}
if (empty($arcs['extract']['application/x-tar'])) {
$arcs['extract']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'e -ttar -y', 'ext' => 'tar');
}
}
$this->archivers = $arcs;
}
/**
* Unpack archive
*
* @param string $path archive path
* @param array $arc archiver command and arguments (same as in $this->archivers)
* @return void
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function _unpack($path, $arc) {
$cwd = getcwd();
$dir = $this->_dirname($path);
chdir($dir);
$cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($this->_basename($path));
$this->procExec($cmd, $o, $c);
chdir($cwd);
}
/**
* Recursive symlinks search
*
* @param string $path file/dir path
* @return bool
* @author Dmitry (dio) Levashov
**/
protected function _findSymlinks($path) {
if (is_link($path)) {
return true;
}
if (is_dir($path)) {
foreach (scandir($path) as $name) {
if ($name != '.' && $name != '..') {
$p = $path.DIRECTORY_SEPARATOR.$name;
if (is_link($p)) {
return true;
}
if (is_dir($p) && $this->_findSymlinks($p)) {
return true;
} elseif (is_file($p)) {
$this->archiveSize += filesize($p);
}
}
}
} else {
$this->archiveSize += filesize($path);
}
return false;
}
/**
* Extract files from archive
*
* @param string $path archive path
* @param array $arc archiver command and arguments (same as in $this->archivers)
* @return true
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
**/
protected function _extract($path, $arc) {
if ($this->quarantine) {
$dir = $this->quarantine.DIRECTORY_SEPARATOR.str_replace(' ', '_', microtime()).basename($path);
$archive = $dir.DIRECTORY_SEPARATOR.basename($path);
if (!@mkdir($dir)) {
return false;
}
chmod($dir, 0755);
// copy in quarantine
if (!copy($path, $archive)) {
return false;
}
// extract in quarantine
$this->_unpack($archive, $arc);
@unlink($archive);
// get files list
$ls = array();
foreach (scandir($dir) as $i => $name) {
if ($name != '.' && $name != '..') {
$ls[] = $name;
}
}
// no files - extract error ?
if (empty($ls)) {
return false;
}
$this->archiveSize = 0;
// find symlinks
$symlinks = $this->_findSymlinks($dir);
// remove arc copy
$this->remove($dir);
if ($symlinks) {
return $this->setError(elFinder::ERROR_ARC_SYMLINKS);
}
// check max files size
if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
}
// archive contains one item - extract in archive dir
if (count($ls) == 1) {
$this->_unpack($path, $arc);
$result = dirname($path).DIRECTORY_SEPARATOR.$ls[0];
} else {
// for several files - create new directory
// create unique name for directory
$name = basename($path);
if (preg_match('/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/i', $name, $m)) {
$name = substr($name, 0, strlen($name)-strlen($m[0]));
}
$test = dirname($path).DIRECTORY_SEPARATOR.$name;
if (file_exists($test) || is_link($test)) {
$name = $this->uniqueName(dirname($path), $name, '-', false);
}
$result = dirname($path).DIRECTORY_SEPARATOR.$name;
$archive = $result.DIRECTORY_SEPARATOR.basename($path);
if (!$this->_mkdir(dirname($path), $name) || !copy($path, $archive)) {
return false;
}
$this->_unpack($archive, $arc);
@unlink($archive);
}
return file_exists($result) ? $result : false;
}
}
/**
* Create archive and return its path
*
* @param string $dir target dir
* @param array $files files names list
* @param string $name archive name
* @param array $arc archiver options
* @return string|bool
* @author Dmitry (dio) Levashov,
* @author Alexey Sukhotin
**/
protected function _archive($dir, $files, $name, $arc) {
$cwd = getcwd();
chdir($dir);
$files = array_map('escapeshellarg', $files);
$cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($name).' '.implode(' ', $files);
$this->procExec($cmd, $o, $c);
chdir($cwd);
$path = $dir.DIRECTORY_SEPARATOR.$name;
return file_exists($path) ? $path : false;
}
} // END class

View File

@ -0,0 +1,512 @@
# This file controls what Internet media types are sent to the client for
# given file extension(s). Sending the correct media type to the client
# is important so they know how to handle the content of the file.
# For more information about Internet media types, please read
# RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
# registry is at <ftp://ftp.iana.org/assignments/media-types/>.
# MIME type Extension
application/andrew-inset ez
application/chemtool cht
application/dicom dcm
application/docbook+xml docbook
application/ecmascript ecma
application/flash-video flv
application/illustrator ai
application/javascript js
application/mac-binhex40
application/mathematica nb
application/msword doc
application/octet-stream bin
application/oda oda
application/ogg ogg
application/pdf pdf
application/pgp pgp
application/pgp-encrypted
application/pgp-encrypted pgp gpg
application/pgp-keys
application/pgp-keys skr pkr
application/pgp-signature
application/pgp-signature sig
application/pkcs7-mime
application/pkcs7-signature p7s
application/postscript ps
application/rtf rtf
application/sdp sdp
application/smil smil smi sml
application/stuffit sit
application/vnd.corel-draw cdr
application/vnd.hp-hpgl hpgl
application/vnd.hp-pcl pcl
application/vnd.lotus-1-2-3 123 wk1 wk3 wk4 wks
application/vnd.mozilla.xul+xml xul
application/vnd.ms-excel xls xlc xll xlm xlw xla xlt xld
application/vnd.ms-powerpoint ppz ppt pps pot
application/vnd.oasis.opendocument.chart odc
application/vnd.oasis.opendocument.database odb
application/vnd.oasis.opendocument.formula odf
application/vnd.oasis.opendocument.graphics odg
application/vnd.oasis.opendocument.graphics-template otg
application/vnd.oasis.opendocument.image odi
application/vnd.oasis.opendocument.presentation odp
application/vnd.oasis.opendocument.presentation-template otp
application/vnd.oasis.opendocument.spreadsheet ods
application/vnd.oasis.opendocument.spreadsheet-template ots
application/vnd.oasis.opendocument.text odt
application/vnd.oasis.opendocument.text-master odm
application/vnd.oasis.opendocument.text-template ott
application/vnd.oasis.opendocument.text-web oth
application/vnd.palm pdb
application/vnd.rn-realmedia
application/vnd.rn-realmedia rm
application/vnd.rn-realmedia-secure rms
application/vnd.rn-realmedia-vbr rmvb
application/vnd.stardivision.calc sdc
application/vnd.stardivision.chart sds
application/vnd.stardivision.draw sda
application/vnd.stardivision.impress sdd sdp
application/vnd.stardivision.mail smd
application/vnd.stardivision.math smf
application/vnd.stardivision.writer sdw vor sgl
application/vnd.sun.xml.calc sxc
application/vnd.sun.xml.calc.template stc
application/vnd.sun.xml.draw sxd
application/vnd.sun.xml.draw.template std
application/vnd.sun.xml.impress sxi
application/vnd.sun.xml.impress.template sti
application/vnd.sun.xml.math sxm
application/vnd.sun.xml.writer sxw
application/vnd.sun.xml.writer.global sxg
application/vnd.sun.xml.writer.template stw
application/vnd.wordperfect wpd
application/x-abiword abw abw.CRASHED abw.gz zabw
application/x-amipro sam
application/x-anjuta-project prj
application/x-applix-spreadsheet as
application/x-applix-word aw
application/x-arc
application/x-archive a
application/x-arj arj
application/x-asax asax
application/x-ascx ascx
application/x-ashx ashx
application/x-asix asix
application/x-asmx asmx
application/x-asp asp
application/x-awk
application/x-axd axd
application/x-bcpio bcpio
application/x-bittorrent torrent
application/x-blender blender blend BLEND
application/x-bzip bz bz2
application/x-bzip bz2 bz
application/x-bzip-compressed-tar tar.bz tar.bz2
application/x-bzip-compressed-tar tar.bz tar.bz2 tbz tbz2
application/x-cd-image iso
application/x-cgi cgi
application/x-chess-pgn pgn
application/x-chm chm
application/x-class-file
application/x-cmbx cmbx
application/x-compress Z
application/x-compressed-tar tar.gz tar.Z tgz taz
application/x-compressed-tar tar.gz tgz
application/x-config config
application/x-core
application/x-cpio cpio
application/x-cpio-compressed cpio.gz
application/x-csh csh
application/x-cue cue
application/x-dbase dbf
application/x-dbm
application/x-dc-rom dc
application/x-deb deb
application/x-designer ui
application/x-desktop desktop kdelnk
application/x-devhelp devhelp
application/x-dia-diagram dia
application/x-disco disco
application/x-dvi dvi
application/x-e-theme etheme
application/x-egon egon
application/x-executable exe
application/x-font-afm afm
application/x-font-bdf bdf
application/x-font-dos
application/x-font-framemaker
application/x-font-libgrx
application/x-font-linux-psf psf
application/x-font-otf
application/x-font-pcf pcf
application/x-font-pcf pcf.gz
application/x-font-speedo spd
application/x-font-sunos-news
application/x-font-tex
application/x-font-tex-tfm
application/x-font-ttf ttc TTC
application/x-font-ttf ttf
application/x-font-type1 pfa pfb gsf pcf.Z
application/x-font-vfont
application/x-frame
application/x-frontline aop
application/x-gameboy-rom gb
application/x-gdbm
application/x-gdesklets-display display
application/x-genesis-rom gen md
application/x-gettext-translation gmo
application/x-glabels glabels
application/x-glade glade
application/x-gmc-link
application/x-gnome-db-connection connection
application/x-gnome-db-database database
application/x-gnome-stones caves
application/x-gnucash gnucash gnc xac
application/x-gnumeric gnumeric
application/x-graphite gra
application/x-gtar gtar
application/x-gtktalog
application/x-gzip gz
application/x-gzpostscript ps.gz
application/x-hdf hdf
application/x-ica ica
application/x-ipod-firmware
application/x-jamin jam
application/x-jar jar
application/x-java class
application/x-java-archive jar ear war
application/x-jbuilder-project jpr jpx
application/x-karbon karbon
application/x-kchart chrt
application/x-kformula kfo
application/x-killustrator kil
application/x-kivio flw
application/x-kontour kon
application/x-kpovmodeler kpm
application/x-kpresenter kpr kpt
application/x-krita kra
application/x-kspread ksp
application/x-kspread-crypt
application/x-ksysv-package
application/x-kugar kud
application/x-kword kwd kwt
application/x-kword-crypt
application/x-lha lha lzh
application/x-lha lzh
application/x-lhz lhz
application/x-linguist ts
application/x-lyx lyx
application/x-lzop lzo
application/x-lzop-compressed-tar tar.lzo tzo
application/x-macbinary
application/x-machine-config
application/x-magicpoint mgp
application/x-master-page master
application/x-matroska mkv
application/x-mdp mdp
application/x-mds mds
application/x-mdsx mdsx
application/x-mergeant mergeant
application/x-mif mif
application/x-mozilla-bookmarks
application/x-mps mps
application/x-ms-dos-executable exe
application/x-mswinurl
application/x-mswrite wri
application/x-msx-rom msx
application/x-n64-rom n64
application/x-nautilus-link
application/x-nes-rom nes
application/x-netcdf cdf nc
application/x-netscape-bookmarks
application/x-object o
application/x-ole-storage
application/x-oleo oleo
application/x-palm-database
application/x-palm-database pdb prc
application/x-par2 PAR2 par2
application/x-pef-executable
application/x-perl pl pm al perl
application/x-php php php3 php4
application/x-pkcs12 p12 pfx
application/x-planner planner mrproject
application/x-planperfect pln
application/x-prjx prjx
application/x-profile
application/x-ptoptimizer-script pto
application/x-pw pw
application/x-python-bytecode pyc pyo
application/x-quattro-pro wb1 wb2 wb3
application/x-quattropro wb1 wb2 wb3
application/x-qw qif
application/x-rar rar
application/x-rar-compressed rar
application/x-rdp rdp
application/x-reject rej
application/x-remoting rem
application/x-resources resources
application/x-resourcesx resx
application/x-rpm rpm
application/x-ruby
application/x-sc
application/x-sc sc
application/x-scribus sla sla.gz scd scd.gz
application/x-shar shar
application/x-shared-library-la la
application/x-sharedlib so
application/x-shellscript sh
application/x-shockwave-flash swf
application/x-siag siag
application/x-slp
application/x-smil kino
application/x-smil smi smil
application/x-sms-rom sms gg
application/x-soap-remoting soap
application/x-streamingmedia ssm
application/x-stuffit
application/x-stuffit bin sit
application/x-sv4cpio sv4cpio
application/x-sv4crc sv4crc
application/x-tar tar
application/x-tarz tar.Z
application/x-tex-gf gf
application/x-tex-pk k
application/x-tgif obj
application/x-theme theme
application/x-toc toc
application/x-toutdoux
application/x-trash bak old sik
application/x-troff tr roff t
application/x-troff-man man
application/x-troff-man-compressed
application/x-tzo tar.lzo tzo
application/x-ustar ustar
application/x-wais-source src
application/x-web-config
application/x-wpg wpg
application/x-wsdl wsdl
application/x-x509-ca-cert der cer crt cert pem
application/x-xbel xbel
application/x-zerosize
application/x-zoo zoo
application/xhtml+xml xhtml
application/zip zip
audio/ac3 ac3
audio/basic au snd
audio/midi mid midi
audio/mpeg mp3
audio/prs.sid sid psid
audio/vnd.rn-realaudio ra
audio/x-aac aac
audio/x-adpcm
audio/x-aifc
audio/x-aiff aif aiff
audio/x-aiff aiff aif aifc
audio/x-aiffc
audio/x-flac flac
audio/x-m4a m4a
audio/x-mod mod ult uni XM m15 mtm 669
audio/x-mp3-playlist
audio/x-mpeg
audio/x-mpegurl m3u
audio/x-ms-asx
audio/x-pn-realaudio ra ram rm
audio/x-pn-realaudio ram rmm
audio/x-riff
audio/x-s3m s3m
audio/x-scpls pls
audio/x-scpls pls xpl
audio/x-stm stm
audio/x-voc voc
audio/x-wav wav
audio/x-xi xi
audio/x-xm xm
image/bmp bmp
image/cgm cgm
image/dpx
image/fax-g3 g3
image/g3fax
image/gif gif
image/ief ief
image/jpeg jpeg jpg jpe
image/jpeg2000 jp2
image/png png
image/rle rle
image/svg+xml svg
image/tiff tif tiff
image/vnd.djvu djvu djv
image/vnd.dwg dwg
image/vnd.dxf dxf
image/x-3ds 3ds
image/x-applix-graphics ag
image/x-cmu-raster ras
image/x-compressed-xcf xcf.gz xcf.bz2
image/x-dcraw bay BAY bmq BMQ cr2 CR2 crw CRW cs1 CS1 dc2 DC2 dcr DCR fff FFF k25 K25 kdc KDC mos MOS mrw MRW nef NEF orf ORF pef PEF raf RAF rdc RDC srf SRF x3f X3F
image/x-dib
image/x-eps eps epsi epsf
image/x-fits fits
image/x-fpx
image/x-icb icb
image/x-ico ico
image/x-iff iff
image/x-ilbm ilbm
image/x-jng jng
image/x-lwo lwo lwob
image/x-lws lws
image/x-msod msod
image/x-niff
image/x-pcx
image/x-photo-cd pcd
image/x-pict pict pict1 pict2
image/x-portable-anymap pnm
image/x-portable-bitmap pbm
image/x-portable-graymap pgm
image/x-portable-pixmap ppm
image/x-psd psd
image/x-rgb rgb
image/x-sgi sgi
image/x-sun-raster sun
image/x-tga tga
image/x-win-bitmap cur
image/x-wmf wmf
image/x-xbitmap xbm
image/x-xcf xcf
image/x-xfig fig
image/x-xpixmap xpm
image/x-xwindowdump xwd
inode/blockdevice
inode/chardevice
inode/directory
inode/fifo
inode/mount-point
inode/socket
inode/symlink
message/delivery-status
message/disposition-notification
message/external-body
message/news
message/partial
message/rfc822
message/x-gnu-rmail
model/vrml wrl
multipart/alternative
multipart/appledouble
multipart/digest
multipart/encrypted
multipart/mixed
multipart/related
multipart/report
multipart/signed
multipart/x-mixed-replace
text/calendar vcs ics
text/css css CSSL
text/directory vcf vct gcrd
text/enriched
text/html html htm
text/htmlh
text/mathml mml
text/plain txt asc
text/rdf rdf
text/rfc822-headers
text/richtext rtx
text/rss rss
text/sgml sgml sgm
text/spreadsheet sylk slk
text/tab-separated-values tsv
text/vnd.rn-realtext rt
text/vnd.wap.wml wml
text/x-adasrc adb ads
text/x-authors
text/x-bibtex bib
text/x-boo boo
text/x-c++hdr hh
text/x-c++src cpp cxx cc C c++
text/x-chdr h h++ hp
text/x-comma-separated-values csv
text/x-copying
text/x-credits
text/x-csrc c
text/x-dcl dcl
text/x-dsl dsl
text/x-dsrc d
text/x-dtd dtd
text/x-emacs-lisp el
text/x-fortran f
text/x-gettext-translation po
text/x-gettext-translation-template pot
text/x-gtkrc
text/x-haskell hs
text/x-idl idl
text/x-install
text/x-java java
text/x-js js
text/x-ksysv-log
text/x-literate-haskell lhs
text/x-log log
text/x-makefile
text/x-moc moc
text/x-msil il
text/x-nemerle n
text/x-objcsrc m
text/x-pascal p pas
text/x-patch diff patch
text/x-python py
text/x-readme
text/x-rng rng
text/x-scheme scm
text/x-setext etx
text/x-speech
text/x-sql sql
text/x-suse-ymp ymp
text/x-suse-ymu ymu
text/x-tcl tcl tk
text/x-tex tex ltx sty cls
text/x-texinfo texi texinfo
text/x-texmacs tm ts
text/x-troff-me me
text/x-troff-mm mm
text/x-troff-ms ms
text/x-uil uil
text/x-uri uri url
text/x-vb vb
text/x-xds xds
text/x-xmi xmi
text/x-xsl xsl
text/x-xslfo fo xslfo
text/x-xslt xslt xsl
text/xmcd
text/xml xml
video/3gpp 3gp
video/dv dv dif
video/isivideo
video/mpeg mpeg mpg mp2 mpe vob dat
video/quicktime qt mov moov qtvr
video/vivo
video/vnd.rn-realvideo rv
video/wavelet
video/x-3gpp2 3g2
video/x-anim anim[1-9j]
video/x-avi
video/x-flic fli flc
video/x-mng mng
video/x-ms-asf asf asx
video/x-ms-wmv wmv
video/x-msvideo avi
video/x-nsv nsv NSV
video/x-real-video
video/x-sgi-movie movie
application/x-java-jnlp-file jnlp
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
application/vnd.ms-word.document.macroEnabled.12 docm
application/vnd.ms-word.template.macroEnabled.12 dotm
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
application/vnd.ms-excel.sheet.macroEnabled.12 xlsm
application/vnd.ms-excel.template.macroEnabled.12 xltm
application/vnd.ms-excel.addin.macroEnabled.12 xlam
application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
application/vnd.openxmlformats-officedocument.presentationml.template potx
application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam

View File

@ -0,0 +1,257 @@
<?php
/**
* @version $Id: k2parameter.php 1829 2013-01-25 15:36:59Z lefteris.kavadas $
* @package K2
* @author JoomlaWorks http://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die ;
if (K2_JVERSION == '30')
{
class K2Parameter
{
function __construct($data, $path = '', $namespace)
{
$this->namespace = $namespace;
$this->values = new JRegistry($data);
}
function get($path, $default = null)
{
return $this->values->get($this->namespace.$path, $default);
}
}
}
else
{
jimport('joomla.html.parameter');
/**
* Parameter handler
*
* @package Joomla.Framework
* @subpackage Parameter
* @since 1.5
*/
class K2Parameter extends JParameter
{
/**
* optional namespace
*
* @access private
* @var array
* @since 1.5
*/
var $namespace = null;
/**
* Constructor
*
* @access protected
* @param string The raw parms text
* @param string Path to the xml setup file
* @param string Namespace to the xml setup file
* @since 1.5
*/
function __construct($data, $path = '', $namespace)
{
parent::__construct('_default');
// Set base path
$this->_elementPath[] = JPATH_COMPONENT_ADMINISTRATOR.DS.'elements';
if (trim($data))
{
$this->loadINI($data);
}
if ($path)
{
@$this->loadSetupFile($path);
}
if ($namespace)
{
$this->namespace = $namespace;
}
$this->_raw = $data;
if (K2_JVERSION != '15')
{
$this->bind($data);
}
}
/**
* Get a value
*
* @access public
* @param string The name of the param
* @param mixed The default value if not found
* @return string
* @since 1.5
*/
function get($key, $default = '', $group = '_default')
{
if (K2_JVERSION != '15')
{
return parent::get($this->namespace.$key, $default);
}
$value = $this->getValue($group.'.'.$this->namespace.$key);
$result = (empty($value) && ($value !== 0) && ($value !== '0')) ? $default : $value;
//if($group != '_default') { echo ($group); }
return $result;
}
/**
* Render a parameter type
*
* @param object A param tag node
* @param string The control name
* @return array Any array of the label, the form element and the tooltip
* @since 1.5
*/
function getParam(&$node, $control_name = 'params', $group = '_default')
{
//get the type of the parameter
$type = $node->attributes('type');
//remove any occurance of a mos_ prefix
$type = str_replace('mos_', '', $type);
$element = $this->loadElement($type);
// error happened
if ($element === false)
{
$result = array();
$result[0] = $node->attributes('name');
$result[1] = JText::_('K2_ELEMENT_NOT_DEFINED_FOR_TYPE').' = '.$type;
$result[5] = $result[0];
return $result;
}
//get value
$value = $this->get($node->attributes('name'), $node->attributes('default'), $group);
//set name
$node->_attributes['name'] = $this->namespace.$node->_attributes['name'];
return $element->render($node, $value, $control_name);
}
/**
* Get a registry value
*
* @access public
* @param string $regpath Registry path (e.g. joomla.content.showauthor)
* @param mixed $default Optional default value
* @return mixed Value of entry or null
* @since 1.5
*/
function getValue($regpath, $default = null)
{
$result = $default;
// Explode the registry path into an array
if ($nodes = explode('.', $regpath))
{
// Get the namespace
//$namespace = array_shift($nodes);
$count = count($nodes);
if ($count < 2)
{
$namespace = $this->_defaultNameSpace;
$nodes[1] = $nodes[0];
}
else
{
$namespace = $nodes[0];
}
if (isset($this->_registry[$namespace]))
{
$ns = &$this->_registry[$namespace]['data'];
$pathNodes = $count - 1;
//for ($i = 0; $i < $pathNodes; $i ++) {
for ($i = 1; $i < $pathNodes; $i++)
{
if ((isset($ns->$nodes[$i])))
$ns = &$ns->$nodes[$i];
}
if (isset($ns->$nodes[$i]))
{
$result = $ns->$nodes[$i];
}
}
}
return $result;
}
/**
* Render
*
* @access public
* @param string The name of the control, or the default text area if a setup file is not found
* @return string HTML
* @since 1.5
*/
function render($name = 'params', $group = '_default')
{
if (!isset($this->_xml[$group]))
{
return false;
}
$params = $this->getParams($name, $group);
$html = array();
$html[] = '<table class="paramlist admintable" cellspacing="1">';
if ($description = $this->_xml[$group]->attributes('description'))
{
// add the params description to the display
$desc = JText::_($description);
$html[] = '<tr><td class="paramlist_description" colspan="2">'.$desc.'</td></tr>';
}
foreach ($params as $param)
{
$html[] = '<tr>';
if ($param[0])
{
$html[] = '<td class="paramlist_key"><span class="editlinktip">'.$param[0].'</span></td>';
$html[] = '<td class="paramlist_value">'.$param[1].'</td>';
}
else
{
$html[] = '<td class="paramlist_value" colspan="2">'.$param[1].'</td>';
}
$html[] = '</tr>';
}
if (count($params) < 1)
{
$html[] = "<tr><td colspan=\"2\"><i>".(K2_JVERSION != '15') ? JText::_('JLIB_HTML_NO_PARAMETERS_FOR_THIS_ITEM') : JText::_('There are no Parameters for this item')."</i></td></tr>";
}
$html[] = '</table>';
return implode("\n", $html);
}
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* @version $Id: k2plugin.php 1964 2013-04-29 13:14:09Z lefteris.kavadas $
* @package K2
* @author JoomlaWorks http://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die ;
jimport('joomla.plugin.plugin');
JLoader::register('K2Parameter', JPATH_ADMINISTRATOR.DS.'components'.DS.'com_k2'.DS.'lib'.DS.'k2parameter.php');
class K2Plugin extends JPlugin
{
/**
* Below we list all available BACKEND events, to trigger K2 plugins and generate additional fields in the item, category and user forms.
*/
/* ------------ Functions to render plugin parameters in the backend - no need to change anything ------------ */
function onRenderAdminForm(&$item, $type, $tab = '')
{
$mainframe = JFactory::getApplication();
$manifest = (K2_JVERSION == '15') ? JPATH_SITE.DS.'plugins'.DS.'k2'.DS.$this->pluginName.'.xml' : JPATH_SITE.DS.'plugins'.DS.'k2'.DS.$this->pluginName.DS.$this->pluginName.'.xml';
if (!empty($tab))
{
$path = $type.'-'.$tab;
}
else
{
$path = $type;
}
if (!isset($item->plugins))
{
$item->plugins = NULL;
}
if (K2_JVERSION == '15')
{
$form = new K2Parameter($item->plugins, $manifest, $this->pluginName);
$fields = $form->render('plugins', $path);
}
else
{
jimport('joomla.form.form');
$form = JForm::getInstance('plg_k2_'.$this->pluginName.'_'.$path, $manifest, array(), true, 'fields[@group="'.$path.'"]');
$values = array();
if ($item->plugins)
{
foreach (json_decode($item->plugins) as $name => $value)
{
$count = 1;
$values[str_replace($this->pluginName, '', $name, $count)] = $value;
}
$form->bind($values);
}
$fields = '';
foreach ($form->getFieldset() as $field)
{
$search = 'name="'.$field->name.'"';
$replace = 'name="plugins['.$this->pluginName.$field->name.']"';
$input = JString::str_ireplace($search, $replace, $field->__get('input'));
$fields .= $field->__get('label').' '.$input;
}
// Legacy code to maintain compatibillity with existing plugins that use params instead of JForm
if (empty($fields) && K2_JVERSION == '25')
{
$form = new K2Parameter($item->plugins, $manifest, $this->pluginName);
$fields = $form->render('plugins', $path);
}
}
if ($fields)
{
$plugin = new stdClass;
$plugin->name = $this->pluginNameHumanReadable;
$plugin->fields = $fields;
return $plugin;
}
}
}

View File

@ -0,0 +1,288 @@
<?php
/**
* @version $Id: recaptchalib.php 1812 2013-01-14 18:45:06Z lefteris.kavadas $
* @package K2
* @author JoomlaWorks http://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die;
/*
* This is a PHP library that handles calling reCAPTCHA.
* - Documentation and latest version
* http://recaptcha.net/plugins/php/
* - Get a reCAPTCHA API Key
* https://www.google.com/recaptcha/admin/create
* - Discussion group
* http://groups.google.com/group/recaptcha
*
* Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
* AUTHORS:
* Mike Crawford
* Ben Maurer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* The reCAPTCHA server URL's
*/
define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");
define("RECAPTCHA_VERIFY_SERVER", "www.google.com");
/**
* Encodes the given data into a query string format
* @param $data - array of string elements to be encoded
* @return string - encoded request
*/
function _recaptcha_qsencode ($data) {
$req = "";
foreach ( $data as $key => $value )
$req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
// Cut the last '&'
$req=substr($req,0,strlen($req)-1);
return $req;
}
/**
* Submits an HTTP POST to a reCAPTCHA server
* @param string $host
* @param string $path
* @param array $data
* @param int port
* @return array response
*/
function _recaptcha_http_post($host, $path, $data, $port = 80) {
$req = _recaptcha_qsencode ($data);
$http_request = "POST $path HTTP/1.0\r\n";
$http_request .= "Host: $host\r\n";
$http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
$http_request .= "Content-Length: " . strlen($req) . "\r\n";
$http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
$http_request .= "\r\n";
$http_request .= $req;
$response = '';
if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
die ('Could not open socket');
}
fwrite($fs, $http_request);
while ( !feof($fs) )
$response .= fgets($fs, 1160); // One TCP-IP packet
fclose($fs);
$response = explode("\r\n\r\n", $response, 2);
return $response;
}
/**
* Gets the challenge HTML (javascript and non-javascript version).
* This is called from the browser, and the resulting reCAPTCHA HTML widget
* is embedded within the HTML form it was called from.
* @param string $pubkey A public key for reCAPTCHA
* @param string $error The error given by reCAPTCHA (optional, default is null)
* @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
* @return string - The HTML to be embedded in the user's form.
*/
function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
{
if ($pubkey == null || $pubkey == '') {
die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
}
if ($use_ssl) {
$server = RECAPTCHA_API_SECURE_SERVER;
} else {
$server = RECAPTCHA_API_SERVER;
}
$errorpart = "";
if ($error) {
$errorpart = "&amp;error=" . $error;
}
return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
<noscript>
<iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript>';
}
/**
* A ReCaptchaResponse is returned from recaptcha_check_answer()
*/
class ReCaptchaResponse {
var $is_valid;
var $error;
}
/**
* Calls an HTTP POST function to verify if the user's guess was correct
* @param string $privkey
* @param string $remoteip
* @param string $challenge
* @param string $response
* @param array $extra_params an array of extra variables to post to the server
* @return ReCaptchaResponse
*/
function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
{
if ($privkey == null || $privkey == '') {
die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
}
if ($remoteip == null || $remoteip == '') {
die ("For security reasons, you must pass the remote ip to reCAPTCHA");
}
//discard spam submissions
if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
$recaptcha_response = new ReCaptchaResponse();
$recaptcha_response->is_valid = false;
$recaptcha_response->error = 'incorrect-captcha-sol';
return $recaptcha_response;
}
$response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
array (
'privatekey' => $privkey,
'remoteip' => $remoteip,
'challenge' => $challenge,
'response' => $response
) + $extra_params
);
$answers = explode ("\n", $response [1]);
$recaptcha_response = new ReCaptchaResponse();
if (trim ($answers [0]) == 'true') {
$recaptcha_response->is_valid = true;
}
else {
$recaptcha_response->is_valid = false;
$recaptcha_response->error = $answers [1];
}
return $recaptcha_response;
}
/**
* gets a URL where the user can sign up for reCAPTCHA. If your application
* has a configuration page where you enter a key, you should provide a link
* using this function.
* @param string $domain The domain where the page is hosted
* @param string $appname The name of your application
*/
function recaptcha_get_signup_url ($domain = null, $appname = null) {
return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
}
function _recaptcha_aes_pad($val) {
$block_size = 16;
$numpad = $block_size - (strlen ($val) % $block_size);
return str_pad($val, strlen ($val) + $numpad, chr($numpad));
}
/* Mailhide related code */
function _recaptcha_aes_encrypt($val,$ky) {
if (! function_exists ("mcrypt_encrypt")) {
die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
}
$mode=MCRYPT_MODE_CBC;
$enc=MCRYPT_RIJNDAEL_128;
$val=_recaptcha_aes_pad($val);
return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
}
function _recaptcha_mailhide_urlbase64 ($x) {
return strtr(base64_encode ($x), '+/', '-_');
}
/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
function recaptcha_mailhide_url($pubkey, $privkey, $email) {
if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
"you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
}
$ky = pack('H*', $privkey);
$cryptmail = _recaptcha_aes_encrypt ($email, $ky);
return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
}
/**
* gets the parts of the email to expose to the user.
* eg, given johndoe@example,com return ["john", "example.com"].
* the email is then displayed as john...@example.com
*/
function _recaptcha_mailhide_email_parts ($email) {
$arr = preg_split("/@/", $email );
if (strlen ($arr[0]) <= 4) {
$arr[0] = substr ($arr[0], 0, 1);
} else if (strlen ($arr[0]) <= 6) {
$arr[0] = substr ($arr[0], 0, 3);
} else {
$arr[0] = substr ($arr[0], 0, 4);
}
return $arr;
}
/**
* Gets html to display an email address given a public an private key.
* to get a key, go to:
*
* http://www.google.com/recaptcha/mailhide/apikey
*/
function recaptcha_mailhide_html($pubkey, $privkey, $email) {
$emailparts = _recaptcha_mailhide_email_parts ($email);
$url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
"' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
}
?>