Plugin Directory

Changeset 2781840


Ignore:
Timestamp:
09/08/2022 09:50:07 AM (4 years ago)
Author:
mbj-webdevelopment
Message:

tags/4.0.0

Location:
donation-button
Files:
292 added
8 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • donation-button/trunk/README.txt

    r2637863 r2781840  
    33Tags: button shortcode, campaign monitor, charity, church, churches, crowdfunding, donate, donation, donation plugin, donations, fundraiser, fundraising, gifts, giving, non-profit, nonprofit, paypal, PayPal Donate, PayPal donations, recurring, recurring donations, wordpress donation plugin, wordpress donations, worship, wp donation, constant contact, donation goal, donation history, donation widget, getresponse, icontact, infusionsoft, mailchimp, multi currency, paypal automation, twilio sms
    44Requires at least: 3.0.1
    5 Tested up to: 5.8.2
    6 stable tag: 3.0.7
     5Tested up to: 6.0.2
     6stable tag: 4.0.0
    77License: GNU General Public License v3.0
    88License URI: http://www.gnu.org/licenses/gpl-3.0.html
     
    145145
    146146== Changelog ==
     147= 4.0.0 =
     148* Verification - WP 6.0.2 compatibility.
     149
    147150= 1.5.2 =
    148151*   Mixed content while using https on my site with this addon.
  • donation-button/trunk/admin/partials/lib/campaign_monitor/class/services_json.php

    r1247237 r2781840  
    11<?php
    22
    3 define('SERVICES_JSON_SLICE', 1);
    4 
    5 define('SERVICES_JSON_IN_STR', 2);
    6 define('SERVICES_JSON_IN_ARR', 3);
    7 define('SERVICES_JSON_IN_OBJ', 4);
    8 define('SERVICES_JSON_IN_CMT', 5);
    9 define('SERVICES_JSON_LOOSE_TYPE', 16);
    10 define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
    11 
    12 class Services_JSON {
    13 
    14     function Services_JSON($use = 0) {
    15         $this->use = $use;
    16     }
    17 
    18     function utf162utf8($utf16) {
    19         if (function_exists('mb_convert_encoding')) {
    20             return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
    21         }
    22 
    23         $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
    24 
    25         switch (true) {
    26             case ((0x7F & $bytes) == $bytes):
    27                 return chr(0x7F & $bytes);
    28 
    29             case (0x07FF & $bytes) == $bytes:
    30                 return chr(0xC0 | (($bytes >> 6) & 0x1F))
    31                         . chr(0x80 | ($bytes & 0x3F));
    32 
    33             case (0xFFFF & $bytes) == $bytes:
    34                 return chr(0xE0 | (($bytes >> 12) & 0x0F))
    35                         . chr(0x80 | (($bytes >> 6) & 0x3F))
    36                         . chr(0x80 | ($bytes & 0x3F));
    37         }
    38         return '';
    39     }
    40 
    41     function utf82utf16($utf8) {
    42         if (function_exists('mb_convert_encoding')) {
    43             return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
    44         }
    45 
    46         switch (strlen($utf8)) {
    47             case 1:
    48                 return $utf8;
    49 
    50             case 2:
    51                 return chr(0x07 & (ord($utf8{0}) >> 2))
    52                         . chr((0xC0 & (ord($utf8{0}) << 6)) | (0x3F & ord($utf8{1})));
    53 
    54             case 3:
    55                 return chr((0xF0 & (ord($utf8{0}) << 4)) | (0x0F & (ord($utf8{1}) >> 2)))
    56                         . chr((0xC0 & (ord($utf8{1}) << 6)) | (0x7F & ord($utf8{2})));
    57         }
    58 
    59         return '';
    60     }
    61 
    62     function encode($var) {
    63         switch (gettype($var)) {
    64             case 'boolean':
    65                 return $var ? 'true' : 'false';
    66 
    67             case 'NULL':
    68                 return 'null';
    69 
    70             case 'integer':
    71                 return (int) $var;
    72 
    73             case 'double':
    74             case 'float':
    75                 return (float) $var;
    76 
    77             case 'string':
    78                 $ascii = '';
    79                 $strlen_var = strlen($var);
    80 
    81                 for ($c = 0; $c < $strlen_var; ++$c) {
    82 
    83                     $ord_var_c = ord($var{$c});
    84 
    85                     switch (true) {
    86                         case $ord_var_c == 0x08:
    87                             $ascii .= '\b';
    88                             break;
    89                         case $ord_var_c == 0x09:
    90                             $ascii .= '\t';
    91                             break;
    92                         case $ord_var_c == 0x0A:
    93                             $ascii .= '\n';
    94                             break;
    95                         case $ord_var_c == 0x0C:
    96                             $ascii .= '\f';
    97                             break;
    98                         case $ord_var_c == 0x0D:
    99                             $ascii .= '\r';
    100                             break;
    101 
    102                         case $ord_var_c == 0x22:
    103                         case $ord_var_c == 0x2F:
    104                         case $ord_var_c == 0x5C:
    105                             // double quote, slash, slosh
    106                             $ascii .= '\\' . $var{$c};
    107                             break;
    108 
    109                         case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
    110                             // characters U-00000000 - U-0000007F (same as ASCII)
    111                             $ascii .= $var{$c};
    112                             break;
    113 
    114                         case (($ord_var_c & 0xE0) == 0xC0):
    115                             // characters U-00000080 - U-000007FF, mask 110XXXXX
    116                             // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    117                             $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
    118                             $c += 1;
    119                             $utf16 = $this->utf82utf16($char);
    120                             $ascii .= sprintf('\u%04s', bin2hex($utf16));
    121                             break;
    122 
    123                         case (($ord_var_c & 0xF0) == 0xE0):
    124                             // characters U-00000800 - U-0000FFFF, mask 1110XXXX
    125                             // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    126                             $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}));
    127                             $c += 2;
    128                             $utf16 = $this->utf82utf16($char);
    129                             $ascii .= sprintf('\u%04s', bin2hex($utf16));
    130                             break;
    131 
    132                         case (($ord_var_c & 0xF8) == 0xF0):
    133                             // characters U-00010000 - U-001FFFFF, mask 11110XXX
    134                             // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    135                             $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}));
    136                             $c += 3;
    137                             $utf16 = $this->utf82utf16($char);
    138                             $ascii .= sprintf('\u%04s', bin2hex($utf16));
    139                             break;
    140 
    141                         case (($ord_var_c & 0xFC) == 0xF8):
    142                             // characters U-00200000 - U-03FFFFFF, mask 111110XX
    143                             // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    144                             $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}), ord($var{$c + 4}));
    145                             $c += 4;
    146                             $utf16 = $this->utf82utf16($char);
    147                             $ascii .= sprintf('\u%04s', bin2hex($utf16));
    148                             break;
    149 
    150                         case (($ord_var_c & 0xFE) == 0xFC):
    151                             // characters U-04000000 - U-7FFFFFFF, mask 1111110X
    152                             // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    153                             $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}));
    154                             $c += 5;
    155                             $utf16 = $this->utf82utf16($char);
    156                             $ascii .= sprintf('\u%04s', bin2hex($utf16));
    157                             break;
    158                     }
    159                 }
    160 
    161                 return '"' . $ascii . '"';
    162 
    163             case 'array':
    164                 /*
    165                  * As per JSON spec if any array key is not an integer
    166                  * we must treat the the whole array as an object. We
    167                  * also try to catch a sparsely populated associative
    168                  * array with numeric keys here because some JS engines
    169                  * will create an array with empty indexes up to
    170                  * max_index which can cause memory issues and because
    171                  * the keys, which may be relevant, will be remapped
    172                  * otherwise.
    173                  *
    174                  * As per the ECMA and JSON specification an object may
    175                  * have any string as a property. Unfortunately due to
    176                  * a hole in the ECMA specification if the key is a
    177                  * ECMA reserved word or starts with a digit the
    178                  * parameter is only accessible using ECMAScript's
    179                  * bracket notation.
    180                  */
    181 
    182                 // treat as a JSON object
    183                 if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
    184                     $properties = array_map(array($this, 'name_value'), array_keys($var), array_values($var));
    185 
    186                     foreach ($properties as $property) {
    187                         if ($this->isError($property)) {
    188                             return $property;
    189                         }
    190                     }
    191 
    192                     return '{' . join(',', $properties) . '}';
    193                 }
    194 
    195                 // treat it like a regular array
    196                 $elements = array_map(array($this, 'encode'), $var);
    197 
    198                 foreach ($elements as $element) {
    199                     if ($this->isError($element)) {
    200                         return $element;
    201                     }
    202                 }
    203 
    204                 return '[' . join(',', $elements) . ']';
    205 
    206             case 'object':
    207                 $vars = get_object_vars($var);
    208 
    209                 $properties = array_map(array($this, 'name_value'), array_keys($vars), array_values($vars));
    210 
    211                 foreach ($properties as $property) {
    212                     if ($this->isError($property)) {
    213                         return $property;
    214                     }
    215                 }
    216 
    217                 return '{' . join(',', $properties) . '}';
    218 
    219             default:
    220                 return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) ? 'null' : new Services_JSON_Error(gettype($var) . " can not be encoded as JSON string");
    221         }
    222     }
    223 
    224     /**
    225      * array-walking function for use in generating JSON-formatted name-value pairs
    226      *
    227      * @param    string  $name   name of key to use
    228      * @param    mixed   $value  reference to an array element to be encoded
    229      *
    230      * @return   string  JSON-formatted name-value pair, like '"name":value'
    231      * @access   private
    232      */
    233     function name_value($name, $value) {
    234         $encoded_value = $this->encode($value);
    235 
    236         if ($this->isError($encoded_value)) {
    237             return $encoded_value;
    238         }
    239 
    240         return $this->encode(strval($name)) . ':' . $encoded_value;
    241     }
    242 
    243     /**
    244      * reduce a string by removing leading and trailing comments and whitespace
    245      *
    246      * @param    $str    string      string value to strip of comments and whitespace
    247      *
    248      * @return   string  string value stripped of comments and whitespace
    249      * @access   private
    250      */
    251     function reduce_string($str) {
    252         $str = preg_replace(array(
    253             // eliminate single line comments in '// ...' form
    254             '#^\s*//(.+)$#m',
    255             // eliminate multi-line comments in '/* ... */' form, at start of string
    256             '#^\s*/\*(.+)\*/#Us',
    257             // eliminate multi-line comments in '/* ... */' form, at end of string
    258             '#/\*(.+)\*/\s*$#Us'
    259                 ), '', $str);
    260 
    261         // eliminate extraneous space
    262         return trim($str);
    263     }
    264 
    265     /**
    266      * decodes a JSON string into appropriate variable
    267      *
    268      * @param    string  $str    JSON-formatted string
    269      *
    270      * @return   mixed   number, boolean, string, array, or object
    271      *                   corresponding to given JSON input string.
    272      *                   See argument 1 to Services_JSON() above for object-output behavior.
    273      *                   Note that decode() always returns strings
    274      *                   in ASCII or UTF-8 format!
    275      * @access   public
    276      */
    277     function decode($str) {
    278         $str = $this->reduce_string($str);
    279 
    280         switch (strtolower($str)) {
    281             case 'true':
    282                 return true;
    283 
    284             case 'false':
    285                 return false;
    286 
    287             case 'null':
    288                 return null;
    289 
    290             default:
    291                 $m = array();
    292 
    293                 if (is_numeric($str)) {
    294                     // Lookie-loo, it's a number
    295                     // This would work on its own, but I'm trying to be
    296                     // good about returning integers where appropriate:
    297                     // return (float)$str;
    298                     // Return float or int, as appropriate
    299                     return ((float) $str == (integer) $str) ? (integer) $str : (float) $str;
    300                 } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
    301                     // STRINGS RETURNED IN UTF-8 FORMAT
    302                     $delim = substr($str, 0, 1);
    303                     $chrs = substr($str, 1, -1);
    304                     $utf8 = '';
    305                     $strlen_chrs = strlen($chrs);
    306 
    307                     for ($c = 0; $c < $strlen_chrs; ++$c) {
    308 
    309                         $substr_chrs_c_2 = substr($chrs, $c, 2);
    310                         $ord_chrs_c = ord($chrs{$c});
     3/**
     4 * Converts to and from JSON format.
     5 *
     6 * JSON (JavaScript Object Notation) is a lightweight data-interchange
     7 * format. It is easy for humans to read and write. It is easy for machines
     8 * to parse and generate. It is based on a subset of the JavaScript
     9 * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
     10 * This feature can also be found in  Python. JSON is a text format that is
     11 * completely language independent but uses conventions that are familiar
     12 * to programmers of the C-family of languages, including C, C++, C#, Java,
     13 * JavaScript, Perl, TCL, and many others. These properties make JSON an
     14 * ideal data-interchange language.
     15 *
     16 * This package provides a simple encoder and decoder for JSON notation. It
     17 * is intended for use with client-side Javascript applications that make
     18 * use of HTTPRequest to perform server communication functions - data can
     19 * be encoded into JSON notation for use in a client-side javascript, or
     20 * decoded from incoming Javascript requests. JSON format is native to
     21 * Javascript, and can be directly eval()'ed with no further parsing
     22 * overhead
     23 *
     24 * All strings should be in ASCII or UTF-8 format!
     25 *
     26 * LICENSE: Redistribution and use in source and binary forms, with or
     27 * without modification, are permitted provided that the following
     28 * conditions are met: Redistributions of source code must retain the
     29 * above copyright notice, this list of conditions and the following
     30 * disclaimer. Redistributions in binary form must reproduce the above
     31 * copyright notice, this list of conditions and the following disclaimer
     32 * in the documentation and/or other materials provided with the
     33 * distribution.
     34 *
     35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
     36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     37 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
     38 * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     40 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     41 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     42 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
     44 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
     45 * DAMAGE.
     46 *
     47 * @category
     48 * @package     Services_JSON
     49 * @author      Michal Migurski <mike-json@teczno.com>
     50 * @author      Matt Knapp <mdknapp[at]gmail[dot]com>
     51 * @author      Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
     52 * @copyright   2005 Michal Migurski
     53 * @version     CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
     54 * @license     http://www.opensource.org/licenses/bsd-license.php
     55 * @link        http://pear.php.net/pepr/pepr-proposal-show.php?id=198
     56 */
     57
     58/**
     59 * Marker constant for Services_JSON::decode(), used to flag stack state
     60 */
     61defined('SERVICES_JSON_SLICE') or define('SERVICES_JSON_SLICE',   1);
     62
     63/**
     64 * Marker constant for Services_JSON::decode(), used to flag stack state
     65 */
     66defined('SERVICES_JSON_IN_STR') or define('SERVICES_JSON_IN_STR',  2);
     67
     68/**
     69 * Marker constant for Services_JSON::decode(), used to flag stack state
     70 */
     71defined('SERVICES_JSON_IN_ARR') or define('SERVICES_JSON_IN_ARR',  3);
     72
     73/**
     74 * Marker constant for Services_JSON::decode(), used to flag stack state
     75 */
     76defined('SERVICES_JSON_IN_OBJ') or define('SERVICES_JSON_IN_OBJ',  4);
     77
     78/**
     79 * Marker constant for Services_JSON::decode(), used to flag stack state
     80 */
     81defined('SERVICES_JSON_IN_CMT') or define('SERVICES_JSON_IN_CMT', 5);
     82
     83/**
     84 * Behavior switch for Services_JSON::decode()
     85 */
     86defined('SERVICES_JSON_LOOSE_TYPE') or define('SERVICES_JSON_LOOSE_TYPE', 16);
     87
     88/**
     89 * Behavior switch for Services_JSON::decode()
     90 */
     91defined('SERVICES_JSON_SUPPRESS_ERRORS') or define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
     92
     93/**
     94 * Converts to and from JSON format.
     95 *
     96 * Brief example of use:
     97 *
     98 * <code>
     99 * // create a new instance of Services_JSON
     100 * $json = new Services_JSON();
     101 *
     102 * // convert a complexe value to JSON notation, and send it to the browser
     103 * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
     104 * $output = $json->encode($value);
     105 *
     106 * print($output);
     107 * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
     108 *
     109 * // accept incoming POST data, assumed to be in JSON notation
     110 * $input = file_get_contents('php://input', 1000000);
     111 * $value = $json->decode($input);
     112 * </code>
     113 */
     114if (!class_exists('Services_JSON')) {
     115    class Services_JSON
     116    {
     117       /**
     118        * constructs a new JSON instance
     119        *
     120        * @param    int     $use    object behavior flags; combine with boolean-OR
     121        *
     122        *                           possible values:
     123        *                           - SERVICES_JSON_LOOSE_TYPE:  loose typing.
     124        *                                   "{...}" syntax creates associative arrays
     125        *                                   instead of objects in decode().
     126        *                           - SERVICES_JSON_SUPPRESS_ERRORS:  error suppression.
     127        *                                   Values which can't be encoded (e.g. resources)
     128        *                                   appear as NULL instead of throwing errors.
     129        *                                   By default, a deeply-nested resource will
     130        *                                   bubble up with an error, so all return values
     131        *                                   from encode() should be checked with isError()
     132        */
     133        function __construct($use = 0)
     134        {
     135            $this->use = $use;
     136        }
     137
     138       /**
     139        * convert a string from one UTF-16 char to one UTF-8 char
     140        *
     141        * Normally should be handled by mb_convert_encoding, but
     142        * provides a slower PHP-only method for installations
     143        * that lack the multibye string extension.
     144        *
     145        * @param    string  $utf16  UTF-16 character
     146        * @return   string  UTF-8 character
     147        * @access   private
     148        */
     149        function utf162utf8($utf16)
     150        {
     151            // oh please oh please oh please oh please oh please
     152            if(function_exists('mb_convert_encoding')) {
     153                return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
     154            }
     155
     156            $bytes = (ord($utf16[0]) << 8) | ord($utf16[1]);
     157
     158            switch(true) {
     159                case ((0x7F & $bytes) == $bytes):
     160                    // this case should never be reached, because we are in ASCII range
     161                    // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     162                    return chr(0x7F & $bytes);
     163
     164                case (0x07FF & $bytes) == $bytes:
     165                    // return a 2-byte UTF-8 character
     166                    // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     167                    return chr(0xC0 | (($bytes >> 6) & 0x1F))
     168                         . chr(0x80 | ($bytes & 0x3F));
     169
     170                case (0xFFFF & $bytes) == $bytes:
     171                    // return a 3-byte UTF-8 character
     172                    // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     173                    return chr(0xE0 | (($bytes >> 12) & 0x0F))
     174                         . chr(0x80 | (($bytes >> 6) & 0x3F))
     175                         . chr(0x80 | ($bytes & 0x3F));
     176            }
     177
     178            // ignoring UTF-32 for now, sorry
     179            return '';
     180        }
     181
     182       /**
     183        * convert a string from one UTF-8 char to one UTF-16 char
     184        *
     185        * Normally should be handled by mb_convert_encoding, but
     186        * provides a slower PHP-only method for installations
     187        * that lack the multibye string extension.
     188        *
     189        * @param    string  $utf8   UTF-8 character
     190        * @return   string  UTF-16 character
     191        * @access   private
     192        */
     193        function utf82utf16($utf8)
     194        {
     195            // oh please oh please oh please oh please oh please
     196            if(function_exists('mb_convert_encoding')) {
     197                return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
     198            }
     199
     200            switch(strlen($utf8)) {
     201                case 1:
     202                    // this case should never be reached, because we are in ASCII range
     203                    // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     204                    return $utf8;
     205
     206                case 2:
     207                    // return a UTF-16 character from a 2-byte UTF-8 char
     208                    // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     209                    return chr(0x07 & (ord($utf8[0]) >> 2))
     210                         . chr((0xC0 & (ord($utf8[0]) << 6))
     211                             | (0x3F & ord($utf8[1])));
     212
     213                case 3:
     214                    // return a UTF-16 character from a 3-byte UTF-8 char
     215                    // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     216                    return chr((0xF0 & (ord($utf8[0]) << 4))
     217                             | (0x0F & (ord($utf8[1]) >> 2)))
     218                         . chr((0xC0 & (ord($utf8[1]) << 6))
     219                             | (0x7F & ord($utf8[2])));
     220            }
     221
     222            // ignoring UTF-32 for now, sorry
     223            return '';
     224        }
     225
     226       /**
     227        * encodes an arbitrary variable into JSON format
     228        *
     229        * @param    mixed   $var    any number, boolean, string, array, or object to be encoded.
     230        *                           see argument 1 to Services_JSON() above for array-parsing behavior.
     231        *                           if var is a strng, note that encode() always expects it
     232        *                           to be in ASCII or UTF-8 format!
     233        *
     234        * @return   mixed   JSON string representation of input var or an error if a problem occurs
     235        * @access   public
     236        */
     237        function encode($var)
     238        {
     239            switch (gettype($var)) {
     240                case 'boolean':
     241                    return $var ? 'true' : 'false';
     242
     243                case 'NULL':
     244                    return 'null';
     245
     246                case 'integer':
     247                    return (int) $var;
     248
     249                case 'double':
     250                case 'float':
     251                    return (float) $var;
     252
     253                case 'string':
     254                    // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
     255                    $ascii = '';
     256                    $strlen_var = strlen($var);
     257
     258                   /*
     259                    * Iterate over every character in the string,
     260                    * escaping with a slash or encoding to UTF-8 where necessary
     261                    */
     262                    for ($c = 0; $c < $strlen_var; ++$c) {
     263
     264                        $ord_var_c = ord($var[$c]);
    311265
    312266                        switch (true) {
    313                             case $substr_chrs_c_2 == '\b':
    314                                 $utf8 .= chr(0x08);
    315                                 ++$c;
    316                                 break;
    317                             case $substr_chrs_c_2 == '\t':
    318                                 $utf8 .= chr(0x09);
    319                                 ++$c;
    320                                 break;
    321                             case $substr_chrs_c_2 == '\n':
    322                                 $utf8 .= chr(0x0A);
    323                                 ++$c;
    324                                 break;
    325                             case $substr_chrs_c_2 == '\f':
    326                                 $utf8 .= chr(0x0C);
    327                                 ++$c;
    328                                 break;
    329                             case $substr_chrs_c_2 == '\r':
    330                                 $utf8 .= chr(0x0D);
    331                                 ++$c;
    332                                 break;
    333 
    334                             case $substr_chrs_c_2 == '\\"':
    335                             case $substr_chrs_c_2 == '\\\'':
    336                             case $substr_chrs_c_2 == '\\\\':
    337                             case $substr_chrs_c_2 == '\\/':
    338                                 if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
    339                                         ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
    340                                     $utf8 .= $chrs{ ++$c};
    341                                 }
    342                                 break;
    343 
    344                             case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
    345                                 // single, escaped unicode character
    346                                 $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
    347                                         . chr(hexdec(substr($chrs, ($c + 4), 2)));
    348                                 $utf8 .= $this->utf162utf8($utf16);
    349                                 $c += 5;
    350                                 break;
    351 
    352                             case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
    353                                 $utf8 .= $chrs{$c};
    354                                 break;
    355 
    356                             case ($ord_chrs_c & 0xE0) == 0xC0:
     267                            case $ord_var_c == 0x08:
     268                                $ascii .= '\b';
     269                                break;
     270                            case $ord_var_c == 0x09:
     271                                $ascii .= '\t';
     272                                break;
     273                            case $ord_var_c == 0x0A:
     274                                $ascii .= '\n';
     275                                break;
     276                            case $ord_var_c == 0x0C:
     277                                $ascii .= '\f';
     278                                break;
     279                            case $ord_var_c == 0x0D:
     280                                $ascii .= '\r';
     281                                break;
     282
     283                            case $ord_var_c == 0x22:
     284                            case $ord_var_c == 0x2F:
     285                            case $ord_var_c == 0x5C:
     286                                // double quote, slash, slosh
     287                                $ascii .= '\\'.$var[$c];
     288                                break;
     289
     290                            case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
     291                                // characters U-00000000 - U-0000007F (same as ASCII)
     292                                $ascii .= $var[$c];
     293                                break;
     294
     295                            case (($ord_var_c & 0xE0) == 0xC0):
    357296                                // characters U-00000080 - U-000007FF, mask 110XXXXX
    358                                 //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    359                                 $utf8 .= substr($chrs, $c, 2);
    360                                 ++$c;
    361                                 break;
    362 
    363                             case ($ord_chrs_c & 0xF0) == 0xE0:
     297                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     298                                $char = pack('C*', $ord_var_c, ord($var[$c + 1]));
     299                                $c += 1;
     300                                $utf16 = $this->utf82utf16($char);
     301                                $ascii .= sprintf('\u%04s', bin2hex($utf16));
     302                                break;
     303
     304                            case (($ord_var_c & 0xF0) == 0xE0):
    364305                                // characters U-00000800 - U-0000FFFF, mask 1110XXXX
    365306                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    366                                 $utf8 .= substr($chrs, $c, 3);
     307                                $char = pack('C*', $ord_var_c,
     308                                             ord($var[$c + 1]),
     309                                             ord($var[$c + 2]));
    367310                                $c += 2;
    368                                 break;
    369 
    370                             case ($ord_chrs_c & 0xF8) == 0xF0:
     311                                $utf16 = $this->utf82utf16($char);
     312                                $ascii .= sprintf('\u%04s', bin2hex($utf16));
     313                                break;
     314
     315                            case (($ord_var_c & 0xF8) == 0xF0):
    371316                                // characters U-00010000 - U-001FFFFF, mask 11110XXX
    372317                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    373                                 $utf8 .= substr($chrs, $c, 4);
     318                                $char = pack('C*', $ord_var_c,
     319                                             ord($var[$c + 1]),
     320                                             ord($var[$c + 2]),
     321                                             ord($var[$c + 3]));
    374322                                $c += 3;
    375                                 break;
    376 
    377                             case ($ord_chrs_c & 0xFC) == 0xF8:
     323                                $utf16 = $this->utf82utf16($char);
     324                                $ascii .= sprintf('\u%04s', bin2hex($utf16));
     325                                break;
     326
     327                            case (($ord_var_c & 0xFC) == 0xF8):
    378328                                // characters U-00200000 - U-03FFFFFF, mask 111110XX
    379329                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    380                                 $utf8 .= substr($chrs, $c, 5);
     330                                $char = pack('C*', $ord_var_c,
     331                                             ord($var[$c + 1]),
     332                                             ord($var[$c + 2]),
     333                                             ord($var[$c + 3]),
     334                                             ord($var[$c + 4]));
    381335                                $c += 4;
    382                                 break;
    383 
    384                             case ($ord_chrs_c & 0xFE) == 0xFC:
     336                                $utf16 = $this->utf82utf16($char);
     337                                $ascii .= sprintf('\u%04s', bin2hex($utf16));
     338                                break;
     339
     340                            case (($ord_var_c & 0xFE) == 0xFC):
    385341                                // characters U-04000000 - U-7FFFFFFF, mask 1111110X
    386342                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
    387                                 $utf8 .= substr($chrs, $c, 6);
     343                                $char = pack('C*', $ord_var_c,
     344                                             ord($var[$c + 1]),
     345                                             ord($var[$c + 2]),
     346                                             ord($var[$c + 3]),
     347                                             ord($var[$c + 4]),
     348                                             ord($var[$c + 5]));
    388349                                $c += 5;
     350                                $utf16 = $this->utf82utf16($char);
     351                                $ascii .= sprintf('\u%04s', bin2hex($utf16));
    389352                                break;
    390353                        }
    391354                    }
    392355
    393                     return $utf8;
    394                 } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
    395                     // array, or object notation
    396 
    397                     if ($str{0} == '[') {
    398                         $stk = array(SERVICES_JSON_IN_ARR);
    399                         $arr = array();
    400                     } else {
    401                         if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
    402                             $stk = array(SERVICES_JSON_IN_OBJ);
    403                             $obj = array();
     356                    return '"'.$ascii.'"';
     357
     358                case 'array':
     359                   /*
     360                    * As per JSON spec if any array key is not an integer
     361                    * we must treat the the whole array as an object. We
     362                    * also try to catch a sparsely populated associative
     363                    * array with numeric keys here because some JS engines
     364                    * will create an array with empty indexes up to
     365                    * max_index which can cause memory issues and because
     366                    * the keys, which may be relevant, will be remapped
     367                    * otherwise.
     368                    *
     369                    * As per the ECMA and JSON specification an object may
     370                    * have any string as a property. Unfortunately due to
     371                    * a hole in the ECMA specification if the key is a
     372                    * ECMA reserved word or starts with a digit the
     373                    * parameter is only accessible using ECMAScript's
     374                    * bracket notation.
     375                    */
     376
     377                    // treat as a JSON object
     378                    if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
     379                        $properties = array_map(array($this, 'name_value'),
     380                                                array_keys($var),
     381                                                array_values($var));
     382
     383                        foreach($properties as $property) {
     384                            if($this->isError($property)) {
     385                                return $property;
     386                            }
     387                        }
     388
     389                        return '{' . join(',', $properties) . '}';
     390                    }
     391
     392                    // treat it like a regular array
     393                    $elements = array_map(array($this, 'encode'), $var);
     394
     395                    foreach($elements as $element) {
     396                        if($this->isError($element)) {
     397                            return $element;
     398                        }
     399                    }
     400
     401                    return '[' . join(',', $elements) . ']';
     402
     403                case 'object':
     404                    $vars = get_object_vars($var);
     405
     406                    $properties = array_map(array($this, 'name_value'),
     407                                            array_keys($vars),
     408                                            array_values($vars));
     409
     410                    foreach($properties as $property) {
     411                        if($this->isError($property)) {
     412                            return $property;
     413                        }
     414                    }
     415
     416                    return '{' . join(',', $properties) . '}';
     417
     418                default:
     419                    return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
     420                        ? 'null'
     421                        : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
     422            }
     423        }
     424
     425       /**
     426        * array-walking function for use in generating JSON-formatted name-value pairs
     427        *
     428        * @param    string  $name   name of key to use
     429        * @param    mixed   $value  reference to an array element to be encoded
     430        *
     431        * @return   string  JSON-formatted name-value pair, like '"name":value'
     432        * @access   private
     433        */
     434        function name_value($name, $value)
     435        {
     436            $encoded_value = $this->encode($value);
     437
     438            if($this->isError($encoded_value)) {
     439                return $encoded_value;
     440            }
     441
     442            return $this->encode(strval($name)) . ':' . $encoded_value;
     443        }
     444
     445       /**
     446        * reduce a string by removing leading and trailing comments and whitespace
     447        *
     448        * @param    $str    string      string value to strip of comments and whitespace
     449        *
     450        * @return   string  string value stripped of comments and whitespace
     451        * @access   private
     452        */
     453        function reduce_string($str)
     454        {
     455            $str = preg_replace(array(
     456
     457                    // eliminate single line comments in '// ...' form
     458                    '#^\s*//(.+)$#m',
     459
     460                    // eliminate multi-line comments in '/* ... */' form, at start of string
     461                    '#^\s*/\*(.+)\*/#Us',
     462
     463                    // eliminate multi-line comments in '/* ... */' form, at end of string
     464                    '#/\*(.+)\*/\s*$#Us'
     465
     466                ), '', $str);
     467
     468            // eliminate extraneous space
     469            return trim($str);
     470        }
     471
     472       /**
     473        * decodes a JSON string into appropriate variable
     474        *
     475        * @param    string  $str    JSON-formatted string
     476        *
     477        * @return   mixed   number, boolean, string, array, or object
     478        *                   corresponding to given JSON input string.
     479        *                   See argument 1 to Services_JSON() above for object-output behavior.
     480        *                   Note that decode() always returns strings
     481        *                   in ASCII or UTF-8 format!
     482        * @access   public
     483        */
     484        function decode($str)
     485        {
     486            $str = $this->reduce_string($str);
     487
     488            switch (strtolower($str)) {
     489                case 'true':
     490                    return true;
     491
     492                case 'false':
     493                    return false;
     494
     495                case 'null':
     496                    return null;
     497
     498                default:
     499                    $m = array();
     500
     501                    if (is_numeric($str)) {
     502                        // Lookie-loo, it's a number
     503
     504                        // This would work on its own, but I'm trying to be
     505                        // good about returning integers where appropriate:
     506                        // return (float)$str;
     507
     508                        // Return float or int, as appropriate
     509                        return ((float)$str == (integer)$str)
     510                            ? (integer)$str
     511                            : (float)$str;
     512
     513                    } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
     514                        // STRINGS RETURNED IN UTF-8 FORMAT
     515                        $delim = substr($str, 0, 1);
     516                        $chrs = substr($str, 1, -1);
     517                        $utf8 = '';
     518                        $strlen_chrs = strlen($chrs);
     519
     520                        for ($c = 0; $c < $strlen_chrs; ++$c) {
     521
     522                            $substr_chrs_c_2 = substr($chrs, $c, 2);
     523                            $ord_chrs_c = ord($chrs[$c]);
     524
     525                            switch (true) {
     526                                case $substr_chrs_c_2 == '\b':
     527                                    $utf8 .= chr(0x08);
     528                                    ++$c;
     529                                    break;
     530                                case $substr_chrs_c_2 == '\t':
     531                                    $utf8 .= chr(0x09);
     532                                    ++$c;
     533                                    break;
     534                                case $substr_chrs_c_2 == '\n':
     535                                    $utf8 .= chr(0x0A);
     536                                    ++$c;
     537                                    break;
     538                                case $substr_chrs_c_2 == '\f':
     539                                    $utf8 .= chr(0x0C);
     540                                    ++$c;
     541                                    break;
     542                                case $substr_chrs_c_2 == '\r':
     543                                    $utf8 .= chr(0x0D);
     544                                    ++$c;
     545                                    break;
     546
     547                                case $substr_chrs_c_2 == '\\"':
     548                                case $substr_chrs_c_2 == '\\\'':
     549                                case $substr_chrs_c_2 == '\\\\':
     550                                case $substr_chrs_c_2 == '\\/':
     551                                    if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
     552                                       ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
     553                                        $utf8 .= $chrs[++$c];
     554                                    }
     555                                    break;
     556
     557                                case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
     558                                    // single, escaped unicode character
     559                                    $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
     560                                           . chr(hexdec(substr($chrs, ($c + 4), 2)));
     561                                    $utf8 .= $this->utf162utf8($utf16);
     562                                    $c += 5;
     563                                    break;
     564
     565                                case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
     566                                    $utf8 .= $chrs[$c];
     567                                    break;
     568
     569                                case ($ord_chrs_c & 0xE0) == 0xC0:
     570                                    // characters U-00000080 - U-000007FF, mask 110XXXXX
     571                                    //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     572                                    $utf8 .= substr($chrs, $c, 2);
     573                                    ++$c;
     574                                    break;
     575
     576                                case ($ord_chrs_c & 0xF0) == 0xE0:
     577                                    // characters U-00000800 - U-0000FFFF, mask 1110XXXX
     578                                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     579                                    $utf8 .= substr($chrs, $c, 3);
     580                                    $c += 2;
     581                                    break;
     582
     583                                case ($ord_chrs_c & 0xF8) == 0xF0:
     584                                    // characters U-00010000 - U-001FFFFF, mask 11110XXX
     585                                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     586                                    $utf8 .= substr($chrs, $c, 4);
     587                                    $c += 3;
     588                                    break;
     589
     590                                case ($ord_chrs_c & 0xFC) == 0xF8:
     591                                    // characters U-00200000 - U-03FFFFFF, mask 111110XX
     592                                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     593                                    $utf8 .= substr($chrs, $c, 5);
     594                                    $c += 4;
     595                                    break;
     596
     597                                case ($ord_chrs_c & 0xFE) == 0xFC:
     598                                    // characters U-04000000 - U-7FFFFFFF, mask 1111110X
     599                                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
     600                                    $utf8 .= substr($chrs, $c, 6);
     601                                    $c += 5;
     602                                    break;
     603
     604                            }
     605
     606                        }
     607
     608                        return $utf8;
     609
     610                    } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
     611                        // array, or object notation
     612
     613                        if ($str[0] == '[') {
     614                            $stk = array(SERVICES_JSON_IN_ARR);
     615                            $arr = array();
    404616                        } else {
    405                             $stk = array(SERVICES_JSON_IN_OBJ);
    406                             $obj = new stdClass();
    407                         }
    408                     }
    409 
    410                     array_push($stk, array('what' => SERVICES_JSON_SLICE,
    411                         'where' => 0,
    412                         'delim' => false));
    413 
    414                     $chrs = substr($str, 1, -1);
    415                     $chrs = $this->reduce_string($chrs);
    416 
    417                     if ($chrs == '') {
     617                            if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
     618                                $stk = array(SERVICES_JSON_IN_OBJ);
     619                                $obj = array();
     620                            } else {
     621                                $stk = array(SERVICES_JSON_IN_OBJ);
     622                                $obj = new stdClass();
     623                            }
     624                        }
     625
     626                        array_push($stk, array('what'  => SERVICES_JSON_SLICE,
     627                                               'where' => 0,
     628                                               'delim' => false));
     629
     630                        $chrs = substr($str, 1, -1);
     631                        $chrs = $this->reduce_string($chrs);
     632
     633                        if ($chrs == '') {
     634                            if (reset($stk) == SERVICES_JSON_IN_ARR) {
     635                                return $arr;
     636
     637                            } else {
     638                                return $obj;
     639
     640                            }
     641                        }
     642
     643                        //print("\nparsing {$chrs}\n");
     644
     645                        $strlen_chrs = strlen($chrs);
     646
     647                        for ($c = 0; $c <= $strlen_chrs; ++$c) {
     648
     649                            $top = end($stk);
     650                            $substr_chrs_c_2 = substr($chrs, $c, 2);
     651
     652                            if (($c == $strlen_chrs) || (($chrs[$c] == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
     653                                // found a comma that is not inside a string, array, etc.,
     654                                // OR we've reached the end of the character list
     655                                $slice = substr($chrs, $top['where'], ($c - $top['where']));
     656                                array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
     657                                //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
     658
     659                                if (reset($stk) == SERVICES_JSON_IN_ARR) {
     660                                    // we are in an array, so just push an element onto the stack
     661                                    array_push($arr, $this->decode($slice));
     662
     663                                } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
     664                                    // we are in an object, so figure
     665                                    // out the property name and set an
     666                                    // element in an associative array,
     667                                    // for now
     668                                    $parts = array();
     669                                   
     670                                    if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
     671                                        // "name":value pair
     672                                        $key = $this->decode($parts[1]);
     673                                        $val = $this->decode($parts[2]);
     674
     675                                        if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
     676                                            $obj[$key] = $val;
     677                                        } else {
     678                                            $obj->$key = $val;
     679                                        }
     680                                    } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
     681                                        // name:value pair, where name is unquoted
     682                                        $key = $parts[1];
     683                                        $val = $this->decode($parts[2]);
     684
     685                                        if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
     686                                            $obj[$key] = $val;
     687                                        } else {
     688                                            $obj->$key = $val;
     689                                        }
     690                                    }
     691
     692                                }
     693
     694                            } elseif ((($chrs[$c] == '"') || ($chrs[$c] == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
     695                                // found a quote, and we are not inside a string
     696                                array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c]));
     697                                //print("Found start of string at {$c}\n");
     698
     699                            } elseif (($chrs[$c] == $top['delim']) &&
     700                                     ($top['what'] == SERVICES_JSON_IN_STR) &&
     701                                     ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
     702                                // found a quote, we're in a string, and it's not escaped
     703                                // we know that it's not escaped becase there is _not_ an
     704                                // odd number of backslashes at the end of the string so far
     705                                array_pop($stk);
     706                                //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
     707
     708                            } elseif (($chrs[$c] == '[') &&
     709                                     in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
     710                                // found a left-bracket, and we are in an array, object, or slice
     711                                array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
     712                                //print("Found start of array at {$c}\n");
     713
     714                            } elseif (($chrs[$c] == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
     715                                // found a right-bracket, and we're in an array
     716                                array_pop($stk);
     717                                //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
     718
     719                            } elseif (($chrs[$c] == '{') &&
     720                                     in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
     721                                // found a left-brace, and we are in an array, object, or slice
     722                                array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
     723                                //print("Found start of object at {$c}\n");
     724
     725                            } elseif (($chrs[$c] == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
     726                                // found a right-brace, and we're in an object
     727                                array_pop($stk);
     728                                //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
     729
     730                            } elseif (($substr_chrs_c_2 == '/*') &&
     731                                     in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
     732                                // found a comment start, and we are in an array, object, or slice
     733                                array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
     734                                $c++;
     735                                //print("Found start of comment at {$c}\n");
     736
     737                            } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
     738                                // found a comment end, and we're in one now
     739                                array_pop($stk);
     740                                $c++;
     741
     742                                for ($i = $top['where']; $i <= $c; ++$i)
     743                                    $chrs = substr_replace($chrs, ' ', $i, 1);
     744
     745                                //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
     746
     747                            }
     748
     749                        }
     750
    418751                        if (reset($stk) == SERVICES_JSON_IN_ARR) {
    419752                            return $arr;
    420                         } else {
     753
     754                        } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
    421755                            return $obj;
    422                         }
     756
     757                        }
     758
    423759                    }
    424 
    425                     //print("\nparsing {$chrs}\n");
    426 
    427                     $strlen_chrs = strlen($chrs);
    428 
    429                     for ($c = 0; $c <= $strlen_chrs; ++$c) {
    430 
    431                         $top = end($stk);
    432                         $substr_chrs_c_2 = substr($chrs, $c, 2);
    433 
    434                         if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
    435                             // found a comma that is not inside a string, array, etc.,
    436                             // OR we've reached the end of the character list
    437                             $slice = substr($chrs, $top['where'], ($c - $top['where']));
    438                             array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
    439                             //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
    440 
    441                             if (reset($stk) == SERVICES_JSON_IN_ARR) {
    442                                 // we are in an array, so just push an element onto the stack
    443                                 array_push($arr, $this->decode($slice));
    444                             } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
    445                                 // we are in an object, so figure
    446                                 // out the property name and set an
    447                                 // element in an associative array,
    448                                 // for now
    449                                 $parts = array();
    450 
    451                                 if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
    452                                     // "name":value pair
    453                                     $key = $this->decode($parts[1]);
    454                                     $val = $this->decode($parts[2]);
    455 
    456                                     if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
    457                                         $obj[$key] = $val;
    458                                     } else {
    459                                         $obj->$key = $val;
    460                                     }
    461                                 } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
    462                                     // name:value pair, where name is unquoted
    463                                     $key = $parts[1];
    464                                     $val = $this->decode($parts[2]);
    465 
    466                                     if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
    467                                         $obj[$key] = $val;
    468                                     } else {
    469                                         $obj->$key = $val;
    470                                     }
    471                                 }
    472                             }
    473                         } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
    474                             // found a quote, and we are not inside a string
    475                             array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
    476                             //print("Found start of string at {$c}\n");
    477                         } elseif (($chrs{$c} == $top['delim']) &&
    478                                 ($top['what'] == SERVICES_JSON_IN_STR) &&
    479                                 ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
    480                             // found a quote, we're in a string, and it's not escaped
    481                             // we know that it's not escaped becase there is _not_ an
    482                             // odd number of backslashes at the end of the string so far
    483                             array_pop($stk);
    484                             //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
    485                         } elseif (($chrs{$c} == '[') &&
    486                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
    487                             // found a left-bracket, and we are in an array, object, or slice
    488                             array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
    489                             //print("Found start of array at {$c}\n");
    490                         } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
    491                             // found a right-bracket, and we're in an array
    492                             array_pop($stk);
    493                             //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
    494                         } elseif (($chrs{$c} == '{') &&
    495                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
    496                             // found a left-brace, and we are in an array, object, or slice
    497                             array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
    498                             //print("Found start of object at {$c}\n");
    499                         } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
    500                             // found a right-brace, and we're in an object
    501                             array_pop($stk);
    502                             //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
    503                         } elseif (($substr_chrs_c_2 == '/*') &&
    504                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
    505                             // found a comment start, and we are in an array, object, or slice
    506                             array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
    507                             $c++;
    508                             //print("Found start of comment at {$c}\n");
    509                         } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
    510                             // found a comment end, and we're in one now
    511                             array_pop($stk);
    512                             $c++;
    513 
    514                             for ($i = $top['where']; $i <= $c; ++$i)
    515                                 $chrs = substr_replace($chrs, ' ', $i, 1);
    516 
    517                             //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
    518                         }
    519                     }
    520 
    521                     if (reset($stk) == SERVICES_JSON_IN_ARR) {
    522                         return $arr;
    523                     } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
    524                         return $obj;
    525                     }
    526                 }
     760            }
     761        }
     762       
     763        function isError($data, $code = null)
     764        {
     765            if (is_object($data) && (get_class($data) == 'services_json_error' ||
     766                                     is_subclass_of($data, 'services_json_error'))) {
     767                return true;
     768            }
     769
     770            return false;
    527771        }
    528772    }
    529 
    530     function isError($data, $code = null) {
    531         if (is_object($data) && (get_class($data) == 'services_json_error' ||
    532                 is_subclass_of($data, 'services_json_error'))) {
    533             return true;
    534         }
    535 
    536         return false;
     773}
     774
     775if (!class_exists('Services_JSON_Error')) {
     776    class Services_JSON_Error
     777    {
     778        function __construct($message = 'unknown error', $code = null,
     779                             $mode = null, $options = null, $userinfo = null)
     780        {
     781
     782        }
    537783    }
    538 
    539784}
    540 
    541 class Services_JSON_Error {
    542 
    543     function Services_JSON_Error($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null) {
    544        
    545     }
    546 
    547 }
    548 
     785 
    549786?>
  • donation-button/trunk/donation-button.php

    r2637863 r2781840  
    66 * Plugin URI:        https://www.premiumdev.com/
    77 * Description:       Easy to used PayPal Donation button with Auto Responder.
    8  * Version:           3.0.7
     8 * Version:           4.0.0
    99 * Author:            mbj-webdevelopment
    1010 * Author URI:        https://www.premiumdev.com/
  • donation-button/trunk/includes/class-donation-button.php

    r2637863 r2781840  
    4747    public function __construct() {
    4848        $this->plugin_name = 'donation-button';
    49         $this->version = '3.0.7';
     49        $this->version = '4.0.0';
    5050        $this->load_dependencies();
    5151        $this->set_locale();
Note: See TracChangeset for help on using the changeset viewer.