source: trunk/library/Zend/Ldap/Converter.php @ 4456

Revision 4456, 14.2 KB checked in by airton, 13 years ago (diff)

Ticket #1991 - Parametrizacao das buscas LDAP no Expresso Mail - Adicionando arquivos e bibliotecas

  • Property svn:executable set to *
Line 
1<?php
2/**
3 * Zend Framework
4 *
5 * LICENSE
6 *
7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
14 *
15 * @category   Zend
16 * @package    Zend_Ldap
17 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license    http://framework.zend.com/license/new-bsd     New BSD License
19 * @version    $Id: Converter.php 23486 2010-12-10 04:05:30Z mjh_ca $
20 */
21
22/**
23 * Zend_Ldap_Converter is a collection of useful LDAP related conversion functions.
24 *
25 * @category   Zend
26 * @package    Zend_Ldap
27 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
28 * @license    http://framework.zend.com/license/new-bsd     New BSD License
29 */
30class Zend_Ldap_Converter
31{
32    const STANDARD         = 0;
33    const BOOLEAN          = 1;
34    const GENERALIZED_TIME = 2;
35
36    /**
37     * Converts all ASCII chars < 32 to "\HEX"
38     *
39     * @see Net_LDAP2_Util::asc2hex32() from Benedikt Hallinger <beni@php.net>
40     * @link http://pear.php.net/package/Net_LDAP2
41     * @author Benedikt Hallinger <beni@php.net>
42     *
43     * @param  string $string String to convert
44     * @return string
45     */
46    public static function ascToHex32($string)
47    {
48        for ($i = 0; $i<strlen($string); $i++) {
49            $char = substr($string, $i, 1);
50            if (ord($char)<32) {
51                $hex = dechex(ord($char));
52                if (strlen($hex) == 1) $hex = '0' . $hex;
53                $string = str_replace($char, '\\' . $hex, $string);
54            }
55        }
56        return $string;
57    }
58
59    /**
60     * Converts all Hex expressions ("\HEX") to their original ASCII characters
61     *
62     * @see Net_LDAP2_Util::hex2asc() from Benedikt Hallinger <beni@php.net>,
63     * heavily based on work from DavidSmith@byu.net
64     * @link http://pear.php.net/package/Net_LDAP2
65     * @author Benedikt Hallinger <beni@php.net>, heavily based on work from DavidSmith@byu.net
66     *
67     * @param  string $string String to convert
68     * @return string
69     */
70    public static function hex32ToAsc($string)
71    {
72        $string = preg_replace("/\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\1')).''", $string);
73        return $string;
74    }
75
76    /**
77     * Convert any value to an LDAP-compatible value.
78     *
79     * By setting the <var>$type</var>-parameter the conversion of a certain
80     * type can be forced
81     *
82     * @todo write more tests
83     *
84     * @param    mixed     $value     The value to convert
85     * @param    int       $ytpe      The conversion type to use
86     * @return    string
87     * @throws    Zend_Ldap_Converter_Exception
88     */
89    public static function toLdap($value, $type = self::STANDARD)
90    {
91        try {
92            switch ($type) {
93                case self::BOOLEAN:
94                    return self::toldapBoolean($value);
95                    break;
96                case self::GENERALIZED_TIME:
97                    return self::toLdapDatetime($value);
98                    break;
99                default:
100                    if (is_string($value)) {
101                        return $value;
102                    } else if (is_int($value) || is_float($value)) {
103                        return (string)$value;
104                    } else if (is_bool($value)) {
105                        return self::toldapBoolean($value);
106                    } else if (is_object($value)) {
107                        if ($value instanceof DateTime) {
108                            return self::toLdapDatetime($value);
109                        } else if ($value instanceof Zend_Date) {
110                            return self::toLdapDatetime($value);
111                        } else {
112                            return self::toLdapSerialize($value);
113                        }
114                    } else if (is_array($value)) {
115                        return self::toLdapSerialize($value);
116                    } else if (is_resource($value) && get_resource_type($value) === 'stream') {
117                        return stream_get_contents($value);
118                    } else {
119                        return null;
120                    }
121                    break;
122            }
123        } catch (Exception $e) {
124            throw new Zend_Ldap_Converter_Exception($e->getMessage(), $e->getCode(), $e);
125        }
126    }
127
128    /**
129     * Converts a date-entity to an LDAP-compatible date-string
130     *
131     * The date-entity <var>$date</var> can be either a timestamp, a
132     * DateTime Object, a string that is parseable by strtotime() or a Zend_Date
133     * Object.
134     *
135     * @param    integer|string|DateTimt|Zend_Date        $date    The date-entity
136     * @param    boolean                                    $asUtc    Whether to return the LDAP-compatible date-string
137     *                                                          as UTC or as local value
138     * @return    string
139     * @throws    InvalidArgumentException
140     */
141    public static function toLdapDateTime($date, $asUtc = true)
142    {
143        if (!($date instanceof DateTime)) {
144            if (is_int($date)) {
145                $date = new DateTime('@' . $date);
146                $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
147            } else if (is_string($date)) {
148                $date = new DateTime($date);
149            } else if ($date instanceof Zend_Date) {
150                $date = new DateTime($date->get(Zend_Date::ISO_8601));
151            } else {
152                throw new InvalidArgumentException('Parameter $date is not of the expected type');
153            }
154        }
155        $timezone = $date->format('O');
156        if (true === $asUtc) {
157            $date->setTimezone(new DateTimeZone('UTC'));
158            $timezone = 'Z';
159        }
160        if ( '+0000' === $timezone ) {
161            $timezone = 'Z';
162        }
163        return $date->format('YmdHis') . $timezone;
164    }
165
166    /**
167     * Convert a boolean value to an LDAP-compatible string
168     *
169     * This converts a boolean value of TRUE, an integer-value of 1 and a
170     * case-insensitive string 'true' to an LDAP-compatible 'TRUE'. All other
171     * other values are converted to an LDAP-compatible 'FALSE'.
172     *
173     * @param    boolean|integer|string        $value    The boolean value to encode
174     * @return    string
175     */
176    public static function toLdapBoolean($value)
177    {
178        $return = 'FALSE';
179        if (!is_scalar($value)) {
180            return $return;
181        }
182        if (true === $value || 'true' === strtolower($value) || 1 === $value) {
183            $return = 'TRUE';
184        }
185        return $return;
186    }
187
188    /**
189     * Serialize any value for storage in LDAP
190     *
191     * @param    mixed        $value    The value to serialize
192     * @return    string
193     */
194    public static function toLdapSerialize($value)
195    {
196        return serialize($value);
197    }
198
199    /**
200     * Convert an LDAP-compatible value to a corresponding PHP-value.
201     *
202     * By setting the <var>$type</var>-parameter the conversion of a certain
203     * type can be forced
204     * .
205     * @param    string    $value             The value to convert
206     * @param    int        $ytpe              The conversion type to use
207     * @param    boolean    $dateTimeAsUtc    Return DateTime values in UTC timezone
208     * @return    mixed
209     * @throws    Zend_Ldap_Converter_Exception
210     */
211    public static function fromLdap($value, $type = self::STANDARD, $dateTimeAsUtc = true)
212    {
213        switch ($type) {
214            case self::BOOLEAN:
215                return self::fromldapBoolean($value);
216                break;
217            case self::GENERALIZED_TIME:
218                return self::fromLdapDateTime($value);
219                break;
220            default:
221                if (is_numeric($value)) {
222                    return (float)$value;
223                } else if ('TRUE' === $value || 'FALSE' === $value) {
224                    return self::fromLdapBoolean($value);
225                }
226                if (preg_match('/^\d{4}[\d\+\-Z\.]*$/', $value)) {
227                    return self::fromLdapDateTime($value, $dateTimeAsUtc);
228                }
229                try {
230                    return self::fromLdapUnserialize($value);
231                } catch (UnexpectedValueException $e) { }
232                break;
233        }
234        return $value;
235    }
236
237    /**
238     * Convert an LDAP-Generalized-Time-entry into a DateTime-Object
239     *
240     * CAVEAT: The DateTime-Object returned will alwasy be set to UTC-Timezone.
241     *
242     * @param    string        $date    The generalized-Time
243     * @param    boolean        $asUtc    Return the DateTime with UTC timezone
244     * @return    DateTime
245     * @throws    InvalidArgumentException if a non-parseable-format is given
246     */
247    public static function fromLdapDateTime($date, $asUtc = true)
248    {
249        $datepart = array ();
250        if (!preg_match('/^(\d{4})/', $date, $datepart) ) {
251            throw new InvalidArgumentException('Invalid date format found');
252        }
253
254        if ($datepart[1] < 4) {
255            throw new InvalidArgumentException('Invalid date format found (too short)');
256        }
257
258        $time = array (
259            // The year is mandatory!
260            'year'   => $datepart[1],
261            'month'  => 1,
262            'day'    => 1,
263            'hour'   => 0,
264            'minute' => 0,
265            'second' => 0,
266            'offdir' => '+',
267            'offsethours' => 0,
268            'offsetminutes' => 0
269        );
270
271        $length = strlen($date);
272
273        // Check for month.
274        if ($length >= 6) {
275            $month = substr($date, 4, 2);
276            if ($month < 1 || $month > 12) {
277                throw new InvalidArgumentException('Invalid date format found (invalid month)');
278            }
279            $time['month'] = $month;
280        }
281
282        // Check for day
283        if ($length >= 8) {
284            $day = substr($date, 6, 2);
285            if ($day < 1 || $day > 31) {
286                throw new InvalidArgumentException('Invalid date format found (invalid day)');
287            }
288            $time['day'] = $day;
289        }
290
291        // Check for Hour
292        if ($length >= 10) {
293            $hour = substr($date, 8, 2);
294            if ($hour < 0 || $hour > 23) {
295                throw new InvalidArgumentException('Invalid date format found (invalid hour)');
296            }
297            $time['hour'] = $hour;
298        }
299
300        // Check for minute
301        if ($length >= 12) {
302            $minute = substr($date, 10, 2);
303            if ($minute < 0 || $minute > 59) {
304                throw new InvalidArgumentException('Invalid date format found (invalid minute)');
305            }
306            $time['minute'] = $minute;
307        }
308
309        // Check for seconds
310        if ($length >= 14) {
311            $second = substr($date, 12, 2);
312            if ($second < 0 || $second > 59) {
313                throw new InvalidArgumentException('Invalid date format found (invalid second)');
314            }
315            $time['second'] = $second;
316        }
317
318        // Set Offset
319        $offsetRegEx = '/([Z\-\+])(\d{2}\'?){0,1}(\d{2}\'?){0,1}$/';
320        $off         = array ();
321        if (preg_match($offsetRegEx, $date, $off)) {
322            $offset = $off[1];
323            if ($offset == '+' || $offset == '-') {
324                $time['offdir'] = $offset;
325                // we have an offset, so lets calculate it.
326                if (isset($off[2])) {
327                    $offsetHours = substr($off[2], 0, 2);
328                    if ($offsetHours < 0 || $offsetHours > 12) {
329                        throw new InvalidArgumentException('Invalid date format found (invalid offset hour)');
330                    }
331                    $time['offsethours'] = $offsetHours;
332                }
333                if (isset($off[3])) {
334                    $offsetMinutes = substr($off[3], 0, 2);
335                    if ($offsetMinutes < 0 || $offsetMinutes > 59) {
336                        throw new InvalidArgumentException('Invalid date format found (invalid offset minute)');
337                    }
338                    $time['offsetminutes'] = $offsetMinutes;
339                }
340            }
341        }
342
343        // Raw-Data is present, so lets create a DateTime-Object from it.
344        $offset = $time['offdir']
345                . str_pad($time['offsethours'],2,'0',STR_PAD_LEFT)
346                . str_pad($time['offsetminutes'],2,'0',STR_PAD_LEFT);
347        $timestring = $time['year'] . '-'
348                    . str_pad($time['month'], 2, '0', STR_PAD_LEFT) . '-'
349                    . str_pad($time['day'], 2, '0', STR_PAD_LEFT) . ' '
350                    . str_pad($time['hour'], 2, '0', STR_PAD_LEFT) . ':'
351                    . str_pad($time['minute'], 2, '0', STR_PAD_LEFT) . ':'
352                    . str_pad($time['second'], 2, '0', STR_PAD_LEFT)
353                    . $time['offdir']
354                    . str_pad($time['offsethours'], 2, '0', STR_PAD_LEFT)
355                    . str_pad($time['offsetminutes'], 2, '0', STR_PAD_LEFT);
356        $date = new DateTime($timestring);
357        if ($asUtc) {
358            $date->setTimezone(new DateTimeZone('UTC'));
359        }
360        return $date;
361    }
362
363    /**
364     * Convert an LDAP-compatible boolean value into a PHP-compatible one
365     *
366     * @param    string        $value        The value to convert
367     * @return    boolean
368     * @throws    InvalidArgumentException
369     */
370    public static function fromLdapBoolean($value)
371    {
372        if ( 'TRUE' === $value ) {
373            return true;
374        } else if ( 'FALSE' === $value ) {
375            return false;
376        } else {
377            throw new InvalidArgumentException('The given value is not a boolean value');
378        }
379    }
380
381    /**
382     * Unserialize a serialized value to return the corresponding object
383     *
384     * @param    string        $value    The value to convert
385     * @return    mixed
386     * @throws    UnexpectedValueException
387     */
388    public static function fromLdapUnserialize($value)
389    {
390        $v = @unserialize($value);
391        if (false===$v && $value != 'b:0;') {
392            throw new UnexpectedValueException('The given value could not be unserialized');
393        }
394        return $v;
395    }
396}
Note: See TracBrowser for help on using the repository browser.