./0000700000175000017500000000000011520221772010526 5ustar tokkeetokkee./kohana/0000755000175000017500000000000011263472446012013 5ustar tokkeetokkee./kohana/system/0000755000175000017500000000000011263472444013335 5ustar tokkeetokkee./kohana/system/core/0000755000175000017500000000000011263472437014267 5ustar tokkeetokkee./kohana/system/core/Bootstrap.php0000644000175000017500000000270711212336332016746 0ustar tokkeetokkee $event_callback) { if ($callback === $event_callback) { unset(self::$events[$name][$i]); } } } } /** * Execute all of the callbacks attached to an event. * * @param string event name * @param array data can be processed as Event::$data by the callbacks * @return void */ public static function run($name, & $data = NULL) { if ( ! empty(self::$events[$name])) { // So callbacks can access Event::$data self::$data =& $data; $callbacks = self::get($name); foreach ($callbacks as $callback) { call_user_func($callback); } // Do this to prevent data from getting 'stuck' $clear_data = ''; self::$data =& $clear_data; } // The event has been run! self::$has_run[$name] = $name; } /** * Check if a given event has been run. * * @param string event name * @return boolean */ public static function has_run($name) { return isset(self::$has_run[$name]); } } // End Event./kohana/system/core/utf8.php0000644000175000017500000004635611121324570015667 0ustar tokkeetokkeePCRE has not been compiled with UTF-8 support. '. 'See PCRE Pattern Modifiers '. 'for more information. This application cannot be run without UTF-8 support.', E_USER_ERROR ); } if ( ! extension_loaded('iconv')) { trigger_error ( 'The iconv extension is not loaded. '. 'Without iconv, strings cannot be properly translated to UTF-8 from user input. '. 'This application cannot be run without UTF-8 support.', E_USER_ERROR ); } if (extension_loaded('mbstring') AND (ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING)) { trigger_error ( 'The mbstring extension is overloading PHP\'s native string functions. '. 'Disable this by setting mbstring.func_overload to 0, 1, 4 or 5 in php.ini or a .htaccess file.'. 'This application cannot be run without UTF-8 support.', E_USER_ERROR ); } // Check PCRE support for Unicode properties such as \p and \X. $ER = error_reporting(0); define('PCRE_UNICODE_PROPERTIES', (bool) preg_match('/^\pL$/u', 'ñ')); error_reporting($ER); // SERVER_UTF8 ? use mb_* functions : use non-native functions if (extension_loaded('mbstring')) { mb_internal_encoding('UTF-8'); define('SERVER_UTF8', TRUE); } else { define('SERVER_UTF8', FALSE); } // Convert all global variables to UTF-8. $_GET = utf8::clean($_GET); $_POST = utf8::clean($_POST); $_COOKIE = utf8::clean($_COOKIE); $_SERVER = utf8::clean($_SERVER); if (PHP_SAPI == 'cli') { // Convert command line arguments $_SERVER['argv'] = utf8::clean($_SERVER['argv']); } final class utf8 { // Called methods static $called = array(); /** * Recursively cleans arrays, objects, and strings. Removes ASCII control * codes and converts to UTF-8 while silently discarding incompatible * UTF-8 characters. * * @param string string to clean * @return string */ public static function clean($str) { if (is_array($str) OR is_object($str)) { foreach ($str as $key => $val) { // Recursion! $str[self::clean($key)] = self::clean($val); } } elseif (is_string($str) AND $str !== '') { // Remove control characters $str = self::strip_ascii_ctrl($str); if ( ! self::is_ascii($str)) { // Disable notices $ER = error_reporting(~E_NOTICE); // iconv is expensive, so it is only used when needed $str = iconv('UTF-8', 'UTF-8//IGNORE', $str); // Turn notices back on error_reporting($ER); } } return $str; } /** * Tests whether a string contains only 7bit ASCII bytes. This is used to * determine when to use native functions or UTF-8 functions. * * @param string string to check * @return bool */ public static function is_ascii($str) { return ! preg_match('/[^\x00-\x7F]/S', $str); } /** * Strips out device control codes in the ASCII range. * * @param string string to clean * @return string */ public static function strip_ascii_ctrl($str) { return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $str); } /** * Strips out all non-7bit ASCII bytes. * * @param string string to clean * @return string */ public static function strip_non_ascii($str) { return preg_replace('/[^\x00-\x7F]+/S', '', $str); } /** * Replaces special/accented UTF-8 characters by ASCII-7 'equivalents'. * * @author Andreas Gohr * * @param string string to transliterate * @param integer -1 lowercase only, +1 uppercase only, 0 both cases * @return string */ public static function transliterate_to_ascii($str, $case = 0) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _transliterate_to_ascii($str, $case); } /** * Returns the length of the given string. * @see http://php.net/strlen * * @param string string being measured for length * @return integer */ public static function strlen($str) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strlen($str); } /** * Finds position of first occurrence of a UTF-8 string. * @see http://php.net/strlen * * @author Harry Fuecks * * @param string haystack * @param string needle * @param integer offset from which character in haystack to start searching * @return integer position of needle * @return boolean FALSE if the needle is not found */ public static function strpos($str, $search, $offset = 0) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strpos($str, $search, $offset); } /** * Finds position of last occurrence of a char in a UTF-8 string. * @see http://php.net/strrpos * * @author Harry Fuecks * * @param string haystack * @param string needle * @param integer offset from which character in haystack to start searching * @return integer position of needle * @return boolean FALSE if the needle is not found */ public static function strrpos($str, $search, $offset = 0) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strrpos($str, $search, $offset); } /** * Returns part of a UTF-8 string. * @see http://php.net/substr * * @author Chris Smith * * @param string input string * @param integer offset * @param integer length limit * @return string */ public static function substr($str, $offset, $length = NULL) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _substr($str, $offset, $length); } /** * Replaces text within a portion of a UTF-8 string. * @see http://php.net/substr_replace * * @author Harry Fuecks * * @param string input string * @param string replacement string * @param integer offset * @return string */ public static function substr_replace($str, $replacement, $offset, $length = NULL) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _substr_replace($str, $replacement, $offset, $length); } /** * Makes a UTF-8 string lowercase. * @see http://php.net/strtolower * * @author Andreas Gohr * * @param string mixed case string * @return string */ public static function strtolower($str) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strtolower($str); } /** * Makes a UTF-8 string uppercase. * @see http://php.net/strtoupper * * @author Andreas Gohr * * @param string mixed case string * @return string */ public static function strtoupper($str) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strtoupper($str); } /** * Makes a UTF-8 string's first character uppercase. * @see http://php.net/ucfirst * * @author Harry Fuecks * * @param string mixed case string * @return string */ public static function ucfirst($str) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _ucfirst($str); } /** * Makes the first character of every word in a UTF-8 string uppercase. * @see http://php.net/ucwords * * @author Harry Fuecks * * @param string mixed case string * @return string */ public static function ucwords($str) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _ucwords($str); } /** * Case-insensitive UTF-8 string comparison. * @see http://php.net/strcasecmp * * @author Harry Fuecks * * @param string string to compare * @param string string to compare * @return integer less than 0 if str1 is less than str2 * @return integer greater than 0 if str1 is greater than str2 * @return integer 0 if they are equal */ public static function strcasecmp($str1, $str2) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strcasecmp($str1, $str2); } /** * Returns a string or an array with all occurrences of search in subject (ignoring case). * replaced with the given replace value. * @see http://php.net/str_ireplace * * @note It's not fast and gets slower if $search and/or $replace are arrays. * @author Harry Fuecks * * @param string input string * @param string needle * @return string matched substring if found * @return boolean FALSE if the substring was not found */ public static function stristr($str, $search) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _stristr($str, $search); } /** * Finds the length of the initial segment matching mask. * @see http://php.net/strspn * * @author Harry Fuecks * * @param string input string * @param string mask for search * @param integer start position of the string to examine * @param integer length of the string to examine * @return integer length of the initial segment that contains characters in the mask */ public static function strspn($str, $mask, $offset = NULL, $length = NULL) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strspn($str, $mask, $offset, $length); } /** * Finds the length of the initial segment not matching mask. * @see http://php.net/strcspn * * @author Harry Fuecks * * @param string input string * @param string mask for search * @param integer start position of the string to examine * @param integer length of the string to examine * @return integer length of the initial segment that contains characters not in the mask */ public static function strcspn($str, $mask, $offset = NULL, $length = NULL) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strcspn($str, $mask, $offset, $length); } /** * Pads a UTF-8 string to a certain length with another string. * @see http://php.net/str_pad * * @author Harry Fuecks * * @param string input string * @param integer desired string length after padding * @param string string to use as padding * @param string padding type: STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH * @return string */ public static function str_pad($str, $final_str_length, $pad_str = ' ', $pad_type = STR_PAD_RIGHT) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _str_pad($str, $final_str_length, $pad_str, $pad_type); } /** * Converts a UTF-8 string to an array. * @see http://php.net/str_split * * @author Harry Fuecks * * @param string input string * @param integer maximum length of each chunk * @return array */ public static function str_split($str, $split_length = 1) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _str_split($str, $split_length); } /** * Reverses a UTF-8 string. * @see http://php.net/strrev * * @author Harry Fuecks * * @param string string to be reversed * @return string */ public static function strrev($str) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _strrev($str); } /** * Strips whitespace (or other UTF-8 characters) from the beginning and * end of a string. * @see http://php.net/trim * * @author Andreas Gohr * * @param string input string * @param string string of characters to remove * @return string */ public static function trim($str, $charlist = NULL) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _trim($str, $charlist); } /** * Strips whitespace (or other UTF-8 characters) from the beginning of a string. * @see http://php.net/ltrim * * @author Andreas Gohr * * @param string input string * @param string string of characters to remove * @return string */ public static function ltrim($str, $charlist = NULL) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _ltrim($str, $charlist); } /** * Strips whitespace (or other UTF-8 characters) from the end of a string. * @see http://php.net/rtrim * * @author Andreas Gohr * * @param string input string * @param string string of characters to remove * @return string */ public static function rtrim($str, $charlist = NULL) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _rtrim($str, $charlist); } /** * Returns the unicode ordinal for a character. * @see http://php.net/ord * * @author Harry Fuecks * * @param string UTF-8 encoded character * @return integer */ public static function ord($chr) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _ord($chr); } /** * Takes an UTF-8 string and returns an array of ints representing the Unicode characters. * Astral planes are supported i.e. the ints in the output can be > 0xFFFF. * Occurrances of the BOM are ignored. Surrogates are not allowed. * * The Original Code is Mozilla Communicator client code. * The Initial Developer of the Original Code is Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer. * Ported to PHP by Henri Sivonen , see http://hsivonen.iki.fi/php-utf8/. * Slight modifications to fit with phputf8 library by Harry Fuecks . * * @param string UTF-8 encoded string * @return array unicode code points * @return boolean FALSE if the string is invalid */ public static function to_unicode($str) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _to_unicode($str); } /** * Takes an array of ints representing the Unicode characters and returns a UTF-8 string. * Astral planes are supported i.e. the ints in the input can be > 0xFFFF. * Occurrances of the BOM are ignored. Surrogates are not allowed. * * The Original Code is Mozilla Communicator client code. * The Initial Developer of the Original Code is Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer. * Ported to PHP by Henri Sivonen , see http://hsivonen.iki.fi/php-utf8/. * Slight modifications to fit with phputf8 library by Harry Fuecks . * * @param array unicode code points representing a string * @return string utf8 string of characters * @return boolean FALSE if a code point cannot be found */ public static function from_unicode($arr) { if ( ! isset(self::$called[__FUNCTION__])) { require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; // Function has been called self::$called[__FUNCTION__] = TRUE; } return _from_unicode($arr); } } // End utf8./kohana/system/core/Benchmark.php0000644000175000017500000000533711164666402016677 0ustar tokkeetokkee microtime(TRUE), 'stop' => FALSE, 'memory_start' => self::memory_usage(), 'memory_stop' => FALSE ); array_unshift(self::$marks[$name], $mark); } /** * Set a benchmark stop point. * * @param string benchmark name * @return void */ public static function stop($name) { if (isset(self::$marks[$name]) AND self::$marks[$name][0]['stop'] === FALSE) { self::$marks[$name][0]['stop'] = microtime(TRUE); self::$marks[$name][0]['memory_stop'] = self::memory_usage(); } } /** * Get the elapsed time between a start and stop. * * @param string benchmark name, TRUE for all * @param integer number of decimal places to count to * @return array */ public static function get($name, $decimals = 4) { if ($name === TRUE) { $times = array(); $names = array_keys(self::$marks); foreach ($names as $name) { // Get each mark recursively $times[$name] = self::get($name, $decimals); } // Return the array return $times; } if ( ! isset(self::$marks[$name])) return FALSE; if (self::$marks[$name][0]['stop'] === FALSE) { // Stop the benchmark to prevent mis-matched results self::stop($name); } // Return a string version of the time between the start and stop points // Properly reading a float requires using number_format or sprintf $time = $memory = 0; for ($i = 0; $i < count(self::$marks[$name]); $i++) { $time += self::$marks[$name][$i]['stop'] - self::$marks[$name][$i]['start']; $memory += self::$marks[$name][$i]['memory_stop'] - self::$marks[$name][$i]['memory_start']; } return array ( 'time' => number_format($time, $decimals), 'memory' => $memory, 'count' => count(self::$marks[$name]) ); } /** * Returns the current memory usage. This is only possible if the * memory_get_usage function is supported in PHP. * * @return integer */ private static function memory_usage() { static $func; if ($func === NULL) { // Test if memory usage can be seen $func = function_exists('memory_get_usage'); } return $func ? memory_get_usage() : 0; } } // End Benchmark ./kohana/system/core/utf8/0000755000175000017500000000000011263472437015155 5ustar tokkeetokkee./kohana/system/core/utf8/ltrim.php0000644000175000017500000000105711121324570017003 0ustar tokkeetokkee0x0041, 0x03C6=>0x03A6, 0x0163=>0x0162, 0x00E5=>0x00C5, 0x0062=>0x0042, 0x013A=>0x0139, 0x00E1=>0x00C1, 0x0142=>0x0141, 0x03CD=>0x038E, 0x0101=>0x0100, 0x0491=>0x0490, 0x03B4=>0x0394, 0x015B=>0x015A, 0x0064=>0x0044, 0x03B3=>0x0393, 0x00F4=>0x00D4, 0x044A=>0x042A, 0x0439=>0x0419, 0x0113=>0x0112, 0x043C=>0x041C, 0x015F=>0x015E, 0x0144=>0x0143, 0x00EE=>0x00CE, 0x045E=>0x040E, 0x044F=>0x042F, 0x03BA=>0x039A, 0x0155=>0x0154, 0x0069=>0x0049, 0x0073=>0x0053, 0x1E1F=>0x1E1E, 0x0135=>0x0134, 0x0447=>0x0427, 0x03C0=>0x03A0, 0x0438=>0x0418, 0x00F3=>0x00D3, 0x0440=>0x0420, 0x0454=>0x0404, 0x0435=>0x0415, 0x0449=>0x0429, 0x014B=>0x014A, 0x0431=>0x0411, 0x0459=>0x0409, 0x1E03=>0x1E02, 0x00F6=>0x00D6, 0x00F9=>0x00D9, 0x006E=>0x004E, 0x0451=>0x0401, 0x03C4=>0x03A4, 0x0443=>0x0423, 0x015D=>0x015C, 0x0453=>0x0403, 0x03C8=>0x03A8, 0x0159=>0x0158, 0x0067=>0x0047, 0x00E4=>0x00C4, 0x03AC=>0x0386, 0x03AE=>0x0389, 0x0167=>0x0166, 0x03BE=>0x039E, 0x0165=>0x0164, 0x0117=>0x0116, 0x0109=>0x0108, 0x0076=>0x0056, 0x00FE=>0x00DE, 0x0157=>0x0156, 0x00FA=>0x00DA, 0x1E61=>0x1E60, 0x1E83=>0x1E82, 0x00E2=>0x00C2, 0x0119=>0x0118, 0x0146=>0x0145, 0x0070=>0x0050, 0x0151=>0x0150, 0x044E=>0x042E, 0x0129=>0x0128, 0x03C7=>0x03A7, 0x013E=>0x013D, 0x0442=>0x0422, 0x007A=>0x005A, 0x0448=>0x0428, 0x03C1=>0x03A1, 0x1E81=>0x1E80, 0x016D=>0x016C, 0x00F5=>0x00D5, 0x0075=>0x0055, 0x0177=>0x0176, 0x00FC=>0x00DC, 0x1E57=>0x1E56, 0x03C3=>0x03A3, 0x043A=>0x041A, 0x006D=>0x004D, 0x016B=>0x016A, 0x0171=>0x0170, 0x0444=>0x0424, 0x00EC=>0x00CC, 0x0169=>0x0168, 0x03BF=>0x039F, 0x006B=>0x004B, 0x00F2=>0x00D2, 0x00E0=>0x00C0, 0x0434=>0x0414, 0x03C9=>0x03A9, 0x1E6B=>0x1E6A, 0x00E3=>0x00C3, 0x044D=>0x042D, 0x0436=>0x0416, 0x01A1=>0x01A0, 0x010D=>0x010C, 0x011D=>0x011C, 0x00F0=>0x00D0, 0x013C=>0x013B, 0x045F=>0x040F, 0x045A=>0x040A, 0x00E8=>0x00C8, 0x03C5=>0x03A5, 0x0066=>0x0046, 0x00FD=>0x00DD, 0x0063=>0x0043, 0x021B=>0x021A, 0x00EA=>0x00CA, 0x03B9=>0x0399, 0x017A=>0x0179, 0x00EF=>0x00CF, 0x01B0=>0x01AF, 0x0065=>0x0045, 0x03BB=>0x039B, 0x03B8=>0x0398, 0x03BC=>0x039C, 0x045C=>0x040C, 0x043F=>0x041F, 0x044C=>0x042C, 0x00FE=>0x00DE, 0x00F0=>0x00D0, 0x1EF3=>0x1EF2, 0x0068=>0x0048, 0x00EB=>0x00CB, 0x0111=>0x0110, 0x0433=>0x0413, 0x012F=>0x012E, 0x00E6=>0x00C6, 0x0078=>0x0058, 0x0161=>0x0160, 0x016F=>0x016E, 0x03B1=>0x0391, 0x0457=>0x0407, 0x0173=>0x0172, 0x00FF=>0x0178, 0x006F=>0x004F, 0x043B=>0x041B, 0x03B5=>0x0395, 0x0445=>0x0425, 0x0121=>0x0120, 0x017E=>0x017D, 0x017C=>0x017B, 0x03B6=>0x0396, 0x03B2=>0x0392, 0x03AD=>0x0388, 0x1E85=>0x1E84, 0x0175=>0x0174, 0x0071=>0x0051, 0x0437=>0x0417, 0x1E0B=>0x1E0A, 0x0148=>0x0147, 0x0105=>0x0104, 0x0458=>0x0408, 0x014D=>0x014C, 0x00ED=>0x00CD, 0x0079=>0x0059, 0x010B=>0x010A, 0x03CE=>0x038F, 0x0072=>0x0052, 0x0430=>0x0410, 0x0455=>0x0405, 0x0452=>0x0402, 0x0127=>0x0126, 0x0137=>0x0136, 0x012B=>0x012A, 0x03AF=>0x038A, 0x044B=>0x042B, 0x006C=>0x004C, 0x03B7=>0x0397, 0x0125=>0x0124, 0x0219=>0x0218, 0x00FB=>0x00DB, 0x011F=>0x011E, 0x043E=>0x041E, 0x1E41=>0x1E40, 0x03BD=>0x039D, 0x0107=>0x0106, 0x03CB=>0x03AB, 0x0446=>0x0426, 0x00FE=>0x00DE, 0x00E7=>0x00C7, 0x03CA=>0x03AA, 0x0441=>0x0421, 0x0432=>0x0412, 0x010F=>0x010E, 0x00F8=>0x00D8, 0x0077=>0x0057, 0x011B=>0x011A, 0x0074=>0x0054, 0x006A=>0x004A, 0x045B=>0x040B, 0x0456=>0x0406, 0x0103=>0x0102, 0x03BB=>0x039B, 0x00F1=>0x00D1, 0x043D=>0x041D, 0x03CC=>0x038C, 0x00E9=>0x00C9, 0x00F0=>0x00D0, 0x0457=>0x0407, 0x0123=>0x0122, ); } $uni = utf8::to_unicode($str); if ($uni === FALSE) return FALSE; for ($i = 0, $c = count($uni); $i < $c; $i++) { if (isset($UTF8_LOWER_TO_UPPER[$uni[$i]])) { $uni[$i] = $UTF8_LOWER_TO_UPPER[$uni[$i]]; } } return utf8::from_unicode($uni); }./kohana/system/core/utf8/str_pad.php0000644000175000017500000000311111151055263017304 0ustar tokkeetokkee= 0) AND ($arr[$k] <= 0x007f)) { echo chr($arr[$k]); } // 2 byte sequence elseif ($arr[$k] <= 0x07ff) { echo chr(0xc0 | ($arr[$k] >> 6)); echo chr(0x80 | ($arr[$k] & 0x003f)); } // Byte order mark (skip) elseif ($arr[$k] == 0xFEFF) { // nop -- zap the BOM } // Test for illegal surrogates elseif ($arr[$k] >= 0xD800 AND $arr[$k] <= 0xDFFF) { // Found a surrogate trigger_error('utf8::from_unicode: Illegal surrogate at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); return FALSE; } // 3 byte sequence elseif ($arr[$k] <= 0xffff) { echo chr(0xe0 | ($arr[$k] >> 12)); echo chr(0x80 | (($arr[$k] >> 6) & 0x003f)); echo chr(0x80 | ($arr[$k] & 0x003f)); } // 4 byte sequence elseif ($arr[$k] <= 0x10ffff) { echo chr(0xf0 | ($arr[$k] >> 18)); echo chr(0x80 | (($arr[$k] >> 12) & 0x3f)); echo chr(0x80 | (($arr[$k] >> 6) & 0x3f)); echo chr(0x80 | ($arr[$k] & 0x3f)); } // Out of range else { trigger_error('utf8::from_unicode: Codepoint out of Unicode range at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); return FALSE; } } $result = ob_get_contents(); ob_end_clean(); return $result; } ./kohana/system/core/utf8/transliterate_to_ascii.php0000644000175000017500000000742711121324570022416 0ustar tokkeetokkee 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o', 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k', 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o', 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o', 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c', 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't', 'ū' => 'u', 'č' => 'c', 'ö' => 'o', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l', 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z', 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't', 'ŗ' => 'r', 'ä' => 'a', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'u', 'ò' => 'o', 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j', 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o', 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g', 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a', 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e', ); } $str = str_replace( array_keys($UTF8_LOWER_ACCENTS), array_values($UTF8_LOWER_ACCENTS), $str ); } if ($case >= 0) { if ($UTF8_UPPER_ACCENTS === NULL) { $UTF8_UPPER_ACCENTS = array( 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O', 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K', 'Ĕ' => 'E', 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O', 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O', 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C', 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T', 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'O', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L', 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z', 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T', 'Ŗ' => 'R', 'Ä' => 'A', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'U', 'Ò' => 'O', 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J', 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O', 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G', 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A', 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', ); } $str = str_replace( array_keys($UTF8_UPPER_ACCENTS), array_values($UTF8_UPPER_ACCENTS), $str ); } return $str; }./kohana/system/core/utf8/strtolower.php0000644000175000017500000001035111121324570020075 0ustar tokkeetokkee0x0061, 0x03A6=>0x03C6, 0x0162=>0x0163, 0x00C5=>0x00E5, 0x0042=>0x0062, 0x0139=>0x013A, 0x00C1=>0x00E1, 0x0141=>0x0142, 0x038E=>0x03CD, 0x0100=>0x0101, 0x0490=>0x0491, 0x0394=>0x03B4, 0x015A=>0x015B, 0x0044=>0x0064, 0x0393=>0x03B3, 0x00D4=>0x00F4, 0x042A=>0x044A, 0x0419=>0x0439, 0x0112=>0x0113, 0x041C=>0x043C, 0x015E=>0x015F, 0x0143=>0x0144, 0x00CE=>0x00EE, 0x040E=>0x045E, 0x042F=>0x044F, 0x039A=>0x03BA, 0x0154=>0x0155, 0x0049=>0x0069, 0x0053=>0x0073, 0x1E1E=>0x1E1F, 0x0134=>0x0135, 0x0427=>0x0447, 0x03A0=>0x03C0, 0x0418=>0x0438, 0x00D3=>0x00F3, 0x0420=>0x0440, 0x0404=>0x0454, 0x0415=>0x0435, 0x0429=>0x0449, 0x014A=>0x014B, 0x0411=>0x0431, 0x0409=>0x0459, 0x1E02=>0x1E03, 0x00D6=>0x00F6, 0x00D9=>0x00F9, 0x004E=>0x006E, 0x0401=>0x0451, 0x03A4=>0x03C4, 0x0423=>0x0443, 0x015C=>0x015D, 0x0403=>0x0453, 0x03A8=>0x03C8, 0x0158=>0x0159, 0x0047=>0x0067, 0x00C4=>0x00E4, 0x0386=>0x03AC, 0x0389=>0x03AE, 0x0166=>0x0167, 0x039E=>0x03BE, 0x0164=>0x0165, 0x0116=>0x0117, 0x0108=>0x0109, 0x0056=>0x0076, 0x00DE=>0x00FE, 0x0156=>0x0157, 0x00DA=>0x00FA, 0x1E60=>0x1E61, 0x1E82=>0x1E83, 0x00C2=>0x00E2, 0x0118=>0x0119, 0x0145=>0x0146, 0x0050=>0x0070, 0x0150=>0x0151, 0x042E=>0x044E, 0x0128=>0x0129, 0x03A7=>0x03C7, 0x013D=>0x013E, 0x0422=>0x0442, 0x005A=>0x007A, 0x0428=>0x0448, 0x03A1=>0x03C1, 0x1E80=>0x1E81, 0x016C=>0x016D, 0x00D5=>0x00F5, 0x0055=>0x0075, 0x0176=>0x0177, 0x00DC=>0x00FC, 0x1E56=>0x1E57, 0x03A3=>0x03C3, 0x041A=>0x043A, 0x004D=>0x006D, 0x016A=>0x016B, 0x0170=>0x0171, 0x0424=>0x0444, 0x00CC=>0x00EC, 0x0168=>0x0169, 0x039F=>0x03BF, 0x004B=>0x006B, 0x00D2=>0x00F2, 0x00C0=>0x00E0, 0x0414=>0x0434, 0x03A9=>0x03C9, 0x1E6A=>0x1E6B, 0x00C3=>0x00E3, 0x042D=>0x044D, 0x0416=>0x0436, 0x01A0=>0x01A1, 0x010C=>0x010D, 0x011C=>0x011D, 0x00D0=>0x00F0, 0x013B=>0x013C, 0x040F=>0x045F, 0x040A=>0x045A, 0x00C8=>0x00E8, 0x03A5=>0x03C5, 0x0046=>0x0066, 0x00DD=>0x00FD, 0x0043=>0x0063, 0x021A=>0x021B, 0x00CA=>0x00EA, 0x0399=>0x03B9, 0x0179=>0x017A, 0x00CF=>0x00EF, 0x01AF=>0x01B0, 0x0045=>0x0065, 0x039B=>0x03BB, 0x0398=>0x03B8, 0x039C=>0x03BC, 0x040C=>0x045C, 0x041F=>0x043F, 0x042C=>0x044C, 0x00DE=>0x00FE, 0x00D0=>0x00F0, 0x1EF2=>0x1EF3, 0x0048=>0x0068, 0x00CB=>0x00EB, 0x0110=>0x0111, 0x0413=>0x0433, 0x012E=>0x012F, 0x00C6=>0x00E6, 0x0058=>0x0078, 0x0160=>0x0161, 0x016E=>0x016F, 0x0391=>0x03B1, 0x0407=>0x0457, 0x0172=>0x0173, 0x0178=>0x00FF, 0x004F=>0x006F, 0x041B=>0x043B, 0x0395=>0x03B5, 0x0425=>0x0445, 0x0120=>0x0121, 0x017D=>0x017E, 0x017B=>0x017C, 0x0396=>0x03B6, 0x0392=>0x03B2, 0x0388=>0x03AD, 0x1E84=>0x1E85, 0x0174=>0x0175, 0x0051=>0x0071, 0x0417=>0x0437, 0x1E0A=>0x1E0B, 0x0147=>0x0148, 0x0104=>0x0105, 0x0408=>0x0458, 0x014C=>0x014D, 0x00CD=>0x00ED, 0x0059=>0x0079, 0x010A=>0x010B, 0x038F=>0x03CE, 0x0052=>0x0072, 0x0410=>0x0430, 0x0405=>0x0455, 0x0402=>0x0452, 0x0126=>0x0127, 0x0136=>0x0137, 0x012A=>0x012B, 0x038A=>0x03AF, 0x042B=>0x044B, 0x004C=>0x006C, 0x0397=>0x03B7, 0x0124=>0x0125, 0x0218=>0x0219, 0x00DB=>0x00FB, 0x011E=>0x011F, 0x041E=>0x043E, 0x1E40=>0x1E41, 0x039D=>0x03BD, 0x0106=>0x0107, 0x03AB=>0x03CB, 0x0426=>0x0446, 0x00DE=>0x00FE, 0x00C7=>0x00E7, 0x03AA=>0x03CA, 0x0421=>0x0441, 0x0412=>0x0432, 0x010E=>0x010F, 0x00D8=>0x00F8, 0x0057=>0x0077, 0x011A=>0x011B, 0x0054=>0x0074, 0x004A=>0x006A, 0x040B=>0x045B, 0x0406=>0x0456, 0x0102=>0x0103, 0x039B=>0x03BB, 0x00D1=>0x00F1, 0x041D=>0x043D, 0x038C=>0x03CC, 0x00C9=>0x00E9, 0x00D0=>0x00F0, 0x0407=>0x0457, 0x0122=>0x0123, ); } $uni = utf8::to_unicode($str); if ($uni === FALSE) return FALSE; for ($i = 0, $c = count($uni); $i < $c; $i++) { if (isset($UTF8_UPPER_TO_LOWER[$uni[$i]])) { $uni[$i] = $UTF8_UPPER_TO_LOWER[$uni[$i]]; } } return utf8::from_unicode($uni); }./kohana/system/core/utf8/strrpos.php0000644000175000017500000000142011121324570017362 0ustar tokkeetokkee $val) { $str[$key] = utf8::str_ireplace($search, $replace, $val, $count); } return $str; } if (is_array($search)) { $keys = array_keys($search); foreach ($keys as $k) { if (is_array($replace)) { if (array_key_exists($k, $replace)) { $str = utf8::str_ireplace($search[$k], $replace[$k], $str, $count); } else { $str = utf8::str_ireplace($search[$k], '', $str, $count); } } else { $str = utf8::str_ireplace($search[$k], $replace, $str, $count); } } return $str; } $search = utf8::strtolower($search); $str_lower = utf8::strtolower($str); $total_matched_strlen = 0; $i = 0; while (preg_match('/(.*?)'.preg_quote($search, '/').'/s', $str_lower, $matches)) { $matched_strlen = strlen($matches[0]); $str_lower = substr($str_lower, $matched_strlen); $offset = $total_matched_strlen + strlen($matches[1]) + ($i * (strlen($replace) - 1)); $str = substr_replace($str, $replace, $offset, strlen($search)); $total_matched_strlen += $matched_strlen; $i++; } $count += $i; return $str; } ./kohana/system/core/utf8/strlen.php0000644000175000017500000000101511121324570017155 0ustar tokkeetokkee= 0 AND $ord0 <= 127) { return $ord0; } if ( ! isset($chr[1])) { trigger_error('Short sequence - at least 2 bytes expected, only 1 seen', E_USER_WARNING); return FALSE; } $ord1 = ord($chr[1]); if ($ord0 >= 192 AND $ord0 <= 223) { return ($ord0 - 192) * 64 + ($ord1 - 128); } if ( ! isset($chr[2])) { trigger_error('Short sequence - at least 3 bytes expected, only 2 seen', E_USER_WARNING); return FALSE; } $ord2 = ord($chr[2]); if ($ord0 >= 224 AND $ord0 <= 239) { return ($ord0 - 224) * 4096 + ($ord1 - 128) * 64 + ($ord2 - 128); } if ( ! isset($chr[3])) { trigger_error('Short sequence - at least 4 bytes expected, only 3 seen', E_USER_WARNING); return FALSE; } $ord3 = ord($chr[3]); if ($ord0 >= 240 AND $ord0 <= 247) { return ($ord0 - 240) * 262144 + ($ord1 - 128) * 4096 + ($ord2-128) * 64 + ($ord3 - 128); } if ( ! isset($chr[4])) { trigger_error('Short sequence - at least 5 bytes expected, only 4 seen', E_USER_WARNING); return FALSE; } $ord4 = ord($chr[4]); if ($ord0 >= 248 AND $ord0 <= 251) { return ($ord0 - 248) * 16777216 + ($ord1-128) * 262144 + ($ord2 - 128) * 4096 + ($ord3 - 128) * 64 + ($ord4 - 128); } if ( ! isset($chr[5])) { trigger_error('Short sequence - at least 6 bytes expected, only 5 seen', E_USER_WARNING); return FALSE; } if ($ord0 >= 252 AND $ord0 <= 253) { return ($ord0 - 252) * 1073741824 + ($ord1 - 128) * 16777216 + ($ord2 - 128) * 262144 + ($ord3 - 128) * 4096 + ($ord4 - 128) * 64 + (ord($chr[5]) - 128); } if ($ord0 >= 254 AND $ord0 <= 255) { trigger_error('Invalid UTF-8 with surrogate ordinal '.$ord0, E_USER_WARNING); return FALSE; } }./kohana/system/core/utf8/ucfirst.php0000644000175000017500000000071011121324570017326 0ustar tokkeetokkee= $strlen OR ($length < 0 AND $length <= $offset - $strlen)) return ''; // Whole string if ($offset == 0 AND ($length === NULL OR $length >= $strlen)) return $str; // Build regex $regex = '^'; // Create an offset expression if ($offset > 0) { // PCRE repeating quantifiers must be less than 65536, so repeat when necessary $x = (int) ($offset / 65535); $y = (int) ($offset % 65535); $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; $regex .= ($y == 0) ? '' : '.{'.$y.'}'; } // Create a length expression if ($length === NULL) { $regex .= '(.*)'; // No length set, grab it all } // Find length from the left (positive length) elseif ($length > 0) { // Reduce length so that it can't go beyond the end of the string $length = min($strlen - $offset, $length); $x = (int) ($length / 65535); $y = (int) ($length % 65535); $regex .= '('; $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; $regex .= '.{'.$y.'})'; } // Find length from the right (negative length) else { $x = (int) (-$length / 65535); $y = (int) (-$length % 65535); $regex .= '(.*)'; $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; $regex .= '.{'.$y.'}'; } preg_match('/'.$regex.'/us', $str, $matches); return $matches[1]; }./kohana/system/core/utf8/to_unicode.php0000644000175000017500000000734011121324570020005 0ustar tokkeetokkee 0x10FFFF)) { trigger_error('utf8::to_unicode: Illegal sequence or codepoint in UTF-8 at byte '.$i, E_USER_WARNING); return FALSE; } if (0xFEFF != $mUcs4) { // BOM is legal but we don't want to output it $out[] = $mUcs4; } // Initialize UTF-8 cache $mState = 0; $mUcs4 = 0; $mBytes = 1; } } else { // ((0xC0 & (*in) != 0x80) AND (mState != 0)) // Incomplete multi-octet sequence trigger_error('utf8::to_unicode: Incomplete multi-octet sequence in UTF-8 at byte '.$i, E_USER_WARNING); return FALSE; } } } return $out; }./kohana/system/core/Kohana.php0000644000175000017500000012237111207541462016200 0ustar tokkeetokkee 1, 'alert' => 2, 'info' => 3, 'debug' => 4, ); // Internal caches and write status private static $internal_cache = array(); private static $write_cache; private static $internal_cache_path; private static $internal_cache_key; private static $internal_cache_encrypt; /** * Sets up the PHP environment. Adds error/exception handling, output * buffering, and adds an auto-loading method for loading classes. * * This method is run immediately when this file is loaded, and is * benchmarked as environment_setup. * * For security, this function also destroys the $_REQUEST global variable. * Using the proper global (GET, POST, COOKIE, etc) is inherently more secure. * The recommended way to fetch a global variable is using the Input library. * @see http://www.php.net/globals * * @return void */ public static function setup() { static $run; // This function can only be run once if ($run === TRUE) return; // Start the environment setup benchmark Benchmark::start(SYSTEM_BENCHMARK.'_environment_setup'); // Define Kohana error constant define('E_KOHANA', 42); // Define 404 error constant define('E_PAGE_NOT_FOUND', 43); // Define database error constant define('E_DATABASE_ERROR', 44); if (self::$cache_lifetime = self::config('core.internal_cache')) { // Are we using encryption for caches? self::$internal_cache_encrypt = self::config('core.internal_cache_encrypt'); if(self::$internal_cache_encrypt===TRUE) { self::$internal_cache_key = self::config('core.internal_cache_key'); // Be sure the key is of acceptable length for the mcrypt algorithm used self::$internal_cache_key = substr(self::$internal_cache_key, 0, 24); } // Set the directory to be used for the internal cache if ( ! self::$internal_cache_path = self::config('core.internal_cache_path')) { self::$internal_cache_path = APPPATH.'cache/'; } // Load cached configuration and language files self::$internal_cache['configuration'] = self::cache('configuration', self::$cache_lifetime); self::$internal_cache['language'] = self::cache('language', self::$cache_lifetime); // Load cached file paths self::$internal_cache['find_file_paths'] = self::cache('find_file_paths', self::$cache_lifetime); // Enable cache saving Event::add('system.shutdown', array(__CLASS__, 'internal_cache_save')); } // Disable notices and "strict" errors $ER = error_reporting(~E_NOTICE & ~E_STRICT); // Set the user agent self::$user_agent = ( ! empty($_SERVER['HTTP_USER_AGENT']) ? trim($_SERVER['HTTP_USER_AGENT']) : ''); if (function_exists('date_default_timezone_set')) { $timezone = self::config('locale.timezone'); // Set default timezone, due to increased validation of date settings // which cause massive amounts of E_NOTICEs to be generated in PHP 5.2+ date_default_timezone_set(empty($timezone) ? date_default_timezone_get() : $timezone); } // Restore error reporting error_reporting($ER); // Start output buffering ob_start(array(__CLASS__, 'output_buffer')); // Save buffering level self::$buffer_level = ob_get_level(); // Set autoloader spl_autoload_register(array('Kohana', 'auto_load')); // Set error handler set_error_handler(array('Kohana', 'exception_handler')); // Set exception handler set_exception_handler(array('Kohana', 'exception_handler')); // Send default text/html UTF-8 header header('Content-Type: text/html; charset=UTF-8'); // Load locales $locales = self::config('locale.language'); // Make first locale UTF-8 $locales[0] .= '.UTF-8'; // Set locale information self::$locale = setlocale(LC_ALL, $locales); if (self::$configuration['core']['log_threshold'] > 0) { // Set the log directory self::log_directory(self::$configuration['core']['log_directory']); // Enable log writing at shutdown register_shutdown_function(array(__CLASS__, 'log_save')); } // Enable Kohana routing Event::add('system.routing', array('Router', 'find_uri')); Event::add('system.routing', array('Router', 'setup')); // Enable Kohana controller initialization Event::add('system.execute', array('Kohana', 'instance')); // Enable Kohana 404 pages Event::add('system.404', array('Kohana', 'show_404')); // Enable Kohana output handling Event::add('system.shutdown', array('Kohana', 'shutdown')); if (self::config('core.enable_hooks') === TRUE) { // Find all the hook files $hooks = self::list_files('hooks', TRUE); foreach ($hooks as $file) { // Load the hook include $file; } } // Setup is complete, prevent it from being run again $run = TRUE; // Stop the environment setup routine Benchmark::stop(SYSTEM_BENCHMARK.'_environment_setup'); } /** * Loads the controller and initializes it. Runs the pre_controller, * post_controller_constructor, and post_controller events. Triggers * a system.404 event when the route cannot be mapped to a controller. * * This method is benchmarked as controller_setup and controller_execution. * * @return object instance of controller */ public static function & instance() { if (self::$instance === NULL) { Benchmark::start(SYSTEM_BENCHMARK.'_controller_setup'); // Include the Controller file require Router::$controller_path; try { // Start validation of the controller $class = new ReflectionClass(ucfirst(Router::$controller).'_Controller'); } catch (ReflectionException $e) { // Controller does not exist Event::run('system.404'); } if ($class->isAbstract() OR (IN_PRODUCTION AND $class->getConstant('ALLOW_PRODUCTION') == FALSE)) { // Controller is not allowed to run in production Event::run('system.404'); } // Run system.pre_controller Event::run('system.pre_controller'); // Create a new controller instance $controller = $class->newInstance(); // Controller constructor has been executed Event::run('system.post_controller_constructor'); try { // Load the controller method $method = $class->getMethod(Router::$method); // Method exists if (Router::$method[0] === '_') { // Do not allow access to hidden methods Event::run('system.404'); } if ($method->isProtected() or $method->isPrivate()) { // Do not attempt to invoke protected methods throw new ReflectionException('protected controller method'); } // Default arguments $arguments = Router::$arguments; } catch (ReflectionException $e) { // Use __call instead $method = $class->getMethod('__call'); // Use arguments in __call format $arguments = array(Router::$method, Router::$arguments); } // Stop the controller setup benchmark Benchmark::stop(SYSTEM_BENCHMARK.'_controller_setup'); // Start the controller execution benchmark Benchmark::start(SYSTEM_BENCHMARK.'_controller_execution'); // Execute the controller method $method->invokeArgs($controller, $arguments); // Controller method has been executed Event::run('system.post_controller'); // Stop the controller execution benchmark Benchmark::stop(SYSTEM_BENCHMARK.'_controller_execution'); } return self::$instance; } /** * Get all include paths. APPPATH is the first path, followed by module * paths in the order they are configured, follow by the SYSPATH. * * @param boolean re-process the include paths * @return array */ public static function include_paths($process = FALSE) { if ($process === TRUE) { // Add APPPATH as the first path self::$include_paths = array(APPPATH); foreach (self::$configuration['core']['modules'] as $path) { if ($path = str_replace('\\', '/', realpath($path))) { // Add a valid path self::$include_paths[] = $path.'/'; } } // Add SYSPATH as the last path self::$include_paths[] = SYSPATH; } return self::$include_paths; } /** * Get a config item or group. * * @param string item name * @param boolean force a forward slash (/) at the end of the item * @param boolean is the item required? * @return mixed */ public static function config($key, $slash = FALSE, $required = TRUE) { if (self::$configuration === NULL) { // Load core configuration self::$configuration['core'] = self::config_load('core'); // Re-parse the include paths self::include_paths(TRUE); } // Get the group name from the key $group = explode('.', $key, 2); $group = $group[0]; if ( ! isset(self::$configuration[$group])) { // Load the configuration group self::$configuration[$group] = self::config_load($group, $required); } // Get the value of the key string $value = self::key_string(self::$configuration, $key); if ($slash === TRUE AND is_string($value) AND $value !== '') { // Force the value to end with "/" $value = rtrim($value, '/').'/'; } return $value; } /** * Sets a configuration item, if allowed. * * @param string config key string * @param string config value * @return boolean */ public static function config_set($key, $value) { // Do this to make sure that the config array is already loaded self::config($key); if (substr($key, 0, 7) === 'routes.') { // Routes cannot contain sub keys due to possible dots in regex $keys = explode('.', $key, 2); } else { // Convert dot-noted key string to an array $keys = explode('.', $key); } // Used for recursion $conf =& self::$configuration; $last = count($keys) - 1; foreach ($keys as $i => $k) { if ($i === $last) { $conf[$k] = $value; } else { $conf =& $conf[$k]; } } if ($key === 'core.modules') { // Reprocess the include paths self::include_paths(TRUE); } return TRUE; } /** * Load a config file. * * @param string config filename, without extension * @param boolean is the file required? * @return array */ public static function config_load($name, $required = TRUE) { if ($name === 'core') { // Load the application configuration file require APPPATH.'config/config'.EXT; if ( ! isset($config['site_domain'])) { // Invalid config file die('Your Kohana application configuration file is not valid.'); } return $config; } if (isset(self::$internal_cache['configuration'][$name])) return self::$internal_cache['configuration'][$name]; // Load matching configs $configuration = array(); if ($files = self::find_file('config', $name, $required)) { foreach ($files as $file) { require $file; if (isset($config) AND is_array($config)) { // Merge in configuration $configuration = array_merge($configuration, $config); } } } if ( ! isset(self::$write_cache['configuration'])) { // Cache has changed self::$write_cache['configuration'] = TRUE; } return self::$internal_cache['configuration'][$name] = $configuration; } /** * Clears a config group from the cached configuration. * * @param string config group * @return void */ public static function config_clear($group) { // Remove the group from config unset(self::$configuration[$group], self::$internal_cache['configuration'][$group]); if ( ! isset(self::$write_cache['configuration'])) { // Cache has changed self::$write_cache['configuration'] = TRUE; } } /** * Add a new message to the log. * * @param string type of message * @param string message text * @return void */ public static function log($type, $message) { if (self::$log_levels[$type] <= self::$configuration['core']['log_threshold']) { $message = array(date('Y-m-d H:i:s P'), $type, $message); // Run the system.log event Event::run('system.log', $message); self::$log[] = $message; } } /** * Save all currently logged messages. * * @return void */ public static function log_save() { if (empty(self::$log) OR self::$configuration['core']['log_threshold'] < 1) return; // Filename of the log $filename = self::log_directory().date('Y-m-d').'.log'.EXT; if ( ! is_file($filename)) { // Write the SYSPATH checking header file_put_contents($filename, ''.PHP_EOL.PHP_EOL); // Prevent external writes chmod($filename, 0644); } // Messages to write $messages = array(); do { // Load the next mess list ($date, $type, $text) = array_shift(self::$log); // Add a new message line $messages[] = $date.' --- '.$type.': '.$text; } while ( ! empty(self::$log)); // Write messages to log file file_put_contents($filename, implode(PHP_EOL, $messages).PHP_EOL, FILE_APPEND); } /** * Get or set the logging directory. * * @param string new log directory * @return string */ public static function log_directory($dir = NULL) { static $directory; if ( ! empty($dir)) { // Get the directory path $dir = realpath($dir); if (is_dir($dir) AND is_writable($dir)) { // Change the log directory $directory = str_replace('\\', '/', $dir).'/'; } else { // Log directory is invalid throw new Kohana_Exception('core.log_dir_unwritable', $dir); } } return $directory; } /** * Load data from a simple cache file. This should only be used internally, * and is NOT a replacement for the Cache library. * * @param string unique name of cache * @param integer expiration in seconds * @return mixed */ public static function cache($name, $lifetime) { if ($lifetime > 0) { $path = self::$internal_cache_path.'kohana_'.$name; if (is_file($path)) { // Check the file modification time if ((time() - filemtime($path)) < $lifetime) { // Cache is valid! Now, do we need to decrypt it? if(self::$internal_cache_encrypt===TRUE) { $data = file_get_contents($path); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, self::$internal_cache_key, $data, MCRYPT_MODE_ECB, $iv); $cache = unserialize($decrypted_text); // If the key changed, delete the cache file if(!$cache) unlink($path); // If cache is false (as above) return NULL, otherwise, return the cache return ($cache ? $cache : NULL); } else { return unserialize(file_get_contents($path)); } } else { // Cache is invalid, delete it unlink($path); } } } // No cache found return NULL; } /** * Save data to a simple cache file. This should only be used internally, and * is NOT a replacement for the Cache library. * * @param string cache name * @param mixed data to cache * @param integer expiration in seconds * @return boolean */ public static function cache_save($name, $data, $lifetime) { if ($lifetime < 1) return FALSE; $path = self::$internal_cache_path.'kohana_'.$name; if ($data === NULL) { // Delete cache return (is_file($path) and unlink($path)); } else { // Using encryption? Encrypt the data when we write it if(self::$internal_cache_encrypt===TRUE) { // Encrypt and write data to cache file $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); // Serialize and encrypt! $encrypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::$internal_cache_key, serialize($data), MCRYPT_MODE_ECB, $iv); return (bool) file_put_contents($path, $encrypted_text); } else { // Write data to cache file return (bool) file_put_contents($path, serialize($data)); } } } /** * Kohana output handler. Called during ob_clean, ob_flush, and their variants. * * @param string current output buffer * @return string */ public static function output_buffer($output) { // Could be flushing, so send headers first if ( ! Event::has_run('system.send_headers')) { // Run the send_headers event Event::run('system.send_headers'); } self::$output = $output; // Set and return the final output return self::$output; } /** * Closes all open output buffers, either by flushing or cleaning, and stores the Kohana * output buffer for display during shutdown. * * @param boolean disable to clear buffers, rather than flushing * @return void */ public static function close_buffers($flush = TRUE) { if (ob_get_level() >= self::$buffer_level) { // Set the close function $close = ($flush === TRUE) ? 'ob_end_flush' : 'ob_end_clean'; while (ob_get_level() > self::$buffer_level) { // Flush or clean the buffer $close(); } // Store the Kohana output buffer ob_end_clean(); } } /** * Triggers the shutdown of Kohana by closing the output buffer, runs the system.display event. * * @return void */ public static function shutdown() { // Close output buffers self::close_buffers(TRUE); // Run the output event Event::run('system.display', self::$output); // Render the final output self::render(self::$output); } /** * Inserts global Kohana variables into the generated output and prints it. * * @param string final output that will displayed * @return void */ public static function render($output) { if (self::config('core.render_stats') === TRUE) { // Fetch memory usage in MB $memory = function_exists('memory_get_usage') ? (memory_get_usage() / 1024 / 1024) : 0; // Fetch benchmark for page execution time $benchmark = Benchmark::get(SYSTEM_BENCHMARK.'_total_execution'); // Replace the global template variables $output = str_replace( array ( '{kohana_version}', '{kohana_codename}', '{execution_time}', '{memory_usage}', '{included_files}', ), array ( KOHANA_VERSION, KOHANA_CODENAME, $benchmark['time'], number_format($memory, 2).'MB', count(get_included_files()), ), $output ); } if ($level = self::config('core.output_compression') AND ini_get('output_handler') !== 'ob_gzhandler' AND (int) ini_get('zlib.output_compression') === 0) { if ($level < 1 OR $level > 9) { // Normalize the level to be an integer between 1 and 9. This // step must be done to prevent gzencode from triggering an error $level = max(1, min($level, 9)); } if (stripos(@$_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { $compress = 'gzip'; } elseif (stripos(@$_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== FALSE) { $compress = 'deflate'; } } if (isset($compress) AND $level > 0) { switch ($compress) { case 'gzip': // Compress output using gzip $output = gzencode($output, $level); break; case 'deflate': // Compress output using zlib (HTTP deflate) $output = gzdeflate($output, $level); break; } // This header must be sent with compressed content to prevent // browser caches from breaking header('Vary: Accept-Encoding'); // Send the content encoding header header('Content-Encoding: '.$compress); // Sending Content-Length in CGI can result in unexpected behavior if (stripos(PHP_SAPI, 'cgi') === FALSE) { header('Content-Length: '.strlen($output)); } } echo $output; } /** * Displays a 404 page. * * @throws Kohana_404_Exception * @param string URI of page * @param string custom template * @return void */ public static function show_404($page = FALSE, $template = FALSE) { throw new Kohana_404_Exception($page, $template); } /** * Dual-purpose PHP error and exception handler. Uses the kohana_error_page * view to display the message. * * @param integer|object exception object or error code * @param string error message * @param string filename * @param integer line number * @return void */ public static function exception_handler($exception, $message = NULL, $file = NULL, $line = NULL) { try { // PHP errors have 5 args, always $PHP_ERROR = (func_num_args() === 5); // Test to see if errors should be displayed if ($PHP_ERROR AND (error_reporting() & $exception) === 0) return; // This is useful for hooks to determine if a page has an error self::$has_error = TRUE; // Error handling will use exactly 5 args, every time if ($PHP_ERROR) { $code = $exception; $type = 'PHP Error'; $template = 'kohana_error_page'; } else { $code = $exception->getCode(); $type = get_class($exception); $message = $exception->getMessage(); $file = $exception->getFile(); $line = $exception->getLine(); $template = ($exception instanceof Kohana_Exception) ? $exception->getTemplate() : 'kohana_error_page'; } if (is_numeric($code)) { $codes = self::lang('errors'); if ( ! empty($codes[$code])) { list($level, $error, $description) = $codes[$code]; } else { $level = 1; $error = $PHP_ERROR ? 'Unknown Error' : get_class($exception); $description = ''; } } else { // Custom error message, this will never be logged $level = 5; $error = $code; $description = ''; } // Remove the DOCROOT from the path, as a security precaution $file = str_replace('\\', '/', realpath($file)); $file = preg_replace('|^'.preg_quote(DOCROOT).'|', '', $file); if ($level <= self::$configuration['core']['log_threshold']) { // Log the error self::log('error', self::lang('core.uncaught_exception', $type, $message, $file, $line)); } if ($PHP_ERROR) { $description = self::lang('errors.'.E_RECOVERABLE_ERROR); $description = is_array($description) ? $description[2] : ''; if ( ! headers_sent()) { // Send the 500 header header('HTTP/1.1 500 Internal Server Error'); } } else { if (method_exists($exception, 'sendHeaders') AND ! headers_sent()) { // Send the headers if they have not already been sent $exception->sendHeaders(); } } // Close all output buffers except for Kohana while (ob_get_level() > self::$buffer_level) { ob_end_clean(); } // Test if display_errors is on if (self::$configuration['core']['display_errors'] === TRUE) { if ( ! IN_PRODUCTION AND $line != FALSE) { // Remove the first entry of debug_backtrace(), it is the exception_handler call $trace = $PHP_ERROR ? array_slice(debug_backtrace(), 1) : $exception->getTrace(); // Beautify backtrace $trace = self::backtrace($trace); } // Load the error require self::find_file('views', empty($template) ? 'kohana_error_page' : $template); } else { // Get the i18n messages $error = self::lang('core.generic_error'); $message = self::lang('core.errors_disabled', url::site(), url::site(Router::$current_uri)); // Load the errors_disabled view require self::find_file('views', 'kohana_error_disabled'); } if ( ! Event::has_run('system.shutdown')) { // Run the shutdown even to ensure a clean exit Event::run('system.shutdown'); } // Turn off error reporting error_reporting(0); exit; } catch (Exception $e) { if (IN_PRODUCTION) { die('Fatal Error'); } else { die('Fatal Error: '.$e->getMessage().' File: '.$e->getFile().' Line: '.$e->getLine()); } } } /** * Provides class auto-loading. * * @throws Kohana_Exception * @param string name of class * @return bool */ public static function auto_load($class) { if (class_exists($class, FALSE)) return TRUE; if (($suffix = strrpos($class, '_')) > 0) { // Find the class suffix $suffix = substr($class, $suffix + 1); } else { // No suffix $suffix = FALSE; } if ($suffix === 'Core') { $type = 'libraries'; $file = substr($class, 0, -5); } elseif ($suffix === 'Controller') { $type = 'controllers'; // Lowercase filename $file = strtolower(substr($class, 0, -11)); } elseif ($suffix === 'Model') { $type = 'models'; // Lowercase filename $file = strtolower(substr($class, 0, -6)); } elseif ($suffix === 'Driver') { $type = 'libraries/drivers'; $file = str_replace('_', '/', substr($class, 0, -7)); } else { // This could be either a library or a helper, but libraries must // always be capitalized, so we check if the first character is // uppercase. If it is, we are loading a library, not a helper. $type = ($class[0] < 'a') ? 'libraries' : 'helpers'; $file = $class; } if ($filename = self::find_file($type, $file)) { // Load the class require $filename; } else { // The class could not be found return FALSE; } if ($filename = self::find_file($type, self::$configuration['core']['extension_prefix'].$class)) { // Load the class extension require $filename; } elseif ($suffix !== 'Core' AND class_exists($class.'_Core', FALSE)) { // Class extension to be evaluated $extension = 'class '.$class.' extends '.$class.'_Core { }'; // Start class analysis $core = new ReflectionClass($class.'_Core'); if ($core->isAbstract()) { // Make the extension abstract $extension = 'abstract '.$extension; } // Transparent class extensions are handled using eval. This is // a disgusting hack, but it gets the job done. eval($extension); } return TRUE; } /** * Find a resource file in a given directory. Files will be located according * to the order of the include paths. Configuration and i18n files will be * returned in reverse order. * * @throws Kohana_Exception if file is required and not found * @param string directory to search in * @param string filename to look for (without extension) * @param boolean file required * @param string file extension * @return array if the type is config, i18n or l10n * @return string if the file is found * @return FALSE if the file is not found */ public static function find_file($directory, $filename, $required = FALSE, $ext = FALSE) { // NOTE: This test MUST be not be a strict comparison (===), or empty // extensions will be allowed! if ($ext == '') { // Use the default extension $ext = EXT; } else { // Add a period before the extension $ext = '.'.$ext; } // Search path $search = $directory.'/'.$filename.$ext; if (isset(self::$internal_cache['find_file_paths'][$search])) return self::$internal_cache['find_file_paths'][$search]; // Load include paths $paths = self::$include_paths; // Nothing found, yet $found = NULL; if ($directory === 'config' OR $directory === 'i18n') { // Search in reverse, for merging $paths = array_reverse($paths); foreach ($paths as $path) { if (is_file($path.$search)) { // A matching file has been found $found[] = $path.$search; } } } else { foreach ($paths as $path) { if (is_file($path.$search)) { // A matching file has been found $found = $path.$search; // Stop searching break; } } } if ($found === NULL) { if ($required === TRUE) { // Directory i18n key $directory = 'core.'.inflector::singular($directory); // If the file is required, throw an exception throw new Kohana_Exception('core.resource_not_found', self::lang($directory), $filename); } else { // Nothing was found, return FALSE $found = FALSE; } } if ( ! isset(self::$write_cache['find_file_paths'])) { // Write cache at shutdown self::$write_cache['find_file_paths'] = TRUE; } return self::$internal_cache['find_file_paths'][$search] = $found; } /** * Lists all files and directories in a resource path. * * @param string directory to search * @param boolean list all files to the maximum depth? * @param string full path to search (used for recursion, *never* set this manually) * @return array filenames and directories */ public static function list_files($directory, $recursive = FALSE, $path = FALSE) { $files = array(); if ($path === FALSE) { $paths = array_reverse(self::include_paths()); foreach ($paths as $path) { // Recursively get and merge all files $files = array_merge($files, self::list_files($directory, $recursive, $path.$directory)); } } else { $path = rtrim($path, '/').'/'; if (is_readable($path)) { $items = (array) glob($path.'*'); if ( ! empty($items)) { foreach ($items as $index => $item) { $files[] = $item = str_replace('\\', '/', $item); // Handle recursion if (is_dir($item) AND $recursive == TRUE) { // Filename should only be the basename $item = pathinfo($item, PATHINFO_BASENAME); // Append sub-directory search $files = array_merge($files, self::list_files($directory, TRUE, $path.$item)); } } } } } return $files; } /** * Fetch an i18n language item. * * @param string language key to fetch * @param array additional information to insert into the line * @return string i18n language string, or the requested key if the i18n item is not found */ public static function lang($key, $args = array()) { // Extract the main group from the key $group = explode('.', $key, 2); $group = $group[0]; // Get locale name $locale = self::config('locale.language.0'); if ( ! isset(self::$internal_cache['language'][$locale][$group])) { // Messages for this group $messages = array(); if ($files = self::find_file('i18n', $locale.'/'.$group)) { foreach ($files as $file) { include $file; // Merge in configuration if ( ! empty($lang) AND is_array($lang)) { foreach ($lang as $k => $v) { $messages[$k] = $v; } } } } if ( ! isset(self::$write_cache['language'])) { // Write language cache self::$write_cache['language'] = TRUE; } self::$internal_cache['language'][$locale][$group] = $messages; } // Get the line from cache $line = self::key_string(self::$internal_cache['language'][$locale], $key); if ($line === NULL) { self::log('error', 'Missing i18n entry '.$key.' for language '.$locale); // Return the key string as fallback return $key; } if (is_string($line) AND func_num_args() > 1) { $args = array_slice(func_get_args(), 1); // Add the arguments into the line $line = vsprintf($line, is_array($args[0]) ? $args[0] : $args); } return $line; } /** * Returns the value of a key, defined by a 'dot-noted' string, from an array. * * @param array array to search * @param string dot-noted string: foo.bar.baz * @return string if the key is found * @return void if the key is not found */ public static function key_string($array, $keys) { if (empty($array)) return NULL; // Prepare for loop $keys = explode('.', $keys); do { // Get the next key $key = array_shift($keys); if (isset($array[$key])) { if (is_array($array[$key]) AND ! empty($keys)) { // Dig down to prepare the next loop $array = $array[$key]; } else { // Requested key was found return $array[$key]; } } else { // Requested key is not set break; } } while ( ! empty($keys)); return NULL; } /** * Sets values in an array by using a 'dot-noted' string. * * @param array array to set keys in (reference) * @param string dot-noted string: foo.bar.baz * @return mixed fill value for the key * @return void */ public static function key_string_set( & $array, $keys, $fill = NULL) { if (is_object($array) AND ($array instanceof ArrayObject)) { // Copy the array $array_copy = $array->getArrayCopy(); // Is an object $array_object = TRUE; } else { if ( ! is_array($array)) { // Must always be an array $array = (array) $array; } // Copy is a reference to the array $array_copy =& $array; } if (empty($keys)) return $array; // Create keys $keys = explode('.', $keys); // Create reference to the array $row =& $array_copy; for ($i = 0, $end = count($keys) - 1; $i <= $end; $i++) { // Get the current key $key = $keys[$i]; if ( ! isset($row[$key])) { if (isset($keys[$i + 1])) { // Make the value an array $row[$key] = array(); } else { // Add the fill key $row[$key] = $fill; } } elseif (isset($keys[$i + 1])) { // Make the value an array $row[$key] = (array) $row[$key]; } // Go down a level, creating a new row reference $row =& $row[$key]; } if (isset($array_object)) { // Swap the array back in $array->exchangeArray($array_copy); } } /** * Retrieves current user agent information: * keys: browser, version, platform, mobile, robot, referrer, languages, charsets * tests: is_browser, is_mobile, is_robot, accept_lang, accept_charset * * @param string key or test name * @param string used with "accept" tests: user_agent(accept_lang, en) * @return array languages and charsets * @return string all other keys * @return boolean all tests */ public static function user_agent($key = 'agent', $compare = NULL) { static $info; // Return the raw string if ($key === 'agent') return self::$user_agent; if ($info === NULL) { // Parse the user agent and extract basic information $agents = self::config('user_agents'); foreach ($agents as $type => $data) { foreach ($data as $agent => $name) { if (stripos(self::$user_agent, $agent) !== FALSE) { if ($type === 'browser' AND preg_match('|'.preg_quote($agent).'[^0-9.]*+([0-9.][0-9.a-z]*)|i', self::$user_agent, $match)) { // Set the browser version $info['version'] = $match[1]; } // Set the agent name $info[$type] = $name; break; } } } } if (empty($info[$key])) { switch ($key) { case 'is_robot': case 'is_browser': case 'is_mobile': // A boolean result $return = ! empty($info[substr($key, 3)]); break; case 'languages': $return = array(); if ( ! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { if (preg_match_all('/[-a-z]{2,}/', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])), $matches)) { // Found a result $return = $matches[0]; } } break; case 'charsets': $return = array(); if ( ! empty($_SERVER['HTTP_ACCEPT_CHARSET'])) { if (preg_match_all('/[-a-z0-9]{2,}/', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])), $matches)) { // Found a result $return = $matches[0]; } } break; case 'referrer': if ( ! empty($_SERVER['HTTP_REFERER'])) { // Found a result $return = trim($_SERVER['HTTP_REFERER']); } break; } // Cache the return value isset($return) and $info[$key] = $return; } if ( ! empty($compare)) { // The comparison must always be lowercase $compare = strtolower($compare); switch ($key) { case 'accept_lang': // Check if the lange is accepted return in_array($compare, self::user_agent('languages')); break; case 'accept_charset': // Check if the charset is accepted return in_array($compare, self::user_agent('charsets')); break; default: // Invalid comparison return FALSE; break; } } // Return the key, if set return isset($info[$key]) ? $info[$key] : NULL; } /** * Quick debugging of any variable. Any number of parameters can be set. * * @return string */ public static function debug() { if (func_num_args() === 0) return; // Get params $params = func_get_args(); $output = array(); foreach ($params as $var) { $output[] = '
('.gettype($var).') '.html::specialchars(print_r($var, TRUE)).'
'; } return implode("\n", $output); } /** * Displays nice backtrace information. * @see http://php.net/debug_backtrace * * @param array backtrace generated by an exception or debug_backtrace * @return string */ public static function backtrace($trace) { if ( ! is_array($trace)) return; // Final output $output = array(); foreach ($trace as $entry) { $temp = '
  • '; if (isset($entry['file'])) { $temp .= self::lang('core.error_file_line', preg_replace('!^'.preg_quote(DOCROOT).'!', '', $entry['file']), $entry['line']); } $temp .= '
    ';
    
    			if (isset($entry['class']))
    			{
    				// Add class and call type
    				$temp .= $entry['class'].$entry['type'];
    			}
    
    			// Add function
    			$temp .= $entry['function'].'( ';
    
    			// Add function args
    			if (isset($entry['args']) AND is_array($entry['args']))
    			{
    				// Separator starts as nothing
    				$sep = '';
    
    				while ($arg = array_shift($entry['args']))
    				{
    					if (is_string($arg) AND is_file($arg))
    					{
    						// Remove docroot from filename
    						$arg = preg_replace('!^'.preg_quote(DOCROOT).'!', '', $arg);
    					}
    
    					$temp .= $sep.html::specialchars(print_r($arg, TRUE));
    
    					// Change separator to a comma
    					$sep = ', ';
    				}
    			}
    
    			$temp .= ' )
  • '; $output[] = $temp; } return '
      '.implode("\n", $output).'
    '; } /** * Saves the internal caches: configuration, include paths, etc. * * @return boolean */ public static function internal_cache_save() { if ( ! is_array(self::$write_cache)) return FALSE; // Get internal cache names $caches = array_keys(self::$write_cache); // Nothing written $written = FALSE; foreach ($caches as $cache) { if (isset(self::$internal_cache[$cache])) { // Write the cache file self::cache_save($cache, self::$internal_cache[$cache], self::$configuration['core']['internal_cache']); // A cache has been written $written = TRUE; } } return $written; } } // End Kohana /** * Creates a generic i18n exception. */ class Kohana_Exception extends Exception { // Template file protected $template = 'kohana_error_page'; // Header protected $header = FALSE; // Error code protected $code = E_KOHANA; /** * Set exception message. * * @param string i18n language key for the message * @param array addition line parameters */ public function __construct($error) { $args = array_slice(func_get_args(), 1); // Fetch the error message $message = Kohana::lang($error, $args); if ($message === $error OR empty($message)) { // Unable to locate the message for the error $message = 'Unknown Exception: '.$error; } // Sets $this->message the proper way parent::__construct($message); } /** * Magic method for converting an object to a string. * * @return string i18n message */ public function __toString() { return (string) $this->message; } /** * Fetch the template name. * * @return string */ public function getTemplate() { return $this->template; } /** * Sends an Internal Server Error header. * * @return void */ public function sendHeaders() { // Send the 500 header header('HTTP/1.1 500 Internal Server Error'); } } // End Kohana Exception /** * Creates a custom exception. */ class Kohana_User_Exception extends Kohana_Exception { /** * Set exception title and message. * * @param string exception title string * @param string exception message string * @param string custom error template */ public function __construct($title, $message, $template = FALSE) { Exception::__construct($message); $this->code = $title; if ($template !== FALSE) { $this->template = $template; } } } // End Kohana PHP Exception /** * Creates a Page Not Found exception. */ class Kohana_404_Exception extends Kohana_Exception { protected $code = E_PAGE_NOT_FOUND; /** * Set internal properties. * * @param string URL of page * @param string custom error template */ public function __construct($page = FALSE, $template = FALSE) { if ($page === FALSE) { // Construct the page URI using Router properties $page = Router::$current_uri.Router::$url_suffix.Router::$query_string; } Exception::__construct(Kohana::lang('core.page_not_found', $page)); $this->template = $template; } /** * Sends "File Not Found" headers, to emulate server behavior. * * @return void */ public function sendHeaders() { // Send the 404 header header('HTTP/1.1 404 File Not Found'); } } // End Kohana 404 Exception ./kohana/system/fonts/0000755000175000017500000000000011263472440014462 5ustar tokkeetokkee./kohana/system/fonts/DejaVuSerif.ttf0000644000175000017500000112474011036111000017335 0ustar tokkeetokkee0FFTML <GDEFcmgXGPOSKL&\0 GSUB`O12OS/2i7$VcmapI^7|vcvt 3FfpgmHgaspI glyf~I Uhead'>$6hheaP$hmtx\Gt-(kern]bd̜loca-,maxpE name|!!NpostY:$j\prepuy^iVaVa      6 7 A B I DFLTcyrl*grekFlatnVMKD SRB R AZE RCRT RGAG RISM RKAZ RKRK RKSM RLSM RNSM RSKS RSSM RTAT RTRK Rkernmarkmkmk 6 8>DJPV\bhntzdfGffllfGS  7 7 9 9 ; ?  7 A  $*06<D  "(.4:@FLRX^djpv| $*06<BHNTZ`flrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv| $*06<BHNTZ`flrx~      & , 2 8 > D J P V \ b h n t z     " ( . 4 : @ F L R X ^ d j p v |     $ * 0 6 < B H N T Z ` f l r x ~      & , 2 8 > D J P V \ b h n t z     " ( . 4 : @ F L R X ^ d j p v | ==XX}}RIIggHHHH9D9HhDh 9^D^5V\D\RHHHHvRHHHDRDhDhDHR9DR(DHD9HDRBDBoDoBDB<D  ?@BBBHJCLLFPPGRRHUUI_aJijMnnOuyPUVXYZ^`hiAAjGGkBBlDEmNNoQQpSTqVVsXXt\\u^^vaawhixknzqq~stvvxx||~`t + B C E H"- 5 7 A6A $*06<BHNTZ`flrx~ &,28>DJPV\bhntzDDDDDDDDDDDDDDDDDD|rrDrDrDDDDDDDDDDDD8>4)?k&&&&&&NuuuuNu&ak}}Y N}}}KaaDK&////&K&aaaakaaaaaaakDDD2uDDD}DDDDDDDD}DKkNNYuNNuYYuuuu&aaNNNaa<NNNNNN)& K&Y N2&aaaakaaaaaaaaaaknUaV}U}//99999S$$%%&&''(())**-- .. // 11 22 33445566778899::;;<<==IINNRRUUYZ[[\\  ! "#    ""&&$0077%::??ii&sszz&~~'(  ; ;$$&&**--22 66 77 88 99 ::;;<<DDFFGGHHIIJJLLMMOOPQRRSSTTUUVVWWXXYY ZZ![["\\#]]$% &'&()*+*,-,./00121212))3333+333 455  !!6"" ##6$$7%%8&& ''800 11/66977:88;999::233783;00911<22933<44955<rs9{{=~~>=  8f$%&'()*-./123456789:;<=INRUYZ[\  "&07:?isz~ ; JDFLTcyrl*grekTlatndMKD SRB XAZE dCRT dGAG dISM pKAZ dKRK dKSM pLSM pNSM pSKS pSSM pTAT dTRK ~TUR ccmp&dlig,liga2liga:locl@loclF"*2:BJ@$BlZZZhz LMLL11 !gg"W$=IIKKLMOO      ""$$&&((**,,..0022446688:;==??AAHHRRTTVVLL11ggqo < 0 & IO O I OI (  IL L LI   W WVA : 8 ; 9 > ? 7 @ < A   B C E F G LML1g33fR  PfEd@ m`,d l, d8JJ~!BE?COXauz~_eku .<[ex{-KcEMWY[]}  & 1 : > I d q !! !!!!!"!$!'!+!I!K!""" " "" "-"="C"H"U"a"e"""## ###!#%#(#}##$#&&<&G&g&o'''))**/+,l,w... $EPCOXatz~bjr,0>bw{0Ph HPY[]_  * 9 < G _ j t !! ! !!!!"!$!&!*!<82 dZUPFE@432,zxvtrqponlkjhgedcb_XWO:532!|xtmcaEA,R2B;5ߺnfܱ   ~b|!$BEEPiptuyz?CCOOXXaatuzz~~_.bejkru*W XZ[],.`0<c>[pbewx{{-0KPchLPblnrz EHMPWYY[[]]_}!0>DWZ c  &y * 1 9 : < > G I _ d j q t       !!! ! ! !!!!!!!!"!"!$!$!&!'!*!+!<!I!K!K!S!!""""" " " """" "#"-"8"="B"C"H"H"P"U"`"a"d"e""""""#### ##### #!#%#%#(#(#}#}####$#$#%&&8&< &?&G &`&g &i&o '' !'' "'' #') %)) * * */*/ ++ ,g,l ,u,w .. ....   89 ;> @D FF JP Rk  ,   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ardeixpkvjsgw l|cnTm}bvw~z{: y|p~qz{|z}q sLjq{)j/s3fbwPP;f=fRBsJ}s jjb\jjjj jj)R`fX{Hjj``'''Djb{sj\)'\jj=fHf JJ }T{3`}TjNNs, %Id@QX Y!-,%Id@QX Y!-,  P y PXY%%# P y PXY%-,KPX EDY!-,%E`D-,KSX%%EDY!!-,ED-ff@ ]/10!%!!fsr)! m@a ` b  10@9pp``__OO??]@ q%4632#"&!#5L97NN79LD{h8NN87NM@ b1<20#!#h++W@6 cc       991/<22<2222220!! !3!!!!#!#!5!!5!T54&'3.54673#.'#.qwvrdgripbldeYm vd`D n_VxiXPj!H@  1)t 7#5!#3RWWfoiҙ30CsqngDlEO ٬cSeNfGXVe=yB""kpqZ=yqPikk`hb10#h+ @  q 21990&7󚆆mcdmbjj} @ q 2199056'5bj\]jbm''!LI@+   i   <2<29912290 %#'-73%yL LyL\ \նv}vw} !@r    <<1/<<0!!#!5!1Ϡ1Ϣ11J@   91990>=3J^XE%ZZZs10!!Zs 8  KQX <<<32!53!5>54&#"pkh ou=Ŗq 9< mĖ*M@+ etee)te&ei`+  #) #  +9999190>32!"&'332654&+532654&#"#u^unp _2 p,. ׫23"f~?@%d d M ss i  <<91/<<290KSXY"/ ] ]K TK T[K T[KT[X@878Y@ 8I( 68 GH ]] !53!53!!3Xtj%m ky@%xetee wb `     9190K TK T[KT[X  @878YKTKT[X @ 878Y@& //]]!>32!"&'332654&#"#T4Vgqq Z5VդT$$23"@C %c@" eely#ei`&    &190@%   ) ) NN N!]%2654&#">32#"!2#.#"DlB%O[q n¾FȽKJy^ejr@Mwb  91/90KSXY"K TX  @878YKTX @ 878Y] #!#!-Nuo1\ />@"$e ee*i`0$ ' -'! 09919904&#"3264&#"326#"$5467.54632)|{{|lv͟ҟϴ%]@$ elyee i`& #  &190@ !"AAA ]#"5432!"&'5332"32654&CmO[p m¾KJ xRel%"ɽy @a a ` <21074632#"&4632#"&M88ML99LM89LL98Mh8NN88MM8ML99LMJy"@a  1990>=34632#"&J^X?M88MM88ME%Z 8MN78MM^@29190 5Ѧf@rr<210!!!!^@<919055//y "<@ a ! ei `#! #10%4632#"&>32#>54&#"#hM97NN79MjT{~rah8NN87NMc/.ֶ3H+ʜ{o@Mm@;BAKE'N$ KE($ Ez Kzz@|$z+ |z+7N'(HA ==1N22991<9999990%#"&5463253>54&'&$#"3267#"$'&5476$3254&#"326;]گ];DCjϳZVd_m+`5l}YawLNsyzrRPPR%oT&']gw}LLF]]{GF~b|i}@Qdddd  Mo ob    91/<290KSX22Y"(]@((( (,+]]! 5333!53!3$H}}jkjjHjqd$E@'o obo ~ $ !$ !%229991/2290%!2654&#!532654&+53#5!2!+w埙jj~}jkäs8@ndn i`&' %10o]#"&'&5!2#.#"3267BapmIzq%0dap\@Aq=@ ob o  $ !299991/220@ 0O]%3 !#53#5! !#7ܺwRPjL66Hjkvtq3R@*  obo ~ $ !2221/00O]353#5!#5!!53#5!!53q{R{{{jk q7F@'  obo ~  $ !2221/20353#5!#5!!53#5!3q{>{{jk ~jsG@"  o ndni` &%1990 0 O ].# 3267!5!# !2#q]ͯiY88kMM_b;<q^@.  o bo ~ $ $$ $!2222221/<2<20@ p]353#5!#!#5!#3!53!3qGGjkkkkjj~jq 7@ obo $$! 221/220@ 0 P ` p ]%3!53#5!#GjjjkkTVm@ dn o b $ 12990K TX@878Y0]KTKT[X@878Y533265#5!##"&rXXw^qGca9kk"q(@Dd  dM  o bo $$!2<2991/<22<290KSX2Y"p]@  $ '6 F HW YYhzz    * % % & &'(: 6 6F F @ F @ F @ F@B@@@@@S X X U UPXXi i e efb```y  y  v vvyyC]]353#5!##5!# 3!3qGͪ3 HapmmpbEnpbNQJKQkdappbcVobcqC@!o ob o # $ !2299991/220_]!2654&#!53#5!2#!3wjkjs"@@nn i`#  %#99999190_$o$$] 47>3 ;.'2#"`jmpbE6mdapbcVm:C@QJKQq7$@H  Mo #ob o#   $ $ !%229999991/<2229990KSX9Y"3!.+3!53#5!2%!2654&#!Fe(ٶCpbz'[REjۊQjjkп&)'@B#"$!   M !dn'dni'`* !)$)*9999190KSX99Y"+]@ +0+P+p++]KTKT[KT[X*@**878Y@t( ) ) ) )) )!)"8 9 : : : 99:: :!9"8#I I J I HI I!I"Y Y Y Y Y Y!Y"j l l l k kl l!l"i#{ { { { y{{ {!{"y#7++]]732654&/.54$32#.#"!"&sq֯hq|ɹ˭{HTlt7;A©-+ž{kz<7=2B{@  ob o $ $1/2<20K TX@878Y]K TK T[X@878Y@ /`]!53!#!#5!3I{.{Ij` j`bn@%   ob`$$ $$!1<299990`]KTKT[X@878Y]#5!#326#5!#! H廿jkkkkS@9dd  M o b   91/<290KSX22Y"]@"   (* * ']] #5!###5!f jzkkjkk 3@[d d    dd     M  o b 91/<<<290KSX22Y"]KTX@878Y@   %) $?< 5L FX\ Tm d~ t        &&&&)$ &546 4 7 IIEBFE G D H[[XW[X Y [_______feeehgff g g f d ehjjhusvuu v u w t y||yV]]!# ##5!# 3 #5!#y!7TZ9Bjkk9\kk @gdddd   M o bo  91/<2<290KSX2222Y"]]K TK T[KT[X@878Y@ )(%&65EFVUjicdyz        &&'& ()%%$$/6777 8997FCGGEE KIFIIUSSSSWSV V S [[WYYedeedede e d kllke``eee`xzzzz{yx x y {~||@{{}yuxxur]] 3!53 #5!# #5!# 3!53LP@Iuנjjskkkk?jjZ/@E  d d    M  o bo    $$999991/2<290KSX22Y"]]K TX@878YK TK T[KT[X@878Y@d 6 E [Zf xw       **/::7 8 ? 9 ? 9 ? ???F I V Y [ [ i h o h o `vvx x x )]]!53#5!# #5!#33+uu?jkk\kk,j\? m@#  M b     991/0KSXY"]@  O ]]35!#!!53\{^LzHZH$@ssq10!!!!/jjB*@Mb/9910KSXY"#mo@ssq9910!5!!5o/jNj@ b91290 # #}-m/10!5mPPsdv10K TKT[X@878YKTK T[K T[KT[KT[KT[X@878YKTX@878Y #oudxfD (~@/!  z!#&` z!-" ,' "*)22991/99990@$*o*x(*z( ]]5#"3263!5#"&5463!54&#"#5>32/퉆ts=kn_`VNvzojsJFIydb));!G@%!zqz` 5,'0"2221/990#]7#5!>32#"&'!532654&#"i6{{6ij@jmd__djuʿfD5@  `- *10o]#"532#.#"3267'ްeekw?31/0|}f!O@& zqz` ,',5 *"<<1/990@ ####]%3!5#"5432#5!54&#"32636{{6fjjd_76_d)jifVDN@z  ` *2190@ @]]!32673#"5432.#"V碞y,}34ױJqq@& zq z - '6,0<2<91/222990]KTX@878Y``?]]#.#"!!3!53#5354632qaSOgT)CBKNqkjjRkf9D,f@3, )z) #`- -, '5&7*-22199990@ ....]#"&'53326=#"54325!4&#"32653iX`}6{{6h[&&h`ďd_76_dkJo@,  zqz =,,' :,',021/<299990/]KTX@878Y353#5!>323!534&#"3Th3l_zj@jVlnjjÏjJ` I@ z z , ',021/20]KTX@878Y4632#"&3!53#5!C/.CB//C갰hq.DD./BB(jjRk;9 i@"   z-6' , 01990/ ` p ]KTX@878Yss]4632#"&#5!#"&'533265C/.CA0/C-fëH>_UR[Wq.DD./BBzkq!!`Z{;@X    >>M z zqz   ,',0<9991/<2290KSX9Y"]@  &))899HVWggghw           ( ( ( &)-**+,)/6 6 6959?F D D DEY X X WVVVh f f gegaabef`x x x zxxvz T]])53#5!#5!# 3!533Ji‘j@j kkjj;R @@zqz,',0 21/20 ]KTX  @878Y%3!53#5!鱱ijjj@jJ^D0@A  +'z)%! z.#  = ", , '?=',?(,* '$,&01291/<<222990@ ?2_2o222]KTX111@878Y@/ / // 2 ]>323!534&#"3!534&#"3!53#5!>32%5n`o{`o{h3d|Xuwjj%jj,jjTijp{JDp@.  zz =,,' :,',021/<290/]KTX@878Y353#5!>323!534&#"3Th3l`yjRklnjjÑjfjD +@  `D *10 o]%2654&#""5432hFc32;VD #U@,  z"z ` $,5!,' 0$22212990%%]32654&#"'#5!>32#"&'3!53i6{{6Hiʵkd__dkkfVD#S@+# zz `$,',5 *$2<<12990%%]3!53#"54325!4&#"326536{{6hkkd_76_dkJD@" z z -,' ,021/2990@8/@@@@@@D@@@  ]]KTX@878Y#.#"3!53#5!>32jNKͦh6z-c)ONjjTioksD)@A#"$!>  > M !''`* !->'F$-E*9999190KSX99Y" +]@X'' '!'"'#Z Z Z Z ZZ Z!Z"X# !"# !"# !"#@++]]75332654&/.54632#.#"#"&sj|_{ֽTcjutwZg;wv]YFV1-,f,*gtRRCQ*-/o,;'qh@  z`, '/<291<2990K TX@878Y@&&/ ]#533!!32673#"&5ݢZ4FHBkJk]LU_7'u@"   z `,',:,' /<1/<2299990K TX@878Y]KTX@878Y!3!5#"&5#5!3265#X3k__z'Cjjo9k'@9    >>M z    91/<290KSX22Y" ]@H' Scv   %*** * *80HG GWXghvvwxx x x ]]!#5!# #5!#yy++wykk%kkD!'@[   >  >> > M  z  91/<<<290KSX22Y"`]@ $, (3= 9DJ IW ^di itz z          &() & # **%&:;??????:; 9 ; 8 8:9FEEE F F I H HHHHFQPPPPPPPPP R T XVSPb``dd````` b d fb`uxy}}yyyz@y v q u v vvwwwtw x]] #5!## ##5!#vęw'kkDkk->j'@g >  >>>Mz z    91/<2<290KSX2222Y"K TKT[X@878Y@ %*GIWWYXffhhyy       (),,% % ( '&&&))'9?9?HIGFGZYYYWY WUVVVVjjjgh h h gefx||||y wttttxvuuu []]#5!# 3!53 3!53 #5!#TߏLl%3kkw7jj>jjkk9'@Y  > >M z   - 9991<29990KSX229Y"]@ZYix))* * ''&XSUPUPSV V hd``dvwx~~tty x x yuuvvvv(]]7#5!# #5!##"&'53326Fsy++w2zo/c2^9<7Cñkk%kkT|[D;=R' j@" >> M z z  - - 991/0KSXY"K TK T[X@878Yif ]35!#!!53RjffBkVf#V$^@0 !   ! s ssq! %$ '%<29991/999999990#"&54&+5326546;#"3>l==l>DVdbVititݓhXឈ"XG10#$[@/   ss#sq%' %<29991/9999999903265467.54&+532;#"+FUbcUF?l>>l?W"Whtitݔ'>@    919999990#"/&'&#"5>32326d]` _\Yd^` a\'XTB 9IMWQB:J! !@ ai   1/04632#"&53L97NN79LC{Dm8MN78NN5PL"I@'  `# -" #222212<2<0%#&5473#.'>7u#dd\PjsdZt,+ .'{ i ldL@(  seis   I <2291/22990#.#"!!!53!53#534632Ni q`ydt%UK_ekjRk'h\#/o@= -'! 0 -!-'!0 *$0* $ $*099999991999999907'#"&''7.5467'7>324&#"326^+))-`8wE@}=_))*,_8xEBzQrpqq^z@Fw9^,*(ppr$K@]dd  M s s sb"s# % #I! I%<<9999991/22<22<290KSX22Y"]@6iih     89969::9F K M MKKJ@@BBFIXVYYYYge g g gffgjhohojjhu y||yzF]]!53!5!5'!5!#5!# #5!#!!!!3hlR)WSGmjoiAikk\kkizTij@ G<210##  \= Ak@;39 (',o$ o?i$B3/9)'J54&#.#"#"&'532654'&'.5467.54632{D7k :;\hXds }irNI̭ZM\lkhy ~vmROȦN.S5&`9KHSaSamc_~,/~[PQbTq zc^1~O77! z@   1<20K TK T[KT[KT[X@878YK TK T[KT[X@878YK TX878Y2#"&546!2#"&546=0EB32BE/EB23BE!E03BB30EE03BB30E2JM@+    ? 3?' REK!Q9K!M-K1/90#"&54632#.#"32672#"$'&5476$"3267>54&'.`PWTriwyxvaqmmllmmmmllmm^]__]^⃄^]]^\^=%'mf_cnmmmmnnmmmmng^^]僂^^__^]⃅]^^}(,q@<&+))&i-) #*#Y#Y -2299991999903#5#"&546;54&#"#5>325#"326!!FP0}WtiWfLMBilea\oFTP30pr-T^FEPNQUah%# :@     Z Z <21<222<220 5 5%)+#)+#ssRssR^@ r 10!#!^ZZs10!!Zs$<T@TN N M  1%=1I 7" " PNPN"L7KCL+KCMOU2<99999991/2<229990KSX9Y"32654&+3#'.+3!53#5!2"3267>54&'.'2#"$'&5476$}SSTR}*;tL#>1\TSS`׃^]__]^⃄^]]^\^ㄘmmllmmmmllmmLKJL3(DF/DDCpmS[j^^]僂^^__^]⃅]^^gnmmmmnnmmmmnb+(10K TX@878Y!!Vu= @  i 10"32654&'2#"&546LhgMLhjJ@v+..fiMLfgKKk1.-rB *@r  r   <2<21/<<0!!#!5!!!1Ϡ1yyZk@6   M   h  \ 9999199990KSX9Y"#5>32!53!5%>54&#"FBEJVJaTN^ "hzlKMzBUcLd*R@,& )&h+  #)#\\ +999919990>32#"&'532654&+532654&#"#}I;j_wyHDFb\^ffe5acQLRWFlcHdwdrzJMXR]_JJJCH@ARfO10K TKT[X@878YK TK T[KT[X@878Y3#uf;V'@3   zzz ` , ,',:, '0 2<91/<2299990!]K TX @ 878Y!]!3!5#"&'3!53#5!3265#X4Z9^'鱦^`y'Ahjo$$kkk;-@ ob   912290!####.54$yvkkk/NݸBL  a  104632#"&M97NN79M8MN78ML#u"@    991/90!#"&'532654&'B@?~p*X.)O#9B,,@p1QY 5-X< ?@Mh \ 12990KSXY"535733fTzj^T^d ,@ i Y Y99102654&#""&54632!!jklihmliԯP-LװױbhH# :@     Z Z <<1<222<220 5 %5 s+)N+(#^R^sXXs^R^sXX'd&{5?&{'5tdd'd&u5 "8@a ! e` i#! #10#"&54632#"$54675332673 M87NN79LjU{~q`m8NN87NM/.ֶ3+ʜ{k&$ :uk&$ 8uk&$ ;u^&$ 9u\&$ 7um )@a dd )('d&d  %"#$M %o  f'#o!$ ('& *%"   *99999991/<29990KSX22Y"]@://   / & ) "!   ///..)(%'&+/]]4&#"326! 53.546323!53!3wY?@WW@?Y#"HHKrrNH}}Z?YWA?XXj%zSrrP#jjHj#@Udd  ddMo!ob o~  $ "$ $<22991/<2220KSX2Y"]@ !"#0%O%o%%]!#53!3!53#5!#5!!53#5!!53dZ昤XN{P{{{MjHjjk su&&zLq3k&( :uq3k&( 8uq3k&( ;uq3\&( 7uqk&, :uqk&, 8uWk&, ;u_\&, 7uq M@%  obo   $!<2299991/22<200]%3 !#!!53#53#5! !#8ܼPyȾRPjL66H}1je}kvtd^&1 9usk&2 :Husk&2 8Husk&2 ;Hus^&2 9Hus\&2 7HuD /@   <291<290  ' 7 1s33r4rP13p4pq3d' +s@:, +&  ) *& nn&i`,,#* # )+#%,99999999199990_-o--].#"324&'7!"&''7&5!27A| "5@}!"{WWoeNWUC`PXVwQ`YYQJuRlSVVEiZUSG`bk&8 :u`bk&8 8u`bk&8 ;u`b\&8 7uZk&< 8uqM@&oo ob o # $ !222299991/220_]!2654&#!53#5!#!2#!3wp9jkkj;3@;-.# z#"'q` z*-.$-">1'*'"', 04999991/99990@D --./5``o55/0123-/0123]].#"!534632#"#"&'5332654&/.546wz 6IYwUOmofoPuVhYwZj8l]4M/7cr%#eiyhTuI6ARzfd&DC9ff&Dv9ff&Dp9f7&D~9f!&Dj9f&D|9fD 8?@G,2*$ 29z*z2/*<'!6`@ $+-?+239**@22999912<2999990@(AoA*+,9?]]5#"326#"&5463!54&#"#5>32>32!32673#"&.#"/퉆tsmS}t_`V7Ju衟y+z\NvzoF[XIxcc))WZXY}[,fuD&FzdfVd&HC^fVf&Hv^fVf&Hp^fV!&Hj^`d&CHJf&vH f&pH!&jHfj-a@3-,+'$#"!( `(q.-, #"! '($+ D*.99999999199990 /o/].#"32654&#"5432.''%.'7%5-Q(/l#K4I2%%=_w\B% pاy/"5k7N:QV^DNJ7&Q~fjd&RChfjf&Rvhfjf&Rphfj7&R~hfj!&Rjhy '@a ar  <<104632#"&4632#"&!!M87NN79LM87NN79L8MN78MLU8NN87NML} +@?+*&  ) *& &`,,#* # )#+D#*,99999999199990@ -o-wx]].#"32654&'7#"&''7.54327H&pJ-(oJw>@^CL=>^@Lo99Hv1g=;Ly3Jv56?Ms232?7d&XCH7f&XvH7f&XpH7!&XjH9f&\vD;V #S@+ "z zq` $,5!,' 0$2221299990%]32654&#"#5!>32#"&'3!53i6{{6Hijmd__dkk9!&\jD1'q;$f&q#Di'z!$f-&zSDw'}$fwD'}bDsk&& 85uff&Fv^sk' ;=u&ff&phFs^' ?=u&f!&{hFsk&& <5uff&Fq^qk&' <uf&G 6Zqf)d@2!z! 'zqz` $,',5$ **<2<91/<2990@ ++++]%3!5#"5432!5!5#5!3#54&#"32636{{6Ffjjd_76_dJjujjiq32'q<(fV&q^Hq3m' >u(fVH&z^Hq3^' ?u(fV!&{^Hqw3'}q(fwVD'}Hq3k&( <5ufVf&Hq^sk' ;Xu*f9f&p\Jsm&* >3uf9H&Jzs^' ?Xu*f9!&{\Js6'*f9'\Jqk' ;}u+k' ;uKq'@ $&$$" $$ !(<2222<2222221@# o b%!o~/<2<2@   9/<<220@ )p)))]!5!53#535#5!#!5#5!#3#3!53!3wGGfjzkkkkz?jj~jJ%@= $, ,':," ',0&<2221@"z q#z/<29999@ z 9/<20/''']KTX&&&@878Y353#535#5!!!>323!534&#"3Th<3l_zjPzvjzlnjjÏjJ^' 9u,7'~Gi2'q<,`'q]m' >u,H'zGqw&,}Jw`&L}q^&, ?uJ`' @@zz,',0 21/20 ]KTX  @878Y%3!53#5!갰hjjjRkqV &,-4@"!1J9&LMH@6%1TVk' ;u-;9Ef'pqS't.;S'N;$@X    >>M z zz   ,',0<9991/<2290KSX9Y"]@  &))899HVWggghw           ( ( ( &)-**+,)/6 6 6959?F D D DEY X X WVVVh f f gegaabef`x x x zxxvz T]])53#5!#5!# 3!533Ji‘jOkkkjjqm' 8fw/;Rl' 8vOqS'/;XR'0$Oq' 6n/;X' 6Oq'y(/;E'y|}OV)Q@-  o bo  $ $ !<2299991/290353'7#5!#%!53{FF3F{jq\kk\-{a@% z qz, ' , 0<2<9991/290P]KTX@878Y%3!53'7#5!7ꮊ=Ǯf`VjbVdl' 8jv1J6&vKQdE'1JSD'Qdu&1 <gJf&Qq^q}&jQ`V'M@ $%!(221@ $%!dnob! i%o/290353#5!>32#"&'5332765&#"3`{JGIp[Xu1/Ѿkkrt""caKI@$kJ9JD(l@',':,%',0)261@%" z'z /290ss]@ /*`****]353#5!>32#"&'53327654&#"3Th3lUSëH>_UR[++`yjRklnec!!`Z><Ñjs2'qH<2fj&qhRsm' >Hu2fjH&zhRsk' @Hu2fjf'Rwu!^@0 obo~    %"2299991/0 #0#]%# !! )#5!!53#5!!53q7#3P{Ryy{jjb_ fD ,3k@/ '--z  0*$`4'3 - !*429912<2<9990@P5 -3]]%2654&#"!32673#"&'#"5432>32.#"h碞y,IEςFIzF}ba`c32c``cױq7l' 8v5J6&vKUqS7'5JSD'4Uq7k&5 <uJf&Uq4l' 8v6s6&vKVk' ;u6sf&pVu&6zsuD&Vzk&6 <usf&VquB'z7;u'q&zWBk&7 <u;'M&W 6B@  $ $ <<1@o o bo/2<2<20K TX@878Y]K TK T[X@878Y@ /`]!53!5!!#!#5!!!3 I{.{I j=w@`wj;'q!#533!!3#327673#"'&5#53ݢZ4FH!!BBkJkԇL*+_GF,`b^' 9u877&~HX`b2'qa<87&qxX`bm' >u87H&zHX`bi&8|mc7&X|U`bk' @u87f&rX`gb&8}h7w)'&X}h 3r' ;|:!f'ppZZr' ;|<9f&p<\Z\&< 7u\?l' 8v=R6&vK]\?p' ?=R&{<]\?k&= <uRf&]qJqi@-'6, 0<21@ z qz/2990]KTX@878Y``?]]%3!53#5354632#.#"CBaSOg**jjjRkKN8;;(7#535#5!!!>32#"&'!532654&#"찰h<6{{6ijPzvjzd_ _djuʿ@d(2"#6763!2)53327654'&+!2654'&#!/DGfsb#tsOPabNLKKk+SRjY[XL$]\OOabj??+>ONqdO;+327654'&#"#5!67632#"'&'!53#5JIHIIHIJPi6TS{||{ST6edqqppeed/0 /0dj@jqd%!2654&#! 3 )53#+w|bNjVvjv; 32654&#">32#"&'!53#56{{6ʿmd_ _dj~s4@ % &'1@nidn `06$32!"$'332#"sB7apmnzq%0HdapU@AXSIHSs9^6#"&'&'&576!247632#4'&#"#&'&#"32767Bap67IzcmQKrHBA>_2*R[Vq%op{{{{ll0lkdap\ (W:<!`--zYYPOf1#"'&5763267632#4'&#"#&'&#"3267'ް荍ed12R<|HAB>_1+R[,*kFGLLKLw? H5!`--==@@st4tt|}q@"#6763! )5; 76!#/DG^wP˺#ܺjY[Xg tjlHqd %!"3#3! $5476!3!#յSRNb|S{jNMkkjސvL;+54'&#"3276!#3!5#"'&32!#OIJIHHIJI6ST{||{TS6iieeppqqdejjd0/60/dfjD&2%#"'&'57276'4'&#"'&7632" 76&bB!&bb6hhpl HHEI%Mb鍌荍?ɔLKKL(LK18DCY.-14B_ KCuu8uttuq3)3!!#3!!#!#33>{{{R{LqLks!*"#6763 #"'&'&'&=!'&!3276Sll0BE77pc}~ap67{}#|}}|OPklVpb2122apG1ܜ}(H@ !'$%)91@!e e tee'i`)90#.#";#"32673#"$5467.546!2{p 2_۴&˸ ~j9iѫ 5V7"'533276'#5!#5!!53#5!Xrw/0{>{{]VDKM9k =c7;q/#4'&'&#"!!#"&'5332765#53547632qa *Og**)\]CBa *Og**\]CB.'89k1[[.'98k[[sM^0"#5'&# 327!5!! '&76!267632#4'&@}$q4QjLSeY=@}|_nv6P DnpkӚ_bTM9uG_<=c6e kk&%3!53!5!#5!#!! G jjj Lkkq!632#4'&'" 3!3!53#5!#}|CAG9_1%=WKͪ<Gj`-&<3jjjkkF( #5!# 3!533!5347632#4'&#"‘baM=A>_2*R[++kkjjjjK_^!`--=;;R53#5!3#3!53<ijpj&jjjfT'&'&#"#56763273!53 3!53''%%"#5<^212/o==2<wqŪy&= \D.-|bVskk"kkcVJ^3%#"'&5#5!#32765#5!#32765#5!#3!5#"&5nSR`o{@A`o{A@3d|uwggjj+]^jj$]^jjijp{3V533265#5!#5!###"'&r/,Xw^ yEIJc019kf/kky]JVDq@/  zz =,,' :,',021/290/]KTX@878Y353#5!>323!534&#"3Th3l`yjRklnjjÑjs'"&'&7>3 '276!'&#"HapmmpbE77pc}~}s # s} o}}o dapjpbcVpb21k$ܜnP&2c+D&Rs+7"&'&7>32676323!534&#"'2#"Hapmmpb̚==IGƾ^wX,77pc}~dapjpbcT(kkږ0pb21kQJKQfV9D'476323!534&#"#"3226& e-AHðW[A 鐐ؗ  kk{ 328@#!2#!3!53"#676!27654&#!/DGbs-NNqrjjY[XI'#PQ;V8327654'&#"47632#4'&#"67632#"'&'3!53JIHIIHIJabCFB>_1+R[,*6TS{||{ST6HiedqqppeeT\]!`-->54'&#"#67632327673ӄ{VW˹|RSXYq||hWXŶ98^]^]sH3ٟ_^=7+ҾaaA;7::lGFRQsD1%#"'&5476?67654'&#"#5>32327673bgtsCB--<;tujcT>=0/AA|GFj;,,WVoFG/-*)(CR))tg*,fBB,-1++FY/.;;wS:9 0"!276'&6=3327673#"'&7&"# 76!275.dzYl;+[R+*_>ABHaxwfAk{_H>~=_@@VmQ>.,`"]s]=;9'q'#533!!32673#"&'533276=#"&5ݢZ4FHBëH>_UR[,*0>kJk]LU_!!`Z>_2*R[++'k]L*+_CCGFk_^!`--=;VB#"&7!#!#5!327673 IIJGI{.{I/-yX,,r"5`NK10cZ&8,A&X'}'.!#! 764'5!#5! '&'&'&5476DuP]\Nu9:ncco::{zL-F骩6FӉW֗g[`0/\gհq%!'&5#5!#764'&'531KuG*֑\Xlj}9;mci Ae kk}B/ rSٗd[0'c%3!53#5!# 632#&'&#" 3+uuCFB>_*+R~3gjjjkk\k!`--Hl9M=% #"&'53326?#5!# >32#.#"L2zo/c2^9<7C%Fsy+ 2zo/c2^9<7C9|[D;=\kk%|[D;=\?!!53!5#5!!#!FLzr{BH,<ZHR'53!#!3#!53!5'jfɄBkf!j#VijVzfI##5!#!!"'&'3327654'&_X{iOfeuopnp YX[[TfZ}Cyx}|9DdcfefI#"32673# '&5476?5!#5![[XY pnpouefOi{XTefŬcd9|}xy}`ff6I'#"32673# '&5476?5!#5![[XY pnpouefOfjJefŬcd9|}xyVݸQfa&#676323!!53!567!5!67654'&#"pkmlht0ou="&[ @NON\q 9‡0m"!~UUGGq !"&'332654&#!#5!#5!32cunp ={džUH23"tk'6I'$!"'&'3327654'&#!#5!#5!feuopnp YX[[ȱi yx}|9Ddcfeialq%33##"'&'53327654'&+#53rRbbaHBA>_+*R[++++[tqjM^]]"`,.><<>j#+'!5!3!!!!#!5!ssssS Ѣ %#5#9cq k'?j'q Vf'@j'f f'@GqV''-P/q9'MP/;9A'MOdV '-1d9'M1J9'M'Qk&$ <uff&Dq8Vk&, <uf&qGsk&2 <Gufjf&Rqg`bk&8 <u7f&XqG`b'72'qH<`b' 87'Jt`b' <7'Jt`b' :7'JtfVD'f2'q9<''u$f2'9<'9D1'q;f'qs&.# 32675!5!5!5!3## !2#q]DɅͯiY88kkkMM_b;<f9D2#534'&#"3267#"&'53326=#"325!#3{IJiX`}6{{6hkde8&&h`ďd_76_dkksk' <Yu*f9f'\Jqk' <Gu. ' <KNsg'}L2fgjD&}lRsg2'qH<fgj&qhfIk' <Kuyf6If&qA;9f&qGq '=j'q V']j'f ']Gsk' 8Uu*f9f'\Jq+5!3!53#5!#!#5!#3276#5!# '&GG]^FJfR~jjkkkkqqqvUl+dk' :su1Jd'RQk0'!4&#"3233!53!3!53&'&54767"$GY?@WW@?@3P'$}}\#%P?TeW~YWA?XO2QrP?&jjHjjw%=SrQ? fk (6B5#"3263!5#"&5463!54&#"#5>323"&47674&#"326/퉆ts=kn_`VŸ1)OOHdX@AWWA@XNvzojsJFIydb))(P栠PG?XW@AWXk' 8ufk'd'k' 8IuL}f'k' Au$ff'9D'u$fH'9Dq3k' Au(fVf'^Hq3'u(fVH'^Hk' Au,`f&E]'u,H'Hsk' A6u2fjf'hRs'Hu2fjH'hRq7k' Au5Jf'(Uq7'u5JH'(U`bk' Atu87f'HX`b'u87H'HX4&6s4D&V4B&7;4'q&Wqk' <u+ ' <KK`Vb353#5!>323!53&#"3`{JѾkkrt'kk$kfja 9 54!"54&#"3262; !"'&'#767#"32#5! ]5.퓌 fAd T{{6f3k{_H>i]=G=_@@B6 /76_d)j\?35!#!!3'6767\{^P^, HZHZPE^=ORp'35!#!!3'6767RjffP^, Vf#VZPE]EY^' ?u$f!'9Dqu3'(fuVD'SHs'Ifj2'qh<s'Ifj2'q`<s\' ?Hs2fj &{hRs'H'Hu2fj2'qh<Z2'q<<9&q<\;% %354'632!"'#767'&5#5!Do$k rni^m|iG UeOjJ%D4%3544&#"3!53#5!>32632!"'#767'&5Do`yh3l$k ro^m|@ÑjjRkln֐WG UeO;%q&%354632!"'#767'&5#533!Do$k roZ^m|XiG UeOkJk;9'U@ - 6',01@ z990/`p]KTX@8Ys s ]#5!#"&'533265fëH>_UR[Wkq!!`Z{fG 754&#"326732654&#"5#"32#5!>32#"&'{6{{6i6{{6iʿd_76_d)jmd_ _dfVGD 0=4&#"326553>32#"&';#!53#"3232654&#"{6{{66{{6Hkk;d_ _dkkd_76_di"#5373 3!53!3!'7#;! c7P5N}* 4@VHNdj=.hGjjHj99V:.$.'7&'&5!27#&'32673#"&/7&'&#"|N:#7IzgsuPvq {0Ba=p9EO[\ *GJ;daqY%V *'7&5327#&'32673#"'7&'&#"qLhed99gL\k  Lw'ްчAG^?ɐ1 {?n9-t|}|N@v&353!5!#5!#!!!53q G {j Lkk)53'!#!7#53!N|I{3PJ{IsjE`9GRy_Js9D?32673#"'&/&'&'5332654&/.54632#.#"#"'J*P+9^2c=>]2O j|_{ֽTcjutwZ76!];D(^1(>Vf#VIa;D(3!2#0#3!5332654&#VU$+`>H&0ʕk&,`" jjLmD 27654'&#"#5>;23!53VNNNNU$+`>H1ZgQPQP&,`" rqrMjjfD ,32654&#"#5!>32#!32673#"'&퉆tsGF\=kJIn_`[ZVstvzoGGD.jsJFIyCBdb)mnfD!O@& zz` ',,5 *"<<1/990@ ####]%3!5#"54325!#54&#"32636{{6hkkd_76_dk#ifD'%!53#5!67632#"'&327654'&#"h6TS{|}{ST6JIIHHIIJkRjd/0 /0ieeppqqed;'867632#"'&'!53547632#&'&#"327654'&#"6TS{||{ST6baHBA>_+*R[++JIHIIHIJEd/0 /0djc]^!`--=;*edqqppeefD A@  -!԰ KT KT[X8Y1@  `!0>32#"'&'3327654'&#"f'ް荍eddekGFLLLKw課0@@sttt|}f%D.%546! !"'#767&'&57632#&'&#"C ڴ} k r eddekFGLL\m}G UeO 0@@stf9'8327673#"'&=#"'&32#5!54'&#"32764*,[R+*_>BAHba6ST{}|{TS6fIJHIIHJIh<>--`!]^&d0/60/d)jieeppqqdef%647632#&'&#"3!5#"'&3254'&#"3276zbaHBA>_+*R[++6ST{}|{TR7IJHIIHJI4]^!`--=;jd0/60/ieeppqqdefVD!7632#"'&'33276=%!.#"fwv,MNyQQ@HIXX}?@nmj_^fVD!!54'&#"#67632#"'&73267fQQyNM,vw鍎IH'nm?@}XX̕_^x:D-9#"'&'#"'&'&'&#"#67632%332327654KM/_q`T )e !QyNL ,vwrAER@HBAN0]Qk̕vp>,m?>XX!%=;>+eU^_\;d20s@) !)*1KSKQZX8Y/3<91@-z%!%  %`19/90@ p2`P!@2 2]`2P2@2q47632#.#"!3#"32673#"'&74767&'&bb6hhpl ^]\MJ5Wt ljlhP{ziGxR6f*DCYZi>ie2D"'56763273327#&'&''"'&'53327654'&+53 54^HH lphh6b[rBDRj-J-#6Ws_S 6RxGgz}Oiljl tW5JM\]-.YC?u=;>-N& \Q#6NOP$fjR2Ot<>ifD9"327654'&+5327654'&$%67632#"'& X)G`&>l:9FG&&GF9:yU:eNJkjKLLK(p7 %{ 33`i54d54j_34KS4MMfGHGGg;9`'#5!3##"&'533265#53fëH>_UR[WkjȤ!!`Z{8jf9 :!"3265#"&'53326=#"543!547632#&'&#"{~~iX`}6{XabHAB>_*+R[,*Htp|}&&h`ďd_76]^!`--=<f9''!##"&'53326=#"54!"3265#iX`}6{'k[&&h`ďd_76!tf;(7&'&#"32767#5!#"'&57632j >Rx[Y\O=G5 S]lkz폎Te`l!Z/@ywtdMn8+^8+- #5!##5!##"'&5476327654'&'fPSatsR4aA/!56'B8iU4Tkk?kkcӤÂKJgAkyЋ6"6/"9wB&6626;2#54+"#"'&54767#"#327654'&'X0i/D_;a*jp1O@q1)f3-SZ:%8,NY/2E9K/ߚ|xN+kk.Pf}W);A*&@fr|7V'3#"'&5#5!3265#5!3!'Ǯ3QQkTS_0/zXj87ed9kHHkjT/676323!534'&#"3!53547632#&'&#"3PRl/0zbaHBA>_+*R[++jl77jjGHjjc]^!`--=9T9J?67632#"'&'533276=4'&#"3!53547632#&'&#"3PRlbaHBA>_+*R[++/0zbaHBA>_+*R[++jl77^]!`--><GHjjc]^!`--=;J`& D CJc' #5!3"'&h*,[b]_]k8<=c^YJ`' D@ zz ,',0 221/220 ]KTX  @878Y%3!53#5!#갰jjjRkgI(%3!53&'&#"#67632#5!32673#"'*`33[i+0`33[jjj~('LJI;jPKJIIs%3!53$'&72#5!3#'&W;iH;jjjj8dj ccri;9b#5!327673#"'&5i*,[R+*_>BAHbaj<>--`!]^ ;6g-#5!#3!53#5!!!"'&'3327654'&._Jf鱱ibOfeuopnp YX[[ffjj@jVyx}|9DdcfeJ^D0%#"'&5#5!32765#5!32765#5!3!5#"'&5RSnRR^`o{@AX00o{A@X3d|SSu;=JV^D23!53#"'&'#"'&5#5!32765#5!32765#5!3d|SS5RSnRR^`o{@AX00o{A@Xkkjp>=qu;3267632abHAB>_*+R[,*`o{@A00o{A@h3d|SS5RSnRRh^]!`--><]]jj,CD]]jjTijp>=qu;_+*R[++h3RQl00yCCh^]!`--><$kl77jjIH^]J9D.4'&#"3!53#5!67632327673#"'&500yCCh3QRlUS*,[R+*_>BAHbajIH^]jjRkl77ec<>--`!]^T'353#5!#5!##3T jRkkk'=Y7\`7Y=>"jGGgMM47MMgGG(xjlͩjx(POpoOQj=f=jQOopOPfVj#+3!53&'&767#5!#'676'&Ʈ갪qqooS3KL3 P2KK2jj)zzkkgyyiNt8uNfLutLJ'332765#5!#3!5#"'&JjNKHI36UUz-21 ON^^jjio65J332765#5!#3!5#"'&JjNKKI36UUz-21 ON^[jjio65J9'+!5#"'&'332765#5!#32673#"'&'k6UUz-217jNKHI3++\RT^>AAHa]o65  ON^^jj<>Z`!]ZJXD#.#"3!53#5!67632jNKIHͦh6UUz-12)ON^^rjjio56J9D+#.#"327673#"'&=#5!67632jNKIH*,[R+*_>BAHbah6UUz-12)ON^^<>--`!]^hio56Tp=%3!53547632#&'&#"ͥabHAB>_*+R[,*jjj j^]!`-->BAHbaj j<>--`!]^jjjG')3!&'&+3!73#5!2%32764'&+2$$0((Ez!^UT>=6m2334k IgRbyggYgJJf??.3323G')#!53#'!#32767!#32764'&#z=>TUzE((0$$~k4332m??fJJgYggybRgI K3233r9DB327673#"'&=353332654&/.54632#.#"#"'+++[R*+_>ABHabjGF|_{ֽTcjutwZgbd<>--`!]^w;8]YFV1-,f,*gtRRCQ*-/o;9'#"'&'533276'&7632#&'&#"yaHBA>_+*RY-<j_waHBA>_+*R[+;^ht]!`-->Pnr]"`,.>Qmi;9q.3##"&'533265#53+5;54632#.#"ëH>_UR[WCBaSOg**~jȤ!!`Z{8jkKN8;J9>%6'&#"#567632327673#"'&?;+[R*+_>ABHa <-YR*+_>ABHahGnQ=--`!^|nP>--`!]}:9 0276'&# %# '&!237&7632#&'&#"#54Y.5AfxaHBA>_*+R[+;lYzd>H_{k~G=]s]"`,.>QmV@@_;'D%3##!5!4&#"#>32Z4FH!!BBkkJkL+*_FG;V'q#533!!327673#"'&5ݢZ4FH!!BBkJkЇL+*_FG7'(!3#3!5#"'&=#53#5!!#!3276X3QQkTS_ߠ!0/zCA'jjj87edMjkHH^\fH,##"&'&'&54767!5! 7654'&'5!8ZZ++PH^_jkIR*+ZZwzZ[&Z[==ve@o`cIC#$FDKaan@j.Ιppppgf.Jx'"3#&'&5#5!7654'&'pYZ*,PH^^ki]h*+\}p[==v@o`cIC#$^S]k8<<kgf.' 3!53 3!53y՟qw'Dkk%kk!'!3!533 33!53v<;w>-kkDkk 3!53 3!5367632#&'&#"Fy՟qw2==o/212^<7!"2kk%kk|-.DT)57#5% #5%7'ڹh3ooHoojR9'35!#!!327673#"'&=Rjff*,[R*+_>BAHdaVf#V҃;>--`!]\hRB'%254#"!5!#!!2!#?0jff.lcyVf#VEȾf6I'##5!#!!"'&'3327654'&_JjfOfeuopnp YX[[f#Vyx}|9Ddcfe6I'$, '&654'&+5!#!#'7&"2( /i-[[_JjfOfeq vLo6V{fef#Vyx}K56{_x!%327654'&#"#5>323+5tZ,**,ZR++`>HbRrj><¾<>.,`" ^Mjjx#!+53&'&547632#&'&#";3ȸrRbbaHBA>_+*R[++++[tj{M^]]"`,.><<>*jx";##"'&'53327654'&+#5rRbbbHBB>`VRZ,**,Ztj M^]^!`Z=<<=jr9'747632#&'&#"327673#"'&5rbaHBA>_+*R[++++[R*+_>ABHab}7^]!`-->;<>--`!]^s -47632"'&2#""&'&7>3 " 0." B^ "rapmmpbEnpb.""""./B!!QJKQkdapjpbcVobcI+'pfD:%27676'&'&#";#"#&'&54767&'&547632 X)G`&>l:9FG&&GF9:U:eNJkjKLLKjj(p7F%| 34_i55c55i`33̶LMgGGGGgLMf9#&'&#"32767#5!#"'&57632547632#.#"k>Rx[Y\O=G5 S]lkz폎Z_aaHAA>^TR\++՝/@ywzdMn8]^!`Z=;F'{;93& Dx E;T'7!#3!533!53 #5!#^@_*+R[,*IJHIIHJIkkd0/60/dL]^!`--=;eeppqqdex)%3+53#53327654'&#"#5>323#RtZ,**,ZR++`>HbRrjjjfj><¾<>.,`" ^Mjx+!+53#535&'&547632#&'&#";3#3ȸrRbbaHBA>_+*R[++++[tjfjM^]]"`,.><<>jjf ',54&#"326!!53!+5#"32#5!!{ffBk7ї6{{6fyiVզd_76_d)j};f67D#5!#3!5#"32#5!!!"'&'3327654'&%54&#"326_Ji6{{6feOfeuopnp YX[[ ffjd_76_d)jVyx}|9Ddcfe8ifB8=%254#"%54'&#"3276!3!2!#5!5#"'&32#5!!f?IJHIIHJIdf.6ST{}|{TS6fwlcyieeppqqdeVDȾd0/60/d)j8;-qF#533!!3267332654&/.54632#.#"#"&'5#"&5ݢZ4FHB:G|_{ֽTcjutw-.CCgb GkJk]LU_19;]YFV1-,f,*gtRRC(*)-.HFo,, C;9C@#"'&'533276'!32673#"&5#533!&7&7632#&'&#"NxaHBA>_+*RY-<x14FHBGxaHBA>_+*RY-;^hs]!`-->PnC]LU_kJs]"]/.>Qmi;%q=E6! !"'#767#"&5#533!!32767&57632#&'&#"54]} k rGZ4FH!!:eddekFGLL_C ڴ G UXGCkJk]L**]z0@@st\m}J9A!53!3!53#5354632#.#"!>32#"&'53327654&#"3)CBaSOgT3lUSëH>_UR[,*`yjRjjRkKNqlnec!!`Z><Ñj;%44632#.#"#"'&'!53#5!332654&/.ֽTcjutw-.CCgbih|_{ ,*gtRRC(*)-.HFoj@j'wv]YFV1-,;!!53!#!53#5!!ffBk5iy'Vj@j};G`)#53## ##5!##53## ##5!#_I_[I*kP_I_[I*k5/<<C<ABHab0/z'jkl77<=--`!^]HGj;9B54'&#"#567632#3265#5!3327673#"'&=37#"&5++[R*+_>ABHab0/zV*,[R+*_>BAHba3RQl'<=--`!^]HGjY<>--`!]^h=l77.!53#53676323!534'&#"34gm 23Cm34ecKP)*c;;=99w;;m((44c;.1676323!534'&#"3!53547632#&'&#" 13Cm34ecKP)*cg<=j-()&;38=99w;;m((44c;;\44 z6#K. "4632#"'#53#"'&'5332765'**l<=j,))&;384&&47%ME}@?[%@ b  91990>=3ME}F@?[% 0.'03%N}EFP[?u452654DŽu@XX@sPOOP=>X@?X=>POPPu"'&4763"3sPOOPs@XX@PPOP>=X?@X>..#327654'&#"#5676323+5L::6?)+*/o?@@5Jqqxr""mj""6z 44}5+;;..!+53&'&547632#&'&#";3exqqJ5@@?o/+*(>6;88;Lr;d+5}44 z6DjmDi;?f[@ 91290K TKT[X@878YK TK T[KT[KT[X@878Y3# #ttf?fL@ 91<90K TKT[X@878YKTX@878Y33ttx5h3Ԕ5"b+qh3Ԕ"x)3!#c=c= llx!#c=xu#lu#mZ:8 533##5#5s)9H n@  [[120KTX@878YK TX@878YKTKT[KT[X@878Y332673#"&` hddh ` HOGGO7u! -  10K TK T[X @ 878Y2#"&5460EB33BE!E03BB30E \@  [[10K TK T[K T[X@878YK TK T[X@878Y#"&546324&#"326sssszX@AWWA@Xssss?XW@AWXLw&@   9991/9990!33267#"&546^WC8:$C q|<{/.8  YQ1iJ7@  [[99991<299990@A            ]K TKT[KT[X@878YKTKT[KT[X@878Y'.#"#>3232673#"&9!*0`f[&@%9"+0`f[&@Z7OL!7PKf:@ 91<20K TKT[X@878Y3#3#rtfxtZ%3327#&'&',rBDRj-J/!6Ws_S c=;>-N( \Q.#+x#5!#7#5!##"'&73254hs}>m,wQ(('<<<cWYPFE{7<=@E-,LKNX_a,+KKC@?BB2'0J9R/. : !..&('>U01 .7#5!#3!53'3!537'#5!#] \ZXZ\U5S<<<<<<<<..!+53&'&547632#&'&#";3exqqJ5@@?o/+*(>6;88;Lr;d+5}44 z6DjmDi;+4#!5+>4+4!5!3#>”x(+4!5!3#>”PP+43#!5>x(+4)5!3+”y>=3%>=3%ME}^ME}F@?[P@?[ydCRfv?fpD7~b+!!V )9Hz7u!{71!jB2#567654'&#"5676+ 1El6)IR,ao 18X(Op6'< "|f?fqLm3~*m'"Af###=rtfxx)9'{z)9H #."#> ` hh ` ")OGGO& #6767LF::u*pPgIJ62'67&'&5476 D( JP 1"&6"7#,LS#&8F'kv2&'&75476-"6&"1 PK ('F8&#SL,#7}f3#DƐtf}eC Sev[G%53#5#5"lG%33##lۥpNt!#!pޔt"JZA532654&'#"&|..8  ZP2hM^WC8:$C q|<:_"'&4763"3sOPPOs@XX@:OPPP{X@?X6533!5"%##5#5񥔥۔G% 533##5#5%!!"۔9'#"&'533276=ëH>_UR[++褻!!`Z><9T%332673#"&5ݹ*,[RU_>HÀ<>Z`!!xub{Ax5bjAAf|`74gd >=37LF::ud*pPgIJ6#uzLw}Jd3~+f#!#5iVyC>b#"3327473327673#"'&0W ` : J ` 9 J ` T0N  J?q$?p&C9bzE9d #."#> ` hh ` "EOGGOKDe~.+fqpmB]y=Q'9'&'&#"#676763232767673#"'&'&#"#676763 gf7K`25cdTi gf7K`2=[X`i gf7K`25cdT) 9>(&;=3)B 9>(&;F*)F 9>(&;=3):5!jj:5!jj'LL^??'&NsP9EG@e2#52654&#sOPPOs@XX@OPPP{X@?X&l53!3y?g!!ub&b&C>b632#&'&#"#&'&#"#320W ` : J ` 9 J ` T0N  J!U '77''thuuhtthuuhwuhtthuuhtth.54675>54'&'!KP7!LO0PQX$  +0PQX$   '7 !{p#&'& #676)$ɟd$):`wwww`Ttf3AntVH%#AnHP =3?H33g(Ղ] Jy>=3462"J^X?MpMMpE%ZpMN78MRfO10K TKT[X@878YK TK T[KT[X@878Y3#uf7R&jf& BLyf'\f'Vf'V=f& @f'Wf&0&H$qd%q7 %3!53#5!#5!{>jjjkNp)3 p=/JHyq3(\?=q+s ,`@n ni `-,')!&$  %-221@ +"!(%&/K TKT[X&8Y220_.o..]%2#""&'&547>3 #3!53#5HapmmpbEnpbo{{{{NQJKQkdappbcVobc q,q.% 3!5333!5bJH\jyjjkjjf0d1q#%53!3!#!##3!53#5{N{D{{7{{{{L]Lcs2q]q3S !53! !#5! {5h{I.B7Z<s'093!535&'&'.46767675#5!#67654'&'mmpd}dNNe|dpmmpgyBqGqBygm`}}c˫c}}`/OF! ajja !FOOHdkkdHZvmVcVmvZ ;`11;#"3!53$'&6+5321#5!#676,f[to[f]BGA^"#kwijj i~3k_Ckk|C_}')M@( n!iw   '%*991/<22990%!53!565#"!3!&5476$32`PuuNsnccotӶF7SF-W`֗g[`_\gb\& 7uZ\& 7uf0f&edf&JVJf&LJf&HJx&Wf0D$2'&'&5476276737'&' &'&767t(_>n{||uVL'$ge`"hF$&7}ˏA:?2sWIINsSoV7$C;%oi4;^ΝKyuz8Q &{eq{ V9-%32654'&+5327654'&7632!"'9P[]_2XH/M\wRx_FE|he=;Z]kH=EOq08tdTS(ml^\JSc'%'&7#5!76'&'53>:/Ej.4T (0pt(g(32#4&#"h3l`yklnÑfi+1@  *221@z q`9/0'&#"!32762#"DKLCSDLLD@AkKJkjJ' #5!7'&hJ8|̎]"k#JyuzPF'xT &'&#"#5676323!53 3!53%"#5<^212/o==2wqŪy\D.-|#kk"kkFV'n@,',:, '02<1@  zz `/<299990]K TX@878Y]!3!5#"&'##5!3265#X4Z9^'^`y'Ahjo$$+fkJr'%6767676'&'53##5!zP_=*9HpqP>H_{ኹht0tFld\Fa ;1mTfJ=,g\,kSU) 3$#5254# '&54767$54%!#!N_K19+kZs{'Ii@k>moHrZLlwVe z&fjDRJ'J@%z z =,' ,,:,',01/<2220/@]353#5!#3!53!3T!jRkkjjRjVMD32654'&#"#476763 #"&'9HWQIWaCX{6HihzoeOzr#. _dfUD %$#5254#$'&532#.#"9+kZ茍eekKMHrZLl1/0qrf:' %2654'&'" !!#"76hKCGK8rFlmuk3|S'7'&7!#!J7}̎]if"KyuzP kJx'"3#&'&5#5!765'&'p}]WAMA-B_URK;X./z~+45ˆFspTS'D.1xz #BJ[5"5ghZS'Ds`U!!`Z>ZsV $%2#"#&'&'&7>3 HR`[apmmpbEnpb~YNQJKQfn #2apjpbcVob2"fVjD%26& #&'& hؗ﹥ssF8]m{2|sU{# '&'&5!2#.#"%$#52'&hpmIzq%{tX,kZ 2,gp\@AĵrZLlfU$&3$#5254#$'&57637673#j`LKM9+kZ茍Ĝ.R k3[t^qrrZLlz2]Iq7)GPr%47632#.#"!!#"&'533276{e3vFbKIP,>?|f2tGbJHP+AbdVRE@jbdVRFgk: )##5!33:Ey3j  #!3qq|OiU# #&'#&'&#6$3 #5276xP{rp%qzH !9vC o`[YXA@뗲72k\VLD#&'&'#&%5 #66`0  2oP^R V Tf4!|nXv\GE67327673#"'&'&7'&76?'&'&#"#567632676FC(yZh4*<^212/3 8 c}}capmmpbEnpbQ}dapjpbcVobcfE+%673#&'&'&'&'6767676#&'&!!j4!HZZ.= ore_\kLH<$ FKAc2:/BA>NiSfE+% !5!&'&'&#676"'&'&'&'3" $<ۂHLk\_ero =.ZZH!4FiN>AB/:2cAKq!2654&#!53#5!#!2#!3wp9jkkj;V 32654&#"#5!>32#"&'i6{{6HiOTjmd_ _ds#"&'&5!2#.#"3267BapmIzq%0dap\@Af353#5! !#3!53#3q  ǿjkAkjj+=j`V_' !#3!53##GZӇӸ'"fhjvqUVD'!!#5#53476763 #"&'32654'&#"reeWaBY{6IVPJkppkzr#. _dihzoes332#"#6$3 #"$s0ا%qzImpaSHISXA@Upads )4632#"&#"&'&5!2#.#"3267M97NN79MBapmIzq%08MN78MLdap\@As )#"&54632332#"#6$3 #"$EM97NN79M.0ا%qzImpa9LM87NMSHISXA@Upadq3k' :uSq3\' 7uSBBBB|#I #Iabh FaF`C`#BC`CUXC`C85YBB #Ih; 5#I@PX@855YE,U@&% $ $ -<1@$d)n!% n  ob o /2<204&#"3!53!#!#5!6$32#"&'533265x¼{?{89@ $ $ $$ !221@ ob o/<220#3!53!3!53#5kjjjjkq3s&B7r@    91@M n` ob<2990KSX@  d d d9Y"&'5332?#5!# #5!#)Jr\8T0G%P`n""dK}Tkk2kkb.u/%.7`@+ $&$3$/$8<<2<<21@ b'7no/<<2KSX&/n#<<2&/n#$o<<2Y0!#32+3!535#".54>;5#326&+";/FaootzDžgWϫԦkSBuzǒJqjjq?܂pǩ?S ;qF@$ $ $ $ !291@ obo /2<20)53#5!#!#5!#3#4GGj$kjjjjT>C@$$$$ 2<21@ obo/2<20#3!53! $5#5!#3!#5ƾB&kjjƬkkkq\@$$ $$$ $ !221@ob o /22<<20@ ]%!#5!#3!53#5!#!#5!#1GG1G{jjkkjjjjqd@ $$$$$ $ ! 291@ob o /22<<20@ ]!#3#4#!53#5!#!#5!#!#iGj$dG1G1jT>kjjjjFG@  $$ 291@o  obo/20%!2654&#!#3 )53!# Cp{jkLjLqn',jq@@ #  $!2291@o ob o /220%!2654&#!)53#5!#3  !pGYjLjkksV@ & ' 91@   n dni`90@ ////] !"$'3!2!5! #"#$I^B`O 0 %q<U^F"z@Xq (Q@ &  $ $!)2<2991@#nin` ob o/22990%3!53#5!#!76! ! '&!2#"Gg3E]6jjjkkV_AQKJQF `@$$ !2<1@M oobo/<222290KSX@$$   <7367632#"'& 3 e "Y^SZjHdB6[Z醆՘+k^EQ-B_ 42lGjQO͒3I+'"8@ , 0#221@z"z" z /2290 #!53#532654&+32654&+\zu(ק_jstiu~v'^q #힖jSj[YDDZp[[n;' 0@,- , 021@  z  z/20#5!3!53#5j6'ߦjjSjJ' !H@,  ,-!"99991@ z z/2220 #]3!%#5!#3#'&#!"#32>56 hddh8J^a3jj{fVDHC'+@  ,+,),<2<29991@M (#*z%  z/<<2<<290KSX@#  > >      <<<<< >    Y##5!# 3!533!53#5J‘'jbjjjjjjSj$'$?@= , = ,-%1@ " z` z/220%>76=#5!#3!53!#"&/326("  ({SBDL?)?*hMȼjjjjDuSPHO}J'@== , , ,,09991@ z z/<2<290KSX@>>Y353#5! !#3!53#3J++jSj%jjj65jF'@ ,==,: ,022<221@ z  z /<2<20/]@)////____]3!53!3!53#5!#!#5!CjjfjjSjj=jjfjDRF'E@ , = ,:, 0221@ z z/<220/]#3!53!3!53#5馦'jjjBjjSj;VDSfDFS'3@-, - , 1@   z/2<20#5!3!53!#iߦi'ߦjjB!9'\OV#0=b@8 ,2*,,0><<<<1@#21$0!zq>;'!5-`>z>2<2<290#5!7632#"/3!53#"32'&#"32?32654&#"ƱiC0ii0CC0ii0CC(MSSM(CC(MSSM(iF22FejjF2/-2F((FUF((j'[J'M@= , , :, 0291@ zz /2<20/])53#5!#!#5!#3#'&IhiTjjBjj{F'^@,,=,:, 2<1@ zz/2<2 #I#IRX 8Y0#3!53!"&5#5!#3!#5ݦb^E<Z'jjj9M@jjsPjJ8'^@,, ,== , 0221@z z /22<<20@  //]%!#5!#3!53#5!#!#5!#{BjjjjSjjBjjJ8'f@ ,,,== , 0 291@z z /22<<20@ //  !]!#3#'&#!53#5!#!#5!#!#4hd'j{jSjjBjjB<'T@,, - 21@z  z z/2<0@ ]%32654&+##!#3 )53`evwdxʦjp\\o jj<'#i@,",!,  ,0$22221@z z! z /<2<20@  ]%32654&+)53#5!#3 3!53#5!evwdajjp\\ojSjjLjjSjl<'N@,  ,0221@ zz z /220@  ]%32654&+)53#5!#3 evwdajp\\ojSjjfDR@ - 291@z`IIPX@8Y0! #632#"&'33 !5Dk'4" $\_i;D(T@ D& ,  ,0)2<22991@ #` z z/229903!53#5!#367632#"'&'2654&#" ~zjjTikٌ͙wA'BB@= , 2<1@Mz z z/<222#I #IRX8Y90KSXK RX >>  << #I@aC`#BC`CPXC`C8YYY#"3#3!53#!53.54637lfemRGЩUhdOOfjjjjwfVd&sCfV!&sjhBBBB|#I%+#Iabh%FaF`C`#BC`CUX+C`C8+5YBB%+#Ih;%5"#I@PX"@8"55Y+9$53#5!!!6!2'654&#"3!53+ϰhg;[kjk~[wUūjjR;f&v:qfDQ@ - *291@z `IIPX@8Y0%673#"'32#.# !!j4!q\k$ F3)0/{iSsDVJ`L!'jHJ KTKT[KT[$KT[X"@""8448YKTKT[X"""@8448Y;9M$'"+L@' =,+,- ,<1@+z  z `#z/220!53!#"/32>6=#5!#32!'32654&+:&{IIXL44?0# ĻevwdfHӔO}lMȼjjfp^^oF'(\@$ ,== : , 0)22<<221@( z  z /<2<2<20)53!3!53#5!#!#5!#3232654&+evwd4ffjjSjj=jjp^^o+%j@= , , $,!&<2<<1@z #z%q z/<2<<0KTKT[X !=8Y!!>323!5354&#"3!53#53#5!3l_zϰh'klnjjÏjjRkjFf&vHxFd&vC9' <'m@==, , 0221@ z  z/<2<20$KTX@8@8Y!"#'&#!53#5!#!#5!#3Qdhd[iTjjBjjiF(!5#5!#!#'&+3 )53#"!2654&#!FGobYb !gkkgj<}"%3264&+3 )53#"#5!#5!!#&#evwdVbb(i(bbjpojSzizq,2#.#"!!3 3# '&!3!53#5!#!76735!23!53&+3!53#"3--t/KZZK/tZj\@`'HH`@jj>D~jjDjC'( 53>35!23!53&+3!53#"3##&>d d>&DjV%QVV%Vejjw#fjj#jsfD '&'& 325 VQh~h  {2|߽jh5!# 632#4&#"# 2?aP_T5Rjkkz&gQ:jUD5!# 632#4&#"#+"F2NW_L:;~ykk%ğ()_1P2^ 5!5#5!#!!3 )53!2654&#!2@G@Y {gkkg{j⛪$%3264&+53#5!3#3 )53evwdȱijpojijfWq  /@   $ !21@ obo/20%3!53#5!3!{jjjk%`;X 0@,- , 021@  z  z/203!3!53#5yi'1TjjTig53#5!#5!!!3!53gȾ{{k{jjp;'53#5!#5!!!3!53;i6|{jߦ{jjXqEb,3!53#5!#5!6%$#"&'5332654'&{>9"nGIrXXw^NxpZUjjkp&+rI""ca5Q[V;9q'(3!53#5!#5!!2#"'533276=4&#igMSca|_URT2,_jjTiem_]B`Z>5Ï/353 #5!##5!##5!# 3#4#!533!53'3-"eGe"-j$dAAjkkykkykkU>jjjxjC'/353 #5!##5!##5!# 3#'&#!533!53'3ɶhdʏʘj.%jjbjjbjj{jjj.Kjou&z,UZuD&zuq353#5!##5!# 3#4#!533qGjj;'!533!53#5!##5!# 3#'&#ۘ‘hdjjjTikckk{d#!#3##5!# 3!533!53#535#qGF'353#5!#!#5!#3#'&#!53!3FhdjSjj=jj{jfjq353#5!#!#5!#5!3!53!3qG{jkkkjj~jFx'353#5!#!#5!#5!3!53!3Fj6jSjj>iߦjjfjqE 326%$#"&'5332654'&3!53!3!53#5!#9"nGIrXXw^NxpZUʌ&+rI""ca5Q[Vojjjjkk;9'.3!53!3!53#5!#!2#"'533276=4&#BgMSca|_URT2,_jjBjjTiiem_]B`Z>5Ïsu'zL_fuD&zdB!53!#!#5!3#4#I{.{Ij$dj` T>S'!53!#!#5!3#'&#7iihdjB {Z<V'5!# #5!#3!53-)wkkkkwjjsZ5!# #5!#!!3!53!5!5+uu?6ʿ63jkk\kk,{jj&{xV'5!# #5!#!!3!535!5!5-)wkkkkwG{jj{G !53 3!53 #5!# #5!# 3#4#XLP@Iu״j$djjjskkkk@T>q'!53 3!53 #5!##5!# 3#'&#l%ߏLhdj>jjkk3kkw7{1!53!#!#5!!#5!#3#4#I{.{IGj$dj`jjT>S'!53!#!#5!!#5!#3#'&#7iihdjB Bjj{w!53! $5#5!#3!#5!#3#4#3?Ej$dj#9kkǘrkkT>F'!!53!"'&5#5!#3!#5!#3#'&#T<)?hdjW6%MTjjs-#jj{#53#5!#! 3!534&#!3a9)kjjkkWpkJKq,m' >uTCH'ztqE167$#"&'5332654'&3!53#5!##5!#,5"nGIrXXw^NxpZUGh +rI""ca5Q[Vojjkk5kk;9'.3!53#5!##5!#32#"'533276=4&#8zMSca|_URT2,_4jjTikckkem_]B`Z>5ÏqE%%0!3!53#5!#!#5!##"&'53326GGGIrXXzX%~jjkkkk""caF9'%!3!53#5!#!#5!##"'533276ca|_URZ,.hlfjjSjj=jjۣ_]B`Z>>)"#3! $5#5!#3!#5!#3d$j?E"9kkǘrkkF'!)"#3!"'&5#5!#3!#5!#3dhT<)?W6%MTjjs-#jj;X !#3!53#;鱱jjj@i'z(!Nf-&zSn\&N 7uf!&nj9fDq3m' >uSfVH&z^ssQfVDs\' 7HufV!&jh\' 7uTC!'jto\' 7uUZ!&j ufIyf6I'Aq2'q<VF'qvq\' 7uVF!'jvs\&\ 7Hufj!&|jhs2fjD$s\& 7Hufj!&jhs\' 7ukf!&j32'q<a9'q\' 7ua9!'jk' @ua9f'\' 7;ueF!'jq353#5!#5!3#4#q{j$djkT>;'353#5!#5!3#'&#Fi5hdjTi{qn\' 7 ui<!'j9n1:4.+"#5#5%7>323!354.#!53#5!#!23! 2'3W?#y$?'k6 N`5zzzyyyJqM'z%&'6!#39ac20Ag?a, eIIg&C[5`n*+%354&#!53!".5'5!#3!#5!#323!l-zp[S'yy/ zzTUJmBBeLEpQbc52C){cczn`n/#2>54.+53!3!57#5!#32!A4!"@^=zy&yyz.cp8p )TK8J+e.ih*ccKC4.+";2>53#!".=4>?!#57!3#'5!,(]mbi7*aul])PtuŎPb]EqMOYE<}wiN.0n{A;usJx:GoڙSUلti~P_a/a.F[hu<n1%3!3!57#5!#3!Vzy&yyzz%bb.bbN`nf%4.#!3!53!3!53#5!#!23!;*z'xx(yyzZ3^F*T+;$``dd.bb(E_7fw94.#!;2>5#!".5%".=#5!#3!'!2"3"b,G4"3"坥i>iK*+B,yy %w5lW6{"=-5J/3VB)E\2/FT%fbbZ6+c AdDO7";7#4.#!!"$&=4>3!!23!ϔQ%Ec|R--4-yٸr9iry H~_7~f鄲K}]6CbA S^tb_5`Y3]Qe%3!".=#5!#3!#3!v/H1wx6Cqq3I"9K(bb?@c`nR )4.#!3%7!53!".5#5!#!2&Ea;1XF;}!{.I8) yxGiE"MAaA!/DfD"a` !7HPS&>cc9iZ14.#!>57#!".5!53'5!#!21D(1G-(?+/UvGN|X/xx|@vX5`"E8"$G8#)CU-L`7,TxMod-bb1To?H";2>54.++".5)5%".5'#5!'3!#!23!rNd8/H2r2M49/N;%O|XYf7(E2v{)"/|;D`=}!4T>%O@*&>P*B@L) WyL"&OxQ^G5L0jcc{-,b=iQfnE+23!54&#!!23!534.#!3!53#53U=!Y?4Z[-z%z0O:y&yy2N7*f8-(V```C5R8``axYU4.+";2>5#".'+".=4>;22>5!^8rr\ezC0IazJpEyeO7d)FBA"9YNK,W~[31X|[\yW/)E^406C/"<-%aokBlA2Z|ZƐ3T>,8" 9f\Wf:9f_P*':'2A#p3#+".5#".=5!#3!#;2>5#5%p|)\gk`-1F,xw1L3Ax &C51;! z|IJmI$"EkI"=R0UcbN'4 c@5G,.K6a)%3%"&5'".5'#5!#;3!5!3!ylj}0I1xyO? 5( zyy$>x~ 3U@bbBD*C0 cbO`n34.#!+".5#5!#;265#5!#!23!9)FoFQb7zy'=,TU||[?eF%{ !:+SZV*9cO6dc7cK-wbb^IxXgn2##+".5#5!#;2>5#5!2~9eSHi?yy$;++:#|INvN(*QxMbb.5354.#!53'5!2#!!23!Wd;1I1x%A2yyud,+cv=cu<}!UU :.E:'fb6P6>`C#9Zn6_xYR4.+";2>52654.'+".=4>;2!P3KbxGZK|eL25Me{GZlo9HG/N9,v]^[2/V{a^{W0 Q~W.=U}\44[~U`Va7sRB4/& QY/=k]^`66a^*jdN :K]:X_n 2";4.+32>7+3!5#"3!2PF_;;_F>aFFa>A}t|%u6wo2s2;1osэF}`` .3F1754&#%3!5%".55!'3!#5!!2!v\T{#{`:eK+ww.I5 {}6`I+{&fr``J"A^<cc&H7"cb)E[3en.!!34.#%"3!534>3!23!Rx +- y)x$Rb z$ejHHk__,x{?_n1%3!".5#5!#3!#5!#3!Tz}_X)yy&?/\zzz#B#QbccGc? ccO`n02#+".=4>73;25!".5#5!#3%#'!/zAiBAmE-EQ$s\T(wy2.| 6gO1+Lg<|$KD9 N`bbH"G9%~bn2%34.#!3!53#5!#!23!R{-L7x)wwzF{[5} @1S=#5!'3# -?NV]-JS+UJ}dL21Jc{JY)^\UA'rzz443&kڙ r#?Vfs;TaagJLI9"7_ODb:!4BB;bb_n;";2>54.++".5463!#5!#!23!fHgB6R8d-G0-%/5e^Zm>z~1+ZI/z!%A2h@V51WE@|#/ Z{K )PxOz.bb=[54.#!3!53#5!2#!23!%#7'7-9 !6'z(vvJ?z`;6]|EoQmBt<,"2U0(__c*@L#6T;#>X4bn\>+".=4>3;2>=4.#!#5!#3!!32\2UrAxiʞ`5Wn9W2^UI.]UJ6=iNy~1l0CpXB+/VzJ^@jL*`>)Eb?,=EL%G}^7aacj8pnn2%!354.#!53#5!#!#5!#3%!2!Tz4L3myyux||Ӄ{#*9"e.cc.cccbpo^n @4+32>53+3!53#"7!5463%!".5'#5!#3!2츸CZ7z#{DT/x'yW|N%y{1ZH^p?(-G5``>#LzW``N'A1cc#IqNZ;)#+".5!!53#5!#;2>5#5!;z8bO_n;yy{5N4%A0{!KhA@iKoc.ccCA];8P3Hcn1754.#!3!57#5!#!23!U{)?+{$yy{Vw\$z$E_;`_cc3!#5!aoIpQ/sJ 8LX_/jƿ;nc`]-9aFj:Y==}pT1]]xE!:O^h5A]]/aZO;"hQx[H"!8GaI8cI+=82#-;VwRn3%3!".5#5!#3!#5!#3!Vyoe/yvGz||#@CpUcc ccO`n%3!5!57#5!#!#5!#3!x'xxxyy|zaa c.bb.bbd E4.+!2>5";2653+"&=4>;#5!2/!'3!5T; -H3B&F6!/G1Q\`=n^Q4q~u~|%=+h*9"3J.,S@'pLI|Z3rNzT, clvwhdd/#".546732>54.=3K|VPnAUb?1%4Rf3BY51KVK1v%=NQN=%gj64c^r'&5%?hK)2XxFY|^OYqQ><@V=.0=Zd(<#".54>76.=34.#"32>;rjss9%@c\ &;AB5!*=E6 <~gC 0`RW_, /d[X\)vCLi:xpeO3BS5)C6``'.'+HpW A|^xDDw\Sk>?lP;57K%#".54>7>54&'".54>324.#"32>5R]nM)W]WvIbW/TA&%H) (W_K^5T{J#DeBSsH!!GrQIhB mw??rb^tb0-NGC"UR .!#0 '5@%1[E)(F_7R~5% LzzVpA2glSV,#Qe:Qe#4.'.#"'>7.'4>32>32#".54>7.#"54.#"2>;/EuWK_G>*5.(Y3*AS0S~X!-QBCX33XQ-:%G@6&0i)5uѐYrB!2?EIf[O)E[fi16UJD# 1_Zdp$Gc{lDmL)&Zn]\.)VP:;#".54>732>54.#".54>32hu?0=@>!7Y?@U49Q3-Q<#0<<(B04bWLŵ=lX9YC/@ +>P2IqN)9ZAg732>54.+532>54.#".54>32>rdh{D/Nd54*?`B=S34N6QY%G7"5T<5aJ+2,#,D/:iWMxK.L`3AiI(!hj6*Xa:jV< =([Hc>!QfDb<[7".54>32>>7.4.32>4.#"32>;Bw̤r> 4(EoN+0Sl<7YE1 H#/@V81I3CtU0 :0EHII+7 ?_A32#".>32+532>54.#"4.#"326dI{YZ~KAxgeuAKQM^p?L{M5.1S;!7V= 3?A{#@X6ŇFfKyMod/ "A6od//dܢj4d&#5>54.#"#&54>32Շsl$:'2`RHW/FJi}=rcdu@^= /cXxF(dC=aoOLF: H#".54>732>54.+52>'.#"'>3232E{b\|H5O\'tRY) 0'8qJ <4$B <)' TX-+54.#"#5>=4.#"#5>=4.#"#4.'.'>7.54>32>32>32'AW_c-5N40F,/F/*G64G,  2P:8H*8eaW_?>`vq^WvS;3NCA'Q&GIN.bxDFsN(UK: 8KS$%PG6 :JW/LnB^Q|dF%TKf\~N"9[Bq+E)(()E+t7\A$$A\7v+C)((%$&s7Y=!!:O\f3jzX@.8UwP%:+  ,#m&qhx72O76Q66Q66N3/id0D#".54>324&'&.54>324.#"32>FvRt{?J{U'UK8 }4bL.!%s BiAw9&Ea:>V6>^BI\5|h-NsmP$(nMN-D--u044HlH%'PzRd$;l\ri11ad4I#".54>3232>7#".#">3254.#"32>Jb`q?'MsK7P?5!:654?I),HB@" /MQMYwE8R67dM- ?^?8[@#ɋI:ql\S'#$C3!/N:%5!B^h89omxY#(Nrd@O.#5>54.#"#5>=4.#"#.4>32632[`~3C41"I#A@D'Z] +D24P68Q47F++7ADpP,9j^j&HWe8",1'W5I-Z1aYL8 (Hf>T'F&((&F'T>fH(+Ldt{<@rZ> W"iҳIwyLdL#".54>732>54.+532>54.=3:ohnx?'Ea;  <[>NX- AdEg.>&,I]a]I,V6YqwqY6 6FKK Mh>cq=^E9R;&  4bG:DK%#".54>732>5'&'57>54.5>539poRQ:T5";bHC];2Z\b:"PD-0O=?s2:74(2 &8I[59uG]UɊH*NpEFiK/ $#W@U3 BeE (CeI-WH3 *"F7 !/:@;0&3db>32>32#52>54.#"#5>=4.#"3#.54>7>7'":O_6i(&bZo?+TT[;O0'OF#H;&$7D!;V7$AW3eL\4,PfoG;%<]YQkJ% ?cE$lxxlJk[q!g0cjVyH@iMV&I%((%I&VNi@9lafm8gvRDp276++Kdqw8!A#".54.#"#54>3232>54.54>7"!H{X[o>%  ?0J4u5Q9I`8"3;3"80./22KWK3dp=4e^PEW1$,$@0oZ&OmWmF/2C9?:3x' '>>G_}d:u`t%#".54>7&'>7667332>54.'.'#"&54>7.546324.#">4.'326uR擘V%KqMAcI1 +%H2=9/((!'a{r\'  $2&#-cP 15@.&\6UggU4e13*j""$&+0(!W466223  *=;j%+".54>7;2>&54.#"5>5'4&#"#".573267>32>32 :[XfHzM+QtJ(!:Q/Z@S/#..4 ,6,7!)3"(E1..',14=\)6E+AoQ-AyjX?#)[fEpT3G )@X:Xk;%;LOK-:# $.. ,.,((-/-AK356M3?bGx\U0;$#Qdd;cw#".54>732>5<.#52>54.#"#".54>32>3224.#"32>but|Q/@_A3^PjR! 5U@Xc1 *J:#510 ErM_l;;oc!LKFFGB[m=6^JF`9.N;CU0/SC@Q-__W)-=EK$(6$&$%-N:"!BeE=[C, POqClL()$1AO-d)K|UZ}K"8+(8#?nUdY0 &TPcS$-ZW[U(&SP:D#".54>732>5.#".54>32'%30dk=xm^F'7[t= -"-Kb5JV- 2G@D/#;*',L6*-Pl>8XKD% "WsD':Qh@[U-A +BZ9@kN+0Tq@?H$ 'A19?-B]C;hM,(@0@[e:c'>54.#"#5>=4.#"#4.'&'>7.54>32>32&T_:B" -O=;]A#9Y@=Q0$2"1}]7E:fY/TG7b,g>IqM(?q]4`O<E[j6Zh9`P~l.H'P]tKcW()Id;W&H%((%H&W;dI)*X`%VZYO?0/2;GYoF,G=658! :'W97 $Mpt;7Q62Q9AuP8=%#".54>73265#".54>7332>53[~J0UuD!!3S324.#"#54&#".54>32>324.#"32>R@xilq::Qcs>*UH6 -9DALTK0)1D*/JZ,]oX@jK)(F`8DW17]G>\<Ym=_bCp^C&%9E"1[f^^f[-,9#I5>@BY6Td\\(\oXm>+_o\wE"^dB>'4.#">32/32>54.#"#4>32*$;-$3!3AV@TqB(AV_`+$(JB.3P:6fO/2^WH`:OHI1!9+"9I')H5>tf_~]=O%dNe:0Nb1G{p5&BX2?gd:)Z#".=4>75>7332>54.#'532>54.53]]{ŊJ"B`=*MMP-;HPJ<I&6% )NrJKqK&$>U1}'8$(;E;(X"7GIF7!H{^#MKD4hl7TR8 +9& #+eF\klg+cwB,OoBN^5\2P9+OKIKM))=2+*0324.#524.#"32>Awdrr9>nY2]N>+06L08]E8Z?!nFJ́^U!:M,L]3>0YQ/a{F?mThp<,^P:Zv'>54&#"#54.#">32#>'.'.54>32>324.#">7>"2! E;$=-a 5+3;/zKf< (@MVTM<$G "-5  FqQOg(7I0E^9+B,9eL,#SN@!J'>5/+),9:'3nn 4%*QwNROni3]RDSc='iv{r]BGFAcr*zQih3XV0B)3M0:_E&'BY3*QwI0+*ahmP:p'".54>732>54.5&6?#".54>32>&'.'.''>737%5.#"2>#4=4#>sΩyB1Od2"6P4Ib;#(" #$IHF"2K34Q6@GJ& M? */- $042A4@dE$ 398' $0;:4E_L@J^Crc-%R`CiN5>)8O98]D% CiHBlZMGE% I)+UC*1JU#*YI/%9F!1TF8Dy/ $-37ZyFF=RpMKR)>E[E B?9RZ,x:( .55/ &1+6I#".54&#"#54>32>74>764."32>+Nd_k9*I1M61O8%:%%?V2(DQ,:MlA2SxaC$4N5jn.̀8E|g&/,7DJDY44^L-BPyX:{2;@PȚi7&BZ5AmN,;o2:7%#".'72#".5332>54.#"'>7>7.#".54>32>7>54&#".54>3232654.'76K.&OPPMH 8VB2@DB3 4`V/WB(D/:3F,!0A )9&315 &<:B+*#-1T99'@R*WiR$B>3&:'>6 e"6B 0O92D' 2FV. %,$"E8(F+k6V=!)Hpl#8:B+ ,>Q3FoM)1H/% /I3+O=$  "?@F+ ( ~l0*7M(k.~H1XC'=ti )1>*/9 0< &*' (B.9V;-NB6''IKN-:E% DD z'6Gd9e#".546732>54.#5>54.#5>54.'.533FuT6qj^G)ah! *Lj@BT1#,.,xx@;* *,*oo@;)3bRQyO'.'?P*m%,GX-0]H-"@\:7bI*fa0"9SqIb&/#2D0CiI'&HjDGZ52$ %C7(7# /- $@4(7"+J:'9S6"<1& ,=+,E4% 6GSd?h4&#"3>#".54>3 #32>54.#52654.#52>54.'7T@K-9 Oi>$8F";01<<2hL+WW *_n(JiAJ^5'LJHZ-:KN(B/*;$!?CB4 KE,TzNf->W)F9,$/9"4-&-!e%!4?0N6&7D=9,4/,:![gM 2CRZ^eN@4.#"73>737".'#5>7.54>324X@yu,DN# *SB(DmN"LKG-gr|B 5kor;NUU!RtJ#KZ9ncT=#3jZ'ɏd##dV{j.  #6A<6* 2o~SkF!=Wk}d<R>'##".546732>73#".546732>54.'5',VOD13ali$Lh>&m#"(Ga9HvbR$}:\r8OxQ(8qq^{Hx 3WC;Y<5U>[8VidS>3 4\HGW=$B(,'%C\8^/QWfDw0.aj!L :JM>oS1-fxNtN)cd:[%#".54>732>54.'5>54.'.54>2.#"T6(SD+1Rm;,]WM:!~lzB=d}AIqV@T,B[?Ia98]zC`[- >.A)5Q?2@X|WKiC@lQ AR.&<-4YJ<%.>R6n/dP#"32>534.#"'##".54>$735#"$.54>3237'#376t`*~)J8!*g #>V4pxPOn 7egm~EM JAwfqi8 gMMgnOT>_A|u"3#m0 u~Qh AvNuM'2[MYW.(U]MZ1!HrQyC5Id<T'b4.#"32>".54>323>73>32#"&'##732>54.#"3v8N/$WJ2-GY-1N6_q?Bt\5?D!,N?8=?[uA7>54.#".54>3232>5<.'7X[XW^KvF4jV5$,G4 td@/cR5*T{QLfG1<_g.Ok=;YID&>Ueod8=332>54.'3#".'32>74.'7#"&5d*F\39I*;Y:{W~P&CrU*I=1u3232>76&'7#".54%5.732>54&#"dR]nM $5ES,YzK!2G+.R>$$(=7&:hWK}Z2T{J!BcBSuK"Jf?Fmw??rb2_VK),,)PMI"'9' -!*9d3J13U=#(D[3j% Lz]Ve83gl,\dljB 14#"32>7! 4>323267#".#"363205&Ge? $$:*":%0.# @2~y5H* /O9 >  !+d  /64>2".4>2".4>2".h%*&&*%&*%%*&%*%%*%`,'',','','},((,'d[E'>54.#".#".#".54>73.'.54>32l 1`Q6]C&'MpI&E9* d %4C(+*-   .="=V-/DzdZzGiUlC -\J/  '$ 5+" 'I!7R[p?6afD 8?32654&#"'>32#!32673#"&'#"!54&#"#>323267U퉆tsmS}t_`V7Juy+zvzoF[XIxcc))WZXY*}[ԺfD22#"'&'53327654'&+5327654'&'&#676KLLKT__hc >>ul:9FG&&GF99ms|[YDgGGHGf%]-.43_j45d45i`32\|a_JJ`- #"&5462#5!#3!C/.CB^C.DD./BBjjkfD(/" 6&!54&#"#>32>32#"&'#"73267(Ry,IEςFIz8F}ba`cc``c)fjD 4& #4 ؗ2fj  653 5=(.2+z!53##!#!2654&#!jjokktX4j^`z{ 14632#"&4632#"&!53##!#!2654&#!E03BB30EE03BB30Ejjokk$0FB42BF0DB22BDX2l`^z\p0#!#3!2654&#!#3!2654&#!#3!53# uwjj%jj,jjTijp{5n`o{`o{3d|!5333!53'!3ZISOjP\iOtNgC; ;;;#!#535!3!53#5!#5!!53#5!!53 4?8w`gRtMN6NNN;;;32v6ʝ8`=GEEG=aEG>ȼ86?ef?77d>77G632654&+53#5!2+3?^bb^xxőFZUVY;<;G#3#.+3!53#5!2%3264&+j,@rݓ*G>xx݉mi_ZZ_; 3.; M.;;32VUVXth&eCp\TER <32+32673#"'&VUVXth&eCp..TER <<:87HI4~BE>IP9;@)(jY]f)C&%87x ==@'53#3#5#"'&63254'&#"32761oo"45M|ON}M54"..XZ-..-ZX..]<$;]8WW;k98?>|{@?89@| 7>32654&#"'>32+32673#"&'#"&'!54&#"#>323267VUVIHYE4N|ZQIS <IP'32ff)CK87x0312x{GFbc3hjkg% #53>32#"&'#5732654&#"p"iM||Mi"\XY\\YX\;8658];kq{|}qk@ 3#5#"&632#5354&#"326o"iM|}Mi"mt\XZ[[ZX\;]85686;;kq}|{q@!32673#"&54632.#" fcMa]z\UP\ x{GFbbchjjh@!!54'&#"#67632#"'&73267@33dL11]KKyYYQR.-VP\ x>=#$Fb12WUSSch55kg@U1"&54767&'&54632#&'&#";#"2673T0/UU/0|5<''ID%$,-WW-,HEHN ^98VO:'( ((9OW x45<8;683FI65@U02#"'&'53327654'&+532654'&#&#>B/0UU0/|5<323!534&#"3!534&#"3!53#53>32"hEihhe=FMQde=FMReio!c?Ni{BCtu;;4[Mhc;;8YKhc;;;j32#"&'5332654&#"35io!fDn55{l-S'<649697yK\i{62DImQhd;@26&""&6 '___&Ã@>32#"&'53326'&#"@oYXXY@~@D -,R^`0/_KY=_dVVVUN$$AAEF@ 4&"#46 @__&ƀ@ 2653 &5__ڱ% "32654&#"'#53>32#"&'3!53 \XY\\YX\tp"iM||Mi"mp;kq{|}qe<]8658<<%#53533#32673#"&5ffu!,-*WY[eS<py>32#"&'!532654&#"iX`}6{{6h&&h`ďd_ _dktGgq'53#5!#3#3!53rjkgzjjjf9R%3#"&'533276=!53#5!ëH>_UR[++ijjh!!`Z>w^y<S+L!- 05&T,@U1"'&'3367654'&+532654'&#"#567632B99_ NIE$#,,WWX#%DJ''?B<<5|/0UU0/56IF36;8:<54x WO9(( (':OV/+#.#"3#3!53#5354632+=42A5oootq*T*w*+?QM<$;;88y>:aR=;_I""6{ 45\v3#"&'533276=#53#53 m{k.R'<549ppu\i{62""I:;;5 53#5!#!535xxow!N;<< /<D#"'&'5332654'&#"3!534'&#"3!53#536763267632<=>k.))'<3:6FM)(deFMReio!12?N45"35Ei44b\54 {6DI['&44c;;8Y%&hc;;;j< #"@B!";9u/13!53#"'&'#"&5#5332765#5332765#535om c?N54!44Eihh=FM()eFM)(d<<-;?#"?A!"tu?<\M44d32327673#"'&5?MP*+eio!fDn5594<'*)-l>=m)(44d;;97yKI""6{ 45\553#53#5!##35WW(~JYq;C,-UNRC++JI%&U\_**IIA>8I""6{ 45\dC! 42'0%%9R./ :! .%'(>T10 &#"'&'533276'&7632#&'&#"L=l.))'<638& C< K=l-*)'<49% ;bPA4 {62"->lrQ?4 {6#->%&#53533#32673#"&'53326=#"&5ffu!,-*Wzl.R'<63:6&eS<88y+;< m()53@+#"&'&'&54767#5!27654'&'53`993-;XHI#<]tUh?>>?hV9:]/"3#&'&5#537654'&'Ga893-;ufuVH&z^q7^' ?u)Jq]&I5<sk&*Xuf9&J\q^' ?}u+J]&KH<qx'}+Jx'Kq\' 7}u+ ^&KH<qu&+Ju&K'qC&+}JC&KFK&,K&LHqr&. 8L|;&N 8?qx&.I;x&Nq&.I;&Nqx'/;xR'FOix2&q<xq3&qF=q&/s&OHq'/ 'HOfk' 8u0J^f'Pf^' ?u0J^!&P{fx'0Jx^D'Pd^' ?gu1J!'{Qdx'g1JxD'Qd&1gJD&Qd'g1JD'Qs&2'Hu :Hfj&R'hhxs'Hu&2 8Hfj'hx'hRqk' 8u3;Vf'Sq^' ?u3;V!&S{q7^' ?u5J!&U(qx7'5JxD'HUqx72&q<Jx&q4q7'5D&UH^' ?u6s!&V{x'6sxD'Vx^' ?usx!'B^' ?u7;']'{:<WxB&7;x'q&WB&7;-q&WB'7;Aq'W`xb'87x''RX`Kb&87K'&XR`b'87''RX`b&8'u 87&X'HHr`b&8'u7]&X'HH<j&9 97&YBx'9x''DY 3k' :u:!d'oZ 3k' 8u:!f'oZ 3\' 7u:!!'jpZ 3^' ?u:!!&Zo x3&:!x'&Zo ^' ?u;j!&[B \' 7u;j!&[BZ^' ?u<9!&\<\?k' ;u=Rf&]\x?&=Rx'&]\?&=R'&]J&K'^&W9<!&Zo9&\<fL&Dls!&Vx&$fxD&D9E&$uf&D9x&$'ufxf&D'99 'u&$ 8%f'9&Dv9 &$'u :%f&D'99 &$'u f{&D'99&$'u 9f&D'99ox&$'ufxH&D'99qx3&(fxVD&H^q3E&(ufV&H^q3j&( 9fV7&H^qx3k&(' ;ufxVf&H'^^qE&,uJ`&=qx',Jx`'VLsx'H2fxjD'hRsE&2Hufj&Rhsxk&2'H ;Hufxjf&R'hh`xb'87x'&X`bE&8u7&XHZr&< :|96&\CxZ'<9''h\ZL'|<9'<\Zj' 9<97'<\f0&*|f0&bf0&7f0&Df0&8f0&Ef0&9f0&F&*&bX ',7| ',D &8d /&TE&9&Fsd&*$d&bd&7!d&Dd&8Bd&El /'* 'b '7| 'D m':8d 'pEJVJ&*dJVJ&bXJVJ&7\JVJ&DlJVJ&8JVJ&EJVJ&9xJVJ&Fx '* 'b A'7| Y'D 'L8d '|EW'9XQ'FXJ&*FJ&bL&7g&Dd@&8 &E&9L&FO '* 'b p'7| v'D 'F8d 4'|E'9Xz'FXfj& *]fj& b]fj& 7Nfj& D]fj& 8fj& E &* n&Qb 'g7| 'vD  '8d D''EJx&*NJx&b?Jx&79Jx&DWJx&8{Jx&EJx&9QJx&FE 'b 'ZD l'E'XFXZ"&*0Z"&b0Z"&7 Z"&D,Z"&8<Z"&EDZ"&98Z"&F@ '&* {&Tb 'j7| 'vD '8d S',E'9XG' FXf0d&Vf0fdd&VrdfJVJd&VJVJfd&VXJffjd& V{fjfJxd&VcJxfZ"d&V1Z"ffP0&2zfP0&2{fP0&2|fP0&2}fP0&2~fP0&2fP0&2fP0&2P')P') P') P') P') P/')P')P')JPJ'jJPJ'jJPJ'jJPJ'jJPJ'jJPJ'jJPJ'jJPJ'j P') P')s P A')5 P Y')M P') P ')PW')KPQ')EZP"'@ZP"'@ZP"'@ZP"'@ZP"'@ZP"'@ZP"'@ZP"'@ P'')R P{') P') P') P')B PS')~P')0PG')rf0H&zf0&qfP0d&2fP0D&2fP0f&2f07&+fP07&2!i&z!1&q;d&VdfP')*P2'67&'&5476D' JO 1!&6"7#,LS#&8F'J7~7J&j+VJPJd'jJPJD'jJPJf'jJVJ7&+xJPJ7'j0d'tV^fd'V^fqP')}'* Vd'*(aJ'+*H&zU!&qL&TR7&+d&,d]m& >ui2&q<Dd'V^f'Vbv&a$bJ'+bJxH&zQJx&q]Jx&TBJxVM&*DVM&bDJx7&+HJx&,<Zi&z!Z1&q;pd'V^@f  'b77'Vj7RsdCZP"d'@ZP"''@ZP"f'@Z"'+>ZP"'@Z?d'"V^=fed'>V^Wf}P'')RRfv2&'&75476,"7&"1 OJ ''F8&#SL,#7ZZs10!!ZsZZssZb/10!!ZcbZb/10!!ZLbZb/10!!ZLbb/10!!b]&BB%@ i  91990#>7%ME}@?[@ b  91990>=3NF~+?=[Z@   91990>=3Z_WE%Z.'3N~F+P[=/@  i  991<290#>7#>7LE|ME}@?[P@?[r3@  b  991<290>=3%>=3NF~@LE}+?=[P??[Z`2@     991<290>=3%>=3Z_W;_XE%ZPE%Zr.'3.'3rN~FN}E+P[=?P[?9; 6@   b HH  <2<21<2<203%%#5#p##pFs9;\@1  b  H  H <222<22212<2<22<203%%%%#55#p##p##p##pFE%'3!    104632#"&3~|}}||}3q3 64632#"M87NN790pNN87N $4632#"$4632#"{M87NN79 M87NN790pNN87NMpNN87N/ #&@a! `$ $1<<220%4632#"&%4632#"&%4632#"&%M87NN79LVM87NN79LVM87NN79Lh8NN87NM88NN87NM88NN87NMq L #0<@L|@B?@=@=>?>M G$jjGj=*j1?7`A=iM$>0-'@!' :  - :4! D4 J M9912<<2290KSXY"2#"&546"32654&"32654&"32654&#'2#"&5463#2#"&546WddWVbcXcdWVbcXbdVVbaU"ZܻۻZݦ!\ܻۻ ۻۼ q o !-9DOS]2#"&546"32654&%2#"&546"32654&"32654&"26&#'2#"&5463#  &54 WddWVbcWddWVbcXcdWVbcXbdbaU"Z<¹ۻZZۻZݦ!&\ۻ ۻۼs##@Z210 5s)+#ssR##@Z<105 +(#^R^sXX't&>32##4632#"67654'&jT{:IaM97NN795S4ZI)/.ֶ3 B{pNN87N(;eO- BE&""|&"[|'t"4 2654&" '&5476 0jjj}_^^_R_^^ļrrrrrrr/462#"3!53#53}+:*)inoo4&&4%n;;<5P@'  M  h  \<<91<<290KSXY" !535!533#3TNriTTRD$!67632#"&'5332654'&#"#%$01;bacbHNNrfmv:;n?/0%;\ KKJJOTtnl::%( ,27654'&#"67632#"'&54632#.#"85445bch4K&EG?[Z¢]^7<=?OZMBB::lm::pjo<j%LKij 8554&'5[aUUa7<;7=r.!53#53676323!534'&#"34gm 23Cm34ecKP)*c;Eh3 Dh吏uZ#0;37367"76!32!73 4&+3 #"'3254#"8t* @|0vDP4JJH4\V|JJDR_^wژznX,sB7#RmNCq]$)05353#535#535#5!23#3##!3!27!5!654'%!&#!qVVVVI ^FEZ M@8Bj6kVkkq@Xkk^CrjVkRC327673# $547#53676?67!5!654'&#"#676323#! 8^]^]s{U͹$!7RSXYq||h YՌ :lGFRQ3K=j^=7 j+ҾA7jb@*jq!*#&'&76753#&'&'6767q+t]d{dCBd|jL?\WP ~~ef@Af(;ϭ;'_x'&r_ ')r`3#353#5!#!#5!#3!53!33!3`R8Dyyy yyyydy\bl3#7!>323!654'&#"chHl?'ox!z"sjVlne=fCUjjgE=!HZ353#5!#5!#!335Z mU/yyyy7By\RoizL+ /#"&63264&"!!463"##52765#5!+ghhg-OOuNN̓ԗ#"yԗ#"t+iihhhP">Qrkf`)353#5!2#!332654&+367654'&`R&ppyefjGgfGyyy㭑vx:SR9V 2F$! ;#"&2#">54.&7u[xy5y3L5{z/SS:%/?`{|;a?//?`hjdt/92)BKLB̾>cxc#@`UcTR~RSdU_A#$A_UbSQ`#'1B3!.+3!53#5! %326&+#!&'&/67654&'&?Yz-ڙEaV=Ty"&$:%&˦.\1<,0: \W`yÌMyyy!h?#J*^p)7Q%+7fCa#+(z@D  # '%!b) &S"7$S P PP TPS$T 7)2291<<22<22999903#3!53#3#53#5)#5#3!53##^VVV+TVV}-DVVABBBB7VBBBhBBBhL 35!#!!53 3L{5jhA\}'}''!#! 4'5!#5! &'&54DuPNusnccotL-FS6FӉW֗g[`_\gaq.mF'353#5!#3!53!33!#3FPpppy5yyyy5y52S '$4'&7#5!76'&'53%7654&3276&/7#cĚA6\k36|u, >KhO$<.)37X#E̸Gwgnk!4fMJ,:]B`%b*VEZ;h1.p` %3!53#5!#5!3#ӿ3yyyy-`2#3!53!3!53#5#!#2yyy-yyyS%!5! !#5! !53#7MXh{{ڗAcP*Z\H!!6$3 !"$'53 !"kJu^uopkoSUggHF_`2/.2%!#!5!)+!5!_++!# #3bef9 '%3265!#73#7! !%#$65&?}F o)jIIbSy,G|dyyYgy[Mk"&44#"26?6$ #7!3!7 '&547 3 &477_n{- ց$=9cyAdCDph'=q[Hz*`华"Xico*xeydKX"?Ԗ8pCsL?vDD ,364'&"3273# '&547 &4?67354B8;&*Y~VNwS3hoL%96XUS\wԹfFS(kO\:qhjG;  462"&3!73#7!&>4&"3#*NOox0<1 !pp-ha7g`yy5y(%#(<(j59 #+462"&#7!!"'72672654#>7#LOO%@8x,q%L0 !=79wJRp-gb7f`y\'?:^{(<(.A1UK+qa 7 >54&#"%!>3 #"&'332654&'3!53>7'#FWWfMi.30CsqngDlEO 'cSNfGXVe=yB""kpqZ=yq Pikk`X'ud'5{ZX'ud'5tq'd'5{Zq'd'5tdq'd'5u5q'd'5'd'5{D'd'5'd'5{d'd'5uD'd'5O'd'5'5{q,qH %3!53#5!+3)׾jjjkkq %3!53#5!+3#3gpjjjkkq #5!###3!53#5!Z{jzkkjjjkk9h%3!53###5!# #5!# 9jjjjkkzkk%3!53###5!# #5!+3:) ɾjjjjkkzkk %3!53###5!# #5!#!#3#3 ʾ Yjjjjkkzkkqj 3!53#5!# #5!# 3!533 h@Iuנ.Ljjkkkk?jjs ; %3!53 3!53 #5!# #5!## FTLP@I˿ujjjjjskkkk? #%3!53 3!53 #5!# #5!+3!# ־IJLP@Ipujjjjjskkkk?q/s&q'f0J`LJ'LLJ~'L'LLJ'YL'Y'LY t'L'LY 'L'L'L YJ'[Lj'['L[ r'L'L[;ROfDFfGJ^DPq 0 ) ) # !33 !P]P7#˺#7vAtjLlHq &#5! )5; !#67654'&/RP˺#7ܺxxc9LL9jkvtjLlHasXutWq 0)56'3 !#5#35&'&76! ) 6#7ܺxx{6 xxNP]P22 DLlHa2lk2aD vAts332#"#6$3 #"$s0ا%qzImpaSHISXA@UpadfD33276'&#"#67632#"&fwKLLLFGkedde荍?}|ttts@@0L?8 L@  <2991@    990@ D D@@@@@ T TPPPP ]!#53? _   J@  991@ /<2990@ KKOOOO@ [[____ ]!53%   _ uh8 L@  <2991@  990@ KKOOOO@ [[____ ]!3#!u _ Qc cQ L@  991@  <2990@ DD@@@@@ TTPPPP ]%#5Qc cQ _ Lh83#!#53} _ _ Qc cQ -#553%Qc cQ  _ F _ -Q %'7srfKrKfP %%7%Kfrfwqj 7%'%sfwjrqwf.j '7.rqwfsrfKL??!'!#53!? _ QE XEuh?5!!3#!'uP _ EXEQc cQErFf'7327>2'&""'&'fK^X{|X>>sWX>UV=Kf^XX>JJ>sXX>J%&=NFB"&'&"'7>232?%7%]=VU>XWs>>X|{X^K^=&%J>XXs>JJ>XX^fL?8!###5333? \ _ \T Q Q!#5553%%Q Q T\ _ \ uh85!333###u T\ _ \ EQQc cQQ3%%#555 QQc cQQ \ _ \T LF8 !#53Tr.r _ Qs sQ nh8 '57!3#4r.rTI _ Es* *sQc cQL?8 3#!#53 _ 88  )5!53%!8 8f _ uh8 3!3#!uf _  Qc cQ !5!!%#5 Qc cQ( _ )5!553%%!EQ QEa  _ E L?c2644#!#530-@@-qq _ @Z@ uhc!3#!"&463" _ qq-@@Qc cQ➢@Z@L?c#!#53!5462+7264&"â _ ➞qmm-@@Z@@ mq➢@Z@@-muhc#"&462!3#!354&"mq _ m@Z@@@➞qmQc cQm-@@Z@Lh8/ 3276;3##"#"&"#"'&+#5332327V*!NUI _ 6%VZ.V.ZV%6 _ IUN!-~Qc cQ** ~-Lh?3#!'!#53!} _ \ _ Qc cQE XE` -'7%l! )ev|  =f !#!#53 _ ^  3#!# _ Qc cQ #53!3 _ V( ^ !3!3#V _ (Qc c  %#5!5!Qc cQ,v _ FmU4 #53!31 _  Z)'R#4."%#54>2'AnnAQc cQ[Ԛ[TnAAnT _ uԚ[[)ZR4>2%#54."[Ԛ[Qc cQAnnAuԚ[[u _ TnAAnTQ %'7%5!!1srfKjrKfɢu?'sr^ !2>4&''7".4677AAnnAA7fKM[[Ԛ[[M7nAAn7KfMԚ[[M!7".467%7%2>4&rM[[Ԛ[[MKf7AAnnAArMԚ[[Mfw7nAAnFE?83!!F QF?5!!#F>    %# >3#5  uEn8!5!3n Q Qun #!5!n >Q #3% Q/> 53Q/ Lh' ^ZZ'!^Lh'^ L2?'>'>u2h' > '!>!F,n'O8JF,n'NK8L?%#53!7!!!!'7!%7! _ Y&VBDMxVBD33 77^^Lh!!'3#7!'7!#53!!!7!7'BY _ Y>VBY _ Y; 33D337c c7 ^^^^uh%'7!5!7!5!7!'3#7!!7'B2 DVBlY _ YDD3377c c^^^L?8%#53!!!! _ Y33` ^^53'#'# ^^G _ Y`33uh83#7!5!7'!5! _ Y`338c c^^#5373c c^^ _ Y33`Lh83#7!#53!!7'! _ YY _ Yv1(3338c c ^^^53'7#5' c c^^^^G _ YY _ Yv1(333.'78KEr|gsiK4sg|rE7%''/'-K4sg|rErg|sEjW%'77?7|rg|sE4Es|gr.jW%'74Es|grtKEr|gsL?%#53!!!!!! _ =5==| uh3#7!5!7!5!'!5! _ =|==5 L?8##53373#' - _ xx~?E ==Ϣm==uh8' #53733#@?~xx _ Em==m==Qc cQ!#!5!5!5!53%!!!!88 88X _ GX3!!!!%#5!5!5!5! 88Qc cQ88MXG _ XL?8#5!#5!##53!#5w _ 碢 #53#53#553%#53 VJ _ \uh853!53!533#!53=VJ _ \EQc cQ3#3#3%#53# Qc cQ _ u?8 !##33!? a }E^^u?8 !33##!u} a QEEQL?8!55!!#53d=_=;EE %3'3!#53#EE dd=_=uh8!7'!!53#5d=_=EERc c#7#%!3#53EERc cfd=_=%5!!!'3'3!#53#dEE dd^SdS=_=+ %3!53#53#'3'3#!5#c^ș dEE=_=d22+ 3'!3#!5#73!53#53#3'E77Ed^ș Py7722d=_=Q+3'!5#73!53#53#3#E;d^ș ŸEy12d=_=OϺ2)#57#53##3'373!3'3c cDD JEE>==_==;H>+%%3!53#57#53##3'3733'3#!5c^ș cDD EED==_==;z 22uhg #3!53#577'!5#35o=_=d22șc cdEE&" %'7!!srfKd{rKfd  7%'%!5!sfwrqwfQ}d3#53#53#7#3'3cc c EEEE=_=`=_=<(uh8"+!6762!3#!"'&'!%3&'&#"#3276uz2PP2 _ 2PP2 (:4.  (:4. ?2PP2?Qc cQ?2PP2? )) ))ZZ'^!uhJ !'3#7!!'3#7!!'3#7!u{ [ {{ [ {{ [ {q , L?8!#!#53!3?Т _ 68 8uh85!3!3#!#u06 _ ʢE8Qc cQ8Lh83#!#!#53!3} _ .. _ ҢQc cQ8 8L?8!###!#53!333?MXG _ X88 88uh85!333!3#!###uX _ GXE88Qc cQ88Lh83#!###!#53!333} _ X _ UXQc cQ88 88L?8 #53!P=_=Q uh8 7%3#!5=_=,QQc cQLh83#!#53%7=_==_=Qc cQ ,  !3!3*B᫻1+h-)6@'! '!* $$*9991990>54&#"#"&54632#"&54324&#"32IH7$$0e՘ݢe WOmVPmmWKt,>bFأ[t}t{| !5!!5!!5gg+|!'7#53#5!!5!73 !@4Eq#W?4,+*â*â g3VM@)ddMwb91/90KSXY"% 33^]<;A+3V! !#3#Ŭ1+%!!"$$3!!"!![Hج(HA,m,Aޠ(\(oLTTLo"*%!!"''&'&$;3#!!'!#"[Hc[mqQV(^cNyLAp,5$A,87T\(8נo[6TLZoLT!5!2#!5!26767!5!&'.H(خHA,m,AdجoLTTLo"*!5!2+'7#53!5!&!&'& 326767Hd[mqQVخ]cNAp1,4#A,d+8Uج8נ~\TLZdooLT5w'=@"  V WV V WV22122<20!#3!53!3!53#56JJJJJJJ5w'!53#5!#!#5!#3'TTwJJJJJJJwJ@#    <91990@  *]]!#'.#!!>?3!5 nNI =DN)u?$ HNh"%!%)/1@ r10!!Ӣ !!#!5!!!1Ϡ1yyTF 4632#"&!!#!5!M97NN79M1Ϡ18MN78MLyy+@M`i10KSXY"3#7RS %#'-73%yL LyL\ \8v}vw}g&"265$62"&VzTT|TQOSWU|ST3"31UevYQJPG__KDa*M2CXXieu~९{YY /D@$ !- $'!!0 $U*U0999919999032654&#".#"326#"&54632>32#"&2TevYQ1UevYQG__KDa_/YYie9XXie~९{⦮uI%!3!~$I%!3!ȢT~$8{#{e8# 37#'usus usous8###٢ee8a3737##'esآes^?ces@es!3# ihTJ3 3##"JT#4$ #4. x(\(ނ~(خ~ނ3 $53 ><جނi~ج(~ނ/%#@  & XX&1026732#"&'.#" #"&546327j Pd@7*8  kOeD=!0 l9TA6?&#Hn!bSA8?S/'/ D'J'1y 4632#"&!!M87NN79L8MN78MLy 4632#"&4632#"!!M87NN79LM87NN79r8MN78MLpNN87NHy "-14632#"&4632#"4632#"&4632#"!!M87NN79LM87NN79M87NN79LM87NN798MN78MLpNN87Ni8MN78MLpNN87NHy*#"/&#"5632324632#"&4632#"ۿ\e\eM87NN79LM87NN79'? E? Eb8MN78MLpNN87N'#"/&#"563232ۿ\e\e'? E? E'32?632&#"#"'ٮe\e\'E ?E ?!!#"/&'&#"5>32326c]\ _\Ye]` a\ZT? 9ILZRB 9If!!#"/&#"5>32326b^` !_\Ye]` a\YSB 9ILZRA 9I8l@9216/$#(!6/,(+! /(/6 6!921$#+9<2919999999999990#"'&'&'&#"5>32326#"/&'&#"5>32326c]\ _\Ye]` a\Xb^` _\Ye]` a\dZT?9ILZRB 9IѓYSB9ILZRA 9IfD 4632#"&!!!!M97NN79M8MN78MLD %4632#"&4632#"&!!!!M97NN79MM97NN79MF8MN78ML8MN78MLD %4632#"&4632#"&!!!!M97NN79M M97NN79MF8MN78ML8MN78MLD 4632#"&4632#"&!!!!M97NN79M M97NN79M8MN78ML8MN78ML1k 4632#"&4632#"&!!!!M97NN79MM97NN79MN8MN78ML8MN78ML!1k 4632#"&4632#"&!!!!`M97NN79MM97NN79MyN8MN78ML8MN78ML!'<@!  r r  <291<2<29990!!!!!'7!5!7!}/H{}?f٠f٠F !!!!!!Ҡ &@r  <2291/90 5 !!po &@ r  <<291/90%!555f%!!"$$3!!"[ج(ނޠ(\(ނ!5!2#!5!2>.Y(خނdجނ$%!!"''&'&$;!!'#"[20ea#!(cNOނABn8 V(\(8נ>+oq? #!'7#53!5!32>&'&TYRخcN_poނoE80Vج8נĠEA)j7!!!!"$$3!!"ج(ނ ̠(\(ނj7!!!5!2#!5!2>.(خނ جނ !#533 $53 >] = ]uجނӢ9 9j~ج(~ނ 4632#"&%3 $53 >M97NN79Mhجނ8MN78ML ~ج(~ނ !5!3!!3 $53 > ,,جނ++բc~ج(~ނ3!!!q<!5!!5qĠj 7!!!!!q ,<j 7!!!5!!5q 0Ġ!#!#<r)3!3Ġr #+$  $!!&'&'&!67676!ج(\(ULoA,,AoL6uULoA,u,AoL\(ج'-AoL7uTLoA-u-AoLTLoA- $  $! 676%!&'. ج(\(J,AA,X,AA,\(جTLooLTLooL &/$  $ 7 &'&  676'&  76ج(\( A  oo AA oo\(جXo AA oos AA  !$  $&'&  >'&ج(\( A oaoނA \(جXo AJa Ao #4632#"&$ >. $  $M97NN79Mނެ(\(8MN78MLނނ\(ج)&"265$62". >. $  $VzTT|TQOSłނެ(\(WU|ST. $  $7L L7L  ۂނެ(\(vKvwKyނނ\(ج!!!! >. $  $VVނެ(\(llނނ\(ج!!& >. $  $Vނެ(\(Ӣނނ\(ج 3!%!)!!!!.p0ppq1qq 3!!%!!@@1q 3!%!  !  m$nn#n 3!4632#"&!M97NN79Mf@8MN78MLY@3!!#٢sgf#!5!s+!!#!gg 35!3! 3!!#٢5ˢgf 3!!!!#٢55ˢ/. 3!!!!#٢ss #!3!!#{^/Ѣ+gf#!#!3!!#{^/++gff 3!!!!##7ss+3!!!'!#٢{[agDzDBf3!!!!!'!#7!٢<SWAs3;XDn)D#!33!!#'7#{^{CnAA+gDD[[f#!3!!!!!'7#7#%7!{^S4WNtX+Dn)DbBL  a  104632#"&M97NN79M8MN78ML 3 %! ||$$$`j!!#jHo#!5oj3!"Hjo!5!3o/j^!#^c?$%%$~  1;FOY!! &546;#"&546 !54632+32#"&=54&#"3#"32653264&"2654&#l(ع(DbEDbbEEbbEDbPDbabbabDv(D(غPEaabbDEbbDbaaE DbbEDb^!3!b?c6732#"'&'.#" Pd@7* l l9TA6?%Hn*u( #"&546323267u Pd@7* l (Vl9DTA6?%Hkn T !!!!%!!Bf6L̔4+x  #/;GS_kw+7CO[gs!2#!"543!254#!"+"=4;2+"=4;2%+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2%+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2'+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2'+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;22+"=4#"=43+"=4;2+"=4;2"=43!2#UݓJIIJ%J%%J%%K$$K%J%J%%J%F%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%%%%C%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%$%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%$%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%%%%%%%*$%%%J%%J%%K$$K%%%%%JJJI%%I&%J%%J%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%J%%%% %I%HJ%%J%%J%%J%%J%%J%.@ 7!!!!!!u(3(! !! $<.73!3!`5!!X3 2!@ 2 5!!5!!5!4)4𬬬 !!!!!4)4XXX 333 Nf  !!!@@@ Nf  53353353353𬬬 3333333XXXX 333322s's' !!!!@@@@22s's'!!!!\!!#!!#\!5!Z!!X!5!$Z!!$X3!-Ԭ3!-.*!!@Ԭ!!@.*5!3,,(!3,X5!!@,(!!@X3!!- 2Ԭ3!!- 2* #!!!P@ZԬ 33!!P-#,Ԭ!!!@# 2Ԭ #!!!P@.* 33!!P-#\*!!!@# 2*!5!3,Z,!!3,X !5!!#@PZ,( !5!33$,PZ,!5!!$@Z, !!!#@PX !!33$,PX*!!!$@X!5!!Z !!!!-XV !5!5!!,ZV!!!X!5!!$#Z !!!!$#XV !5!5!!$#ZV!!!$#X5!3!,-,Ԭ !3!!,-XԬV 5!3!!5,-3,*V!3!,-X*5!!!@,Ԭ !!!!@#XԬV 5!!!!5@,*V!!!@X* #!5!3!,-Z,Ԭ !!3!!,-XԬ !5!3!!,-Z,* !!3!!,-X* !5!!!!@Z,Ԭ !5!3!!$,-#Z,Ԭ !5!!!!$@#Z,Ԭ !!!!!#@#PXԬV #5!5!!!!P$@V,* !!33!!$,P#X*V !5!533!!$P-#ZV* !!!!!@X* !!3!!$,-#X* !!!!!$@#XԬ !5!!!!$@#Z,* !!!!!$@#X*5!35!,-𬬬!!!-,XX33*!!@@*DH5!5!xX333x 2 2H !!!!-Rx !!##xmsZxH !!3!!xm3-sZRH !5!5!5!,NX 5!###lZZXH !5!!!5!4l t,ND 3!!!--Dx 333!x,ԬxD 3!3!,(D 5!5!5!3,,D|X 5!333,,(DX 5!35!3̠| 3!!!!-- 2Rx 333!!xs 2 2Ԭx 3!33!!-s, 2ZR !5!5!5!3,,X !5!333xtZ, 2X 5!3!5!33t, 2H !5!!5!4R 5!!###sZZH 5!!5!3!!t,-sZRD 5!5!3!,-DX 5!333!,,ԬD 5!5!333!DX,!5!5!5!3!!!!,,--R5!333!!###s,,ԬZZ !!!!5!5!333!-s t,ZR, 4763!!"Q[yY[`~| 4'&#!5!2.-Yx[Q`~=?x 5!2653#xY[Q[~|2Ψx !"'&533![Q[Yyx2|~>3m 2>#3> 2> # # 3 3>ݲ}#$cc|5!F3F~|5!|iF3P|!XF!@F~|!|iXF!@P5!5!!5iVV333PP~P!!!iXVV#!#P@P~P;(;!O;!O ;!O;!O;!O;!O;#!O#;(!O(q(!((!((!((!'(I(!]((!((3(:(' q( #'+/3!33!33!33!33!33!3mnmnm;(%8K#!1!!!!!!!#!1!!!!!!!#!1!!!!!!!#!1!!!!!!qlllllllllmmm((((;(!%)-13#3#3!3!##!#3#3#3#3#3#3#^^(ll(lm#;(#q:(!&9'(9(&&9(&9(&&9(&&9('9(&9(&&%! %!!!,7r+uv ))xxp) )$7632#"'327$%&#"%632#"'~~~~eMM>yJJJJJ6````qq|qq#u"@91990  9%-p) 327$%&#"%632#"'MM>y````qq|qqr' '/7?G%&'&'6767&'&'7%'676727"'64'7&"'62&47\+;.81F9K58.42d;E9G,:.80G9J6&8.;+d1O9FLL&_`JnLL'`_n<1& j(0=Ju &,A=N:0('<1& j(0=Ju &1<>EB0(n_II'[[JnII'[[p) %/36%632#"'327&#"6767&'&6py AAAA,+-,,-+A@@Rqq|qq%%mܱ[0$ %@%|"p) )73276'&#"7632#"'327$%&#"%632#"'r99:9rr9:99XWXXXXWXMM>yB!!BB!!oe33eje33````qq|qqp $  $pkk]Ak^p $  $27$%&#pkk]<MAk^a``p $  $"3pkk]<MAk^``p $  $327$pkk]\MMAk^>``p $  $%&#"pkk]Ak^>``p $  $"327$!pkk]<MMgAk^```p $  $"!pkk]<Ak^`p})6%63"'pRqq)#2y|q*q( 2654&#"!|~}}|v< ( $%632#"'327$%&#"!IMM>y_O````|qqqqH( ( !#%&#")%632OyyMMqq>~``  3327$3!#"'$@1>qq``) %63"æqv`) 2#%&#u)q>` 527$3Muyv`>q "'$33yuMq`p)%632#%&#"puqq>``p03327$3#"'$puMMuyy``>qq!% !% !%! !%!$3! 2654&#"4632"&nȊce;~|ddcc||}%!%!!d r<%!%!!We r<%!%!W7 r<%!%!W7 r<% !%!!!!+c,b r<<!% 4632"&! W>>VV}V2 j>VV>>VVJ !%! c  !%! b  p(  7& $  %;<*X֖% !!!!!!,7,rWb<)) Ie% !!!!%!!,crWbM)MM^??@7`d?\gOOOOy>*<?v^  <BHNTZ`fl3264'&#"&7367'67675673#''5&'&'7&'677&'67'%%&'&'%6767%&'0/CB^0/AC/88pkTcR|NOOfUip88pqUfONNQaQh!$ b)dLQk KRt!% c'd&//^000NN|P_Pfp88poQ`QyNNP\ Qgp88pmQ \Py,  M N>&`7" bK*V&"g{ M M !)1a + 0,+0$++A & 6 F V f v ]A ]A]A)9IYiy ],и(и(/A0&060F0V0f0v0000000 ]A00]3 +++&"+&"*и&.01! ! 3254#"&#%#7&'67&'6767KJ]_VNEWMCe2ntjnti7IL6a] ]pu otpu ot !)1a + 0,+0$++A & 6 F V f v ]A ]A]A)9IYiy ],и(и(/A0&060F0V0f0v0000000 ]A00]3 +++&"+&"*и&.01! ! 3254#"3$3&'67&'6767KJ]_TNEAgntjnti7IL6a] Uypu otpu ot %ͺ + ++и/A]A)9IYiy ] "и"/' + ++ и / и$01! ! #$''&'6%&'667KJOR`7IL0c Z    "*2:AIXY/Z/ܸܸи/и/Yи/и/BиB/CиC/EиGиG/LAL&L6LFLVLfLvLLLLLLL ]ALL]F/H///W+$'+$+и'/013#''%#&'52#"'&5476!!'5%!!'53'5%3'5%3#'32765'&#"sNN99=>-1\ H0e%FKSwZGr=;=NN$E| 1 ?'_>?@7`d@\hPPPPy?+<>w_VG{?,rCA0:1@!7+7 + .++..9и  и /к.9A7&767F7V7f7v7777777 ]A77]7!и+=и.B /"/+/-/ / + '2+':+:2'9и и и/2'9017#'#53'&'&54767&'&=33676=3#32654'&i($lm$(($[Uu&tU[$&uU[[UV$|ddb e|$% ZSSZ %_TYYT* $+++A]A)9IYiy ]A&6FVfv ]A]и/"и&/++ #+ #ии!и!/014&#"326&5432%##5!&w衤礡PP䤣L~~| * $!+ + +A&6FVfv ]A]A ]A ) 9 I Y i y ] и/и/&/+ + + и/ и/ 01"32654&'#5!3%#"5476礡𳉧פ㤤ף |~~L #+%+01&$76+"'&5'476%7!ttsstEus pid5s qttrtt<֤ꧦg\ul9S//и/A&6FVfv ]A]9ܸܸ//++0152654&#"#43233#!5 z{ym㗗yyy{(|jǸ /!/ и/и ܸи!ܸA]A)9IYiy ]и/ ///+ + ик  901#53533#632#4654&#"#*jjoon}mZyH{zF2 4˺+ + .++. ܸ"и$и&и (и+-ܸ0и+2и.6/$!+$ + &+&$'и&)и$+и!-и /и1и301"32654&7#"&54767!!53#5!!3!!#3!!8OO87ON=0LmkL/>Λ2  1O79NN97Os0LllllL1KӘJJ-'< ++4)+4к 49ик 49 49" 49#A))]A)))9)I)Y)i)y))))))) ])+и+/, 4942и2/9и4>//:+:и:к 9 99999"9#9+9,9192901%#5#535&'&'5'73'3#'73'676=35'73'33◰zhNgeMjzzTThOʍ7NjYYӖy?//и/и/ܸ ܸиA]A)9IYiy ] + + +01! #!!!'!27674'&#.d ;6zFH%QM_\ǃ$P<C#+///"/01#"'##56'##"/547?^'5@_*SU&/UL ;Yԧ9UP(` XI.s2Q3/4/ ܸ!ܸ и /3и/ܺ+ 9/&+и&/0122732#&547636=4'&# #4'&#"*t pz&=<xQ>hG:V Hek%PF5NP B|-&pA&NFX // 901 &&5 <F:^;" V gdG7C+///99 9/901236;2"##'65##"'&5476;235&'&=476e x<JT`(GeRUdfB3 VNT9D///4 +4 к#94+к=9>901+"'##56#+"'&575477;2732;276=4'3&'"~V"0b*SV*8UiQ"_|Q )w`SgA ? 6N #euB? gIo5 F(pZRw// /9012367632#&5476(t*#\l~ ΨT]1klSI|-X //01 &47E osU H2`g+Z+N+99V9AZZ]AZ)Z9ZIZYZiZyZZZZZZZ ]i//^+J+J):+)и/) и!и),и,/:7и7/JAи:QиQ/:Sи:UиU/V:790126;2"##'65##"'&5476;2&'5476&+"326733276=4/#"567654'&#"35&5hr=)\"IfRUdgC3&=cG kv ==Nr%SZU 6vk 6)S<F98:d  mOE:R p&i  C]&'Ax.+0 nM,W`c%+///9013#"/4?23hH0#!cZ-@o3+///99013#'654'&'#"54732XWz=\9`Y'6?F` 1TFG*֙-@x/e/ /и/и/ ܸи/ܸ//99901#"=4?2%#"=4?26ձ'VQܖCت+YP*~: ۉ8z"Co//ܸи/ ܸи/ܸи ++ +и/и/ 9901"'4723!# 5472!5kmOdXX[;Z$}@Ϝ"  ++к 9A]A)9IYiy ]// /+ 9013363'$6'"-8 w?WXc1 0 // и /и/ ܸи/иܸи/ ܸи и//// /99 9 999013%#'#3%#)N(4/c}4(,=++и ܺ 9ик  9ܺ9к9и!и%и&и'и+и(и)и*к, 9////99 9 999999&9*9,901377#'#'547#5773%%.wwzy.**  <<7CA<<{8AMtuh8 !53#5u=_=c c#u ! ! j.u-1{3 #pph # 3hp(53'#'#'## ɻEEG _ Ax/'/@(#5337373(7 7EE _ A@/'/xel2%2>4."%#54>2"&'7nAAnnAQc cQ[Ԛ[[M7AAnnAAnT _ uԚ[[Ԛ[[MlO%".4>2%#54."26rMԚ[[Ԛ[Qc cQAnnAAnrM[[Ԛ[[u _ TnAAnnAAu%-5=53676$ 33## $'&'336767675&'&'&'#uBV(\(VB _ BVVB,AoMTTMoA,,AoMTTMoA,EqqQc cQqqTLnB-u-BnLTTLnB-u-BnLTL 8 !#53 4 _  u ,8 !3#!u _ 4Qc cQL ,83#!#53 A _ _ Qc cQ L 8%#53!!!! _ Y dC33  ^^u ,83#7!5!7'!5! _ Y 33C d8c c^^L ,83#7!#53!!7'! _ YY _ Y:m3338c c ^^^L 8 3#!#53 a _ 88 u ,8 3!3#!u * _  Qc cQL 8 3#5!#53!5! a>Y _ Y33 ^^u ,8 #3!'3#7!!7'Y _ Y> 33 c c^^^u ,8#!3#!' #537鷷x _ ??x==Qc cQm=====m==gP I,g I,gP' I, I,g I,gP' I, I,g' I, I,gP' I,' I, I,uP IP' I I,P' I I,P' I' I, I,P' I I,P' I' I, I,P' I' I, I,P' I' I,' I, I,u IP' I I,' I I,P' I' I, I,' I I,P' I' I, I,' I' I, I,P' I' I,' I, I,uP' I IP' I' I I,P' I' I I,P' I' I' I, I,P' I' I I,P' I' I' I, I,P' I' I' I, I,P' I' I' I,' I, I,u IP' I I,' I I,P' I' I, I,' I I,P' I' I, I,' I' I, I,P' I' I,' I, I,uP' I IP' I' I I,P' I' I I,P' I' I' I, I,P' I' I I,P' I' I' I, I,P' I' I' I, I,P' I' I' I,' I, I,u' I IP' I' I I,' I' I I,P' I' I' I, I,' I' I I,P' I' I' I, I,' I' I' I, I,P' I' I' I,' I, I,uP' I' I IP' I' I' I I,P' I' I' I I,P' I' I' I' I, I,P' I' I' I I,P' I' I' I' I, I,P' I' I' I' I, I,P' I' I' I' I,' I, I,ag I,pagP' I,p I,ag' I,p I,agP' I,p' I, I,ag' I,p I,agP' I,p' I, I,ag' I,p' I, I,agP' I,p' I,' I, I,aP' I,p IaP' I,p' I I,aP' I,p' I I,aP' I,p' I' I, I,aP' I,p' I I,aP' I,p' I' I, I,aP' I,p' I' I, I,aP' I,p' I' I,' I, I,a' I,p IaP' I,p' I I,a' I,p' I I,aP' I,p' I' I, I,a' I,p' I I,aP' I,p' I' I, I,a' I,p' I' I, I,aP' I,p' I' I,' I, I,aP' I,p' I IaP' I,p' I' I I,aP' I,p' I' I I,aP' I,p' I' I' I, I,aP' I,p' I' I I,aP' I,p' I' I' I, I,aP' I,p' I' I' I, I,aP' I,p' I' I' I,' I, I,a' I,p IaP' I,p' I I,a' I,p' I I,aP' I,p' I' I, I,a' I,p' I I,aP' I,p' I' I, I,a' I,p' I' I, I,aP' I,p' I' I,' I, I,aP' I,p' I IaP' I,p' I' I I,aP' I,p' I' I I,aP' I,p' I' I' I, I,aP' I,p' I' I I,aP' I,p' I' I' I, I,aP' I,p' I' I' I, I,aP' I,p' I' I' I,' I, I,a' I,p' I IaP' I,p' I' I I,a' I,p' I' I I,aP' I,p' I' I' I, I,a' I,p' I' I I,aP' I,p' I' I' I, I,a' I,p' I' I' I, I,aP' I,p' I' I' I,' I, I,aP' I,p' I' I IaP' I,p' I' I' I I,aP' I,p' I' I' I I,aP' I,p' I' I' I' I, I,aP' I,p' I' I' I I,aP' I,p' I' I' I' I, I,aP' I,p' I' I' I' I, I,aP' I,p' I' I' I' I,' I, I,ua IpaP' Ip I,a' Ip I,aP' Ip' I, I,a' Ip I,aP' Ip' I, I,a' Ip' I, I,aP' Ip' I,' I, I,uaP' Ip IaP' Ip' I I,aP' Ip' I I,aP' Ip' I' I, I,aP' Ip' I I,aP' Ip' I' I, I,aP' Ip' I' I, I,aP' Ip' I' I,' I, I,ua' Ip IaP' Ip' I I,a' Ip' I I,aP' Ip' I' I, I,a' Ip' I I,aP' Ip' I' I, I,a' Ip' I' I, I,aP' Ip' I' I,' I, I,uaP' Ip' I IaP' Ip' I' I I,aP' Ip' I' I I,aP' Ip' I' I' I, I,aP' Ip' I' I I,aP' Ip' I' I' I, I,aP' Ip' I' I' I, I,aP' Ip' I' I' I,' I, I,ua' Ip IaP' Ip' I I,a' Ip' I I,aP' Ip' I' I, I,a' Ip' I I,aP' Ip' I' I, I,a' Ip' I' I, I,aP' Ip' I' I,' I, I,uaP' Ip' I IaP' Ip' I' I I,aP' Ip' I' I I,aP' Ip' I' I' I, I,aP' Ip' I' I I,aP' Ip' I' I' I, I,aP' Ip' I' I' I, I,aP' Ip' I' I' I,' I, I,ua' Ip' I IaP' Ip' I' I I,a' Ip' I' I I,aP' Ip' I' I' I, I,a' Ip' I' I I,aP' Ip' I' I' I, I,a' Ip' I' I' I, I,aP' Ip' I' I' I,' I, I,uaP' Ip' I' I IaP' Ip' I' I' I I,aP' Ip' I' I' I I,aP' Ip' I' I' I' I, I,aP' Ip' I' I' I I,aP' Ip' I' I' I' I, I,aP' Ip' I' I' I' I, I,aP' Ip' I' I' I' I,' I, I,a' Ip I,paP' Ip' I,p I,a' Ip' I,p I,aP' Ip' I,p' I, I,a' Ip' I,p I,aP' Ip' I,p' I, I,a' Ip' I,p' I, I,aP' Ip' I,p' I,' I, I,aP' Ip' I,p IaP' Ip' I,p' I I,aP' Ip' I,p' I I,aP' Ip' I,p' I' I, I,aP' Ip' I,p' I I,aP' Ip' I,p' I' I, I,aP' Ip' I,p' I' I, I,aP' Ip' I,p' I' I,' I, I,a' Ip' I,p IaP' Ip' I,p' I I,a' Ip' I,p' I I,aP' Ip' I,p' I' I, I,a' Ip' I,p' I I,aP' Ip' I,p' I' I, I,a' Ip' I,p' I' I, I,aP' Ip' I,p' I' I,' I, I,aP' Ip' I,p' I IaP' Ip' I,p' I' I I,aP' Ip' I,p' I' I I,aP' Ip' I,p' I' I' I, I,aP' Ip' I,p' I' I I,aP' Ip' I,p' I' I' I, I,aP' Ip' I,p' I' I' I, I,aP' Ip' I,p' I' I' I,' I, I,a' Ip' I,p IaP' Ip' I,p' I I,a' Ip' I,p' I I,aP' Ip' I,p' I' I, I,a' Ip' I,p' I I,aP' Ip' I,p' I' I, I,a' Ip' I,p' I' I, I,aP' Ip' I,p' I' I,' I, I,aP' Ip' I,p' I IaP' Ip' I,p' I' I I,aP' Ip' I,p' I' I I,aP' Ip' I,p' I' I' I, I,aP' Ip' I,p' I' I I,aP' Ip' I,p' I' I' I, I,aP' Ip' I,p' I' I' I, I,aP' Ip' I,p' I' I' I,' I, I,a' Ip' I,p' I IaP' Ip' I,p' I' I I,a' Ip' I,p' I' I I,aP' Ip' I,p' I' I' I, I,a' Ip' I,p' I' I I,aP' Ip' I,p' I' I' I, I,a' Ip' I,p' I' I' I, I,aP' Ip' I,p' I' I' I,' I, I,aP' Ip' I,p' I' I IaP' Ip' I,p' I' I' I I,aP' Ip' I,p' I' I' I I,aP' Ip' I,p' I' I' I' I, I,aP' Ip' I,p' I' I' I I,aP' Ip' I,p' I' I' I' I, I,aP' Ip' I,p' I' I' I' I, I,aP' Ip' I,p' I' I' I' I,' I, I,uh8#!5!3!333###!4̢ dL _ L ` 88QQc cQQuh8!###!5!333!333###!`XOX# dL _ L  8888QQc cQQL?83!!!!#5!#53!5!m00Т2Y _ Y33 ^^uh8#5!5!5!5!53!'3#7!!7'G00Y _ Y2'33 c c^^^Lh8!#5!#53!53!'3#7!!7')!Y _ YjjY _ Y33=33  c c^^^^^uh8 #!#3!333#1 l dL _ EQQQc cQL?8 3#5!#53!5!Y _ Y33 ^^uh8 #3!'3#7!!7'Y _ YW33 c c^^^3!!%#5!5! 8Qc cQ8Т _ 6!#!5!53%!!8 806 _ ʢT`53'#'##T G _ =|==5T`#53373`  _ =5==|L?8 !5#!#53? _ 碢 uh8 5!35!3#ur _ EQc cQL?8 !#53!!5#!5s _  uh8 5!3#!5!35!A< _ ddEQc cQnh8#5##53333#!'573}J dL _ r.rT1碢QQQc cQs* *snh8  +6=4632#"$4632#"$4632#"$4632#"$4632#"3#~5(&77&(5(&77&(5(&77&(5(&77&(5(&77&( _ oN77'&76N77'&76N77'&76N77'&76N77'&7c c !5!5!!% ^^} a  %!!5!5QEEQ a }nh83!3#!##'573  _ .r.rTQc cQ8s* *snh83!3#!####'57333U _ XXr.rTXXQc cQ88s* *s8nh8333###!'57 dL _ L r.rTQQc cQQs* *snh83!333###!##'573< dL _ L Ģqr.rTqQQc cQQ8s* *snh8%33333#######'5733 dL _ L ϢXr.r8XQQc cQQ8s* *suF8 !5! Tr.rEQs sn?8 !!'574 r.rs* *suF8!5!3rCTriTr.rEsQQsQs sQn?8'7!!'7#'57rTCrir.rTsss* *sL?8!!#5 k8th8%!=!37' kQQnnL?83#!#53! k r8uh8#3!37'#!r k  QnnQ.i%'%'7fwfKLweKe.h%'7%7%xfLffJfx-/ '7"'7264m0eKPPr [?Kf1PߠPs ?[27"&47%7%F?[ rPߠPKe Z@ sPPewjy %'%&462&"Few1PPr [?1wePPs @Z.j0y64&"'62'7m ?[ rPߠP1we Z@ sPO0eKQ% ' '7 %7%s..sfJJfr-rJfJfQ%' 7 %7% %'%r-rJfJfQss-IffIj7  %'% '7ss-JffJjr-r-fJfJ-Q  '7 '7-r-r-fJfJs-.sfIJfQ 7% 7rrrr~srssrrrQ ' 7  ~rsr$s~~ssr}r}Q ''7%7%%%'%r~rrfqfqEr~s#rfqfQ  7 %'%''%7%~rfrfs~f}sfQ '7%7% ' 7rf~rsrrf~ssrQ %'%'  7fjrr~sFfrrrQ 7'7 %7%rsrfr~frr~rfrfqQ '7%7% ' '7rf~rsrfrf~s~rfLh8!3#!"&'&"'7>2,Q _ ^>XWs>>XQc cQI>XXs>JJ>W,%!5!26553%V[ ɢ] ` P.2%#54&#!5؞Rb dP[VޠP ` ]F^ #!#53!2653^ޠP ` ]_ [Vn 33!3#!"&V] ` P_V[Pd bRW%>4.'7'7Kj;;jKr[FF[wLԴLrZZfK]%%'%.67fw[FF[rKj;;jwfZ ZrLԴrO'7>$ ."UwfZ ZrLԴfK[FF[rKj;;jh?E%7% .'72>bKfZZrLԴ(fw[FF[rKj;;jeB%!5!%."'>$ %'KLԴLrZ ZfKj;;jKr[FF[wrO !533##5#5%'7>$ ."HwfZ ZrLԴJfK[FF[rKj;;j(=m7"&''72>4&SrM[[MfK7nAAnrMԚ[[MKf7AAnG=267%7%".467a7AAn7KfMԚ[[Mn7nAA7fwM[[Ml9)2>4.##".4>76732AnnAAnT Mn[Ԛ[[jv uԚnAAnnA:!nxԚ[[Ԛ-r[l9)2>4.'&'#"".4>33AnnAAnM Tn[Ԛ[[u vjnAAnn!QAnxԚ[[Ԛ[Q-Lh !#53 !3#!Z _  _  Qc cQLh !3#!!#53Z# _  _ Qc cQ^ Lh !3#!!#53Z# _  _ EQc cQ uh8 533##5#5!3#!d _ JQc cQL?8 533##5#5!#53= _ J uh8!5!'77!3#!''Zrr _ &rrErrQc cQrrLh8'/3#!"'&'!#53!6762!3&'&"#276} _ 2PP2 _ 2PP2 (t(  (t( Qc cQ?2PP2? ?2PP2? )) ))#264&"7"&47675553%%QtQQt?2PP2?Q Q8tQQtQ|2P䠠P2 T\ _ \ Fn8 3!#!F  Q QFn8 !#5!3n  Q  Q %#5 Q   3%#5 Q   FEn8 3!3!F  QQ   #3%% Q/( F Fn #!#5!n F (Q  3#55 Q  u ?8 #33!a }E^u ?8 !5!33#} aEQE !5!!%# ^(  %3%!!5 QE( u? !!##3( ^u? 3##!5 8EQ #5!5!^(} a %!!5!538EQa }F ?8 3!3#!F  Q88u n8 !#3!3n Q Q %!!5!88 ࢢW #!5!!% Q/W F? 5!3#!#FW  88un #!#3!n ࢢWQ 3!!5!5 88  5!5!!Q/  F,?'K8J'M8Lu,n'O8N'PQ8F}n 3!!!5!'3F (hP| F,n #!5!5!!#n >>hPQ F}n !5!3!!5n dhO QԵ KF,n 5!!#7!5!F> h> , F? !5'3!!?6/ AFN? !55!!#?6/>  un !5%!5!3?6 A QuNn #!5!!5n >/65QL'PM8'Q8Lu?!264&#!5!2#!u-@@-EqqE)@Z@uhq!!!!!3#!44g _ qQc cQuh#"/&#"563232!3#!zu;jnAsozt;jo@s _ ? E? EQc cQL?8#"/&#"563232!#53zu;jnAsozt;jo@s _ ᓮ? E? E uh8#"/&#"563232!3#!zu;jnAsozt;jo@s _ ᓮ? E? EQc cQuoh8'1%#"/&#"563232#"/&#"563232!3#!zu;jnAsozt;jo@spzu;jnAsozt;jo@s _ ? E? E? E? EQc cQLd?6 5!#53d _ Ѧ! Lre!!#53!?2 _ 'ת Ӫudh655 !3#! _ //yFQc cQudh !3#!!!"&63!!"u _  ͑ NnnWQc cQ"͢nnLk%%!!"$'&'!#53!676$3!!"!!VB _ 7BV(A,/,A޴q qoLTTLoLd? !#53264&#!5!2#!5? _ NnnN ͑W Xnn͢Z+t%"&767&'&63"3!!"3f f͑NnnNDNnnN+"f f"͢nnnn@+Z2#5264&#!5!264&#f f͑NnnNDNnnNf f͢nnnn46 676 #4&"#4&""f f"͢nnnnEg g͑NnnNDNnnNx '&' &532653265f f͢nnnn֑g g͑NnnNDNnnN#u  u-/ 'J'&/-27!5!7632#"&'.#"!!#"&546327jR_Pd@7*8  k^_OeD=!0 TA6?&#Hc!SA8?S/4#"&5463232#5!767!5!7632#"&'.#"!!!lL_OeD=!0 d<_Pd@7*8  b`SA8?SfEZQTA6?&#HMD% '7%'11m,J+mU1L1wl++l/"%77%7 '711m+J,mU11l+K+lj^ 7%'71M1m+,m1L1ql++l/j"^ '%' '71M1vm,+m11wl+K+lLh8!53#5!#537'!55*`=_==_=c c EEEEL?8 !#53?=_=  )#53#c =_= !3#53Qc c=_=  '7%'m,J+m9wl++l/" '7m+J,m9l+K+lj^ 7%'7m+,m^l++l/j"^ '7vm,+m^l+K+lLh8!53#5!#53*`=_==_=c c 3#53#53cc c =_=`=_=uh %#5!5!Qc cQ _ Vu1h !5!53^ )V _ L? !!%#5Qc c _ L1? 53%!! ^) _ %!%!!W7 r%!!!W7 %!!,7rj~jJ!353#5!>323#'&#!534&#"3Th3lhd_zj@jVln{jÏjq353#5!##5!# 3#4+3qGͪj$dij;)53#5!#5!# 3#'&#!533Jihd‘j@j kk{j\?35!#!!#4#\{^j$dHZHD>R'35!#!!#'&#RjffhdVf#V{q{!3!53#5!#!53#G{{~jjkkF'53#5!3!53#5!#{{fjjSjjZ@-'5&'&'&'&54767347676567654'&#"q;FHA-BV"H)27=ט+LdP # [$!9) 3}3P1 020 KT KT[X@848YKTX@848Y4632327&54632#".}E00E2mm2E00E-*.EE0 0EE.-0b^2]9fU1 020 KTX@848YKTKT[KT[X@848Y4632327&54632! &0""02||20""04400$$##$$00J*5v@ -1%-$1,/'$64,-'6 , 06<2<<<91@!+ $/z$#( q05z ,3/<222<2<22290%3!53#5354632#.#"!54632#.#"!!3!53BB`RPfTBB`RPfT(jjRkKNqKNqkjjJ'"}@1z"q z - =,' , ,'0#<221/<222990@ $/$o$$]KTX###@878Y'.#"!3!53!3!53#5354632/^z{Ǯ갰WYVUdCjjRjjRk`Ju@. z zqz  =',, ',0<2<991/<222990/]KTX@878Y!3!53#"!!3!53#53546ף'ٮ갰Vjj@dkjjRk`H ;@%/,-'2-4%-$7,5'$:,-'6 , 0<<2<<<1@$+ $5z$#( q.36;z ,19/<<222<2<22290/=12]!3!53#5354632#.#"!54632'.#"!3!53!3!53CBaSOgT-WY^z{ǮjjRkKNq`VUdCjjRjjF6y@-'6 , 07<2<@ 2,1,'5,<<@#,!'&,/'91@"&15z. %4/<<222@0 z (z!qq220!3!53#5354632#.#"!5463!3!53#"!!3!53CBaSOgT+ף'ٮjjRkKNq`Vjj@dkjjO.&#"3!53#5354632!!32673#"&5#53Cr갰W[CZ4FHB.dCjjRk` Nk]LU_kdV#.#"#"&'5332654&/.54632&54632!!32673#"&5#5354&#"jjutw-.CCgbj|_{ֽ V?@<Z4FHBhHE+gtRRC(*)-.HFo,,wv]YFV1-,fW))+`prk]LU_kreoX-TL !%$32654&#"3>3235>54$#" M97NN79ar~{TpMN78N{+3캶.L#5333!53!3!73#z23E{}<ؖMy\yy1y#;l`R$(:H353#5! !32654&+32654&+#67>54'&67654'&'`uyHBi?#"L?W-3S3QGyyƤf}v-iCZ5*"(!4M0k?4'%*Ly8!Z$;`'%32+53#5! !%#676'&UoɏB YABy,GE+yyy%;53;`353#5!#5!!53#5!!533`>yyy!\`353#5!#5!!53#5!33`3{ yy!y\V3$2.#"3267#5!# !267'&?-ҿT;I6::T | Q?=Ʊ&&xNLhi@AAguity'<̫:`` 353#5!#33`8yyyy\jV{533265#5!#!"&6765MLaMS2G)S^X+yy"e%L3`3 353#5!##5!# 3!333`y-ٓg8?MUyyy!yy3yy\Bu`s 353#5!#!533`L%yyy-\V{!353#5! !#3!53#3#3%#3Vhg13呑D|_yyByyysy\V *ABC%2#" ! %&7>4.'2%{TxyS}|;a?//@`);`?//?`<!%\BKLByddERSdT`AFB_UcTQRScU_@F@`UcTR1P|xL)H7332654&/.54$!2#.#"!"$654'&/.'&54ؿn۲' ĵhлђ::AP_cAD;`<1ZHbvrZd+78Ǹ,,gf]a4742O}AH/71GTH3 5#"32634.'&547hFnzjsq_q cjMORdyp(@1 P)NI`yTP?{Wc""ldlRr<3^MUfK`Und/F#77#5!>32#"&'!5326&#"#>54.ǘ-pp-_jmYYmj_yp,00, ;G3# /+4#y#xSQQSyfʯ1"C56 AYXDuQC( TD&# !2#.#"3267&&4oup~r}zk>.uv.=HL& (**هπxT,qo+ Th $354&#"3263!5#"32#5!3&'&767o`inYZmi`b-pp-pk::W:dd;i6ySQ,*QSxy"rqCstDTD%*4&#"!32673# ! &=473&5N^[O%|s+. C%$#Xҩwηzt#(vshjh?$#.#"!!3!53#535463234pKEPH :UN R@p NLsyyy5yklP7T9hD+2A!"&'53326=#"325!4&#"326565#&'&76jsq-pp-`inYZmi`HpW:dd;W::`!!ifySQ,*QSy6V`^CstDrq?!1353#5!>323!534&#"3334.F@}EUkdp p#5/y#x}_Tyy5i#y"-/.3/1+Dg<)F #'4632#"&3!53#5!32654&#"3#pQOooOQpo ((!ppTQooQOonuyy5y-((5h9= +34632#"&#5!#"&'5326532654&#">5#oRNpoOQp)F %3!53#5!3#?oppyyy#xe"FHD0=LP>323!534&#"3!534&#"3!53#5!>3234.%34.#Js=S^h>R_h>np"4.)p&:pyjayyhyyhyy5y]Vc"9y +Eg<'"323!534&#"33%34.F@}EUkdp p#5/y5y_Tyy5i#y5/.3/1+Dg<)TD+%26&" ! 67654'&'&p[Z\\?>-$yy$-/,$yy$,0Tq+)w"qq"x!qq"z/VFD !%3326&#"%#5!>32#"&'3!5;#676'&)_jmYYmj_-pp-bp::X;ee;HiʯySQQSHyy!qrDtsDTVhD"&53!53#"325!4&#"32653%&'&76їc-pp-`inYZmi`ypjW:dd;W::!yySQ,*QSy6!CstDrq;LD#.#"3!53#5!>32#LqPLtF4|Yp3US̵\yy5yok >5X-D)S7332654&/.54632#.#"!"&67>54'&/&'.'&54`qlsIi^Ձq lo@SѠcO E(1Q1 '$+9," E)w}KF@F%)!mnEB6>%51nQ)3"% .).3+ O ۜ p#yJyuDVZQ8+);)/')3!5#"&5#5!3265#5#.'#?}BXkckq*p"40'Ry_T+ykyR51Cg<)'!#5!# #5!# 3ub  {Igyy`yyR5 '#5!## ##5!##37 37Pȋ}tZ}|%FD';LyyRfyyyR'4'#5!# 3!53 3!53 #5!# #ϼ<\ɏJwgOyyFyyyyyy59' #"&'5326?#5!##5!#!70s1xGqCCAP(1se4ubMJGc%5yyuyyjHF' 35!#!!53 37Hb5wwp4,y9+wF`1 )$26&" ! '676'&'&QYYY>+*>+##,/-##-/XHIpq,, LM-f- !5!5%!!3w;yyw,#>3 !53!57$54&#"!!67654&'&'xzz?`Év?^3@4::TVdB%%ДJ=o^DUlJo**zɴ*7H>3 !"&'332654&+532654&#"#67>54'&'67654&'&'v!vy B4vyT9;5?9vI_f10*14O# ##̱((Hx{'(lHC<o21U:U!#1?2JSMT=)53!5!!!3 3#qxC6ys+o#/!>3 !"&'332654&#"#!!67654'&'BZ@zxLw3d[P9uw:P[34(*F?Be32! !2#.#"26&"64&'&577A_^XZvynwXXWvb!2C!u44qffiѯPW !7N@%mǗ' #!#!!7!XE4+()Pj#!-7AKW $5467.54$! 4&#"264&#"326>54&'&547&547>54.ȺL\]KKK']rs\]rq^=VPPc""bQPF-[_Z .nZ)J̥Υ$Ⱦ'wwuuշaLTu!IxMOuU!uTMae^|k\^g&\-JF7o!+8"26#"54! !"&'3326.547676'&!WWX B^$23232653#"'0)'4`fU$>71,)/ag^CH> 9.dv 7/ir-qP10@ //]K TX@878YKTX@878Y#u?u@ 91290K TX@878Y@/// ]KTX@878YKTX@878Y3#'#tt?c@ 91<90K TX@878Y@//// ]KTX@878Y373tt7 #."#>32^kk^7667u}|7 N@ [[1<0K TK T[K T[X@878Y@  ]332673#"&^k\\k^7667u}|u -  10K TK T[X  @878Y2#"&546/FC22CFF.2CC2.F3#3#uuT #!#uuJw`'&}J`'%3!53#53#5!3#갰hjjjfjkj 47632"'&!"/.!"B^"!q.""""./B!!;93'#'# 54!2#5!'&#"32+qdof8o~bBKL<kqqZ{_K'&HJx`'&Vd9$@ $#$! $  $!!%221@! o b"o/2<2299dn%0@ ! ! MKSXY" ]@0&O&p&&&]]353#5!#5!##"'&'53367653d @NtBA>_+*}A*&Fjkf/kkyPc!`--?9j;< '4632#"&^GDaaDG^F``FDa`@53_<VV: o m p o Jf7q3!JZ?JJqsjqqqdsq)q5TqPq1fdsbqsq{V`9  H\f;{fffJf'JJ{;;;J'Jf;fJs7;'7!7R7h\}Z5Z5d3;#5^dJsqqqq)q)q)W)_uqdsssssd````HhqX;fffffff{fffffJ f'JfffffL'7'7'7'7;fffs{fs{fs{fs{fjqfuqfqfqfqfqfqfdsfdsfdsfdsfq'q'J)J)i)])qJ)qJiqDJ5T{;q;;Pq;Pq;Pq4;_q;ZV-d'Jd'Jd'Jq`'Jsfsfsf wfqJqJqJ{s{s{s{sV7;V7;V7;`'7`'7`'7`'7`'7`'79 !HH\7R\7R\7RJ;@q;q;ss{fuqj@q;fqs}5;dsuJ)q)&qF;TJ3'JsncQsufb@;q{sS;7;VW7;VZ',}qM\7Rfff~q'J\\ q q Vfqq ; 5d {dJf)Vsf`'7`'7`'7`'7`'7ffffsfdsfq sfsfff; q q Vfdsf ;qd'JffdLffqfqf))]sfsfqJqJ`'7`'7{sV7;q' `f\7RfqfsfsfsfsfH;J;{;ff.{%P&Vs7RLLfff;{f{f-fvfffx%dh/ef;wffZf^'7'T'TJ#JJ II;;JJJ&;J+TfRf.ffJJiJJJTTGGr,;;J;7;7;'7fJ!>TR{Rf{JJJrsIf;fUF;;+TwfJJfDffx;;B;&J,;h;GG?;";v.p....q."..c.:uuuu>.?.33uuuuZLW..7d.?.BAl~[lp7#L"p::J3P.#qqNq\qs)qq1fdqsqbqSVHs `})bHgf%dJ#JJgfJf%dVSJf#JFT3FJhSfBJ{fvfmSJZFZ#JfJZfF~=~=tM,\sfs{fqGkGB\\{f{;s{f{fhq;s1f`Usssqqdqs{)q)_5T4q1q:qqqqLqfqoqq1q41fqsqbqsVu q/ !q !q[Fqdqs qvFfWI1;Jf\]ZUFUFF$9JUFfUF;{fmSCO%JJFpJpJ<^<[<{f; Aff+1;{fsJ{;$F'+FUF@<F< q;\skfm2[$`q;;Lg0;q;\oKZ1q;1d2 F<q!F qF q;s{fVmSHH 2SF'J)q\q;qUFUF;fffqfsfsf\o]ZffqUFqUFsfsfsfs{f/JFLq1;q^<nnXnnnmZn_Z6n:xZnn#nx,nFnnnnn,nznnnVnZcnnnjnHdPdPQe'PFZd9d8FdPdPd@dMd2G=dd2=,d:Pe?PdQd%dSdXP(P?2QddReRdPd dddSdddpdPdffJfff G GGGHeGGGXG)@h?h?!HdGG\ ?<.@@3@@3%3@@@@@3@f/%/1/@@@@3%%1#//.1#feGq3@@@@@/3@1#///Hg%f5//A</15@@H%1#@/444@@fq;q;q;s{fjqfjqfjqfjqfjqfqfqfqfqfqfqJdsfq'Jq'Jq' q'Jq'J)Fq;q;q;Pq;PiPqPq 1fJ1fJ1fJd'Jd'Jd'Jd'Jsfsfbq;bq;qJqJqJq{s{s{sV7;V7;V7;V7;`'7`'7`'7`'7`'79 !9 !9 !9 !9 !  H\7R\7R\7R'J7!:fsffffffffqfqfqfqf)qJ)qJsfsfsf`'7`'7HHHHgfgfgfgfgfgfgfgf    KdKdKdKdKdKd     G JJJJJJJJ  F v #J#J###@###+    o  ffffff      JJJJJJJJ  Z ZZZZZZZZ     gfgfKdKdJJ##JffJJZZgfgfgfgfgfgfgfgf    JJJJJJJJ  F v ZZZZZZZZ     gfgfgfgfgfgfgfJJJJJK3Pq##!####)])iJJJJJJHH^.R ZZZZZ}VZZZZZZ%Z9933V q q338JE54/555D5(5O5553999f[v.5455Z5d555D5(5O5553999f[@@@d.@HRuq>R^V_a_`'bPZL`V`L}}qFH2``S3uuD aZZd5DdDO)qqIqq i tq u  Pqsjq1fJJJJ 2J ;{ffJ qjq qs{fLuL-.LurNLuLnLuLuLuLL` FZuFF uu LZLLuFFLLuLuL..LuLuLuuuLuuuZuLuLLuLLuL #hW|W|33^5^5Vp===jT+// u/DD??++* xZ+xxxxxxx||''''''''''''''''''''''q''''''''''llgg'''''''''''''''''pprppppppppp7p7Tpp''''3'''ppppp'''',,,,,,,,S,,,,,C,,X,,B,,X,,x,ueDu xL xu xL xL xu xL xL xu xL xu xuuuuuuuuuuuuuuuuuuLuLuLuTTLuLunnnnnnnununLtLu..-.-L,.FVWrher(GLLLuLuLFFF FuuuuFuFuFuFFFFFFuuuuuLuuLLuuLLZ@ /+/+///LL//LuuLL''''q'Jq;\7RqrFZJJf}JVJVJ9H>F,Ovd45````V`j``VVF55 /T/TTTq?T? FhF FwFFVT/T7;X1/H`TjoTJJ;Jd,$ 79k:;<&:$7$9$:$<$I$W$Y$Z$\$$$$$$%$&$'$6$7$8$9$:$$$$0$1$2$3$4$5$r$s${$$ $ $ %&%&&%*&%2&%<%&%&%&%&%&%&%&%%&%&%&%&%&%&%&%&%&%&%&%&%8%:%&%&%&%&&''&''9(&))))))$N)Du)H)R)N)N)N)N)N)u)u)u)u)u)u)u)))))))))))N)u)N)u)N)u))))))))))u)))**&**<**:--a--.k.$.&.2.8.:.<.H.R.X.\}................................}.}......0.1.:/7Y/8/9 /:N/<}/\/////}///&Y/0/:}/{/1}1}1122K2292;3a33a333$D383D3H3R3V3D3D3D3D3D333333333333333333333333!3#3044K44{&4&57595:5<5D/5\55/5/5/5/5/5/5/5&555&5:5{566K6666 6"777777$77&7Da7Fa7Ha7Ra7Vk7Z7777777a77777a7a77a7777a7777a7a7a7a7a7!k7#k7&&8D88D888$8-8888899D992929$u929DD9HD9L9RD9X}9\9u9u9u9u9u9999999D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9}9}9}9}999D99D91}9{K9K::k::N:N:$:DN:HY:L:Ru:U:X:\::::::N:N:N:N:N:N:u:Y:Y:Y:Y:u:u:u:u:u:u:::::::Y:u:::1:{&:&;;$;&;2;;;;;;;;;;;;;;;<<<<<<$a<&<Da<HN<L<RN<XN<a<a<a<a<a<<a<a<a<a<a<a<<<N<N<N<N<N<N<N<N<N<N<N<N<N<N<<<N<)<1N==IIII{I~&INRUUY Y Z Z [\\79:<IWYZ\$%&'6789:012345rs{ 79:<IWYZ\$%&'6789:012345rs{ 79:<IWYZ\$%&'6789:012345rs{ 79:<IWYZ\$%&'6789:012345rs{ 79:<IWYZ\$%&'6789:012345rs{ &&&&&K$9<:}}K9;K9;K9;K9;K9;K9;DD$-DD$-DD$-DD$-$a&DaHNLRNXNaaaaaaaaaaa<NNNNNNNNNNNNNNN)1N&79:<IWYZ\$%&'6789:012345rs{ 79:<IWYZ\$%&'6789:012345rs{ 79:<IWYZ\$%&'6789:012345rs{ &9&9&&<:7Y89 :N<}\}&Y0:}{7Y89 :N<}\}&Y0:}{O7Y89 :N<2\2&Y0:2{ } }  &79:<D/\///////&&:{79:<D/\///////&&:{  K  6   """K""6" ""&&&&&&$&7&&Da&Fa&Ha&Ra&Vk&Z&&&&&&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&!k&#k&&&0D00D000$0-00000777Dn7FU7Ga7HV7I7Ja7L7M7P}7Q}7RU7S7Ta7U}7V7W7X7Y7Z7[7\7]777 ::::::$a:&:Da:HN:L:RN:XN:a:a:a:a:a::a:a:a:a:a:a:<:N:N:N:N:N:N:N:N:N:N:N:N:N:N:::N:):1N??i$i-/iiiiiis7s9ks:s;s<ss&s:z$z-/zzzzzz~$~-/~99~:9~;9~<9~~~~~~~9~:979:;9<YZ&:    { ~&  ; ;DDDD4  xXHd @   P,L,\Pd@\ \!X##$|%L'4)+++,<,,,-./4/0|1,12348567@8p989:x;<< =t>(>?AD EpFFGGH`H`HIJ4K8LM@NlO4PdQ\QRR@STTTUVVWX8XxXYHYZTZtZZ[X[p[[[[]P^^^^^^__,_D_\``,`D`\`t``ab$b<bTblbbcHddddde e$fffffgg g8gPghh`hxhhhhhitjjjjjjkkklll4lLldl|lllllm m$m<mTmdnDn\ntnnnnnooo4oLodo|ooooop p$qr r$r<rTrlrrrrrsLspsssssuuuvv,vDv\vtvw(wwwxx(x@xXxpy0zz(z@zXzpzz{x||||||}},}D}\}t}}}}}~~~4t4Ld| $<TlTl|\`xx8$, P<xD\t$Hx `X(x`P,@Xp0H`x 8Ph0H\t4Ld|`x0 $<Tl,D\t4Ld| $0x 8Ph$,tXP,h$HHXTTp$<p\ôĐŰpǀ8ȼ\Hʠ xT̨0͸ppЀ(Ѥ0Ҡ4ӤTԬ հ|\ؼdtٌڼ0۬<ވHd< ($|\$$P,(<h hxLl(Hp$8L`t4H\p L Dd(Ht0Dp8L`t Tx40Lx$<Td,<p 0@(Xp88HT4D |  ` p  `  , p  <t,l@4p dXh| l8L@ X p!,!<!L!!"#$\$t$$%@%P&&&t'$'4()*H*+x, ,0,@,P,,,--../h001x220234d5,5<667779l: :; <<=>l>|???$??@@AhBBCD@EEF`G4HTHlI I|IJDJTJdJJKL|MTMlMMN\NODOPXPQpQQR,R|RS@STTPTU UV,VVVWTWX(XXY\YZZpZ[\[[\\X\\\]X]^(^^_D_``\`l`|``a@ab8bc cpccccddd d8dPd`dpdddddeee e8ePeheeeeeefff0fHf`fxfffffg,ghggh<hi ij jk4kl(lm@nnohoptqqtrrs|tt|tuluvwDwxxyz(z{8{{|}4}~d<@x<h4 Xt,P|`h8Pd@D$h ll0`@h8(TxtXh(<Pdx Ldd48dd0¬0xtD,Ơ$ǔh0ɠɸ0H`xʐʨ 8Phˀˠ0H`x̨̐ 8Ph̀͘Ͱ(@XpΈΠθ0H`xϐϨ 8PhЀИа0H`xѐѨ 8PhҀҘҰ(@XpӈӠӸ0PpԐ԰(@XpՈՠո0H`x֐֨ 8Ph׀טװ0Ppؐذ0Ppِ٨ @`xڐڨ @`xېۨ 8Ph܀ܘܰ(@Xp݌ݤݼ4Ld|ޔް4Ld|ߔ߬,H`|,D\t,Hd| $@Xt4Lh,D\t (D\l $4L\t4Ld| $<Tl,D\t4Ld| $<Tl\l(DTl(@Xp0@Xp0@Ph 8HDl PxdD`L`x@D$Xtl  4H\p`T @  \ @   T d   dX@`$Dd$<L(x804L\t,<L\X h` ( p  !!D!!"D""#@##$$$p$$%$%`%%&D&''( (P((()0)h))*P**+ +++,,(,L,t,,,,--0-L-h---. .//</x//0H00101x122H233X344T44505l55686|670778X89$9l9:::;4;|;< <|<=H==>>X??D?@(@T@ADAB8BBCCDD`DDE<EdEEEFlG<G\GGGGH@HlHHI,IIJJ<JK(KKL0LLNN\NO,OOPdPQ QQR(RtRSlSTTTUdUUUVV@VdWWXTXY`YZ[ [[\\p\\]]0]T]x]]^ ^L^^_0__`<`t````aahbdbbc8cph(h\hxhhhiii8iliijjPjjk$kHklkkkkl lDldllllmm0mTm|mmmn$nTnnnno$oPoxooop$pPp|pppq$qLqpqqqrrDrprrrs0sdsstt8tpttuuHu|uuvv4v`vvvww4whwwwx xLxxxy y<ypyyzzXzzz{0{`{{|,|||}$}X}x}}}~ ~(~D~`~|~~~$L`|$@\xdx <Ph 8,<D`(Dl@\4`|Dl<x(D @l8|,X\\Dl$L 0x<4X8 €¬8ÌXŠHƄTǐ ȤȤȸ4XlɈɤ,Xlʈʤ,Xt˘˼ 8d̘̬$Hl͘ʹ(LxΤ<hόϸ<hД(\јѬ$HlҘҴ(LxӤ<hԌԸ<hՔ(\ִ֘(Lxפ(T؈شX|٨4hڜ8lۨTܘܬ$Hlݘݴ(Lxޤ<hߌ߸<h(\(Lx(TX|4h8lT(Lx(TX|4h8lTHtDxX8lTDLl$<TXP$@dH8hHD dD(l`  p  @  $   X   P P,`$TDt4h,\xD P@xd`@Ht$xp,\ , l  !!T!!!""8"h"""#$$d$%$%`%%& &'H'(@()*+|,L-|.//////////////////////0x012D223348445d6D77`78489,9:D:;t<<= =>>?@ @@A$ABTBCD EExEFLFG8GGHHIdJ<JK0KL0M<NN8NO\PQ0QRPRSSdSSSTTHTTTUU J +@ ^>_ :Q p    a 4      G V }   " :% & h;   Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. DejaVu changes are in public domain Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. DejaVu changes are in public domain DejaVu SerifDejaVu SerifBookBookDejaVu SerifDejaVu SerifDejaVu SerifDejaVu SerifVersion 2.25Version 2.25DejaVuSerifDejaVuSerifDejaVu fonts teamDejaVu fonts teamhttp://dejavu.sourceforge.nethttp://dejavu.sourceforge.netFonts are (c) Bitstream (see below). DejaVu changes are in public domain. Bitstream Vera Fonts Copyright ------------------------------ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. Bitstream Vera Fonts Copyright ------------------------------ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. http://dejavu.sourceforge.net/wiki/index.php/Licensehttp://dejavu.sourceforge.net/wiki/index.php/LicenseDejaVu SerifDejaVu SerifBookBook~Z J  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L sfthyphenAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflex Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019FOhornohornuni01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEUhornuhornuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BBuni01BCuni01BDuni01BEuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217 Scommaaccent scommaaccentuni021Auni021Buni021Euni021Funi0220uni0221uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236dotlessjuni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0245uni0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Auni025Buni025Cuni025Duni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0277uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295uni0296uni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A5uni02A6uni02A7uni02A8uni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AFuni02B0uni02B1uni02B2uni02B3uni02B4uni02B5uni02B6uni02B7uni02B8uni02B9uni02BBuni02BCuni02BDuni02BEuni02BFuni02C0uni02C1uni02C8uni02C9uni02CCuni02D0uni02D1uni02D2uni02D3uni02D6uni02DEuni02E0uni02E1uni02E2uni02E3uni02E4uni02E5uni02E6uni02E7uni02E8uni02E9uni02EE gravecomb acutecombuni0302 tildecombuni0304uni0305uni0306uni0307uni0308 hookabovecombuni030Auni030Buni030Cuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320uni0321uni0322 dotbelowcombuni0324uni0325uni0326uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0334uni0335uni0336uni0337uni0338uni0339uni033Auni033Buni033Cuni033Duni033Euni033Funi0343uni034Funi0358uni0361uni0374uni0375uni037Auni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsi IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni03D0theta1Upsilon1uni03D3uni03D4phi1omega1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03F0uni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni0400uni0401uni0402uni0403uni0404uni0405uni0406uni0407uni0408uni0409uni040Auni040Buni040Cuni040Duni040Euni040Funi0410uni0411uni0412uni0413uni0414uni0415uni0416uni0417uni0418uni0419uni041Auni041Buni041Cuni041Duni041Euni041Funi0420uni0421uni0422uni0423uni0424uni0425uni0426uni0427uni0428uni0429uni042Auni042Buni042Cuni042Duni042Euni042Funi0430uni0431uni0432uni0433uni0434uni0435uni0436uni0437uni0438uni0439uni043Auni043Buni043Cuni043Duni043Euni043Funi0440uni0441uni0442uni0443uni0444uni0445uni0446uni0447uni0448uni0449uni044Auni044Buni044Cuni044Duni044Euni044Funi0450uni0451uni0452uni0453uni0454uni0455uni0456uni0457uni0458uni0459uni045Auni045Buni045Cuni045Duni045Euni045Funi0462uni0463uni0464uni0465uni046Auni046Buni0472uni0473uni0474uni0475uni048Cuni048Duni0490uni0491uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04BAuni04BBuni04C0uni04C1uni04C2uni04C3uni04C4uni04C7uni04C8uni04CBuni04CCuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni10A0uni10A1uni10A2uni10A3uni10A4uni10A5uni10A6uni10A7uni10A8uni10A9uni10AAuni10ABuni10ACuni10ADuni10AEuni10AFuni10B0uni10B1uni10B2uni10B3uni10B4uni10B5uni10B6uni10B7uni10B8uni10B9uni10BAuni10BBuni10BCuni10BDuni10BEuni10BFuni10C0uni10C1uni10C2uni10C3uni10C4uni10C5uni10D0uni10D1uni10D2uni10D3uni10D4uni10D5uni10D6uni10D7uni10D8uni10D9uni10DAuni10DBuni10DCuni10DDuni10DEuni10DFuni10E0uni10E1uni10E2uni10E3uni10E4uni10E5uni10E6uni10E7uni10E8uni10E9uni10EAuni10EBuni10ECuni10EDuni10EEuni10EFuni10F0uni10F1uni10F2uni10F3uni10F4uni10F5uni10F6uni10F7uni10F8uni10F9uni10FAuni10FBuni10FCuni1D02uni1D08uni1D09uni1D14uni1D16uni1D17uni1D1Duni1D1Euni1D1Funi1D2Cuni1D2Duni1D2Euni1D30uni1D31uni1D32uni1D33uni1D34uni1D35uni1D36uni1D37uni1D38uni1D39uni1D3Auni1D3Buni1D3Cuni1D3Euni1D3Funi1D40uni1D41uni1D42uni1D43uni1D44uni1D45uni1D46uni1D47uni1D48uni1D49uni1D4Auni1D4Buni1D4Cuni1D4Duni1D4Euni1D4Funi1D50uni1D51uni1D52uni1D53uni1D54uni1D55uni1D56uni1D57uni1D58uni1D59uni1D5Auni1D5Buni1D62uni1D63uni1D64uni1D65uni1D77uni1D78uni1D7Buni1D85uni1D9Buni1D9Cuni1D9Duni1D9Euni1D9Funi1DA0uni1DA1uni1DA2uni1DA3uni1DA4uni1DA5uni1DA6uni1DA7uni1DA8uni1DA9uni1DAAuni1DABuni1DACuni1DADuni1DAEuni1DAFuni1DB0uni1DB1uni1DB2uni1DB3uni1DB4uni1DB5uni1DB6uni1DB7uni1DB9uni1DBAuni1DBBuni1DBCuni1DBDuni1DBEuni1DBFuni1E00uni1E01uni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E3Euni1E3Funi1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7FWgravewgraveWacutewacute Wdieresis wdieresisuni1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1EA0uni1EA1uni1EA2uni1EA3uni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED8uni1ED9uni1EE4uni1EE5uni1EE6uni1EE7Ygraveygraveuni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200Buni200Cuni200Duni200Euni200Funi2010uni2011 figuredashuni2015 underscoredbl quotereverseduni201Funi2023onedotenleadertwodotenleaderuni202Auni202Buni202Cuni202Duni202Euni202Funi2031 exclamdbluni203Duni203Euni2047uni2048uni2049uni205Funi2060uni2061uni2062uni2063uni2064uni206Auni206Buni206Cuni206Duni206Euni206Funi2070uni2071uni2074uni2075uni2076uni2077uni2078uni2079uni207Auni207Buni207Cuni207Duni207Euni207Funi2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni208Auni208Buni208Cuni208Duni208Euni2090uni2091uni2092uni2093uni2094uni20A6Eurouni20AFuni20B1uni20B4uni20B5uni2102uni2103uni2109uni210Duni210Euni2115uni2116uni2119uni211Auni211Duni2124uni2126uni2127uni212Auni212Buni213Cuni213Duni213Euni213Funi2140uni2141uni2142uni2143uni2144uni2145uni2146uni2147uni2148uni2149uni214Bonethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217Funi2180uni2181uni2182uni2183uni2184 arrowleftarrowup arrowright arrowdown arrowboth arrowupdnuni2196uni2197uni2198uni2199uni219Auni219Buni219Cuni219Duni219Euni219Funi21A0uni21A1uni21A2uni21A3uni21A4uni21A5uni21A6uni21A7 arrowupdnbseuni21A9uni21AAuni21ABuni21ACuni21ADuni21AEuni21AFuni21B0uni21B1uni21B2uni21B3uni21B4carriagereturnuni21B6uni21B7uni21B8uni21B9uni21BAuni21BBuni21BCuni21BDuni21BEuni21BFuni21C0uni21C1uni21C2uni21C3uni21C4uni21C5uni21C6uni21C7uni21C8uni21C9uni21CAuni21CBuni21CCuni21CDuni21CEuni21CF arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblbothuni21D5uni21D6uni21D7uni21D8uni21D9uni21DAuni21DBuni21DCuni21DDuni21DEuni21DFuni21E0uni21E1uni21E2uni21E3uni21E4uni21E5uni21E6uni21E7uni21E8uni21E9uni21EAuni21EBuni21ECuni21EDuni21EEuni21EFuni21F0uni21F1uni21F2uni21F3uni21F4uni21F5uni21F6uni21F7uni21F8uni21F9uni21FAuni21FBuni21FCuni21FDuni21FEuni21FF universal existentialuni2204gradientelement notelementsuchthatuni220Cuni2210uni2213uni2214uni2215 asteriskmathuni2218uni2219uni221Buni221C proportional orthogonalangleuni2223uni2224uni2225uni2226 logicaland logicalor intersectionunionuni222Cuni222Duni2238uni2239uni223Auni223Bsimilaruni223Duni2242uni2243uni2250uni2251uni2252uni2253uni2254uni2255 equivalence propersubsetpropersuperset notsubsetuni2285 reflexsubsetreflexsupersetuni228Cuni228Duni228Euni228Funi2290uni2291uni2292uni2293uni2294 circleplusuni2296circlemultiplyuni2298uni2299uni229Auni229Buni229Cuni229Duni229Euni229Funi22A0uni22A1uni22A2uni22A3uni22A4 perpendicularuni22A6uni22A7uni22A8uni22A9uni22AAuni22ABuni22ACuni22ADuni22AEuni22AFdotmathhouseuni2308uni2309uni230Auni230B revlogicalnotuni2311uni2318uni2319 integraltp integralbtuni2325uni2328uni237Duni23AEuni23CFuni2423SF100000uni2501SF110000uni2503uni2504uni2505uni2506uni2507uni2508uni2509uni250Auni250BSF010000uni250Duni250Euni250FSF030000uni2511uni2512uni2513SF020000uni2515uni2516uni2517SF040000uni2519uni251Auni251BSF080000uni251Duni251Euni251Funi2520uni2521uni2522uni2523SF090000uni2525uni2526uni2527uni2528uni2529uni252Auni252BSF060000uni252Duni252Euni252Funi2530uni2531uni2532uni2533SF070000uni2535uni2536uni2537uni2538uni2539uni253Auni253BSF050000uni253Duni253Euni253Funi2540uni2541uni2542uni2543uni2544uni2545uni2546uni2547uni2548uni2549uni254Auni254Buni254Cuni254Duni254Euni254FSF430000SF240000SF510000SF520000SF390000SF220000SF210000SF250000SF500000SF490000SF380000SF280000SF270000SF260000SF360000SF370000SF420000SF190000SF200000SF230000SF470000SF480000SF410000SF450000SF460000SF400000SF540000SF530000SF440000uni256Duni256Euni256Funi2570uni2571uni2572uni2573uni2574uni2575uni2576uni2577uni2578uni2579uni257Auni257Buni257Cuni257Duni257Euni257Fupblockuni2581uni2582uni2583dnblockuni2585uni2586uni2587blockuni2589uni258Auni258Blfblockuni258Duni258Euni258Frtblockltshadeshadedkshadeuni2594uni2595uni2596uni2597uni2598uni2599uni259Auni259Buni259Cuni259Duni259Euni259F filledboxH22073uni25A2uni25A3uni25A4uni25A5uni25A6uni25A7uni25A8uni25A9H18543H18551 filledrectuni25ADuni25AEuni25AFuni25B0uni25B1triagupuni25B3uni25B4uni25B5uni25B6uni25B7uni25B8uni25B9triagrtuni25BBtriagdnuni25BDuni25BEuni25BFuni25C0uni25C1uni25C2uni25C3triaglfuni25C5uni25C6uni25C7uni25C8uni25C9circleuni25CCuni25CDuni25CEH18533uni25D0uni25D1uni25D2uni25D3uni25D4uni25D5uni25D6uni25D7 invbullet invcircleuni25DAuni25DBuni25DCuni25DDuni25DEuni25DFuni25E0uni25E1uni25E2uni25E3uni25E4uni25E5 openbulletuni25E7uni25E8uni25E9uni25EAuni25EBuni25ECuni25EDuni25EEuni25EFuni25F0uni25F1uni25F2uni25F3uni25F4uni25F5uni25F6uni25F7uni25F8uni25F9uni25FAuni25FBuni25FCuni25FDuni25FEuni25FFuni2600uni2638uni2639 smileface invsmilefacesununi263Ffemaleuni2641maleuni2643uni2644uni2645uni2646uni2647spadeuni2661uni2662clubuni2664heartdiamonduni2667uni2669 musicalnotemusicalnotedbluni266Cuni266Duni266Euni266Funi27A1uni27E0uni27E8uni27E9uni27F0uni27F1uni27F2uni27F3uni27F4uni27F5uni27F6uni27F7uni27F8uni27F9uni27FAuni27FBuni27FCuni27FDuni27FEuni27FFuni2800uni2801uni2802uni2803uni2804uni2805uni2806uni2807uni2808uni2809uni280Auni280Buni280Cuni280Duni280Euni280Funi2810uni2811uni2812uni2813uni2814uni2815uni2816uni2817uni2818uni2819uni281Auni281Buni281Cuni281Duni281Euni281Funi2820uni2821uni2822uni2823uni2824uni2825uni2826uni2827uni2828uni2829uni282Auni282Buni282Cuni282Duni282Euni282Funi2830uni2831uni2832uni2833uni2834uni2835uni2836uni2837uni2838uni2839uni283Auni283Buni283Cuni283Duni283Euni283Funi2840uni2841uni2842uni2843uni2844uni2845uni2846uni2847uni2848uni2849uni284Auni284Buni284Cuni284Duni284Euni284Funi2850uni2851uni2852uni2853uni2854uni2855uni2856uni2857uni2858uni2859uni285Auni285Buni285Cuni285Duni285Euni285Funi2860uni2861uni2862uni2863uni2864uni2865uni2866uni2867uni2868uni2869uni286Auni286Buni286Cuni286Duni286Euni286Funi2870uni2871uni2872uni2873uni2874uni2875uni2876uni2877uni2878uni2879uni287Auni287Buni287Cuni287Duni287Euni287Funi2880uni2881uni2882uni2883uni2884uni2885uni2886uni2887uni2888uni2889uni288Auni288Buni288Cuni288Duni288Euni288Funi2890uni2891uni2892uni2893uni2894uni2895uni2896uni2897uni2898uni2899uni289Auni289Buni289Cuni289Duni289Euni289Funi28A0uni28A1uni28A2uni28A3uni28A4uni28A5uni28A6uni28A7uni28A8uni28A9uni28AAuni28ABuni28ACuni28ADuni28AEuni28AFuni28B0uni28B1uni28B2uni28B3uni28B4uni28B5uni28B6uni28B7uni28B8uni28B9uni28BAuni28BBuni28BCuni28BDuni28BEuni28BFuni28C0uni28C1uni28C2uni28C3uni28C4uni28C5uni28C6uni28C7uni28C8uni28C9uni28CAuni28CBuni28CCuni28CDuni28CEuni28CFuni28D0uni28D1uni28D2uni28D3uni28D4uni28D5uni28D6uni28D7uni28D8uni28D9uni28DAuni28DBuni28DCuni28DDuni28DEuni28DFuni28E0uni28E1uni28E2uni28E3uni28E4uni28E5uni28E6uni28E7uni28E8uni28E9uni28EAuni28EBuni28ECuni28EDuni28EEuni28EFuni28F0uni28F1uni28F2uni28F3uni28F4uni28F5uni28F6uni28F7uni28F8uni28F9uni28FAuni28FBuni28FCuni28FDuni28FEuni28FFuni2900uni2901uni2902uni2903uni2904uni2905uni2906uni2907uni2908uni2909uni290Auni290Buni290Cuni290Duni290Euni290Funi2910uni2911uni2912uni2913uni2914uni2915uni2916uni2917uni2918uni2919uni291Auni291Buni291Cuni291Duni291Euni291Funi2920uni2921uni2922uni2923uni2924uni2925uni2926uni2927uni2928uni2929uni292Auni292Buni292Cuni292Duni292Euni292Funi2930uni2931uni2932uni2933uni2934uni2935uni2936uni2937uni2938uni2939uni293Auni293Buni293Cuni293Duni293Euni293Funi2940uni2941uni2942uni2943uni2944uni2945uni2946uni2947uni2948uni2949uni294Auni294Buni294Cuni294Duni294Euni294Funi2950uni2951uni2952uni2953uni2954uni2955uni2956uni2957uni2958uni2959uni295Auni295Buni295Cuni295Duni295Euni295Funi2960uni2961uni2962uni2963uni2964uni2965uni2966uni2967uni2968uni2969uni296Auni296Buni296Cuni296Duni296Euni296Funi2970uni2971uni2972uni2973uni2974uni2975uni2976uni2977uni2978uni2979uni297Auni297Buni297Cuni297Duni297Euni297Funi29EBuni2A0Cuni2A0Duni2A0Euni2A2Funi2B00uni2B01uni2B02uni2B03uni2B04uni2B05uni2B06uni2B07uni2B08uni2B09uni2B0Auni2B0Buni2B0Cuni2B0Duni2B0Euni2B0Funi2B10uni2B11uni2B12uni2B13uni2B14uni2B15uni2B16uni2B17uni2B18uni2B19uni2B1Auni2C67uni2C68uni2C69uni2C6Auni2C6Buni2C6Cuni2C75uni2C76uni2C77uni2E18uni2E2EuniF6C5cyrBrevecyrbreveuniFB00uniFB03uniFB04uniFB05uniFB06uniFE00uniFE01uniFE02uniFE03uniFE04uniFE05uniFE06uniFE07uniFE08uniFE09uniFE0AuniFE0BuniFE0CuniFE0DuniFE0EuniFE0FuniFFF9uniFFFAuniFFFBuniFFFCuniFFFDu1D538u1D539u1D53Bu1D53Cu1D53Du1D53Eu1D540u1D541u1D542u1D543u1D544u1D546u1D54Au1D54Bu1D54Cu1D54Du1D54Eu1D54Fu1D550u1D552u1D553u1D554u1D555u1D556u1D557u1D558u1D559u1D55Au1D55Bu1D55Cu1D55Du1D55Eu1D55Fu1D560u1D561u1D562u1D563u1D564u1D565u1D566u1D567u1D568u1D569u1D56Au1D56Bu1D7D8u1D7D9u1D7DAu1D7DBu1D7DCu1D7DDu1D7DEu1D7DFu1D7E0u1D7E1 dlLtcaronDieresisAcuteTildeGrave CircumflexCaron uni0311.caseBreve Dotaccent Hungarumlaut Doubleacuteiogonek.dotlessuni0268.dotless dotaccent.iuni029D.dotlessuni1E2D.dotlessuni1ECB.dotlessEng.alt brailledot@$d@$ 'd']}  22GG}  2d2dd%x %K.%x @@%0% @@   @I o} @ :]%]@%@0d0 ddl~}~2}|{|{zyx wv wvuv utltsrqp qp p@o}nm>nkm>lk llk k@jddjihihg]hhgf%g]g@f%eddeddcba`_.`_.^]\K[}ZYDXWVUSdRQ2POP}ONA@BL JdI"IH2GGFE EDCDkCBCBA BA@ A @ @@S?>->M=<=K<; <<@; :9:]98987 654543432 321 2 2@1 0/0D/.//. ..- d-,+,K+"++@* *d)(0)A(-(0'-'&:% %]$#$S#"##@"! !]     @#$0S-0 k@-B d-    @    @8k d } d2}-2- Sd+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++./kohana/system/fonts/LICENSE0000644000175000017500000001132011010334653015455 0ustar tokkeetokkeeFonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) Bitstream Vera Fonts Copyright ------------------------------ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. Arev Fonts Copyright ------------------------------ Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Tavmjong Bah" or the word "Arev". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Tavmjong Bah Arev" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the name of Tavmjong Bah shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from Tavmjong Bah. For further information, contact: tavmjong @ free . fr. $Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ ./kohana/system/helpers/0000755000175000017500000000000011263472436015000 5ustar tokkeetokkee./kohana/system/helpers/form.php0000644000175000017500000003117511176155016016456 0ustar tokkeetokkee'."\n"; // Add hidden fields immediate after opening tag empty($hidden) or $form .= form::hidden($hidden); return $form; } /** * Generates an opening HTML form tag that can be used for uploading files. * * @param string form action attribute * @param array extra attributes * @param array hidden fields to be created immediately after the form tag * @return string */ public static function open_multipart($action = NULL, $attr = array(), $hidden = array()) { // Set multi-part form type $attr['enctype'] = 'multipart/form-data'; return form::open($action, $attr, $hidden); } /** * Generates a fieldset opening tag. * * @param array html attributes * @param string a string to be attached to the end of the attributes * @return string */ public static function open_fieldset($data = NULL, $extra = '') { return ''."\n"; } /** * Generates a fieldset closing tag. * * @return string */ public static function close_fieldset() { return ''."\n"; } /** * Generates a legend tag for use with a fieldset. * * @param string legend text * @param array HTML attributes * @param string a string to be attached to the end of the attributes * @return string */ public static function legend($text = '', $data = NULL, $extra = '') { return ''.$text.''."\n"; } /** * Generates hidden form fields. * You can pass a simple key/value string or an associative array with multiple values. * * @param string|array input name (string) or key/value pairs (array) * @param string input value, if using an input name * @return string */ public static function hidden($data, $value = '') { if ( ! is_array($data)) { $data = array ( $data => $value ); } $input = ''; foreach ($data as $name => $value) { $attr = array ( 'type' => 'hidden', 'name' => $name, 'value' => $value ); $input .= form::input($attr)."\n"; } return $input; } /** * Creates an HTML form input tag. Defaults to a text type. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param string a string to be attached to the end of the attributes * @return string */ public static function input($data, $value = '', $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } // Type and value are required attributes $data += array ( 'type' => 'text', 'value' => $value ); return ''; } /** * Creates a HTML form password input tag. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param string a string to be attached to the end of the attributes * @return string */ public static function password($data, $value = '', $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } $data['type'] = 'password'; return form::input($data, $value, $extra); } /** * Creates an HTML form upload input tag. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param string a string to be attached to the end of the attributes * @return string */ public static function upload($data, $value = '', $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } $data['type'] = 'file'; return form::input($data, $value, $extra); } /** * Creates an HTML form textarea tag. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param string a string to be attached to the end of the attributes * @param boolean encode existing entities * @return string */ public static function textarea($data, $value = '', $extra = '', $double_encode = TRUE) { if ( ! is_array($data)) { $data = array('name' => $data); } // Use the value from $data if possible, or use $value $value = isset($data['value']) ? $data['value'] : $value; // Value is not part of the attributes unset($data['value']); return ''.html::specialchars($value, $double_encode).''; } /** * Creates an HTML form select tag, or "dropdown menu". * * @param string|array input name or an array of HTML attributes * @param array select options, when using a name * @param string|array option key(s) that should be selected by default * @param string a string to be attached to the end of the attributes * @return string */ public static function dropdown($data, $options = NULL, $selected = NULL, $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } else { if (isset($data['options'])) { // Use data options $options = $data['options']; } if (isset($data['selected'])) { // Use data selected $selected = $data['selected']; } } if (is_array($selected)) { // Multi-select box $data['multiple'] = 'multiple'; } else { // Single selection (but converted to an array) $selected = array($selected); } $input = ''."\n"; foreach ((array) $options as $key => $val) { // Key should always be a string $key = (string) $key; if (is_array($val)) { $input .= ''."\n"; foreach ($val as $inner_key => $inner_val) { // Inner key should always be a string $inner_key = (string) $inner_key; $sel = in_array($inner_key, $selected) ? ' selected="selected"' : ''; $input .= ''."\n"; } $input .= ''."\n"; } else { $sel = in_array($key, $selected) ? ' selected="selected"' : ''; $input .= ''."\n"; } } $input .= ''; return $input; } /** * Creates an HTML form checkbox input tag. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param boolean make the checkbox checked by default * @param string a string to be attached to the end of the attributes * @return string */ public static function checkbox($data, $value = '', $checked = FALSE, $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } $data['type'] = 'checkbox'; if ($checked == TRUE OR (isset($data['checked']) AND $data['checked'] == TRUE)) { $data['checked'] = 'checked'; } else { unset($data['checked']); } return form::input($data, $value, $extra); } /** * Creates an HTML form radio input tag. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param boolean make the radio selected by default * @param string a string to be attached to the end of the attributes * @return string */ public static function radio($data = '', $value = '', $checked = FALSE, $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } $data['type'] = 'radio'; if ($checked == TRUE OR (isset($data['checked']) AND $data['checked'] == TRUE)) { $data['checked'] = 'checked'; } else { unset($data['checked']); } return form::input($data, $value, $extra); } /** * Creates an HTML form submit input tag. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param string a string to be attached to the end of the attributes * @return string */ public static function submit($data = '', $value = '', $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } if (empty($data['name'])) { // Remove the name if it is empty unset($data['name']); } $data['type'] = 'submit'; return form::input($data, $value, $extra); } /** * Creates an HTML form button input tag. * * @param string|array input name or an array of HTML attributes * @param string input value, when using a name * @param string a string to be attached to the end of the attributes * @return string */ public static function button($data = '', $value = '', $extra = '') { if ( ! is_array($data)) { $data = array('name' => $data); } if (empty($data['name'])) { // Remove the name if it is empty unset($data['name']); } if (isset($data['value']) AND empty($value)) { $value = arr::remove('value', $data); } return ''.$value.''; } /** * Closes an open form tag. * * @param string string to be attached after the closing tag * @return string */ public static function close($extra = '') { return ''."\n".$extra; } /** * Creates an HTML form label tag. * * @param string|array label "for" name or an array of HTML attributes * @param string label text or HTML * @param string a string to be attached to the end of the attributes * @return string */ public static function label($data = '', $text = NULL, $extra = '') { if ( ! is_array($data)) { if (is_string($data)) { // Specify the input this label is for $data = array('for' => $data); } else { // No input specified $data = array(); } } if ($text === NULL AND isset($data['for'])) { // Make the text the human-readable input name $text = ucwords(inflector::humanize($data['for'])); } return ''.$text.''; } /** * Sorts a key/value array of HTML attributes, putting form attributes first, * and returns an attribute string. * * @param array HTML attributes array * @return string */ public static function attributes($attr, $type = NULL) { if (empty($attr)) return ''; if (isset($attr['name']) AND empty($attr['id']) AND strpos($attr['name'], '[') === FALSE) { if ($type === NULL AND ! empty($attr['type'])) { // Set the type by the attributes $type = $attr['type']; } switch ($type) { case 'text': case 'textarea': case 'password': case 'select': case 'checkbox': case 'file': case 'image': case 'button': case 'submit': // Only specific types of inputs use name to id matching $attr['id'] = $attr['name']; break; } } $order = array ( 'action', 'method', 'type', 'id', 'name', 'value', 'src', 'size', 'maxlength', 'rows', 'cols', 'accept', 'tabindex', 'accesskey', 'align', 'alt', 'title', 'class', 'style', 'selected', 'checked', 'readonly', 'disabled' ); $sorted = array(); foreach ($order as $key) { if (isset($attr[$key])) { // Move the attribute to the sorted array $sorted[$key] = $attr[$key]; // Remove the attribute from unsorted array unset($attr[$key]); } } // Combine the sorted and unsorted attributes and create an HTML string return html::attributes(array_merge($sorted, $attr)); } } // End form./kohana/system/helpers/inflector.php0000644000175000017500000001014011156512746017472 0ustar tokkeetokkee 1) return $str; // Cache key name $key = 'singular_'.$str.$count; if (isset(inflector::$cache[$key])) return inflector::$cache[$key]; if (inflector::uncountable($str)) return inflector::$cache[$key] = $str; if (empty(inflector::$irregular)) { // Cache irregular words inflector::$irregular = Kohana::config('inflector.irregular'); } if ($irregular = array_search($str, inflector::$irregular)) { $str = $irregular; } elseif (preg_match('/[sxz]es$/', $str) OR preg_match('/[^aeioudgkprt]hes$/', $str)) { // Remove "es" $str = substr($str, 0, -2); } elseif (preg_match('/[^aeiou]ies$/', $str)) { $str = substr($str, 0, -3).'y'; } elseif (substr($str, -1) === 's' AND substr($str, -2) !== 'ss') { $str = substr($str, 0, -1); } return inflector::$cache[$key] = $str; } /** * Makes a singular word plural. * * @param string word to pluralize * @return string */ public static function plural($str, $count = NULL) { // Remove garbage $str = strtolower(trim($str)); if (is_string($count)) { // Convert to integer when using a digit string $count = (int) $count; } // Do nothing with singular if ($count === 1) return $str; // Cache key name $key = 'plural_'.$str.$count; if (isset(inflector::$cache[$key])) return inflector::$cache[$key]; if (inflector::uncountable($str)) return inflector::$cache[$key] = $str; if (empty(inflector::$irregular)) { // Cache irregular words inflector::$irregular = Kohana::config('inflector.irregular'); } if (isset(inflector::$irregular[$str])) { $str = inflector::$irregular[$str]; } elseif (preg_match('/[sxz]$/', $str) OR preg_match('/[^aeioudgkprt]h$/', $str)) { $str .= 'es'; } elseif (preg_match('/[^aeiou]y$/', $str)) { // Change "y" to "ies" $str = substr_replace($str, 'ies', -1); } else { $str .= 's'; } // Set the cache and return return inflector::$cache[$key] = $str; } /** * Makes a phrase camel case. * * @param string phrase to camelize * @return string */ public static function camelize($str) { $str = 'x'.strtolower(trim($str)); $str = ucwords(preg_replace('/[\s_]+/', ' ', $str)); return substr(str_replace(' ', '', $str), 1); } /** * Makes a phrase underscored instead of spaced. * * @param string phrase to underscore * @return string */ public static function underscore($str) { return preg_replace('/\s+/', '_', trim($str)); } /** * Makes an underscored or dashed phrase human-reable. * * @param string phrase to make human-reable * @return string */ public static function humanize($str) { return preg_replace('/[_-]+/', ' ', trim($str)); } } // End inflector./kohana/system/helpers/expires.php0000644000175000017500000000524511174702356017174 0ustar tokkeetokkee 0) { // Re-send headers header('Last-Modified: '.gmdate('D, d M Y H:i:s T', $mod_time)); header('Expires: '.gmdate('D, d M Y H:i:s T', time() + $mod_time_diff)); header('Cache-Control: max-age='.$mod_time_diff); header('Status: 304 Not Modified', TRUE, 304); // Prevent any output Event::add('system.display', array('expires', 'prevent_output')); // Exit to prevent other output exit; } } return FALSE; } /** * Check headers already created to not step on download or Img_lib's feet * * @return boolean */ public static function check_headers() { foreach (headers_list() as $header) { if ((session_cache_limiter() == '' AND stripos($header, 'Last-Modified:') === 0) OR stripos($header, 'Expires:') === 0) { return FALSE; } } return TRUE; } /** * Prevent any output from being displayed. Executed during system.display. * * @return void */ public static function prevent_output() { Kohana::$output = ''; } } // End expires./kohana/system/helpers/url.php0000644000175000017500000001355611153222404016307 0ustar tokkeetokkee 'Refresh', '300' => 'Multiple Choices', '301' => 'Moved Permanently', '302' => 'Found', '303' => 'See Other', '304' => 'Not Modified', '305' => 'Use Proxy', '307' => 'Temporary Redirect' ); // Validate the method and default to 302 $method = isset($codes[$method]) ? (string) $method : '302'; if ($method === '300') { $uri = (array) $uri; $output = '
      '; foreach ($uri as $link) { $output .= '
    • '.html::anchor($link).'
    • '; } $output .= '
    '; // The first URI will be used for the Location header $uri = $uri[0]; } else { $output = '

    '.html::anchor($uri).'

    '; } // Run the redirect event Event::run('system.redirect', $uri); if (strpos($uri, '://') === FALSE) { // HTTP headers expect absolute URLs $uri = url::site($uri, request::protocol()); } if ($method === 'refresh') { header('Refresh: 0; url='.$uri); } else { header('HTTP/1.1 '.$method.' '.$codes[$method]); header('Location: '.$uri); } // We are about to exit, so run the send_headers event Event::run('system.send_headers'); exit('

    '.$method.' - '.$codes[$method].'

    '.$output); } } // End url./kohana/system/helpers/date.php0000644000175000017500000002401111177437372016430 0ustar tokkeetokkee> 1); } /** * Converts a DOS timestamp to UNIX format. * * @param integer DOS timestamp * @return integer */ public static function dos2unix($timestamp = FALSE) { $sec = 2 * ($timestamp & 0x1f); $min = ($timestamp >> 5) & 0x3f; $hrs = ($timestamp >> 11) & 0x1f; $day = ($timestamp >> 16) & 0x1f; $mon = ($timestamp >> 21) & 0x0f; $year = ($timestamp >> 25) & 0x7f; return mktime($hrs, $min, $sec, $mon, $day, $year + 1980); } /** * Returns the offset (in seconds) between two time zones. * @see http://php.net/timezones * * @param string timezone that to find the offset of * @param string|boolean timezone used as the baseline * @return integer */ public static function offset($remote, $local = TRUE) { static $offsets; // Default values $remote = (string) $remote; $local = ($local === TRUE) ? date_default_timezone_get() : (string) $local; // Cache key name $cache = $remote.$local; if (empty($offsets[$cache])) { // Create timezone objects $remote = new DateTimeZone($remote); $local = new DateTimeZone($local); // Create date objects from timezones $time_there = new DateTime('now', $remote); $time_here = new DateTime('now', $local); // Find the offset $offsets[$cache] = $remote->getOffset($time_there) - $local->getOffset($time_here); } return $offsets[$cache]; } /** * Number of seconds in a minute, incrementing by a step. * * @param integer amount to increment each step by, 1 to 30 * @param integer start value * @param integer end value * @return array A mirrored (foo => foo) array from 1-60. */ public static function seconds($step = 1, $start = 0, $end = 60) { // Always integer $step = (int) $step; $seconds = array(); for ($i = $start; $i < $end; $i += $step) { $seconds[$i] = ($i < 10) ? '0'.$i : $i; } return $seconds; } /** * Number of minutes in an hour, incrementing by a step. * * @param integer amount to increment each step by, 1 to 30 * @return array A mirrored (foo => foo) array from 1-60. */ public static function minutes($step = 5) { // Because there are the same number of minutes as seconds in this set, // we choose to re-use seconds(), rather than creating an entirely new // function. Shhhh, it's cheating! ;) There are several more of these // in the following methods. return date::seconds($step); } /** * Number of hours in a day. * * @param integer amount to increment each step by * @param boolean use 24-hour time * @param integer the hour to start at * @return array A mirrored (foo => foo) array from start-12 or start-23. */ public static function hours($step = 1, $long = FALSE, $start = NULL) { // Default values $step = (int) $step; $long = (bool) $long; $hours = array(); // Set the default start if none was specified. if ($start === NULL) { $start = ($long === FALSE) ? 1 : 0; } $hours = array(); // 24-hour time has 24 hours, instead of 12 $size = ($long === TRUE) ? 23 : 12; for ($i = $start; $i <= $size; $i += $step) { $hours[$i] = $i; } return $hours; } /** * Returns AM or PM, based on a given hour. * * @param integer number of the hour * @return string */ public static function ampm($hour) { // Always integer $hour = (int) $hour; return ($hour > 11) ? 'PM' : 'AM'; } /** * Adjusts a non-24-hour number into a 24-hour number. * * @param integer hour to adjust * @param string AM or PM * @return string */ public static function adjust($hour, $ampm) { $hour = (int) $hour; $ampm = strtolower($ampm); switch ($ampm) { case 'am': if ($hour == 12) $hour = 0; break; case 'pm': if ($hour < 12) $hour += 12; break; } return sprintf('%02s', $hour); } /** * Number of days in month. * * @param integer number of month * @param integer number of year to check month, defaults to the current year * @return array A mirrored (foo => foo) array of the days. */ public static function days($month, $year = FALSE) { static $months; // Always integers $month = (int) $month; $year = (int) $year; // Use the current year by default $year = ($year == FALSE) ? date('Y') : $year; // We use caching for months, because time functions are used if (empty($months[$year][$month])) { $months[$year][$month] = array(); // Use date to find the number of days in the given month $total = date('t', mktime(1, 0, 0, $month, 1, $year)) + 1; for ($i = 1; $i < $total; $i++) { $months[$year][$month][$i] = $i; } } return $months[$year][$month]; } /** * Number of months in a year * * @return array A mirrored (foo => foo) array from 1-12. */ public static function months() { return date::hours(); } /** * Returns an array of years between a starting and ending year. * Uses the current year +/- 5 as the max/min. * * @param integer starting year * @param integer ending year * @return array */ public static function years($start = FALSE, $end = FALSE) { // Default values $start = ($start === FALSE) ? date('Y') - 5 : (int) $start; $end = ($end === FALSE) ? date('Y') + 5 : (int) $end; $years = array(); // Add one, so that "less than" works $end += 1; for ($i = $start; $i < $end; $i++) { $years[$i] = $i; } return $years; } /** * Returns time difference between two timestamps, in human readable format. * * @param integer timestamp * @param integer timestamp, defaults to the current time * @param string formatting string * @return string|array */ public static function timespan($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds') { // Array with the output formats $output = preg_split('/[^a-z]+/', strtolower((string) $output)); // Invalid output if (empty($output)) return FALSE; // Make the output values into keys extract(array_flip($output), EXTR_SKIP); // Default values $time1 = max(0, (int) $time1); $time2 = empty($time2) ? time() : max(0, (int) $time2); // Calculate timespan (seconds) $timespan = abs($time1 - $time2); // All values found using Google Calculator. // Years and months do not match the formula exactly, due to leap years. // Years ago, 60 * 60 * 24 * 365 isset($years) and $timespan -= 31556926 * ($years = (int) floor($timespan / 31556926)); // Months ago, 60 * 60 * 24 * 30 isset($months) and $timespan -= 2629744 * ($months = (int) floor($timespan / 2629743.83)); // Weeks ago, 60 * 60 * 24 * 7 isset($weeks) and $timespan -= 604800 * ($weeks = (int) floor($timespan / 604800)); // Days ago, 60 * 60 * 24 isset($days) and $timespan -= 86400 * ($days = (int) floor($timespan / 86400)); // Hours ago, 60 * 60 isset($hours) and $timespan -= 3600 * ($hours = (int) floor($timespan / 3600)); // Minutes ago, 60 isset($minutes) and $timespan -= 60 * ($minutes = (int) floor($timespan / 60)); // Seconds ago, 1 isset($seconds) and $seconds = $timespan; // Remove the variables that cannot be accessed unset($timespan, $time1, $time2); // Deny access to these variables $deny = array_flip(array('deny', 'key', 'difference', 'output')); // Return the difference $difference = array(); foreach ($output as $key) { if (isset($$key) AND ! isset($deny[$key])) { // Add requested key to the output $difference[$key] = $$key; } } // Invalid output formats string if (empty($difference)) return FALSE; // If only one output format was asked, don't put it in an array if (count($difference) === 1) return current($difference); // Return array return $difference; } /** * Returns time difference between two timestamps, in the format: * N year, N months, N weeks, N days, N hours, N minutes, and N seconds ago * * @param integer timestamp * @param integer timestamp, defaults to the current time * @param string formatting string * @return string */ public static function timespan_string($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds') { if ($difference = date::timespan($time1, $time2, $output) AND is_array($difference)) { // Determine the key of the last item in the array $last = end($difference); $last = key($difference); $span = array(); foreach ($difference as $name => $amount) { if ($amount === 0) { // Skip empty amounts continue; } // Add the amount to the span $span[] = ($name === $last ? ' and ' : ', ').$amount.' '.($amount === 1 ? inflector::singular($name) : $name); } // If the difference is less than 60 seconds, remove the preceding and. if (count($span) === 1) { $span[0] = ltrim($span[0], 'and '); } // Replace difference by making the span into a string $difference = trim(implode('', $span), ','); } elseif (is_int($difference)) { // Single-value return $difference = $difference.' '.($difference === 1 ? inflector::singular($output) : $output); } return $difference; } } // End date./kohana/system/helpers/remote.php0000644000175000017500000000262711121324570016777 0ustar tokkeetokkee= 0; $i -= 2) { // Add up every 2nd digit, starting from the right $checksum += $number[$i]; } for ($i = $length - 2; $i >= 0; $i -= 2) { // Add up every 2nd digit doubled, starting from the right $double = $number[$i] * 2; // Subtract 9 from the double where value is greater than 10 $checksum += ($double >= 10) ? $double - 9 : $double; } // If the checksum is a multiple of 10, the number is valid return ($checksum % 10 === 0); } /** * Checks if a phone number is valid. * * @param string phone number to check * @return boolean */ public static function phone($number, $lengths = NULL) { if ( ! is_array($lengths)) { $lengths = array(7,10,11); } // Remove all non-digit characters from the number $number = preg_replace('/\D+/', '', $number); // Check if the number is within range return in_array(strlen($number), $lengths); } /** * Tests if a string is a valid date string. * * @param string date to check * @return boolean */ public static function date($str) { return (strtotime($str) !== FALSE); } /** * Checks whether a string consists of alphabetical characters only. * * @param string input string * @param boolean trigger UTF-8 compatibility * @return boolean */ public static function alpha($str, $utf8 = FALSE) { return ($utf8 === TRUE) ? (bool) preg_match('/^\pL++$/uD', (string) $str) : ctype_alpha((string) $str); } /** * Checks whether a string consists of alphabetical characters and numbers only. * * @param string input string * @param boolean trigger UTF-8 compatibility * @return boolean */ public static function alpha_numeric($str, $utf8 = FALSE) { return ($utf8 === TRUE) ? (bool) preg_match('/^[\pL\pN]++$/uD', (string) $str) : ctype_alnum((string) $str); } /** * Checks whether a string consists of alphabetical characters, numbers, underscores and dashes only. * * @param string input string * @param boolean trigger UTF-8 compatibility * @return boolean */ public static function alpha_dash($str, $utf8 = FALSE) { return ($utf8 === TRUE) ? (bool) preg_match('/^[-\pL\pN_]++$/uD', (string) $str) : (bool) preg_match('/^[-a-z0-9_]++$/iD', (string) $str); } /** * Checks whether a string consists of digits only (no dots or dashes). * * @param string input string * @param boolean trigger UTF-8 compatibility * @return boolean */ public static function digit($str, $utf8 = FALSE) { return ($utf8 === TRUE) ? (bool) preg_match('/^\pN++$/uD', (string) $str) : ctype_digit((string) $str); } /** * Checks whether a string is a valid number (negative and decimal numbers allowed). * * @see Uses locale conversion to allow decimal point to be locale specific. * @see http://www.php.net/manual/en/function.localeconv.php * * @param string input string * @return boolean */ public static function numeric($str) { // Use localeconv to set the decimal_point value: Usually a comma or period. $locale = localeconv(); return (bool) preg_match('/^-?[0-9'.$locale['decimal_point'].']++$/D', (string) $str); } /** * Checks whether a string is a valid text. Letters, numbers, whitespace, * dashes, periods, and underscores are allowed. * * @param string text to check * @return boolean */ public static function standard_text($str) { // pL matches letters // pN matches numbers // pZ matches whitespace // pPc matches underscores // pPd matches dashes // pPo matches normal puncuation return (bool) preg_match('/^[\pL\pN\pZ\p{Pc}\p{Pd}\p{Po}]++$/uD', (string) $str); } /** * Checks if a string is a proper decimal format. The format array can be * used to specify a decimal length, or a number and decimal length, eg: * array(2) would force the number to have 2 decimal places, array(4,2) * would force the number to have 4 digits and 2 decimal places. * * @param string input string * @param array decimal format: y or x,y * @return boolean */ public static function decimal($str, $format = NULL) { // Create the pattern $pattern = '/^[0-9]%s\.[0-9]%s$/'; if ( ! empty($format)) { if (count($format) > 1) { // Use the format for number and decimal length $pattern = sprintf($pattern, '{'.$format[0].'}', '{'.$format[1].'}'); } elseif (count($format) > 0) { // Use the format as decimal length $pattern = sprintf($pattern, '+', '{'.$format[0].'}'); } } else { // No format $pattern = sprintf($pattern, '+', '+'); } return (bool) preg_match($pattern, (string) $str); } } // End valid./kohana/system/helpers/email.php0000644000175000017500000001130511121324570016564 0ustar tokkeetokkeesetUsername($config['options']['username']); empty($config['options']['password']) or $connection->setPassword($config['options']['password']); if ( ! empty($config['options']['auth'])) { // Get the class name and params list ($class, $params) = arr::callback_string($config['options']['auth']); if ($class === 'PopB4Smtp') { // Load the PopB4Smtp class manually, due to its odd filename require Kohana::find_file('vendor', 'swift/Swift/Authenticator/$PopB4Smtp$'); } // Prepare the class name for auto-loading $class = 'Swift_Authenticator_'.$class; // Attach the authenticator $connection->attachAuthenticator(($params === NULL) ? new $class : new $class($params[0])); } // Set the timeout to 5 seconds $connection->setTimeout(empty($config['options']['timeout']) ? 5 : (int) $config['options']['timeout']); break; case 'sendmail': // Create a sendmail connection $connection = new Swift_Connection_Sendmail ( empty($config['options']) ? Swift_Connection_Sendmail::AUTO_DETECT : $config['options'] ); // Set the timeout to 5 seconds $connection->setTimeout(5); break; default: // Use the native connection $connection = new Swift_Connection_NativeMail($config['options']); break; } // Create the SwiftMailer instance return email::$mail = new Swift($connection); } /** * Send an email message. * * @param string|array recipient email (and name), or an array of To, Cc, Bcc names * @param string|array sender email (and name) * @param string message subject * @param string message body * @param boolean send email as HTML * @return integer number of emails sent */ public static function send($to, $from, $subject, $message, $html = FALSE) { // Connect to SwiftMailer (email::$mail === NULL) and email::connect(); // Determine the message type $html = ($html === TRUE) ? 'text/html' : 'text/plain'; // Create the message $message = new Swift_Message($subject, $message, $html, '8bit', 'utf-8'); if (is_string($to)) { // Single recipient $recipients = new Swift_Address($to); } elseif (is_array($to)) { if (isset($to[0]) AND isset($to[1])) { // Create To: address set $to = array('to' => $to); } // Create a list of recipients $recipients = new Swift_RecipientList; foreach ($to as $method => $set) { if ( ! in_array($method, array('to', 'cc', 'bcc'))) { // Use To: by default $method = 'to'; } // Create method name $method = 'add'.ucfirst($method); if (is_array($set)) { // Add a recipient with name $recipients->$method($set[0], $set[1]); } else { // Add a recipient without name $recipients->$method($set); } } } if (is_string($from)) { // From without a name $from = new Swift_Address($from); } elseif (is_array($from)) { // From with a name $from = new Swift_Address($from[0], $from[1]); } return email::$mail->send($message, $recipients, $from); } } // End email./kohana/system/helpers/download.php0000644000175000017500000000472211121324570017311 0ustar tokkeetokkeecookie($name, $default, $xss_clean); } /** * Nullify and unset a cookie. * * @param string cookie name * @param string URL path * @param string URL domain * @return boolean */ public static function delete($name, $path = NULL, $domain = NULL) { if ( ! isset($_COOKIE[$name])) return FALSE; // Delete the cookie from globals unset($_COOKIE[$name]); // Sets the cookie value to an empty string, and the expiration to 24 hours ago return cookie::set($name, '', -86400, $path, $domain, FALSE, FALSE); } } // End cookie./kohana/system/helpers/request.php0000644000175000017500000001431211203321744017167 0ustar tokkeetokkee 0); } /** * Compare the q values for given array of content types and return the one with the highest value. * If items are found to have the same q value, the first one encountered in the given array wins. * If all items in the given array have a q value of 0, FALSE is returned. * * @param array content types * @param boolean set to TRUE to disable wildcard checking * @return mixed string mime type with highest q value, FALSE if none of the given types are accepted */ public static function preferred_accept($types, $explicit_check = FALSE) { // Initialize $mime_types = array(); $max_q = 0; $preferred = FALSE; // Load q values for all given content types foreach (array_unique($types) as $type) { $mime_types[$type] = request::accepts_at_quality($type, $explicit_check); } // Look for the highest q value foreach ($mime_types as $type => $q) { if ($q > $max_q) { $max_q = $q; $preferred = $type; } } return $preferred; } /** * Returns quality factor at which the client accepts content type. * * @param string content type (e.g. "image/jpg", "jpg") * @param boolean set to TRUE to disable wildcard checking * @return integer|float */ public static function accepts_at_quality($type = NULL, $explicit_check = FALSE) { request::parse_accept_header(); // Normalize type $type = strtolower((string) $type); // General content type (e.g. "jpg") if (strpos($type, '/') === FALSE) { // Don't accept anything by default $q = 0; // Look up relevant mime types foreach ((array) Kohana::config('mimes.'.$type) as $type) { $q2 = request::accepts_at_quality($type, $explicit_check); $q = ($q2 > $q) ? $q2 : $q; } return $q; } // Content type with subtype given (e.g. "image/jpg") $type = explode('/', $type, 2); // Exact match if (isset(request::$accept_types[$type[0]][$type[1]])) return request::$accept_types[$type[0]][$type[1]]; // Wildcard match (if not checking explicitly) if ($explicit_check === FALSE AND isset(request::$accept_types[$type[0]]['*'])) return request::$accept_types[$type[0]]['*']; // Catch-all wildcard match (if not checking explicitly) if ($explicit_check === FALSE AND isset(request::$accept_types['*']['*'])) return request::$accept_types['*']['*']; // Content type not accepted return 0; } /** * Parses client's HTTP Accept request header, and builds array structure representing it. * * @return void */ protected static function parse_accept_header() { // Run this function just once if (request::$accept_types !== NULL) return; // Initialize accept_types array request::$accept_types = array(); // No HTTP Accept header found if (empty($_SERVER['HTTP_ACCEPT'])) { // Accept everything request::$accept_types['*']['*'] = 1; return; } // Remove linebreaks and parse the HTTP Accept header foreach (explode(',', str_replace(array("\r", "\n"), '', $_SERVER['HTTP_ACCEPT'])) as $accept_entry) { // Explode each entry in content type and possible quality factor $accept_entry = explode(';', trim($accept_entry), 2); // Explode each content type (e.g. "text/html") $type = explode('/', $accept_entry[0], 2); // Skip invalid content types if ( ! isset($type[1])) continue; // Assume a default quality factor of 1 if no custom q value found $q = (isset($accept_entry[1]) AND preg_match('~\bq\s*+=\s*+([.0-9]+)~', $accept_entry[1], $match)) ? (float) $match[1] : 1; // Populate accept_types array if ( ! isset(request::$accept_types[$type[0]][$type[1]]) OR $q > request::$accept_types[$type[0]][$type[1]]) { request::$accept_types[$type[0]][$type[1]] = $q; } } } } // End request./kohana/system/helpers/text.php0000644000175000017500000002547011121324570016471 0ustar tokkeetokkee 1) { if (ctype_alpha($str)) { // Add a random digit $str[mt_rand(0, $length - 1)] = chr(mt_rand(48, 57)); } elseif (ctype_digit($str)) { // Add a random letter $str[mt_rand(0, $length - 1)] = chr(mt_rand(65, 90)); } } return $str; } /** * Reduces multiple slashes in a string to single slashes. * * @param string string to reduce slashes of * @return string */ public static function reduce_slashes($str) { return preg_replace('#(? $badword) { $badwords[$key] = str_replace('\*', '\S*?', preg_quote((string) $badword)); } $regex = '('.implode('|', $badwords).')'; if ($replace_partial_words == TRUE) { // Just using \b isn't sufficient when we need to replace a badword that already contains word boundaries itself $regex = '(?<=\b|\s|^)'.$regex.'(?=\b|\s|$)'; } $regex = '!'.$regex.'!ui'; if (utf8::strlen($replacement) == 1) { $regex .= 'e'; return preg_replace($regex, 'str_repeat($replacement, utf8::strlen(\'$1\'))', $str); } return preg_replace($regex, $replacement, $str); } /** * Finds the text that is similar between a set of words. * * @param array words to find similar text of * @return string */ public static function similar(array $words) { // First word is the word to match against $word = current($words); for ($i = 0, $max = strlen($word); $i < $max; ++$i) { foreach ($words as $w) { // Once a difference is found, break out of the loops if ( ! isset($w[$i]) OR $w[$i] !== $word[$i]) break 2; } } // Return the similar text return substr($word, 0, $i); } /** * Converts text email addresses and anchors into links. * * @param string text to auto link * @return string */ public static function auto_link($text) { // Auto link emails first to prevent problems with "www.domain.com@example.com" return text::auto_link_urls(text::auto_link_emails($text)); } /** * Converts text anchors into links. * * @param string text to auto link * @return string */ public static function auto_link_urls($text) { // Finds all http/https/ftp/ftps links that are not part of an existing html anchor if (preg_match_all('~\b(?)(?:ht|f)tps?://\S+(?:/|\b)~i', $text, $matches)) { foreach ($matches[0] as $match) { // Replace each link with an anchor $text = str_replace($match, html::anchor($match), $text); } } // Find all naked www.links.com (without http://) if (preg_match_all('~\b(?|58;)(?!\.)[-+_a-z0-9.]++(? and
    markup to text. Basically nl2br() on steroids. * * @param string subject * @return string */ public static function auto_p($str) { // Trim whitespace if (($str = trim($str)) === '') return ''; // Standardize newlines $str = str_replace(array("\r\n", "\r"), "\n", $str); // Trim whitespace on each line $str = preg_replace('~^[ \t]+~m', '', $str); $str = preg_replace('~[ \t]+$~m', '', $str); // The following regexes only need to be executed if the string contains html if ($html_found = (strpos($str, '<') !== FALSE)) { // Elements that should not be surrounded by p tags $no_p = '(?:p|div|h[1-6r]|ul|ol|li|blockquote|d[dlt]|pre|t[dhr]|t(?:able|body|foot|head)|c(?:aption|olgroup)|form|s(?:elect|tyle)|a(?:ddress|rea)|ma(?:p|th))'; // Put at least two linebreaks before and after $no_p elements $str = preg_replace('~^<'.$no_p.'[^>]*+>~im', "\n$0", $str); $str = preg_replace('~$~im', "$0\n", $str); } // Do the

    magic! $str = '

    '.trim($str).'

    '; $str = preg_replace('~\n{2,}~', "

    \n\n

    ", $str); // The following regexes only need to be executed if the string contains html if ($html_found !== FALSE) { // Remove p tags around $no_p elements $str = preg_replace('~

    (?=]*+>)~i', '', $str); $str = preg_replace('~(]*+>)

    ~i', '$1', $str); } // Convert single linebreaks to
    $str = preg_replace('~(?\n", $str); return $str; } /** * Returns human readable sizes. * @see Based on original functions written by: * @see Aidan Lister: http://aidanlister.com/repos/v/function.size_readable.php * @see Quentin Zervaas: http://www.phpriot.com/d/code/strings/filesize-format/ * * @param integer size in bytes * @param string a definitive unit * @param string the return string format * @param boolean whether to use SI prefixes or IEC * @return string */ public static function bytes($bytes, $force_unit = NULL, $format = NULL, $si = TRUE) { // Format string $format = ($format === NULL) ? '%01.2f %s' : (string) $format; // IEC prefixes (binary) if ($si == FALSE OR strpos($force_unit, 'i') !== FALSE) { $units = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'); $mod = 1024; } // SI prefixes (decimal) else { $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB'); $mod = 1000; } // Determine unit to use if (($power = array_search((string) $force_unit, $units)) === FALSE) { $power = ($bytes > 0) ? floor(log($bytes, $mod)) : 0; } return sprintf($format, $bytes / pow($mod, $power), $units[$power]); } /** * Prevents widow words by inserting a non-breaking space between the last two words. * @see http://www.shauninman.com/archive/2006/08/22/widont_wordpress_plugin * * @param string string to remove widows from * @return string */ public static function widont($str) { $str = rtrim($str); $space = strrpos($str, ' '); if ($space !== FALSE) { $str = substr($str, 0, $space).' '.substr($str, $space + 1); } return $str; } } // End text./kohana/system/helpers/num.php0000644000175000017500000000110111121324570016265 0ustar tokkeetokkee=')) { $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8', FALSE); } else { $str = preg_replace('/&(?!(?:#\d++|[a-z]++);)/ui', '&', $str); $str = str_replace(array('<', '>', '\'', '"'), array('<', '>', ''', '"'), $str); } } return $str; } /** * Perform a html::specialchars() with additional URL specific encoding. * * @param string string to convert * @param boolean encode existing entities * @return string */ public static function specialurlencode($str, $double_encode = TRUE) { return str_replace(' ', '%20', html::specialchars($str, $double_encode)); } /** * Create HTML link anchors. * * @param string URL or URI string * @param string link text * @param array HTML anchor attributes * @param string non-default protocol, eg: https * @param boolean option to escape the title that is output * @return string */ public static function anchor($uri, $title = NULL, $attributes = NULL, $protocol = NULL, $escape_title = FALSE) { if ($uri === '') { $site_url = url::base(FALSE); } elseif (strpos($uri, '#') === 0) { // This is an id target link, not a URL $site_url = $uri; } elseif (strpos($uri, '://') === FALSE) { $site_url = url::site($uri, $protocol); } else { if (html::$windowed_urls === TRUE AND empty($attributes['target'])) { $attributes['target'] = '_blank'; } $site_url = $uri; } return // Parsed URL '
    ' // Title empty? Use the parsed URL .($escape_title ? html::specialchars((($title === NULL) ? $site_url : $title), FALSE) : (($title === NULL) ? $site_url : $title)).''; } /** * Creates an HTML anchor to a file. * * @param string name of file to link to * @param string link text * @param array HTML anchor attributes * @param string non-default protocol, eg: ftp * @return string */ public static function file_anchor($file, $title = NULL, $attributes = NULL, $protocol = NULL) { return // Base URL + URI = full URL '' // Title empty? Use the filename part of the URI .(($title === NULL) ? end(explode('/', $file)) : $title) .''; } /** * Similar to anchor, but with the protocol parameter first. * * @param string link protocol * @param string URI or URL to link to * @param string link text * @param array HTML anchor attributes * @return string */ public static function panchor($protocol, $uri, $title = NULL, $attributes = FALSE) { return html::anchor($uri, $title, $attributes, $protocol); } /** * Create an array of anchors from an array of link/title pairs. * * @param array link/title pairs * @return array */ public static function anchor_array(array $array) { $anchors = array(); foreach ($array as $link => $title) { // Create list of anchors $anchors[] = html::anchor($link, $title); } return $anchors; } /** * Generates an obfuscated version of an email address. * * @param string email address * @return string */ public static function email($email) { $safe = ''; foreach (str_split($email) as $letter) { switch (($letter === '@') ? rand(1, 2) : rand(1, 3)) { // HTML entity code case 1: $safe .= '&#'.ord($letter).';'; break; // Hex character code case 2: $safe .= '&#x'.dechex(ord($letter)).';'; break; // Raw (no) encoding case 3: $safe .= $letter; } } return $safe; } /** * Creates an email anchor. * * @param string email address to send to * @param string link text * @param array HTML anchor attributes * @return string */ public static function mailto($email, $title = NULL, $attributes = NULL) { if (empty($email)) return $title; // Remove the subject or other parameters that do not need to be encoded if (strpos($email, '?') !== FALSE) { // Extract the parameters from the email address list ($email, $params) = explode('?', $email, 2); // Make the params into a query string, replacing spaces $params = '?'.str_replace(' ', '%20', $params); } else { // No parameters $params = ''; } // Obfuscate email address $safe = html::email($email); // Title defaults to the encoded email address empty($title) and $title = $safe; // Parse attributes empty($attributes) or $attributes = html::attributes($attributes); // Encoded start of the href="" is a static encoded version of 'mailto:' return ''.$title.''; } /** * Generate a "breadcrumb" list of anchors representing the URI. * * @param array segments to use as breadcrumbs, defaults to using Router::$segments * @return string */ public static function breadcrumb($segments = NULL) { empty($segments) and $segments = Router::$segments; $array = array(); while ($segment = array_pop($segments)) { $array[] = html::anchor ( // Complete URI for the URL implode('/', $segments).'/'.$segment, // Title for the current segment ucwords(inflector::humanize($segment)) ); } // Retrun the array of all the segments return array_reverse($array); } /** * Creates a meta tag. * * @param string|array tag name, or an array of tags * @param string tag "content" value * @return string */ public static function meta($tag, $value = NULL) { if (is_array($tag)) { $tags = array(); foreach ($tag as $t => $v) { // Build each tag and add it to the array $tags[] = html::meta($t, $v); } // Return all of the tags as a string return implode("\n", $tags); } // Set the meta attribute value $attr = in_array(strtolower($tag), Kohana::config('http.meta_equiv')) ? 'http-equiv' : 'name'; return ''; } /** * Creates a stylesheet link. * * @param string|array filename, or array of filenames to match to array of medias * @param string|array media type of stylesheet, or array to match filenames * @param boolean include the index_page in the link * @return string */ public static function stylesheet($style, $media = FALSE, $index = FALSE) { return html::link($style, 'stylesheet', 'text/css', '.css', $media, $index); } /** * Creates a link tag. * * @param string|array filename * @param string|array relationship * @param string|array mimetype * @param string specifies suffix of the file * @param string|array specifies on what device the document will be displayed * @param boolean include the index_page in the link * @return string */ public static function link($href, $rel, $type, $suffix = FALSE, $media = FALSE, $index = FALSE) { $compiled = ''; if (is_array($href)) { foreach ($href as $_href) { $_rel = is_array($rel) ? array_shift($rel) : $rel; $_type = is_array($type) ? array_shift($type) : $type; $_media = is_array($media) ? array_shift($media) : $media; $compiled .= html::link($_href, $_rel, $_type, $suffix, $_media, $index); } } else { if (strpos($href, '://') === FALSE) { // Make the URL absolute $href = url::base($index).$href; } $length = strlen($suffix); if ( $length > 0 AND substr_compare($href, $suffix, -$length, $length, FALSE) !== 0) { // Add the defined suffix $href .= $suffix; } $attr = array ( 'rel' => $rel, 'type' => $type, 'href' => $href, ); if ( ! empty($media)) { // Add the media type to the attributes $attr['media'] = $media; } $compiled = ''; } return $compiled."\n"; } /** * Creates a script link. * * @param string|array filename * @param boolean include the index_page in the link * @return string */ public static function script($script, $index = FALSE) { $compiled = ''; if (is_array($script)) { foreach ($script as $name) { $compiled .= html::script($name, $index); } } else { if (strpos($script, '://') === FALSE) { // Add the suffix only when it's not already present $script = url::base((bool) $index).$script; } if (substr_compare($script, '.js', -3, 3, FALSE) !== 0) { // Add the javascript suffix $script .= '.js'; } $compiled = ''; } return $compiled."\n"; } /** * Creates a image link. * * @param string image source, or an array of attributes * @param string|array image alt attribute, or an array of attributes * @param boolean include the index_page in the link * @return string */ public static function image($src = NULL, $alt = NULL, $index = FALSE) { // Create attribute list $attributes = is_array($src) ? $src : array('src' => $src); if (is_array($alt)) { $attributes += $alt; } elseif ( ! empty($alt)) { // Add alt to attributes $attributes['alt'] = $alt; } if (strpos($attributes['src'], '://') === FALSE) { // Make the src attribute into an absolute URL $attributes['src'] = url::base($index).$attributes['src']; } return ''; } /** * Compiles an array of HTML attributes into an attribute string. * * @param string|array array of attributes * @return string */ public static function attributes($attrs) { if (empty($attrs)) return ''; if (is_string($attrs)) return ' '.$attrs; $compiled = ''; foreach ($attrs as $key => $val) { $compiled .= ' '.$key.'="'.html::specialchars($val).'"'; } return $compiled; } } // End html ./kohana/system/helpers/format.php0000644000175000017500000000327311156020422016767 0ustar tokkeetokkeexss_clean($str); } /** * Remove image tags from a string. * * @param string string to sanitize * @return string */ public static function strip_image_tags($str) { return preg_replace('#\s]*)["\']?[^>]*)?>#is', '$1', $str); } /** * Remove PHP tags from a string. * * @param string string to sanitize * @return string */ public static function encode_php_tags($str) { return str_replace(array(''), array('<?', '?>'), $str); } } // End security./kohana/system/helpers/feed.php0000644000175000017500000000616111165515437016420 0ustar tokkeetokkeechannel) ? $feed->xpath('//item') : $feed->entry; $i = 0; $items = array(); foreach ($feed as $item) { if ($limit > 0 AND $i++ === $limit) break; $items[] = (array) $item; } return $items; } /** * Creates a feed from the given parameters. * * @param array feed information * @param array items to add to the feed * @param string define which format to use * @param string define which encoding to use * @return string */ public static function create($info, $items, $format = 'rss2', $encoding = 'UTF-8') { $info += array('title' => 'Generated Feed', 'link' => '', 'generator' => 'KohanaPHP'); $feed = ''; $feed = simplexml_load_string($feed); foreach ($info as $name => $value) { if (($name === 'pubDate' OR $name === 'lastBuildDate') AND (is_int($value) OR ctype_digit($value))) { // Convert timestamps to RFC 822 formatted dates $value = date(DATE_RFC822, $value); } elseif (($name === 'link' OR $name === 'docs') AND strpos($value, '://') === FALSE) { // Convert URIs to URLs $value = url::site($value, 'http'); } // Add the info to the channel $feed->channel->addChild($name, $value); } foreach ($items as $item) { // Add the item to the channel $row = $feed->channel->addChild('item'); foreach ($item as $name => $value) { if ($name === 'pubDate' AND (is_int($value) OR ctype_digit($value))) { // Convert timestamps to RFC 822 formatted dates $value = date(DATE_RFC822, $value); } elseif (($name === 'link' OR $name === 'guid') AND strpos($value, '://') === FALSE) { // Convert URIs to URLs $value = url::site($value, 'http'); } // Add the info to the row $row->addChild($name, $value); } } return $feed->asXML(); } } // End feed./kohana/system/helpers/file.php0000644000175000017500000001173311121324570016421 0ustar tokkeetokkee $value) { $value = ($keep_keys === TRUE) ? $value : array_values($value); foreach ($value as $k => $v) { $new_array[$k][$key] = $v; } } return $new_array; } /** * Removes a key from an array and returns the value. * * @param string key to return * @param array array to work on * @return mixed value of the requested array key */ public static function remove($key, & $array) { if ( ! array_key_exists($key, $array)) return NULL; $val = $array[$key]; unset($array[$key]); return $val; } /** * Extract one or more keys from an array. Each key given after the first * argument (the array) will be extracted. Keys that do not exist in the * search array will be NULL in the extracted data. * * @param array array to search * @param string key name * @return array */ public static function extract(array $search, $keys) { // Get the keys, removing the $search array $keys = array_slice(func_get_args(), 1); $found = array(); foreach ($keys as $key) { if (isset($search[$key])) { $found[$key] = $search[$key]; } else { $found[$key] = NULL; } } return $found; } /** * Because PHP does not have this function. * * @param array array to unshift * @param string key to unshift * @param mixed value to unshift * @return array */ public static function unshift_assoc( array & $array, $key, $val) { $array = array_reverse($array, TRUE); $array[$key] = $val; $array = array_reverse($array, TRUE); return $array; } /** * Because PHP does not have this function, and array_walk_recursive creates * references in arrays and is not truly recursive. * * @param mixed callback to apply to each member of the array * @param array array to map to * @return array */ public static function map_recursive($callback, array $array) { foreach ($array as $key => $val) { // Map the callback to the key $array[$key] = is_array($val) ? arr::map_recursive($callback, $val) : call_user_func($callback, $val); } return $array; } /** * @param mixed $needle the value to search for * @param array $haystack an array of values to search in * @param boolean $sort sort the array now * @return integer|FALSE the index of the match or FALSE when not found */ public static function binary_search($needle, $haystack, $sort = FALSE) { if ($sort) { sort($haystack); } $high = count($haystack) - 1; $low = 0; while ($low <= $high) { $mid = ($low + $high) >> 1; if ($haystack[$mid] < $needle) { $low = $mid + 1; } elseif ($haystack[$mid] > $needle) { $high = $mid - 1; } else { return $mid; } } return FALSE; } /** * Emulates array_merge_recursive, but appends numeric keys and replaces * associative keys, instead of appending all keys. * * @param array any number of arrays * @return array */ public static function merge() { $total = func_num_args(); $result = array(); for ($i = 0; $i < $total; $i++) { foreach (func_get_arg($i) as $key => $val) { if (isset($result[$key])) { if (is_array($val)) { // Arrays are merged recursively $result[$key] = arr::merge($result[$key], $val); } elseif (is_int($key)) { // Indexed arrays are appended array_push($result, $val); } else { // Associative arrays are replaced $result[$key] = $val; } } else { // New values are added $result[$key] = $val; } } } return $result; } /** * Overwrites an array with values from input array(s). * Non-existing keys will not be appended! * * @param array key array * @param array input array(s) that will overwrite key array values * @return array */ public static function overwrite($array1, $array2) { foreach (array_intersect_key($array2, $array1) as $key => $value) { $array1[$key] = $value; } if (func_num_args() > 2) { foreach (array_slice(func_get_args(), 2) as $array2) { foreach (array_intersect_key($array2, $array1) as $key => $value) { $array1[$key] = $value; } } } return $array1; } /** * Fill an array with a range of numbers. * * @param integer stepping * @param integer ending number * @return array */ public static function range($step = 10, $max = 100) { if ($step < 1) return array(); $array = array(); for ($i = $step; $i <= $max; $i += $step) { $array[$i] = $i; } return $array; } /** * Recursively convert an array to an object. * * @param array array to convert * @return object */ public static function to_object(array $array, $class = 'stdClass') { $object = new $class; foreach ($array as $key => $value) { if (is_array($value)) { // Convert the array to an object $value = arr::to_object($value, $class); } // Add the value to the object $object->{$key} = $value; } return $object; } } // End arr ./kohana/system/views/0000755000175000017500000000000011263472444014472 5ustar tokkeetokkee./kohana/system/views/kohana_error_disabled.php0000644000175000017500000000123611166754742021514 0ustar tokkeetokkee <?php echo $error ?>

    ./kohana/system/views/kohana/0000755000175000017500000000000011263472444015733 5ustar tokkeetokkee./kohana/system/views/kohana/template.php0000644000175000017500000000267511121324570020256 0ustar tokkeetokkee <?php echo html::specialchars($title) ?>

    ./kohana/system/views/kohana_profiler_table.php0000644000175000017500000000141511121765705021514 0ustar tokkeetokkee > $column) { $class = empty($column['class']) ? '' : ' class="'.$column['class'].'"'; $style = empty($column['style']) ? '' : ' style="'.$column['style'].'"'; $value = $row['data'][$index]; $value = (is_array($value) OR is_object($value)) ? '
    '.html::specialchars(print_r($value, TRUE)).'
    ' : html::specialchars($value); echo '', $value, ''; } ?>
    ./kohana/system/views/kohana_errors.css0000644000175000017500000000245311002053646020033 0ustar tokkeetokkeediv#framework_error { background:#fff; border:solid 1px #ccc; font-family:sans-serif; color:#111; font-size:14px; line-height:130%; } div#framework_error h3 { color:#fff; font-size:16px; padding:8px 6px; margin:0 0 8px; background:#f15a00; text-align:center; } div#framework_error a { color:#228; text-decoration:none; } div#framework_error a:hover { text-decoration:underline; } div#framework_error strong { color:#900; } div#framework_error p { margin:0; padding:4px 6px 10px; } div#framework_error tt, div#framework_error pre, div#framework_error code { font-family:monospace; padding:2px 4px; font-size:12px; color:#333; white-space:pre-wrap; /* CSS 2.1 */ white-space:-moz-pre-wrap; /* For Mozilla */ word-wrap:break-word; /* For IE5.5+ */ } div#framework_error tt { font-style:italic; } div#framework_error tt:before { content:">"; color:#aaa; } div#framework_error code tt:before { content:""; } div#framework_error pre, div#framework_error code { background:#eaeee5; border:solid 0 #D6D8D1; border-width:0 1px 1px 0; } div#framework_error .block { display:block; text-align:left; } div#framework_error .stats { padding:4px; background: #eee; border-top:solid 1px #ccc; text-align:center; font-size:10px; color:#888; } div#framework_error .backtrace { margin:0; padding:0 6px; list-style:none; line-height:12px; }./kohana/system/views/kohana_profiler.php0000644000175000017500000000130411121324570020331 0ustar tokkeetokkee
    render(); } ?>

    Profiler executed in s

    ./kohana/system/views/kohana_error_page.php0000644000175000017500000000207711166754742020665 0ustar tokkeetokkee <?php echo $error ?>

    ./kohana/system/views/kohana_profiler_table.css0000644000175000017500000000221111035447315021506 0ustar tokkeetokkee#kohana-profiler .kp-table { font-size: 1.0em; color: #4D6171; width: 100%; border-collapse: collapse; border-top: 1px solid #E5EFF8; border-right: 1px solid #E5EFF8; border-left: 1px solid #E5EFF8; margin-bottom: 10px; } #kohana-profiler .kp-table td { background-color: #FFFFFF; border-bottom: 1px solid #E5EFF8; padding: 3px; vertical-align: top; } #kohana-profiler .kp-table .kp-title td { font-weight: bold; background-color: inherit; } #kohana-profiler .kp-table .kp-altrow td { background-color: #F7FBFF; } #kohana-profiler .kp-table .kp-totalrow td { background-color: #FAFAFA; border-top: 1px solid #D2DCE5; font-weight: bold; } #kohana-profiler .kp-table .kp-column { width: 100px; border-left: 1px solid #E5EFF8; text-align: center; } #kohana-profiler .kp-table .kp-data, #kohana-profiler .kp-table .kp-name { background-color: #FAFAFB; vertical-align: top; } #kohana-profiler .kp-table .kp-name { width: 200px; border-right: 1px solid #E5EFF8; } #kohana-profiler .kp-table .kp-altrow .kp-data, #kohana-profiler .kp-table .kp-altrow .kp-name { background-color: #F6F8FB; }./kohana/system/views/kohana_calendar.php0000644000175000017500000000300311121324570020256 0ustar tokkeetokkee date('n', $prev), 'year' => date('Y', $prev)))); $next = Router::$current_uri.'?'.http_build_query(array_merge($qs, array('month' => date('n', $next), 'year' => date('Y', $next)))); ?>
  • '.implode('
  • ', $data['output']).'
  • '; } else { $classes = array(); $output = ''; } ?>
    ./kohana/system/views/pagination/0000755000175000017500000000000011263472444016623 5ustar tokkeetokkee./kohana/system/views/pagination/classic.php0000644000175000017500000000200111121324570020733 0ustar tokkeetokkee Last › */ ?>

    ‹  < >  ›

    ./kohana/system/views/pagination/punbb.php0000644000175000017500000000171311121324570020431 0ustar tokkeetokkee

    : 3): ?> 1 $total_pages) continue ?>

    ./kohana/system/views/pagination/digg.php0000644000175000017500000000556211121324570020243 0ustar tokkeetokkee

    «  «  $total_pages - 8): /* « Previous 1 2 … 17 18 19 20 21 22 23 24 25 26 Next » */ ?> 1 2 1 2  »  »

    ./kohana/system/views/pagination/extended.php0000644000175000017500000000206211121324570021121 0ustar tokkeetokkee

    «  «  | | |  »  »

    ./kohana/system/libraries/0000755000175000017500000000000011263472441015306 5ustar tokkeetokkee./kohana/system/libraries/Model.php0000644000175000017500000000116711147406470017064 0ustar tokkeetokkeedb)) { // Load the default database $this->db = Database::instance($this->db); } } } // End Model./kohana/system/libraries/Controller.php0000644000175000017500000000371411207326007020141 0ustar tokkeetokkeeuri = URI::instance(); // Input should always be available $this->input = Input::instance(); } /** * Handles methods that do not exist. * * @param string method name * @param array arguments * @return void */ public function __call($method, $args) { // Default to showing a 404 page Event::run('system.404'); } /** * Includes a View within the controller scope. * * @param string view filename * @param array array of view variables * @return string */ public function _kohana_load_view($kohana_view_filename, $kohana_input_data) { if ($kohana_view_filename == '') return; // Buffering on ob_start(); // Import the view variables to local namespace extract($kohana_input_data, EXTR_SKIP); // Views are straight HTML pages with embedded PHP, so importing them // this way insures that $this can be accessed as if the user was in // the controller, which gives the easiest access to libraries in views try { include $kohana_view_filename; } catch (Exception $e) { ob_end_clean(); throw $e; } // Fetch the output and close the buffer return ob_get_clean(); } } // End Controller Class./kohana/system/libraries/drivers/0000755000175000017500000000000011263472443016766 5ustar tokkeetokkee./kohana/system/libraries/drivers/Captcha/0000755000175000017500000000000011263472442020330 5ustar tokkeetokkee./kohana/system/libraries/drivers/Captcha/Black.php0000644000175000017500000000625711121324570022056 0ustar tokkeetokkeeimage_create(Captcha::$config['background']); // Add random white/gray arcs, amount depends on complexity setting $count = (Captcha::$config['width'] + Captcha::$config['height']) / 2; $count = $count / 5 * min(10, Captcha::$config['complexity']); for ($i = 0; $i < $count; $i++) { imagesetthickness($this->image, mt_rand(1, 2)); $color = imagecolorallocatealpha($this->image, 255, 255, 255, mt_rand(0, 120)); imagearc($this->image, mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(0, 360), mt_rand(0, 360), $color); } // Use different fonts if available $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; // Draw the character's white shadows $size = (int) min(Captcha::$config['height'] / 2, Captcha::$config['width'] * 0.8 / strlen($this->response)); $angle = mt_rand(-15 + strlen($this->response), 15 - strlen($this->response)); $x = mt_rand(1, Captcha::$config['width'] * 0.9 - $size * strlen($this->response)); $y = ((Captcha::$config['height'] - $size) / 2) + $size; $color = imagecolorallocate($this->image, 255, 255, 255); imagefttext($this->image, $size, $angle, $x + 1, $y + 1, $color, $font, $this->response); // Add more shadows for lower complexities (Captcha::$config['complexity'] < 10) and imagefttext($this->image, $size, $angle, $x - 1, $y - 1, $color, $font , $this->response); (Captcha::$config['complexity'] < 8) and imagefttext($this->image, $size, $angle, $x - 2, $y + 2, $color, $font , $this->response); (Captcha::$config['complexity'] < 6) and imagefttext($this->image, $size, $angle, $x + 2, $y - 2, $color, $font , $this->response); (Captcha::$config['complexity'] < 4) and imagefttext($this->image, $size, $angle, $x + 3, $y + 3, $color, $font , $this->response); (Captcha::$config['complexity'] < 2) and imagefttext($this->image, $size, $angle, $x - 3, $y - 3, $color, $font , $this->response); // Finally draw the foreground characters $color = imagecolorallocate($this->image, 0, 0, 0); imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response); // Output return $this->image_render($html); } } // End Captcha Black Driver Class./kohana/system/libraries/drivers/Captcha/Riddle.php0000644000175000017500000000173611121324570022242 0ustar tokkeetokkeeriddle = $riddle[0]; // Return the answer return $riddle[1]; } /** * Outputs the Captcha riddle. * * @param boolean html output * @return mixed */ public function render($html) { return $this->riddle; } } // End Captcha Riddle Driver Class./kohana/system/libraries/drivers/Captcha/Basic.php0000644000175000017500000000537411121324570022062 0ustar tokkeetokkeeimage $this->image_create(Captcha::$config['background']); // Add a random gradient if (empty(Captcha::$config['background'])) { $color1 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); $color2 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); $this->image_gradient($color1, $color2); } // Add a few random lines for ($i = 0, $count = mt_rand(5, Captcha::$config['complexity'] * 4); $i < $count; $i++) { $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(100, 255), mt_rand(50, 120)); imageline($this->image, mt_rand(0, Captcha::$config['width']), 0, mt_rand(0, Captcha::$config['width']), Captcha::$config['height'], $color); } // Calculate character font-size and spacing $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / (strlen($this->response) + 1); $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); // Draw each Captcha character with varying attributes for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) { // Use different fonts if available $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; // Allocate random color, size and rotation attributes to text $color = imagecolorallocate($this->image, mt_rand(0, 150), mt_rand(0, 150), mt_rand(0, 150)); $angle = mt_rand(-40, 20); // Scale the character size on image height $size = $default_size / 10 * mt_rand(8, 12); $box = imageftbbox($size, $angle, $font, $this->response[$i]); // Calculate character starting coordinates $x = $spacing / 4 + $i * $spacing; $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; // Write text character to image imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); } // Output return $this->image_render($html); } } // End Captcha Basic Driver Class./kohana/system/libraries/drivers/Captcha/Math.php0000644000175000017500000000237311121324570021726 0ustar tokkeetokkeemath_exercice = implode(' + ', $numbers).' = '; // Return the answer return array_sum($numbers); } /** * Outputs the Captcha riddle. * * @param boolean html output * @return mixed */ public function render($html) { return $this->math_exercice; } } // End Captcha Math Driver Class./kohana/system/libraries/drivers/Captcha/Word.php0000644000175000017500000000170211121324570021743 0ustar tokkeetokkeeimage $this->image_create(Captcha::$config['background']); // Add a random gradient if (empty(Captcha::$config['background'])) { $color1 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); $color2 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); $this->image_gradient($color1, $color2); } // Add a few random circles for ($i = 0, $count = mt_rand(10, Captcha::$config['complexity'] * 3); $i < $count; $i++) { $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255), mt_rand(80, 120)); $size = mt_rand(5, Captcha::$config['height'] / 3); imagefilledellipse($this->image, mt_rand(0, Captcha::$config['width']), mt_rand(0, Captcha::$config['height']), $size, $size, $color); } // Calculate character font-size and spacing $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / strlen($this->response); $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); // Background alphabetic character attributes $color_limit = mt_rand(96, 160); $chars = 'ABEFGJKLPQRTVY'; // Draw each Captcha character with varying attributes for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) { // Use different fonts if available $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; $angle = mt_rand(-40, 20); // Scale the character size on image height $size = $default_size / 10 * mt_rand(8, 12); $box = imageftbbox($size, $angle, $font, $this->response[$i]); // Calculate character starting coordinates $x = $spacing / 4 + $i * $spacing; $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; // Draw captcha text character // Allocate random color, size and rotation attributes to text $color = imagecolorallocate($this->image, mt_rand(150, 255), mt_rand(200, 255), mt_rand(0, 255)); // Write text character to image imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); // Draw "ghost" alphabetic character $text_color = imagecolorallocatealpha($this->image, mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand(70, 120)); $char = $chars[mt_rand(0, 14)]; imagettftext($this->image, $size * 2, mt_rand(-45, 45), ($x - (mt_rand(5, 10))), ($y + (mt_rand(5, 10))), $text_color, $font, $char); } // Output return $this->image_render($html); } } // End Captcha Alpha Driver Class./kohana/system/libraries/drivers/Database/0000755000175000017500000000000011263472443020472 5ustar tokkeetokkee./kohana/system/libraries/drivers/Database/Mysqli.php0000644000175000017500000001751011202052503022445 0ustar tokkeetokkeedb_config = $config; Kohana::log('debug', 'MySQLi Database Driver Initialized'); } /** * Closes the database connection. */ public function __destruct() { is_object($this->link) and $this->link->close(); } public function connect() { // Check if link already exists if (is_object($this->link)) return $this->link; // Import the connect variables extract($this->db_config['connection']); // Build the connection info $host = isset($host) ? $host : $socket; // Make the connection and select the database if ($this->link = new mysqli($host, $user, $pass, $database, $port)) { if ($charset = $this->db_config['character_set']) { $this->set_charset($charset); } // Clear password after successful connect $this->db_config['connection']['pass'] = NULL; return $this->link; } return FALSE; } public function query($sql) { // Only cache if it's turned on, and only cache if it's not a write statement if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) { $hash = $this->query_hash($sql); if ( ! isset($this->query_cache[$hash])) { // Set the cached object $this->query_cache[$hash] = new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); } else { // Rewind cached result $this->query_cache[$hash]->rewind(); } // Return the cached query return $this->query_cache[$hash]; } return new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); } public function set_charset($charset) { if ($this->link->set_charset($charset) === FALSE) throw new Kohana_Database_Exception('database.error', $this->show_error()); } public function escape_str($str) { if (!$this->db_config['escape']) return $str; is_object($this->link) or $this->connect(); return $this->link->real_escape_string($str); } public function show_error() { return $this->link->error; } } // End Database_Mysqli_Driver Class /** * MySQLi Result */ class Kohana_Mysqli_Result extends Database_Result { // Database connection protected $link; // Data fetching types protected $fetch_type = 'mysqli_fetch_object'; protected $return_type = MYSQLI_ASSOC; /** * Sets up the result variables. * * @param object database link * @param boolean return objects or arrays * @param string SQL query that was run */ public function __construct($link, $object = TRUE, $sql) { $this->link = $link; if ( ! $this->link->multi_query($sql)) { // SQL error throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); } else { $this->result = $this->link->store_result(); // If the query is an object, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query if (is_object($this->result)) { $this->current_row = 0; $this->total_rows = $this->result->num_rows; $this->fetch_type = ($object === TRUE) ? 'fetch_object' : 'fetch_array'; } elseif ($this->link->error) { // SQL error throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); } else { // Its an DELETE, INSERT, REPLACE, or UPDATE query $this->insert_id = $this->link->insert_id; $this->total_rows = $this->link->affected_rows; } } // Set result type $this->result($object); // Store the SQL $this->sql = $sql; } /** * Magic __destruct function, frees the result. */ public function __destruct() { if (is_object($this->result)) { $this->result->free_result(); // this is kinda useless, but needs to be done to avoid the "Commands out of sync; you // can't run this command now" error. Basically, we get all results after the first one // (the one we actually need) and free them. if (is_resource($this->link) AND $this->link->more_results()) { do { if ($result = $this->link->store_result()) { $result->free_result(); } } while ($this->link->next_result()); } } } public function result($object = TRUE, $type = MYSQLI_ASSOC) { $this->fetch_type = ((bool) $object) ? 'fetch_object' : 'fetch_array'; // This check has to be outside the previous statement, because we do not // know the state of fetch_type when $object = NULL // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. if ($this->fetch_type == 'fetch_object') { $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $this->return_type = $type; } return $this; } public function as_array($object = NULL, $type = MYSQLI_ASSOC) { return $this->result_array($object, $type); } public function result_array($object = NULL, $type = MYSQLI_ASSOC) { $rows = array(); if (is_string($object)) { $fetch = $object; } elseif (is_bool($object)) { if ($object === TRUE) { $fetch = 'fetch_object'; // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $fetch = 'fetch_array'; } } else { // Use the default config values $fetch = $this->fetch_type; if ($fetch == 'fetch_object') { $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } } if ($this->result->num_rows) { // Reset the pointer location to make sure things work properly $this->result->data_seek(0); while ($row = $this->result->$fetch($type)) { $rows[] = $row; } } return isset($rows) ? $rows : array(); } public function list_fields() { $field_names = array(); while ($field = $this->result->fetch_field()) { $field_names[] = $field->name; } return $field_names; } public function seek($offset) { if ($this->offsetExists($offset) AND $this->result->data_seek($offset)) { // Set the current row to the offset $this->current_row = $offset; return TRUE; } return FALSE; } public function offsetGet($offset) { if ( ! $this->seek($offset)) return FALSE; // Return the row $fetch = $this->fetch_type; return $this->result->$fetch($this->return_type); } } // End Mysqli_Result Class /** * MySQLi Prepared Statement (experimental) */ class Kohana_Mysqli_Statement { protected $link = NULL; protected $stmt; protected $var_names = array(); protected $var_values = array(); public function __construct($sql, $link) { $this->link = $link; $this->stmt = $this->link->prepare($sql); return $this; } public function __destruct() { $this->stmt->close(); } // Sets the bind parameters public function bind_params($param_types, $params) { $this->var_names = array_keys($params); $this->var_values = array_values($params); call_user_func_array(array($this->stmt, 'bind_param'), array_merge($param_types, $var_names)); return $this; } public function bind_result($params) { call_user_func_array(array($this->stmt, 'bind_result'), $params); } // Runs the statement public function execute() { foreach ($this->var_names as $key => $name) { $$name = $this->var_values[$key]; } $this->stmt->execute(); return $this->stmt; } } ./kohana/system/libraries/drivers/Database/Pgsql.php0000644000175000017500000003020311202052503022247 0ustar tokkeetokkeedb_config = $config; Kohana::log('debug', 'PgSQL Database Driver Initialized'); } public function connect() { // Check if link already exists if (is_resource($this->link)) return $this->link; // Import the connect variables extract($this->db_config['connection']); // Persistent connections enabled? $connect = ($this->db_config['persistent'] == TRUE) ? 'pg_pconnect' : 'pg_connect'; // Build the connection info $port = isset($port) ? 'port=\''.$port.'\'' : ''; $host = isset($host) ? 'host=\''.$host.'\' '.$port : ''; // if no host, connect with the socket $connection_string = $host.' dbname=\''.$database.'\' user=\''.$user.'\' password=\''.$pass.'\''; // Make the connection and select the database if ($this->link = $connect($connection_string)) { if ($charset = $this->db_config['character_set']) { echo $this->set_charset($charset); } // Clear password after successful connect $this->db_config['connection']['pass'] = NULL; return $this->link; } return FALSE; } public function query($sql) { // Only cache if it's turned on, and only cache if it's not a write statement if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|SET)\b#i', $sql)) { $hash = $this->query_hash($sql); if ( ! isset($this->query_cache[$hash])) { // Set the cached object $this->query_cache[$hash] = new Pgsql_Result(pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); } else { // Rewind cached result $this->query_cache[$hash]->rewind(); } return $this->query_cache[$hash]; } // Suppress warning triggered when a database error occurs (e.g., a constraint violation) return new Pgsql_Result(@pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); } public function set_charset($charset) { $this->query('SET client_encoding TO '.pg_escape_string($this->link, $charset)); } public function escape_table($table) { if (!$this->db_config['escape']) return $table; return '"'.str_replace('.', '"."', $table).'"'; } public function escape_column($column) { if (!$this->db_config['escape']) return $column; if ($column == '*') return $column; // This matches any functions we support to SELECT. if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) { if ( count($matches) == 3) { return $matches[1].'('.$this->escape_column($matches[2]).')'; } else if ( count($matches) == 5) { return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); } } // This matches any modifiers we support to SELECT. if ( ! preg_match('/\b(?:all|distinct)\s/i', $column)) { if (stripos($column, ' AS ') !== FALSE) { // Force 'AS' to uppercase $column = str_ireplace(' AS ', ' AS ', $column); // Runs escape_column on both sides of an AS statement $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); // Re-create the AS statement return implode(' AS ', $column); } return preg_replace('/[^.*]+/', '"$0"', $column); } $parts = explode(' ', $column); $column = ''; for ($i = 0, $c = count($parts); $i < $c; $i++) { // The column is always last if ($i == ($c - 1)) { $column .= preg_replace('/[^.*]+/', '"$0"', $parts[$i]); } else // otherwise, it's a modifier { $column .= $parts[$i].' '; } } return $column; } public function regex($field, $match, $type, $num_regexs) { $prefix = ($num_regexs == 0) ? '' : $type; return $prefix.' '.$this->escape_column($field).' ~* \''.$this->escape_str($match).'\''; } public function notregex($field, $match, $type, $num_regexs) { $prefix = $num_regexs == 0 ? '' : $type; return $prefix.' '.$this->escape_column($field).' !~* \''.$this->escape_str($match) . '\''; } public function limit($limit, $offset = 0) { return 'LIMIT '.$limit.' OFFSET '.$offset; } public function compile_select($database) { $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; if (count($database['from']) > 0) { $sql .= "\nFROM "; $sql .= implode(', ', $database['from']); } if (count($database['join']) > 0) { foreach($database['join'] AS $join) { $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; } } if (count($database['where']) > 0) { $sql .= "\nWHERE "; } $sql .= implode("\n", $database['where']); if (count($database['groupby']) > 0) { $sql .= "\nGROUP BY "; $sql .= implode(', ', $database['groupby']); } if (count($database['having']) > 0) { $sql .= "\nHAVING "; $sql .= implode("\n", $database['having']); } if (count($database['orderby']) > 0) { $sql .= "\nORDER BY "; $sql .= implode(', ', $database['orderby']); } if (is_numeric($database['limit'])) { $sql .= "\n"; $sql .= $this->limit($database['limit'], $database['offset']); } return $sql; } public function escape_str($str) { if (!$this->db_config['escape']) return $str; is_resource($this->link) or $this->connect(); return pg_escape_string($this->link, $str); } public function list_tables() { $sql = 'SELECT table_schema || \'.\' || table_name FROM information_schema.tables WHERE table_schema NOT IN (\'pg_catalog\', \'information_schema\')'; $result = $this->query($sql)->result(FALSE, PGSQL_ASSOC); $retval = array(); foreach ($result as $row) { $retval[] = current($row); } return $retval; } public function show_error() { return pg_last_error($this->link); } public function list_fields($table) { $result = NULL; foreach ($this->field_data($table) as $row) { // Make an associative array $result[$row->column_name] = $this->sql_type($row->data_type); if (!strncmp($row->column_default, 'nextval(', 8)) { $result[$row->column_name]['sequenced'] = TRUE; } if ($row->is_nullable === 'YES') { $result[$row->column_name]['null'] = TRUE; } } if (!isset($result)) throw new Kohana_Database_Exception('database.table_not_found', $table); return $result; } public function field_data($table) { // http://www.postgresql.org/docs/8.3/static/infoschema-columns.html $result = $this->query(' SELECT column_name, column_default, is_nullable, data_type, udt_name, character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale FROM information_schema.columns WHERE table_name = \''. $this->escape_str($table) .'\' ORDER BY ordinal_position '); return $result->result_array(TRUE); } } // End Database_Pgsql_Driver Class /** * PostgreSQL Result */ class Pgsql_Result extends Database_Result { // Data fetching types protected $fetch_type = 'pgsql_fetch_object'; protected $return_type = PGSQL_ASSOC; /** * Sets up the result variables. * * @param resource query result * @param resource database link * @param boolean return objects or arrays * @param string SQL query that was run */ public function __construct($result, $link, $object = TRUE, $sql) { $this->link = $link; $this->result = $result; // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query if (is_resource($result)) { // Its an DELETE, INSERT, REPLACE, or UPDATE query if (preg_match('/^(?:delete|insert|replace|update)\b/iD', trim($sql), $matches)) { $this->insert_id = (strtolower($matches[0]) == 'insert') ? $this->insert_id() : FALSE; $this->total_rows = pg_affected_rows($this->result); } else { $this->current_row = 0; $this->total_rows = pg_num_rows($this->result); $this->fetch_type = ($object === TRUE) ? 'pg_fetch_object' : 'pg_fetch_array'; } } else { throw new Kohana_Database_Exception('database.error', pg_last_error().' - '.$sql); } // Set result type $this->result($object); // Store the SQL $this->sql = $sql; } /** * Magic __destruct function, frees the result. */ public function __destruct() { if (is_resource($this->result)) { pg_free_result($this->result); } } public function result($object = TRUE, $type = PGSQL_ASSOC) { $this->fetch_type = ((bool) $object) ? 'pg_fetch_object' : 'pg_fetch_array'; // This check has to be outside the previous statement, because we do not // know the state of fetch_type when $object = NULL // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. if ($this->fetch_type == 'pg_fetch_object') { $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $this->return_type = $type; } return $this; } public function as_array($object = NULL, $type = PGSQL_ASSOC) { return $this->result_array($object, $type); } public function result_array($object = NULL, $type = PGSQL_ASSOC) { $rows = array(); if (is_string($object)) { $fetch = $object; } elseif (is_bool($object)) { if ($object === TRUE) { $fetch = 'pg_fetch_object'; // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $fetch = 'pg_fetch_array'; } } else { // Use the default config values $fetch = $this->fetch_type; if ($fetch == 'pg_fetch_object') { $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } } if ($this->total_rows) { pg_result_seek($this->result, 0); while ($row = $fetch($this->result, NULL, $type)) { $rows[] = $row; } } return $rows; } public function insert_id() { if ($this->insert_id === NULL) { $query = 'SELECT LASTVAL() AS insert_id'; // Disable error reporting for this, just to silence errors on // tables that have no serial column. $ER = error_reporting(0); $result = pg_query($this->link, $query); $insert_id = pg_fetch_array($result, NULL, PGSQL_ASSOC); $this->insert_id = $insert_id['insert_id']; // Reset error reporting error_reporting($ER); } return $this->insert_id; } public function seek($offset) { if ($this->offsetExists($offset) AND pg_result_seek($this->result, $offset)) { // Set the current row to the offset $this->current_row = $offset; return TRUE; } return FALSE; } public function list_fields() { $field_names = array(); $fields = pg_num_fields($this->result); for ($i = 0; $i < $fields; ++$i) { $field_names[] = pg_field_name($this->result, $i); } return $field_names; } /** * ArrayAccess: offsetGet */ public function offsetGet($offset) { if ( ! $this->seek($offset)) return FALSE; // Return the row by calling the defined fetching callback $fetch = $this->fetch_type; return $fetch($this->result, NULL, $this->return_type); } } // End Pgsql_Result Class /** * PostgreSQL Prepared Statement (experimental) */ class Kohana_Pgsql_Statement { protected $link = NULL; protected $stmt; public function __construct($sql, $link) { $this->link = $link; $this->stmt = $this->link->prepare($sql); return $this; } public function __destruct() { $this->stmt->close(); } // Sets the bind parameters public function bind_params() { $argv = func_get_args(); return $this; } // sets the statement values to the bound parameters public function set_vals() { return $this; } // Runs the statement public function execute() { return $this; } } ./kohana/system/libraries/drivers/Database/Mssql.php0000644000175000017500000002554011211612256022277 0ustar tokkeetokkeedb_config = $config; Kohana::log('debug', 'MSSQL Database Driver Initialized'); } /** * Closes the database connection. */ public function __destruct() { is_resource($this->link) and mssql_close($this->link); } /** * Make the connection * * @return return connection */ public function connect() { // Check if link already exists if (is_resource($this->link)) return $this->link; // Import the connect variables extract($this->db_config['connection']); // Persistent connections enabled? $connect = ($this->db_config['persistent'] == TRUE) ? 'mssql_pconnect' : 'mssql_connect'; // Build the connection info $host = isset($host) ? $host : $socket; // Windows uses a comma instead of a colon $port = (isset($port) AND is_string($port)) ? (KOHANA_IS_WIN ? ',' : ':').$port : ''; // Make the connection and select the database if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mssql_select_db($database, $this->link)) { /* This is being removed so I can use it, will need to come up with a more elegant workaround in the future... * if ($charset = $this->db_config['character_set']) { $this->set_charset($charset); } */ // Clear password after successful connect $this->db_config['connection']['pass'] = NULL; return $this->link; } return FALSE; } public function query($sql) { // Only cache if it's turned on, and only cache if it's not a write statement if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET)\b#i', $sql)) { $hash = $this->query_hash($sql); if ( ! isset($this->query_cache[$hash])) { // Set the cached object $this->query_cache[$hash] = new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); } else { // Rewind cached result $this->query_cache[$hash]->rewind(); } // Return the cached query return $this->query_cache[$hash]; } return new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); } public function escape_table($table) { if (stripos($table, ' AS ') !== FALSE) { // Force 'AS' to uppercase $table = str_ireplace(' AS ', ' AS ', $table); // Runs escape_table on both sides of an AS statement $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); // Re-create the AS statement return implode(' AS ', $table); } return '['.str_replace('.', '[.]', $table).']'; } public function escape_column($column) { if (!$this->db_config['escape']) return $column; if ($column == '*') return $column; // This matches any functions we support to SELECT. if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) { if ( count($matches) == 3) { return $matches[1].'('.$this->escape_column($matches[2]).')'; } else if ( count($matches) == 5) { return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); } } // This matches any modifiers we support to SELECT. if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) { if (stripos($column, ' AS ') !== FALSE) { // Force 'AS' to uppercase $column = str_ireplace(' AS ', ' AS ', $column); // Runs escape_column on both sides of an AS statement $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); // Re-create the AS statement return implode(' AS ', $column); } return preg_replace('/[^.*]+/', '[$0]', $column); } $parts = explode(' ', $column); $column = ''; for ($i = 0, $c = count($parts); $i < $c; $i++) { // The column is always last if ($i == ($c - 1)) { $column .= preg_replace('/[^.*]+/', '[$0]', $parts[$i]); } else // otherwise, it's a modifier { $column .= $parts[$i].' '; } } return $column; } /** * Limit in SQL Server 2000 only uses the keyword * 'TOP'; 2007 may have an offset keyword, but * I am unsure - for pagination style limit,offset * functionality, a fancy query needs to be built. * * @param unknown_type $limit * @return unknown */ public function limit($limit, $offset=null) { return 'TOP '.$limit; } public function compile_select($database) { $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; if (count($database['from']) > 0) { // Escape the tables $froms = array(); foreach ($database['from'] as $from) $froms[] = $this->escape_column($from); $sql .= "\nFROM "; $sql .= implode(', ', $froms); } if (count($database['join']) > 0) { foreach($database['join'] AS $join) { $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; } } if (count($database['where']) > 0) { $sql .= "\nWHERE "; } $sql .= implode("\n", $database['where']); if (count($database['groupby']) > 0) { $sql .= "\nGROUP BY "; $sql .= implode(', ', $database['groupby']); } if (count($database['having']) > 0) { $sql .= "\nHAVING "; $sql .= implode("\n", $database['having']); } if (count($database['orderby']) > 0) { $sql .= "\nORDER BY "; $sql .= implode(', ', $database['orderby']); } if (is_numeric($database['limit'])) { $sql .= "\n"; $sql .= $this->limit($database['limit']); } return $sql; } public function escape_str($str) { if (!$this->db_config['escape']) return $str; is_resource($this->link) or $this->connect(); //mssql_real_escape_string($str, $this->link); <-- this function doesn't exist $characters = array('/\x00/', '/\x1a/', '/\n/', '/\r/', '/\\\/', '/\'/'); $replace = array('\\\x00', '\\x1a', '\\n', '\\r', '\\\\', "''"); return preg_replace($characters, $replace, $str); } public function list_tables() { $sql = 'SHOW TABLES FROM ['.$this->db_config['connection']['database'].']'; $result = $this->query($sql)->result(FALSE, MSSQL_ASSOC); $retval = array(); foreach ($result as $row) { $retval[] = current($row); } return $retval; } public function show_error() { return mssql_get_last_message($this->link); } public function list_fields($table) { $result = array(); foreach ($this->field_data($table) as $row) { // Make an associative array $result[$row->Field] = $this->sql_type($row->Type); } return $result; } public function field_data($table) { $query = $this->query("SELECT COLUMN_NAME AS Field, DATA_TYPE as Type FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->escape_table($table)."'", $this->link); return $query->result_array(TRUE); } } /** * MSSQL Result */ class Mssql_Result extends Database_Result { // Fetch function and return type protected $fetch_type = 'mssql_fetch_object'; protected $return_type = MSSQL_ASSOC; /** * Sets up the result variables. * * @param resource query result * @param resource database link * @param boolean return objects or arrays * @param string SQL query that was run */ public function __construct($result, $link, $object = TRUE, $sql) { $this->result = $result; // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query if (is_resource($result)) { $this->current_row = 0; $this->total_rows = mssql_num_rows($this->result); $this->fetch_type = ($object === TRUE) ? 'mssql_fetch_object' : 'mssql_fetch_array'; } elseif (is_bool($result)) { if ($result == FALSE) { // SQL error throw new Kohana_Database_Exception('database.error', mssql_get_last_message($link).' - '.$sql); } else { // Its an DELETE, INSERT, REPLACE, or UPDATE querys $last_id = mssql_query('SELECT @@IDENTITY AS last_id', $link); $result = mssql_fetch_assoc($last_id); $this->insert_id = $result['last_id']; $this->total_rows = mssql_rows_affected($link); } } // Set result type $this->result($object); // Store the SQL $this->sql = $sql; } /** * Destruct, the cleanup crew! */ public function __destruct() { if (is_resource($this->result)) { mssql_free_result($this->result); } } public function result($object = TRUE, $type = MSSQL_ASSOC) { $this->fetch_type = ((bool) $object) ? 'mssql_fetch_object' : 'mssql_fetch_array'; // This check has to be outside the previous statement, because we do not // know the state of fetch_type when $object = NULL // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. if ($this->fetch_type == 'mssql_fetch_object') { $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $this->return_type = $type; } return $this; } public function as_array($object = NULL, $type = MSSQL_ASSOC) { return $this->result_array($object, $type); } public function result_array($object = NULL, $type = MSSQL_ASSOC) { $rows = array(); if (is_string($object)) { $fetch = $object; } elseif (is_bool($object)) { if ($object === TRUE) { $fetch = 'mssql_fetch_object'; // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $fetch = 'mssql_fetch_array'; } } else { // Use the default config values $fetch = $this->fetch_type; if ($fetch == 'mssql_fetch_object') { $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } } if (mssql_num_rows($this->result)) { // Reset the pointer location to make sure things work properly mssql_data_seek($this->result, 0); while ($row = $fetch($this->result, $type)) { $rows[] = $row; } } return isset($rows) ? $rows : array(); } public function list_fields() { $field_names = array(); while ($field = mssql_fetch_field($this->result)) { $field_names[] = $field->name; } return $field_names; } public function seek($offset) { if ( ! $this->offsetExists($offset)) return FALSE; return mssql_data_seek($this->result, $offset); } } // End mssql_Result Class ./kohana/system/libraries/drivers/Database/Mysql.php0000644000175000017500000002635111202052503022277 0ustar tokkeetokkeedb_config = $config; Kohana::log('debug', 'MySQL Database Driver Initialized'); } /** * Closes the database connection. */ public function __destruct() { is_resource($this->link) and mysql_close($this->link); } public function connect() { // Check if link already exists if (is_resource($this->link)) return $this->link; // Import the connect variables extract($this->db_config['connection']); // Persistent connections enabled? $connect = ($this->db_config['persistent'] == TRUE) ? 'mysql_pconnect' : 'mysql_connect'; // Build the connection info $host = isset($host) ? $host : $socket; $port = isset($port) ? ':'.$port : ''; // Make the connection and select the database if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mysql_select_db($database, $this->link)) { if ($charset = $this->db_config['character_set']) { $this->set_charset($charset); } // Clear password after successful connect $this->db_config['connection']['pass'] = NULL; return $this->link; } return FALSE; } public function query($sql) { // Only cache if it's turned on, and only cache if it's not a write statement if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) { $hash = $this->query_hash($sql); if ( ! isset($this->query_cache[$hash])) { // Set the cached object $this->query_cache[$hash] = new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); } else { // Rewind cached result $this->query_cache[$hash]->rewind(); } // Return the cached query return $this->query_cache[$hash]; } return new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); } public function set_charset($charset) { $this->query('SET NAMES '.$this->escape_str($charset)); } public function escape_table($table) { if (!$this->db_config['escape']) return $table; if (stripos($table, ' AS ') !== FALSE) { // Force 'AS' to uppercase $table = str_ireplace(' AS ', ' AS ', $table); // Runs escape_table on both sides of an AS statement $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); // Re-create the AS statement return implode(' AS ', $table); } return '`'.str_replace('.', '`.`', $table).'`'; } public function escape_column($column) { if (!$this->db_config['escape']) return $column; if ($column == '*') return $column; // This matches any functions we support to SELECT. if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) { if ( count($matches) == 3) { return $matches[1].'('.$this->escape_column($matches[2]).')'; } else if ( count($matches) == 5) { return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); } } // This matches any modifiers we support to SELECT. if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) { if (stripos($column, ' AS ') !== FALSE) { // Force 'AS' to uppercase $column = str_ireplace(' AS ', ' AS ', $column); // Runs escape_column on both sides of an AS statement $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); // Re-create the AS statement return implode(' AS ', $column); } return preg_replace('/[^.*]+/', '`$0`', $column); } $parts = explode(' ', $column); $column = ''; for ($i = 0, $c = count($parts); $i < $c; $i++) { // The column is always last if ($i == ($c - 1)) { $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); } else // otherwise, it's a modifier { $column .= $parts[$i].' '; } } return $column; } public function regex($field, $match, $type, $num_regexs) { $prefix = ($num_regexs == 0) ? '' : $type; return $prefix.' '.$this->escape_column($field).' REGEXP \''.$this->escape_str($match).'\''; } public function notregex($field, $match, $type, $num_regexs) { $prefix = $num_regexs == 0 ? '' : $type; return $prefix.' '.$this->escape_column($field).' NOT REGEXP \''.$this->escape_str($match) . '\''; } public function merge($table, $keys, $values) { // Escape the column names foreach ($keys as $key => $value) { $keys[$key] = $this->escape_column($value); } return 'REPLACE INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; } public function limit($limit, $offset = 0) { return 'LIMIT '.$offset.', '.$limit; } public function compile_select($database) { $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; if (count($database['from']) > 0) { // Escape the tables $froms = array(); foreach ($database['from'] as $from) { $froms[] = $this->escape_column($from); } $sql .= "\nFROM ("; $sql .= implode(', ', $froms).")"; } if (count($database['join']) > 0) { foreach($database['join'] AS $join) { $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; } } if (count($database['where']) > 0) { $sql .= "\nWHERE "; } $sql .= implode("\n", $database['where']); if (count($database['groupby']) > 0) { $sql .= "\nGROUP BY "; $sql .= implode(', ', $database['groupby']); } if (count($database['having']) > 0) { $sql .= "\nHAVING "; $sql .= implode("\n", $database['having']); } if (count($database['orderby']) > 0) { $sql .= "\nORDER BY "; $sql .= implode(', ', $database['orderby']); } if (is_numeric($database['limit'])) { $sql .= "\n"; $sql .= $this->limit($database['limit'], $database['offset']); } return $sql; } public function escape_str($str) { if (!$this->db_config['escape']) return $str; is_resource($this->link) or $this->connect(); return mysql_real_escape_string($str, $this->link); } public function list_tables() { $tables = array(); if ($query = $this->query('SHOW TABLES FROM '.$this->escape_table($this->db_config['connection']['database']))) { foreach ($query->result(FALSE) as $row) { $tables[] = current($row); } } return $tables; } public function show_error() { return mysql_error($this->link); } public function list_fields($table) { $result = NULL; foreach ($this->field_data($table) as $row) { // Make an associative array $result[$row->Field] = $this->sql_type($row->Type); if ($row->Key === 'PRI' AND $row->Extra === 'auto_increment') { // For sequenced (AUTO_INCREMENT) tables $result[$row->Field]['sequenced'] = TRUE; } if ($row->Null === 'YES') { // Set NULL status $result[$row->Field]['null'] = TRUE; } } if (!isset($result)) throw new Kohana_Database_Exception('database.table_not_found', $table); return $result; } public function field_data($table) { $result = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table)); return $result->result_array(TRUE); } } // End Database_Mysql_Driver Class /** * MySQL Result */ class Mysql_Result extends Database_Result { // Fetch function and return type protected $fetch_type = 'mysql_fetch_object'; protected $return_type = MYSQL_ASSOC; /** * Sets up the result variables. * * @param resource query result * @param resource database link * @param boolean return objects or arrays * @param string SQL query that was run */ public function __construct($result, $link, $object = TRUE, $sql) { $this->result = $result; // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query if (is_resource($result)) { $this->current_row = 0; $this->total_rows = mysql_num_rows($this->result); $this->fetch_type = ($object === TRUE) ? 'mysql_fetch_object' : 'mysql_fetch_array'; } elseif (is_bool($result)) { if ($result == FALSE) { // SQL error throw new Kohana_Database_Exception('database.error', mysql_error($link).' - '.$sql); } else { // Its an DELETE, INSERT, REPLACE, or UPDATE query $this->insert_id = mysql_insert_id($link); $this->total_rows = mysql_affected_rows($link); } } // Set result type $this->result($object); // Store the SQL $this->sql = $sql; } /** * Destruct, the cleanup crew! */ public function __destruct() { if (is_resource($this->result)) { mysql_free_result($this->result); } } public function result($object = TRUE, $type = MYSQL_ASSOC) { $this->fetch_type = ((bool) $object) ? 'mysql_fetch_object' : 'mysql_fetch_array'; // This check has to be outside the previous statement, because we do not // know the state of fetch_type when $object = NULL // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. if ($this->fetch_type == 'mysql_fetch_object' AND $object === TRUE) { $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $this->return_type = $type; } return $this; } public function as_array($object = NULL, $type = MYSQL_ASSOC) { return $this->result_array($object, $type); } public function result_array($object = NULL, $type = MYSQL_ASSOC) { $rows = array(); if (is_string($object)) { $fetch = $object; } elseif (is_bool($object)) { if ($object === TRUE) { $fetch = 'mysql_fetch_object'; $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $fetch = 'mysql_fetch_array'; } } else { // Use the default config values $fetch = $this->fetch_type; if ($fetch == 'mysql_fetch_object') { $type = (is_string($this->return_type) AND Kohana::auto_load($this->return_type)) ? $this->return_type : 'stdClass'; } } if (mysql_num_rows($this->result)) { // Reset the pointer location to make sure things work properly mysql_data_seek($this->result, 0); while ($row = $fetch($this->result, $type)) { $rows[] = $row; } } return isset($rows) ? $rows : array(); } public function list_fields() { $field_names = array(); while ($field = mysql_fetch_field($this->result)) { $field_names[] = $field->name; } return $field_names; } public function seek($offset) { if ($this->offsetExists($offset) AND mysql_data_seek($this->result, $offset)) { // Set the current row to the offset $this->current_row = $offset; return TRUE; } else { return FALSE; } } } // End Mysql_Result Class ./kohana/system/libraries/drivers/Database/Pdosqlite.php0000644000175000017500000002476011172772557023170 0ustar tokkeetokkee */ class Database_Pdosqlite_Driver extends Database_Driver { // Database connection link protected $link; protected $db_config; /* * Constructor: __construct * Sets up the config for the class. * * Parameters: * config - database configuration * */ public function __construct($config) { $this->db_config = $config; Kohana::log('debug', 'PDO:Sqlite Database Driver Initialized'); } public function connect() { // Import the connect variables extract($this->db_config['connection']); try { $this->link = new PDO('sqlite:'.$socket.$database, $user, $pass, array(PDO::ATTR_PERSISTENT => $this->db_config['persistent'])); $this->link->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); //$this->link->query('PRAGMA count_changes=1;'); if ($charset = $this->db_config['character_set']) { $this->set_charset($charset); } } catch (PDOException $e) { throw new Kohana_Database_Exception('database.error', $e->getMessage()); } // Clear password after successful connect $this->db_config['connection']['pass'] = NULL; return $this->link; } public function query($sql) { try { $sth = $this->link->prepare($sql); } catch (PDOException $e) { throw new Kohana_Database_Exception('database.error', $e->getMessage()); } return new Pdosqlite_Result($sth, $this->link, $this->db_config['object'], $sql); } public function set_charset($charset) { $this->link->query('PRAGMA encoding = '.$this->escape_str($charset)); } public function escape_table($table) { if ( ! $this->db_config['escape']) return $table; return '`'.str_replace('.', '`.`', $table).'`'; } public function escape_column($column) { if ( ! $this->db_config['escape']) return $column; if ($column == '*') return $column; // This matches any functions we support to SELECT. if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) { if ( count($matches) == 3) { return $matches[1].'('.$this->escape_column($matches[2]).')'; } else if ( count($matches) == 5) { return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); } } // This matches any modifiers we support to SELECT. if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) { if (stripos($column, ' AS ') !== FALSE) { // Force 'AS' to uppercase $column = str_ireplace(' AS ', ' AS ', $column); // Runs escape_column on both sides of an AS statement $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); // Re-create the AS statement return implode(' AS ', $column); } return preg_replace('/[^.*]+/', '`$0`', $column); } $parts = explode(' ', $column); $column = ''; for ($i = 0, $c = count($parts); $i < $c; $i++) { // The column is always last if ($i == ($c - 1)) { $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); } else // otherwise, it's a modifier { $column .= $parts[$i].' '; } } return $column; } public function limit($limit, $offset = 0) { return 'LIMIT '.$offset.', '.$limit; } public function compile_select($database) { $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; if (count($database['from']) > 0) { $sql .= "\nFROM "; $sql .= implode(', ', $database['from']); } if (count($database['join']) > 0) { foreach($database['join'] AS $join) { $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; } } if (count($database['where']) > 0) { $sql .= "\nWHERE "; } $sql .= implode("\n", $database['where']); if (count($database['groupby']) > 0) { $sql .= "\nGROUP BY "; $sql .= implode(', ', $database['groupby']); } if (count($database['having']) > 0) { $sql .= "\nHAVING "; $sql .= implode("\n", $database['having']); } if (count($database['orderby']) > 0) { $sql .= "\nORDER BY "; $sql .= implode(', ', $database['orderby']); } if (is_numeric($database['limit'])) { $sql .= "\n"; $sql .= $this->limit($database['limit'], $database['offset']); } return $sql; } public function escape_str($str) { if ( ! $this->db_config['escape']) return $str; if (function_exists('sqlite_escape_string')) { $res = sqlite_escape_string($str); } else { $res = str_replace("'", "''", $str); } return $res; } public function list_tables() { $sql = "SELECT `name` FROM `sqlite_master` WHERE `type`='table' ORDER BY `name`;"; try { $result = $this->query($sql)->result(FALSE, PDO::FETCH_ASSOC); $tables = array(); foreach ($result as $row) { $tables[] = current($row); } } catch (PDOException $e) { throw new Kohana_Database_Exception('database.error', $e->getMessage()); } return $tables; } public function show_error() { $err = $this->link->errorInfo(); return isset($err[2]) ? $err[2] : 'Unknown error!'; } public function list_fields($table, $query = FALSE) { static $tables; if (is_object($query)) { if (empty($tables[$table])) { $tables[$table] = array(); foreach ($query->result() as $row) { $tables[$table][] = $row->name; } } return $tables[$table]; } else { $result = $this->link->query( 'PRAGMA table_info('.$this->escape_table($table).')' ); foreach ($result as $row) { $tables[$table][$row['name']] = $this->sql_type($row['type']); } return $tables[$table]; } } public function field_data($table) { Kohana::log('error', 'This method is under developing'); } /** * Version number query string * * @access public * @return string */ function version() { return $this->link->getAttribute(constant("PDO::ATTR_SERVER_VERSION")); } } // End Database_PdoSqlite_Driver Class /* * PDO-sqlite Result */ class Pdosqlite_Result extends Database_Result { // Data fetching types protected $fetch_type = PDO::FETCH_OBJ; protected $return_type = PDO::FETCH_ASSOC; /** * Sets up the result variables. * * @param resource query result * @param resource database link * @param boolean return objects or arrays * @param string SQL query that was run */ public function __construct($result, $link, $object = TRUE, $sql) { if (is_object($result) OR $result = $link->prepare($sql)) { // run the query. Return true if success, false otherwise if( ! $result->execute()) { // Throw Kohana Exception with error message. See PDOStatement errorInfo() method $arr_infos = $result->errorInfo(); throw new Kohana_Database_Exception('database.error', $arr_infos[2]); } if (preg_match('/^SELECT|PRAGMA|EXPLAIN/i', $sql)) { $this->result = $result; $this->current_row = 0; $this->total_rows = $this->sqlite_row_count(); $this->fetch_type = ($object === TRUE) ? PDO::FETCH_OBJ : PDO::FETCH_ASSOC; } elseif (preg_match('/^DELETE|INSERT|UPDATE/i', $sql)) { $this->insert_id = $link->lastInsertId(); $this->total_rows = $result->rowCount(); } } else { // SQL error throw new Kohana_Database_Exception('database.error', $link->errorInfo().' - '.$sql); } // Set result type $this->result($object); // Store the SQL $this->sql = $sql; } private function sqlite_row_count() { $count = 0; while ($this->result->fetch()) { $count++; } // The query must be re-fetched now. $this->result->execute(); return $count; } /* * Destructor: __destruct * Magic __destruct function, frees the result. */ public function __destruct() { if (is_object($this->result)) { $this->result->closeCursor(); $this->result = NULL; } } public function result($object = TRUE, $type = PDO::FETCH_BOTH) { $this->fetch_type = (bool) $object ? PDO::FETCH_OBJ : PDO::FETCH_BOTH; if ($this->fetch_type == PDO::FETCH_OBJ) { $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $this->return_type = $type; } return $this; } public function as_array($object = NULL, $type = PDO::FETCH_ASSOC) { return $this->result_array($object, $type); } public function result_array($object = NULL, $type = PDO::FETCH_ASSOC) { $rows = array(); if (is_string($object)) { $fetch = $object; } elseif (is_bool($object)) { if ($object === TRUE) { $fetch = PDO::FETCH_OBJ; // NOTE - The class set by $type must be defined before fetching the result, // autoloading is disabled to save a lot of stupid overhead. $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } else { $fetch = PDO::FETCH_OBJ; } } else { // Use the default config values $fetch = $this->fetch_type; if ($fetch == PDO::FETCH_OBJ) { $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; } } try { while ($row = $this->result->fetch($fetch)) { $rows[] = $row; } } catch(PDOException $e) { throw new Kohana_Database_Exception('database.error', $e->getMessage()); return FALSE; } return $rows; } public function list_fields() { $field_names = array(); for ($i = 0, $max = $this->result->columnCount(); $i < $max; $i++) { $info = $this->result->getColumnMeta($i); $field_names[] = $info['name']; } return $field_names; } public function seek($offset) { // To request a scrollable cursor for your PDOStatement object, you must // set the PDO::ATTR_CURSOR attribute to PDO::CURSOR_SCROLL when you // prepare the statement. Kohana::log('error', get_class($this).' does not support scrollable cursors, '.__FUNCTION__.' call ignored'); return FALSE; } public function offsetGet($offset) { try { return $this->result->fetch($this->fetch_type, PDO::FETCH_ORI_ABS, $offset); } catch(PDOException $e) { throw new Kohana_Database_Exception('database.error', $e->getMessage()); } } public function rewind() { // Same problem that seek() has, see above. return $this->seek(0); } } // End PdoSqlite_Result Class./kohana/system/libraries/drivers/Cache.php0000644000175000017500000000145511154023261020474 0ustar tokkeetokkee 'apc', * 'requests' => 10000 * ); * Lifetime does not need to be set as it is * overridden by the session expiration setting. * * $Id: Cache.php 3769 2008-12-15 00:48:56Z zombor $ * * @package Core * @author Kohana Team * @copyright (c) 2007-2008 Kohana Team * @license http://kohanaphp.com/license.html */ class Session_Cache_Driver implements Session_Driver { protected $cache; protected $encrypt; public function __construct() { // Load Encrypt library if (Kohana::config('session.encryption')) { $this->encrypt = new Encrypt; } Kohana::log('debug', 'Session Cache Driver Initialized'); } public function open($path, $name) { $config = Kohana::config('session.storage'); if (empty($config)) { // Load the default group $config = Kohana::config('cache.default'); } elseif (is_string($config)) { $name = $config; // Test the config group name if (($config = Kohana::config('cache.'.$config)) === NULL) throw new Kohana_Exception('cache.undefined_group', $name); } $config['lifetime'] = (Kohana::config('session.expiration') == 0) ? 86400 : Kohana::config('session.expiration'); $this->cache = new Cache($config); return is_object($this->cache); } public function close() { return TRUE; } public function read($id) { $id = 'session_'.$id; if ($data = $this->cache->get($id)) { return Kohana::config('session.encryption') ? $this->encrypt->decode($data) : $data; } // Return value must be string, NOT a boolean return ''; } public function write($id, $data) { $id = 'session_'.$id; $data = Kohana::config('session.encryption') ? $this->encrypt->encode($data) : $data; return $this->cache->set($id, $data); } public function destroy($id) { $id = 'session_'.$id; return $this->cache->delete($id); } public function regenerate() { session_regenerate_id(TRUE); // Return new session id return session_id(); } public function gc($maxlifetime) { // Just return, caches are automatically cleaned up return TRUE; } } // End Session Cache Driver ./kohana/system/libraries/drivers/Session/Cookie.php0000644000175000017500000000313411121324570022322 0ustar tokkeetokkeecookie_name = Kohana::config('session.name').'_data'; if (Kohana::config('session.encryption')) { $this->encrypt = Encrypt::instance(); } Kohana::log('debug', 'Session Cookie Driver Initialized'); } public function open($path, $name) { return TRUE; } public function close() { return TRUE; } public function read($id) { $data = (string) cookie::get($this->cookie_name); if ($data == '') return $data; return empty($this->encrypt) ? base64_decode($data) : $this->encrypt->decode($data); } public function write($id, $data) { $data = empty($this->encrypt) ? base64_encode($data) : $this->encrypt->encode($data); if (strlen($data) > 4048) { Kohana::log('error', 'Session ('.$id.') data exceeds the 4KB limit, ignoring write.'); return FALSE; } return cookie::set($this->cookie_name, $data, Kohana::config('session.expiration')); } public function destroy($id) { return cookie::delete($this->cookie_name); } public function regenerate() { session_regenerate_id(TRUE); // Return new id return session_id(); } public function gc($maxlifetime) { return TRUE; } } // End Session Cookie Driver Class./kohana/system/libraries/drivers/Session/Database.php0000644000175000017500000000651111121324570022617 0ustar tokkeetokkeeencrypt = Encrypt::instance(); } if (is_array($config['storage'])) { if ( ! empty($config['storage']['group'])) { // Set the group name $this->db = $config['storage']['group']; } if ( ! empty($config['storage']['table'])) { // Set the table name $this->table = $config['storage']['table']; } } // Load database $this->db = Database::instance($this->db); Kohana::log('debug', 'Session Database Driver Initialized'); } public function open($path, $name) { return TRUE; } public function close() { return TRUE; } public function read($id) { // Load the session $query = $this->db->from($this->table)->where('session_id', $id)->limit(1)->get()->result(TRUE); if ($query->count() === 0) { // No current session $this->session_id = NULL; return ''; } // Set the current session id $this->session_id = $id; // Load the data $data = $query->current()->data; return ($this->encrypt === NULL) ? base64_decode($data) : $this->encrypt->decode($data); } public function write($id, $data) { $data = array ( 'session_id' => $id, 'last_activity' => time(), 'data' => ($this->encrypt === NULL) ? base64_encode($data) : $this->encrypt->encode($data) ); if ($this->session_id === NULL) { // Insert a new session $query = $this->db->insert($this->table, $data); } elseif ($id === $this->session_id) { // Do not update the session_id unset($data['session_id']); // Update the existing session $query = $this->db->update($this->table, $data, array('session_id' => $id)); } else { // Update the session and id $query = $this->db->update($this->table, $data, array('session_id' => $this->session_id)); // Set the new session id $this->session_id = $id; } return (bool) $query->count(); } public function destroy($id) { // Delete the requested session $this->db->delete($this->table, array('session_id' => $id)); // Session id is no longer valid $this->session_id = NULL; return TRUE; } public function regenerate() { // Generate a new session id session_regenerate_id(); // Return new session id return session_id(); } public function gc($maxlifetime) { // Delete all expired sessions $query = $this->db->delete($this->table, array('last_activity <' => time() - $maxlifetime)); Kohana::log('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.'); return TRUE; } } // End Session Database Driver ./kohana/system/libraries/drivers/Database.php0000644000175000017500000003105011201063060021161 0ustar tokkeetokkeeescape_table($table).' WHERE '.implode(' ', $where); } /** * Builds an UPDATE query. * * @param string table name * @param array key => value pairs * @param array where clause * @return string */ public function update($table, $values, $where) { foreach ($values as $key => $val) { $valstr[] = $this->escape_column($key).' = '.$val; } return 'UPDATE '.$this->escape_table($table).' SET '.implode(', ', $valstr).' WHERE '.implode(' ',$where); } /** * Set the charset using 'SET NAMES '. * * @param string character set to use */ public function set_charset($charset) { throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); } /** * Wrap the tablename in backticks, has support for: table.field syntax. * * @param string table name * @return string */ abstract public function escape_table($table); /** * Escape a column/field name, has support for special commands. * * @param string column name * @return string */ abstract public function escape_column($column); /** * Builds a WHERE portion of a query. * * @param mixed key * @param string value * @param string type * @param int number of where clauses * @param boolean escape the value * @return string */ public function where($key, $value, $type, $num_wheres, $quote) { $prefix = ($num_wheres == 0) ? '' : $type; if ($quote === -1) { $value = ''; } else { if ($value === NULL) { if ( ! $this->has_operator($key)) { $key .= ' IS'; } $value = ' NULL'; } elseif (is_bool($value)) { if ( ! $this->has_operator($key)) { $key .= ' ='; } $value = ($value == TRUE) ? ' 1' : ' 0'; } else { if ( ! $this->has_operator($key) AND ! empty($key)) { $key = $this->escape_column($key).' ='; } else { preg_match('/^(.+?)([<>!=]+|\bIS(?:\s+NULL))\s*$/i', $key, $matches); if (isset($matches[1]) AND isset($matches[2])) { $key = $this->escape_column(trim($matches[1])).' '.trim($matches[2]); } } $value = ' '.(($quote == TRUE) ? $this->escape($value) : $value); } } return $prefix.$key.$value; } /** * Builds a LIKE portion of a query. * * @param mixed field name * @param string value to match with field * @param boolean add wildcards before and after the match * @param string clause type (AND or OR) * @param int number of likes * @return string */ public function like($field, $match, $auto, $type, $num_likes) { $prefix = ($num_likes == 0) ? '' : $type; $match = $this->escape_str($match); if ($auto === TRUE) { // Add the start and end quotes $match = '%'.str_replace('%', '\\%', $match).'%'; } return $prefix.' '.$this->escape_column($field).' LIKE \''.$match . '\''; } /** * Builds a NOT LIKE portion of a query. * * @param mixed field name * @param string value to match with field * @param string clause type (AND or OR) * @param int number of likes * @return string */ public function notlike($field, $match, $auto, $type, $num_likes) { $prefix = ($num_likes == 0) ? '' : $type; $match = $this->escape_str($match); if ($auto === TRUE) { // Add the start and end quotes $match = '%'.$match.'%'; } return $prefix.' '.$this->escape_column($field).' NOT LIKE \''.$match.'\''; } /** * Builds a REGEX portion of a query. * * @param string field name * @param string value to match with field * @param string clause type (AND or OR) * @param integer number of regexes * @return string */ public function regex($field, $match, $type, $num_regexs) { throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); } /** * Builds a NOT REGEX portion of a query. * * @param string field name * @param string value to match with field * @param string clause type (AND or OR) * @param integer number of regexes * @return string */ public function notregex($field, $match, $type, $num_regexs) { throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); } /** * Builds an INSERT query. * * @param string table name * @param array keys * @param array values * @return string */ public function insert($table, $keys, $values) { // Escape the column names foreach ($keys as $key => $value) { $keys[$key] = $this->escape_column($value); } return 'INSERT INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; } /** * Builds a MERGE portion of a query. * * @param string table name * @param array keys * @param array values * @return string */ public function merge($table, $keys, $values) { throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); } /** * Builds a LIMIT portion of a query. * * @param integer limit * @param integer offset * @return string */ abstract public function limit($limit, $offset = 0); /** * Creates a prepared statement. * * @param string SQL query * @return Database_Stmt */ public function stmt_prepare($sql = '') { throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); } /** * Compiles the SELECT statement. * Generates a query string based on which functions were used. * Should not be called directly, the get() function calls it. * * @param array select query values * @return string */ abstract public function compile_select($database); /** * Determines if the string has an arithmetic operator in it. * * @param string string to check * @return boolean */ public function has_operator($str) { return (bool) preg_match('/[<>!=]|\sIS(?:\s+NOT\s+)?\b|BETWEEN/i', trim($str)); } /** * Escapes any input value. * * @param mixed value to escape * @return string */ public function escape($value) { if ( ! $this->db_config['escape']) return $value; switch (gettype($value)) { case 'string': $value = '\''.$this->escape_str($value).'\''; break; case 'boolean': $value = (int) $value; break; case 'double': // Convert to non-locale aware float to prevent possible commas $value = sprintf('%F', $value); break; default: $value = ($value === NULL) ? 'NULL' : $value; break; } return (string) $value; } /** * Escapes a string for a query. * * @param mixed value to escape * @return string */ abstract public function escape_str($str); /** * Lists all tables in the database. * * @return array */ abstract public function list_tables(); /** * Lists all fields in a table. * * @param string table name * @return array */ abstract function list_fields($table); /** * Returns the last database error. * * @return string */ abstract public function show_error(); /** * Returns field data about a table. * * @param string table name * @return array */ abstract public function field_data($table); /** * Fetches SQL type information about a field, in a generic format. * * @param string field datatype * @return array */ protected function sql_type($str) { static $sql_types; if ($sql_types === NULL) { // Load SQL data types $sql_types = Kohana::config('sql_types'); } $str = strtolower(trim($str)); if (($open = strpos($str, '(')) !== FALSE) { // Find closing bracket $close = strpos($str, ')', $open) - 1; // Find the type without the size $type = substr($str, 0, $open); } else { // No length $type = $str; } empty($sql_types[$type]) and exit ( 'Unknown field type: '.$type.'. '. 'Please report this: http://trac.kohanaphp.com/newticket' ); // Fetch the field definition $field = $sql_types[$type]; switch ($field['type']) { case 'string': case 'float': if (isset($close)) { // Add the length to the field info $field['length'] = substr($str, $open + 1, $close - $open); } break; case 'int': // Add unsigned value $field['unsigned'] = (strpos($str, 'unsigned') !== FALSE); break; } return $field; } /** * Clears the internal query cache. * * @param string SQL query */ public function clear_cache($sql = NULL) { if (empty($sql)) { $this->query_cache = array(); } else { unset($this->query_cache[$this->query_hash($sql)]); } Kohana::log('debug', 'Database cache cleared: '.get_class($this)); } /** * Creates a hash for an SQL query string. Replaces newlines with spaces, * trims, and hashes. * * @param string SQL query * @return string */ protected function query_hash($sql) { return sha1(str_replace("\n", ' ', trim($sql))); } } // End Database Driver Interface /** * Database_Result * */ abstract class Database_Result implements ArrayAccess, Iterator, Countable { // Result resource, insert id, and SQL protected $result; protected $insert_id; protected $sql; // Current and total rows protected $current_row = 0; protected $total_rows = 0; // Fetch function and return type protected $fetch_type; protected $return_type; /** * Returns the SQL used to fetch the result. * * @return string */ public function sql() { return $this->sql; } /** * Returns the insert id from the result. * * @return mixed */ public function insert_id() { return $this->insert_id; } /** * Prepares the query result. * * @param boolean return rows as objects * @param mixed type * @return Database_Result */ abstract function result($object = TRUE, $type = FALSE); /** * Builds an array of query results. * * @param boolean return rows as objects * @param mixed type * @return array */ abstract function result_array($object = NULL, $type = FALSE); /** * Gets the fields of an already run query. * * @return array */ abstract public function list_fields(); /** * Seek to an offset in the results. * * @return boolean */ abstract public function seek($offset); /** * Countable: count */ public function count() { return $this->total_rows; } /** * ArrayAccess: offsetExists */ public function offsetExists($offset) { if ($this->total_rows > 0) { $min = 0; $max = $this->total_rows - 1; return ! ($offset < $min OR $offset > $max); } return FALSE; } /** * ArrayAccess: offsetGet */ public function offsetGet($offset) { if ( ! $this->seek($offset)) return FALSE; // Return the row by calling the defined fetching callback return call_user_func($this->fetch_type, $this->result, $this->return_type); } /** * ArrayAccess: offsetSet * * @throws Kohana_Database_Exception */ final public function offsetSet($offset, $value) { throw new Kohana_Database_Exception('database.result_read_only'); } /** * ArrayAccess: offsetUnset * * @throws Kohana_Database_Exception */ final public function offsetUnset($offset) { throw new Kohana_Database_Exception('database.result_read_only'); } /** * Iterator: current */ public function current() { return $this->offsetGet($this->current_row); } /** * Iterator: key */ public function key() { return $this->current_row; } /** * Iterator: next */ public function next() { ++$this->current_row; return $this; } /** * Iterator: prev */ public function prev() { --$this->current_row; return $this; } /** * Iterator: rewind */ public function rewind() { $this->current_row = 0; return $this; } /** * Iterator: valid */ public function valid() { return $this->offsetExists($this->current_row); } } // End Database Result Interface ./kohana/system/libraries/drivers/Cache/0000755000175000017500000000000011263472441017767 5ustar tokkeetokkee./kohana/system/libraries/drivers/Cache/Eaccelerator.php0000644000175000017500000000250511154023261023062 0ustar tokkeetokkeebackend = new Memcache; $this->flags = Kohana::config('cache_memcache.compression') ? MEMCACHE_COMPRESSED : FALSE; $servers = Kohana::config('cache_memcache.servers'); foreach ($servers as $server) { // Make sure all required keys are set $server += array('host' => '127.0.0.1', 'port' => 11211, 'persistent' => FALSE); // Add the server to the pool $this->backend->addServer($server['host'], $server['port'], (bool) $server['persistent']) or Kohana::log('error', 'Cache: Connection failed: '.$server['host']); } // Load tags self::$tags = $this->backend->get(self::TAGS_KEY); if ( ! is_array(self::$tags)) { // Create a new tags array self::$tags = array(); // Tags have been created self::$tags_changed = TRUE; } } public function __destruct() { if (self::$tags_changed === TRUE) { // Save the tags $this->backend->set(self::TAGS_KEY, self::$tags, $this->flags, 0); // Tags are now unchanged self::$tags_changed = FALSE; } } public function find($tag) { if (isset(self::$tags[$tag]) AND $results = $this->backend->get(self::$tags[$tag])) { // Return all the found caches return $results; } else { // No matching tags return array(); } } public function get($id) { return (($return = $this->backend->get($id)) === FALSE) ? NULL : $return; } public function set($id, $data, array $tags = NULL, $lifetime) { if ( ! empty($tags)) { // Tags will be changed self::$tags_changed = TRUE; foreach ($tags as $tag) { // Add the id to each tag self::$tags[$tag][$id] = $id; } } if ($lifetime !== 0) { // Memcache driver expects unix timestamp $lifetime += time(); } // Set a new value return $this->backend->set($id, $data, $this->flags, $lifetime); } public function delete($id, $tag = FALSE) { // Tags will be changed self::$tags_changed = TRUE; if ($id === TRUE) { if ($status = $this->backend->flush()) { // Remove all tags, all items have been deleted self::$tags = array(); // We must sleep after flushing, or overwriting will not work! // @see http://php.net/manual/en/function.memcache-flush.php#81420 sleep(1); } return $status; } elseif ($tag === TRUE) { if (isset(self::$tags[$id])) { foreach (self::$tags[$id] as $_id) { // Delete each id in the tag $this->backend->delete($_id); } // Delete the tag unset(self::$tags[$id]); } return TRUE; } else { foreach (self::$tags as $tag => $_ids) { if (isset(self::$tags[$tag][$id])) { // Remove the id from the tags unset(self::$tags[$tag][$id]); } } return $this->backend->delete($id); } } public function delete_expired() { // Tags will be changed self::$tags_changed = TRUE; foreach (self::$tags as $tag => $_ids) { foreach ($_ids as $id) { if ( ! $this->backend->get($id)) { // This id has disappeared, delete it from the tags unset(self::$tags[$tag][$id]); } } if (empty(self::$tags[$tag])) { // The tag no longer has any valid ids unset(self::$tags[$tag]); } } // Memcache handles garbage collection internally return TRUE; } } // End Cache Memcache Driver ./kohana/system/libraries/drivers/Cache/Apc.php0000644000175000017500000000241411154023261021173 0ustar tokkeetokkeeauth(); $result = TRUE; for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) { if (xcache_clear_cache(XC_TYPE_VAR, $i) !== NULL) { $result = FALSE; break; } } // Undo the login $this->auth(TRUE); return $result; } return TRUE; } public function delete_expired() { return TRUE; } private function auth($reverse = FALSE) { static $backup = array(); $keys = array('PHP_AUTH_USER', 'PHP_AUTH_PW'); foreach ($keys as $key) { if ($reverse) { if (isset($backup[$key])) { $_SERVER[$key] = $backup[$key]; unset($backup[$key]); } else { unset($_SERVER[$key]); } } else { $value = getenv($key); if ( ! empty($value)) { $backup[$key] = $value; } $_SERVER[$key] = Kohana::config('cache_xcache.'.$key); } } } } // End Cache Xcache Driver ./kohana/system/libraries/drivers/Cache/Sqlite.php0000644000175000017500000001363311154023261021736 0ustar tokkeetokkeedb = new SQLiteDatabase($filename, '0666', $error); // Throw an exception if there's an error if ( ! empty($error)) throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); $query = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'caches'"; $tables = $this->db->query($query, SQLITE_BOTH, $error); // Throw an exception if there's an error if ( ! empty($error)) throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); if ($tables->numRows() == 0) { Kohana::log('error', 'Cache: Initializing new SQLite cache database'); // Issue a CREATE TABLE command $this->db->unbufferedQuery(Kohana::config('cache_sqlite.schema')); } } /** * Checks if a cache id is already set. * * @param string cache id * @return boolean */ public function exists($id) { // Find the id that matches $query = "SELECT id FROM caches WHERE id = '$id'"; return ($this->db->query($query)->numRows() > 0); } /** * Sets a cache item to the given data, tags, and lifetime. * * @param string cache id to set * @param string data in the cache * @param array cache tags * @param integer lifetime * @return bool */ public function set($id, $data, array $tags = NULL, $lifetime) { // Serialize and escape the data $data = sqlite_escape_string(serialize($data)); if ( ! empty($tags)) { // Escape the tags, adding brackets so the tag can be explicitly matched $tags = sqlite_escape_string('<'.implode('>,<', $tags).'>'); } // Cache Sqlite driver expects unix timestamp if ($lifetime !== 0) { $lifetime += time(); } $query = $this->exists($id) ? "UPDATE caches SET tags = '$tags', expiration = '$lifetime', cache = '$data' WHERE id = '$id'" : "INSERT INTO caches VALUES('$id', '$tags', '$lifetime', '$data')"; // Run the query $this->db->unbufferedQuery($query, SQLITE_BOTH, $error); if ( ! empty($error)) { self::log_error($error); return FALSE; } else { return TRUE; } } /** * Finds an array of ids for a given tag. * * @param string tag name * @return array of ids that match the tag */ public function find($tag) { $query = "SELECT id,cache FROM caches WHERE tags LIKE '%<{$tag}>%'"; $query = $this->db->query($query, SQLITE_BOTH, $error); // An array will always be returned $result = array(); if ( ! empty($error)) { self::log_error($error); } elseif ($query->numRows() > 0) { // Disable notices for unserializing $ER = error_reporting(~E_NOTICE); while ($row = $query->fetchObject()) { // Add each cache to the array $result[$row->id] = unserialize($row->cache); } // Turn notices back on error_reporting($ER); } return $result; } /** * Fetches a cache item. This will delete the item if it is expired or if * the hash does not match the stored hash. * * @param string cache id * @return mixed|NULL */ public function get($id) { $query = "SELECT id, expiration, cache FROM caches WHERE id = '$id' LIMIT 0, 1"; $query = $this->db->query($query, SQLITE_BOTH, $error); if ( ! empty($error)) { self::log_error($error); } elseif ($cache = $query->fetchObject()) { // Make sure the expiration is valid and that the hash matches if ($cache->expiration != 0 AND $cache->expiration <= time()) { // Cache is not valid, delete it now $this->delete($cache->id); } else { // Disable notices for unserializing $ER = error_reporting(~E_NOTICE); // Return the valid cache data $data = $cache->cache; // Turn notices back on error_reporting($ER); } } // No valid cache found return NULL; } /** * Deletes a cache item by id or tag * * @param string cache id or tag, or TRUE for "all items" * @param bool delete a tag * @return bool */ public function delete($id, $tag = FALSE) { if ($id === TRUE) { // Delete all caches $where = '1'; } elseif ($tag === TRUE) { // Delete by tag $where = "tags LIKE '%<{$id}>%'"; } else { // Delete by id $where = "id = '$id'"; } $this->db->unbufferedQuery('DELETE FROM caches WHERE '.$where, SQLITE_BOTH, $error); if ( ! empty($error)) { self::log_error($error); return FALSE; } else { return TRUE; } } /** * Deletes all cache files that are older than the current time. */ public function delete_expired() { // Delete all expired caches $query = 'DELETE FROM caches WHERE expiration != 0 AND expiration <= '.time(); $this->db->unbufferedQuery($query); return TRUE; } } // End Cache SQLite Driver./kohana/system/libraries/drivers/Cache/File.php0000644000175000017500000001306611154023261021354 0ustar tokkeetokkeedirectory = $directory; } /** * Finds an array of files matching the given id or tag. * * @param string cache id or tag * @param bool search for tags * @return array of filenames matching the id or tag */ public function exists($id, $tag = FALSE) { if ($id === TRUE) { // Find all the files return glob($this->directory.'*~*~*'); } elseif ($tag === TRUE) { // Find all the files that have the tag name $paths = glob($this->directory.'*~*'.$id.'*~*'); // Find all tags matching the given tag $files = array(); foreach ($paths as $path) { // Split the files $tags = explode('~', basename($path)); // Find valid tags if (count($tags) !== 3 OR empty($tags[1])) continue; // Split the tags by plus signs, used to separate tags $tags = explode('+', $tags[1]); if (in_array($tag, $tags)) { // Add the file to the array, it has the requested tag $files[] = $path; } } return $files; } else { // Find the file matching the given id return glob($this->directory.$id.'~*'); } } /** * Sets a cache item to the given data, tags, and lifetime. * * @param string cache id to set * @param string data in the cache * @param array cache tags * @param integer lifetime * @return bool */ public function set($id, $data, array $tags = NULL, $lifetime) { // Remove old cache files $this->delete($id); // Cache File driver expects unix timestamp if ($lifetime !== 0) { $lifetime += time(); } if ( ! empty($tags)) { // Convert the tags into a string list $tags = implode('+', $tags); } // Write out a serialized cache return (bool) file_put_contents($this->directory.$id.'~'.$tags.'~'.$lifetime, serialize($data)); } /** * Finds an array of ids for a given tag. * * @param string tag name * @return array of ids that match the tag */ public function find($tag) { // An array will always be returned $result = array(); if ($paths = $this->exists($tag, TRUE)) { // Length of directory name $offset = strlen($this->directory); // Find all the files with the given tag foreach ($paths as $path) { // Get the id from the filename list($id, $junk) = explode('~', basename($path), 2); if (($data = $this->get($id)) !== FALSE) { // Add the result to the array $result[$id] = $data; } } } return $result; } /** * Fetches a cache item. This will delete the item if it is expired or if * the hash does not match the stored hash. * * @param string cache id * @return mixed|NULL */ public function get($id) { if ($file = $this->exists($id)) { // Use the first file $file = current($file); // Validate that the cache has not expired if ($this->expired($file)) { // Remove this cache, it has expired $this->delete($id); } else { // Turn off errors while reading the file $ER = error_reporting(0); if (($data = file_get_contents($file)) !== FALSE) { // Unserialize the data $data = unserialize($data); } else { // Delete the data unset($data); } // Turn errors back on error_reporting($ER); } } // Return NULL if there is no data return isset($data) ? $data : NULL; } /** * Deletes a cache item by id or tag * * @param string cache id or tag, or TRUE for "all items" * @param boolean use tags * @return boolean */ public function delete($id, $tag = FALSE) { $files = $this->exists($id, $tag); if (empty($files)) return FALSE; // Disable all error reporting while deleting $ER = error_reporting(0); foreach ($files as $file) { // Remove the cache file if ( ! unlink($file)) Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); } // Turn on error reporting again error_reporting($ER); return TRUE; } /** * Deletes all cache files that are older than the current time. * * @return void */ public function delete_expired() { if ($files = $this->exists(TRUE)) { // Disable all error reporting while deleting $ER = error_reporting(0); foreach ($files as $file) { if ($this->expired($file)) { // The cache file has already expired, delete it if ( ! unlink($file)) Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); } } // Turn on error reporting again error_reporting($ER); } } /** * Check if a cache file has expired by filename. * * @param string filename * @return bool */ protected function expired($file) { // Get the expiration time $expires = (int) substr($file, strrpos($file, '~') + 1); // Expirations of 0 are "never expire" return ($expires !== 0 AND $expires <= time()); } } // End Cache File Driver./kohana/system/libraries/drivers/Image/0000755000175000017500000000000011263472441020006 5ustar tokkeetokkee./kohana/system/libraries/drivers/Image/GraphicsMagick.php0000644000175000017500000001325111121754764023401 0ustar tokkeetokkeeext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; // Check to make sure the provided path is correct if ( ! is_file(realpath($config['directory']).'/gm'.$this->ext)) throw new Kohana_Exception('image.graphicsmagick.not_found', 'gm'.$this->ext); // Set the installation directory $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; } /** * Creates a temporary image and executes the given actions. By creating a * temporary copy of the image before manipulating it, this process is atomic. */ public function process($image, $actions, $dir, $file, $render = FALSE) { // We only need the filename $image = $image['file']; // Unique temporary filename $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); // Copy the image to the temporary file copy($image, $this->tmp_image); // Quality change is done last $quality = (int) arr::remove('quality', $actions); // Use 95 for the default quality empty($quality) and $quality = 95; // All calls to these will need to be escaped, so do it now $this->cmd_image = escapeshellarg($this->tmp_image); $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); if ($status = $this->execute($actions)) { // Use convert to change the image into its final version. This is // done to allow the file type to change correctly, and to handle // the quality conversion in the most effective way possible. if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) { $this->errors[] = $error; } else { // Output the image directly to the browser if ($render !== FALSE) { $contents = file_get_contents($this->tmp_image); switch (substr($file, strrpos($file, '.') + 1)) { case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'gif': header('Content-Type: image/gif'); break; case 'png': header('Content-Type: image/png'); break; } echo $contents; } } } // Remove the temporary image unlink($this->tmp_image); $this->tmp_image = ''; return $status; } public function crop($prop) { // Sanitize and normalize the properties into geometry $this->sanitize_geometry($prop); // Set the IM geometry based on the properties $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function flip($dir) { // Convert the direction into a GM command $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function resize($prop) { switch ($prop['master']) { case Image::WIDTH: // Wx $dim = escapeshellarg($prop['width'].'x'); break; case Image::HEIGHT: // xH $dim = escapeshellarg('x'.$prop['height']); break; case Image::AUTO: // WxH $dim = escapeshellarg($prop['width'].'x'.$prop['height']); break; case Image::NONE: // WxH! $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); break; } // Use "convert" to change the width and height if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function rotate($amt) { if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function sharpen($amount) { // Set the sigma, radius, and amount. The amount formula allows a nice // spread between 1 and 100 without pixelizing the image badly. $sigma = 0.5; $radius = $sigma * 2; $amount = round(($amount / 80) * 3.14, 2); // Convert the amount to an GM command $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } protected function properties() { return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); } } // End Image GraphicsMagick Driver./kohana/system/libraries/drivers/Image/GD.php0000644000175000017500000002505211121324570021005 0ustar tokkeetokkeeimage = $image; // Create the GD image resource $this->tmp_image = $create($image['file']); // Get the quality setting from the actions $quality = arr::remove('quality', $actions); if ($status = $this->execute($actions)) { // Prevent the alpha from being lost imagealphablending($this->tmp_image, TRUE); imagesavealpha($this->tmp_image, TRUE); switch ($save) { case 'imagejpeg': // Default the quality to 95 ($quality === NULL) and $quality = 95; break; case 'imagegif': // Remove the quality setting, GIF doesn't use it unset($quality); break; case 'imagepng': // Always use a compression level of 9 for PNGs. This does not // affect quality, it only increases the level of compression! $quality = 9; break; } if ($render === FALSE) { // Set the status to the save return value, saving with the quality requested $status = isset($quality) ? $save($this->tmp_image, $dir.$file, $quality) : $save($this->tmp_image, $dir.$file); } else { // Output the image directly to the browser switch ($save) { case 'imagejpeg': header('Content-Type: image/jpeg'); break; case 'imagegif': header('Content-Type: image/gif'); break; case 'imagepng': header('Content-Type: image/png'); break; } $status = isset($quality) ? $save($this->tmp_image, NULL, $quality) : $save($this->tmp_image); } // Destroy the temporary image imagedestroy($this->tmp_image); } return $status; } public function flip($direction) { // Get the current width and height $width = imagesx($this->tmp_image); $height = imagesy($this->tmp_image); // Create the flipped image $flipped = $this->imagecreatetransparent($width, $height); if ($direction === Image::HORIZONTAL) { for ($x = 0; $x < $width; $x++) { $status = imagecopy($flipped, $this->tmp_image, $x, 0, $width - $x - 1, 0, 1, $height); } } elseif ($direction === Image::VERTICAL) { for ($y = 0; $y < $height; $y++) { $status = imagecopy($flipped, $this->tmp_image, 0, $y, 0, $height - $y - 1, $width, 1); } } else { // Do nothing return TRUE; } if ($status === TRUE) { // Swap the new image for the old one imagedestroy($this->tmp_image); $this->tmp_image = $flipped; } return $status; } public function crop($properties) { // Sanitize the cropping settings $this->sanitize_geometry($properties); // Get the current width and height $width = imagesx($this->tmp_image); $height = imagesy($this->tmp_image); // Create the temporary image to copy to $img = $this->imagecreatetransparent($properties['width'], $properties['height']); // Execute the crop if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, $properties['left'], $properties['top'], $width, $height, $width, $height)) { // Swap the new image for the old one imagedestroy($this->tmp_image); $this->tmp_image = $img; } return $status; } public function resize($properties) { // Get the current width and height $width = imagesx($this->tmp_image); $height = imagesy($this->tmp_image); if (substr($properties['width'], -1) === '%') { // Recalculate the percentage to a pixel size $properties['width'] = round($width * (substr($properties['width'], 0, -1) / 100)); } if (substr($properties['height'], -1) === '%') { // Recalculate the percentage to a pixel size $properties['height'] = round($height * (substr($properties['height'], 0, -1) / 100)); } // Recalculate the width and height, if they are missing empty($properties['width']) and $properties['width'] = round($width * $properties['height'] / $height); empty($properties['height']) and $properties['height'] = round($height * $properties['width'] / $width); if ($properties['master'] === Image::AUTO) { // Change an automatic master dim to the correct type $properties['master'] = (($width / $properties['width']) > ($height / $properties['height'])) ? Image::WIDTH : Image::HEIGHT; } if (empty($properties['height']) OR $properties['master'] === Image::WIDTH) { // Recalculate the height based on the width $properties['height'] = round($height * $properties['width'] / $width); } if (empty($properties['width']) OR $properties['master'] === Image::HEIGHT) { // Recalculate the width based on the height $properties['width'] = round($width * $properties['height'] / $height); } // Test if we can do a resize without resampling to speed up the final resize if ($properties['width'] > $width / 2 AND $properties['height'] > $height / 2) { // Presize width and height $pre_width = $width; $pre_height = $height; // The maximum reduction is 10% greater than the final size $max_reduction_width = round($properties['width'] * 1.1); $max_reduction_height = round($properties['height'] * 1.1); // Reduce the size using an O(2n) algorithm, until it reaches the maximum reduction while ($pre_width / 2 > $max_reduction_width AND $pre_height / 2 > $max_reduction_height) { $pre_width /= 2; $pre_height /= 2; } // Create the temporary image to copy to $img = $this->imagecreatetransparent($pre_width, $pre_height); if ($status = imagecopyresized($img, $this->tmp_image, 0, 0, 0, 0, $pre_width, $pre_height, $width, $height)) { // Swap the new image for the old one imagedestroy($this->tmp_image); $this->tmp_image = $img; } // Set the width and height to the presize $width = $pre_width; $height = $pre_height; } // Create the temporary image to copy to $img = $this->imagecreatetransparent($properties['width'], $properties['height']); // Execute the resize if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, 0, 0, $properties['width'], $properties['height'], $width, $height)) { // Swap the new image for the old one imagedestroy($this->tmp_image); $this->tmp_image = $img; } return $status; } public function rotate($amount) { // Use current image to rotate $img = $this->tmp_image; // White, with an alpha of 0 $transparent = imagecolorallocatealpha($img, 255, 255, 255, 127); // Rotate, setting the transparent color $img = imagerotate($img, 360 - $amount, $transparent, -1); // Fill the background with the transparent "color" imagecolortransparent($img, $transparent); // Merge the images if ($status = imagecopymerge($this->tmp_image, $img, 0, 0, 0, 0, imagesx($this->tmp_image), imagesy($this->tmp_image), 100)) { // Prevent the alpha from being lost imagealphablending($img, TRUE); imagesavealpha($img, TRUE); // Swap the new image for the old one imagedestroy($this->tmp_image); $this->tmp_image = $img; } return $status; } public function sharpen($amount) { // Make sure that the sharpening function is available if ( ! function_exists('imageconvolution')) throw new Kohana_Exception('image.unsupported_method', __FUNCTION__); // Amount should be in the range of 18-10 $amount = round(abs(-18 + ($amount * 0.08)), 2); // Gaussian blur matrix $matrix = array ( array(-1, -1, -1), array(-1, $amount, -1), array(-1, -1, -1), ); // Perform the sharpen return imageconvolution($this->tmp_image, $matrix, $amount - 8, 0); } protected function properties() { return array(imagesx($this->tmp_image), imagesy($this->tmp_image)); } /** * Returns an image with a transparent background. Used for rotating to * prevent unfilled backgrounds. * * @param integer image width * @param integer image height * @return resource */ protected function imagecreatetransparent($width, $height) { if (self::$blank_png === NULL) { // Decode the blank PNG if it has not been done already self::$blank_png = imagecreatefromstring(base64_decode ( 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29'. 'mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBN'. 'CgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQ'. 'AANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoH'. 'AgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB'. '3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII=' )); // Set the blank PNG width and height self::$blank_png_width = imagesx(self::$blank_png); self::$blank_png_height = imagesy(self::$blank_png); } $img = imagecreatetruecolor($width, $height); // Resize the blank image imagecopyresized($img, self::$blank_png, 0, 0, 0, 0, $width, $height, self::$blank_png_width, self::$blank_png_height); // Prevent the alpha from being lost imagealphablending($img, FALSE); imagesavealpha($img, TRUE); return $img; } } // End Image GD Driver./kohana/system/libraries/drivers/Image/ImageMagick.php0000644000175000017500000001327711121324570022657 0ustar tokkeetokkeeext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; // Check to make sure the provided path is correct if ( ! is_file(realpath($config['directory']).'/convert'.$this->ext)) throw new Kohana_Exception('image.imagemagick.not_found', 'convert'.$this->ext); // Set the installation directory $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; } /** * Creates a temporary image and executes the given actions. By creating a * temporary copy of the image before manipulating it, this process is atomic. */ public function process($image, $actions, $dir, $file, $render = FALSE) { // We only need the filename $image = $image['file']; // Unique temporary filename $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); // Copy the image to the temporary file copy($image, $this->tmp_image); // Quality change is done last $quality = (int) arr::remove('quality', $actions); // Use 95 for the default quality empty($quality) and $quality = 95; // All calls to these will need to be escaped, so do it now $this->cmd_image = escapeshellarg($this->tmp_image); $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); if ($status = $this->execute($actions)) { // Use convert to change the image into its final version. This is // done to allow the file type to change correctly, and to handle // the quality conversion in the most effective way possible. if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) { $this->errors[] = $error; } else { // Output the image directly to the browser if ($render !== FALSE) { $contents = file_get_contents($this->tmp_image); switch (substr($file, strrpos($file, '.') + 1)) { case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'gif': header('Content-Type: image/gif'); break; case 'png': header('Content-Type: image/png'); break; } echo $contents; } } } // Remove the temporary image unlink($this->tmp_image); $this->tmp_image = ''; return $status; } public function crop($prop) { // Sanitize and normalize the properties into geometry $this->sanitize_geometry($prop); // Set the IM geometry based on the properties $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function flip($dir) { // Convert the direction into a IM command $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function resize($prop) { switch ($prop['master']) { case Image::WIDTH: // Wx $dim = escapeshellarg($prop['width'].'x'); break; case Image::HEIGHT: // xH $dim = escapeshellarg('x'.$prop['height']); break; case Image::AUTO: // WxH $dim = escapeshellarg($prop['width'].'x'.$prop['height']); break; case Image::NONE: // WxH! $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); break; } // Use "convert" to change the width and height if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function rotate($amt) { if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } public function sharpen($amount) { // Set the sigma, radius, and amount. The amount formula allows a nice // spread between 1 and 100 without pixelizing the image badly. $sigma = 0.5; $radius = $sigma * 2; $amount = round(($amount / 80) * 3.14, 2); // Convert the amount to an IM command $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; } return TRUE; } protected function properties() { return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); } } // End Image ImageMagick Driver./kohana/system/libraries/drivers/Session.php0000644000175000017500000000233511121324570021113 0ustar tokkeetokkee $args) { if ( ! $this->$func($args)) return FALSE; } return TRUE; } /** * Sanitize and normalize a geometry array based on the temporary image * width and height. Valid properties are: width, height, top, left. * * @param array geometry properties * @return void */ protected function sanitize_geometry( & $geometry) { list($width, $height) = $this->properties(); // Turn off error reporting $reporting = error_reporting(0); // Width and height cannot exceed current image size $geometry['width'] = min($geometry['width'], $width); $geometry['height'] = min($geometry['height'], $height); // Set standard coordinates if given, otherwise use pixel values if ($geometry['top'] === 'center') { $geometry['top'] = floor(($height / 2) - ($geometry['height'] / 2)); } elseif ($geometry['top'] === 'top') { $geometry['top'] = 0; } elseif ($geometry['top'] === 'bottom') { $geometry['top'] = $height - $geometry['height']; } // Set standard coordinates if given, otherwise use pixel values if ($geometry['left'] === 'center') { $geometry['left'] = floor(($width / 2) - ($geometry['width'] / 2)); } elseif ($geometry['left'] === 'left') { $geometry['left'] = 0; } elseif ($geometry['left'] === 'right') { $geometry['left'] = $width - $geometry['height']; } // Restore error reporting error_reporting($reporting); } /** * Return the current width and height of the temporary image. This is mainly * needed for sanitizing the geometry. * * @return array width, height */ abstract protected function properties(); /** * Process an image with a set of actions. * * @param string image filename * @param array actions to execute * @param string destination directory path * @param string destination filename * @return boolean */ abstract public function process($image, $actions, $dir, $file); /** * Flip an image. Valid directions are horizontal and vertical. * * @param integer direction to flip * @return boolean */ abstract function flip($direction); /** * Crop an image. Valid properties are: width, height, top, left. * * @param array new properties * @return boolean */ abstract function crop($properties); /** * Resize an image. Valid properties are: width, height, and master. * * @param array new properties * @return boolean */ abstract public function resize($properties); /** * Rotate an image. Valid amounts are -180 to 180. * * @param integer amount to rotate * @return boolean */ abstract public function rotate($amount); /** * Sharpen and image. Valid amounts are 1 to 100. * * @param integer amount to sharpen * @return boolean */ abstract public function sharpen($amount); } // End Image Driver./kohana/system/libraries/drivers/Captcha.php0000644000175000017500000001352511121324570021036 0ustar tokkeetokkeeresponse = $this->generate_challenge(); // Store the correct Captcha response in a session Event::add('system.post_controller', array($this, 'update_response_session')); } /** * Generate a new Captcha challenge. * * @return string the challenge answer */ abstract public function generate_challenge(); /** * Output the Captcha challenge. * * @param boolean html output * @return mixed the rendered Captcha (e.g. an image, riddle, etc.) */ abstract public function render($html); /** * Stores the response for the current Captcha challenge in a session so it is available * on the next page load for Captcha::valid(). This method is called after controller * execution (in the system.post_controller event) in order not to overwrite itself too soon. * * @return void */ public function update_response_session() { Session::instance()->set('captcha_response', sha1(strtoupper($this->response))); } /** * Validates a Captcha response from a user. * * @param string captcha response * @return boolean */ public function valid($response) { return (sha1(strtoupper($response)) === Session::instance()->get('captcha_response')); } /** * Returns the image type. * * @param string filename * @return string|FALSE image type ("png", "gif" or "jpeg") */ public function image_type($filename) { switch (strtolower(substr(strrchr($filename, '.'), 1))) { case 'png': return 'png'; case 'gif': return 'gif'; case 'jpg': case 'jpeg': // Return "jpeg" and not "jpg" because of the GD2 function names return 'jpeg'; default: return FALSE; } } /** * Creates an image resource with the dimensions specified in config. * If a background image is supplied, the image dimensions are used. * * @throws Kohana_Exception if no GD2 support * @param string path to the background image file * @return void */ public function image_create($background = NULL) { // Check for GD2 support if ( ! function_exists('imagegd2')) throw new Kohana_Exception('captcha.requires_GD2'); // Create a new image (black) $this->image = imagecreatetruecolor(Captcha::$config['width'], Captcha::$config['height']); // Use a background image if ( ! empty($background)) { // Create the image using the right function for the filetype $function = 'imagecreatefrom'.$this->image_type($background); $this->background_image = $function($background); // Resize the image if needed if (imagesx($this->background_image) !== Captcha::$config['width'] OR imagesy($this->background_image) !== Captcha::$config['height']) { imagecopyresampled ( $this->image, $this->background_image, 0, 0, 0, 0, Captcha::$config['width'], Captcha::$config['height'], imagesx($this->background_image), imagesy($this->background_image) ); } // Free up resources imagedestroy($this->background_image); } } /** * Fills the background with a gradient. * * @param resource gd image color identifier for start color * @param resource gd image color identifier for end color * @param string direction: 'horizontal' or 'vertical', 'random' by default * @return void */ public function image_gradient($color1, $color2, $direction = NULL) { $directions = array('horizontal', 'vertical'); // Pick a random direction if needed if ( ! in_array($direction, $directions)) { $direction = $directions[array_rand($directions)]; // Switch colors if (mt_rand(0, 1) === 1) { $temp = $color1; $color1 = $color2; $color2 = $temp; } } // Extract RGB values $color1 = imagecolorsforindex($this->image, $color1); $color2 = imagecolorsforindex($this->image, $color2); // Preparations for the gradient loop $steps = ($direction === 'horizontal') ? Captcha::$config['width'] : Captcha::$config['height']; $r1 = ($color1['red'] - $color2['red']) / $steps; $g1 = ($color1['green'] - $color2['green']) / $steps; $b1 = ($color1['blue'] - $color2['blue']) / $steps; if ($direction === 'horizontal') { $x1 =& $i; $y1 = 0; $x2 =& $i; $y2 = Captcha::$config['height']; } else { $x1 = 0; $y1 =& $i; $x2 = Captcha::$config['width']; $y2 =& $i; } // Execute the gradient loop for ($i = 0; $i <= $steps; $i++) { $r2 = $color1['red'] - floor($i * $r1); $g2 = $color1['green'] - floor($i * $g1); $b2 = $color1['blue'] - floor($i * $b1); $color = imagecolorallocate($this->image, $r2, $g2, $b2); imageline($this->image, $x1, $y1, $x2, $y2, $color); } } /** * Returns the img html element or outputs the image to the browser. * * @param boolean html output * @return mixed html string or void */ public function image_render($html) { // Output html element if ($html) return 'Captcha'; // Send the correct HTTP header header('Content-Type: image/'.$this->image_type); // Pick the correct output function $function = 'image'.$this->image_type; $function($this->image); // Free up resources imagedestroy($this->image); } } // End Captcha Driver./kohana/system/libraries/Calendar.php0000644000175000017500000002067411121324570017531 0ustar tokkeetokkee 3) ? '%A' : '%a'; // Days of the week $days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); if (Calendar::$start_monday === TRUE) { // Push Sunday to the end of the days array_push($days, array_shift($days)); } if (strpos(Kohana::config('locale.language.0'), 'en') !== 0) { // This is a bit awkward, but it works properly and is reliable foreach ($days as $i => $day) { // Convert the English names to i18n names $days[$i] = strftime($format, strtotime($day)); } } if (is_int($length) OR ctype_digit($length)) { foreach ($days as $i => $day) { // Shorten the days to the expected length $days[$i] = utf8::substr($day, 0, $length); } } return $days; } /** * Create a new Calendar instance. A month and year can be specified. * By default, the current month and year are used. * * @param integer month number * @param integer year number * @return object */ public static function factory($month = NULL, $year = NULL) { return new Calendar($month, $year); } /** * Create a new Calendar instance. A month and year can be specified. * By default, the current month and year are used. * * @param integer month number * @param integer year number * @return void */ public function __construct($month = NULL, $year = NULL) { empty($month) and $month = date('n'); // Current month empty($year) and $year = date('Y'); // Current year // Set the month and year $this->month = (int) $month; $this->year = (int) $year; if (Calendar::$start_monday === TRUE) { // Week starts on Monday $this->week_start = 1; } } /** * Allows fetching the current month and year. * * @param string key to get * @return mixed */ public function __get($key) { if ($key === 'month' OR $key === 'year') { return $this->$key; } } /** * Calendar_Event factory method. * * @param string unique name for the event * @return object Calendar_Event */ public function event($name = NULL) { return new Calendar_Event($this); } /** * Calendar_Event factory method. * * @chainable * @param string standard event type * @return object */ public function standard($name) { switch ($name) { case 'today': // Add an event for the current day $this->attach($this->event()->condition('timestamp', strtotime('today'))->add_class('today')); break; case 'prev-next': // Add an event for padding days $this->attach($this->event()->condition('current', FALSE)->add_class('prev-next')); break; case 'holidays': // Base event $event = $this->event()->condition('current', TRUE)->add_class('holiday'); // Attach New Years $holiday = clone $event; $this->attach($holiday->condition('month', 1)->condition('day', 1)); // Attach Valentine's Day $holiday = clone $event; $this->attach($holiday->condition('month', 2)->condition('day', 14)); // Attach St. Patrick's Day $holiday = clone $event; $this->attach($holiday->condition('month', 3)->condition('day', 17)); // Attach Easter $holiday = clone $event; $this->attach($holiday->condition('easter', TRUE)); // Attach Memorial Day $holiday = clone $event; $this->attach($holiday->condition('month', 5)->condition('day_of_week', 1)->condition('last_occurrence', TRUE)); // Attach Independance Day $holiday = clone $event; $this->attach($holiday->condition('month', 7)->condition('day', 4)); // Attach Labor Day $holiday = clone $event; $this->attach($holiday->condition('month', 9)->condition('day_of_week', 1)->condition('occurrence', 1)); // Attach Halloween $holiday = clone $event; $this->attach($holiday->condition('month', 10)->condition('day', 31)); // Attach Thanksgiving $holiday = clone $event; $this->attach($holiday->condition('month', 11)->condition('day_of_week', 4)->condition('occurrence', 4)); // Attach Christmas $holiday = clone $event; $this->attach($holiday->condition('month', 12)->condition('day', 25)); break; case 'weekends': // Weekend events $this->attach($this->event()->condition('weekend', TRUE)->add_class('weekend')); break; } return $this; } /** * Returns an array for use with a view. The array contains an array for * each week. Each week contains 7 arrays, with a day number and status: * TRUE if the day is in the month, FALSE if it is padding. * * @return array */ public function weeks() { // First day of the month as a timestamp $first = mktime(1, 0, 0, $this->month, 1, $this->year); // Total number of days in this month $total = (int) date('t', $first); // Last day of the month as a timestamp $last = mktime(1, 0, 0, $this->month, $total, $this->year); // Make the month and week empty arrays $month = $week = array(); // Number of days added. When this reaches 7, start a new week $days = 0; $week_number = 1; if (($w = (int) date('w', $first) - $this->week_start) < 0) { $w = 6; } if ($w > 0) { // Number of days in the previous month $n = (int) date('t', mktime(1, 0, 0, $this->month - 1, 1, $this->year)); // i = number of day, t = number of days to pad for ($i = $n - $w + 1, $t = $w; $t > 0; $t--, $i++) { // Notify the listeners $this->notify(array($this->month - 1, $i, $this->year, $week_number, FALSE)); // Add previous month padding days $week[] = array($i, FALSE, $this->observed_data); $days++; } } // i = number of day for ($i = 1; $i <= $total; $i++) { if ($days % 7 === 0) { // Start a new week $month[] = $week; $week = array(); $week_number++; } // Notify the listeners $this->notify(array($this->month, $i, $this->year, $week_number, TRUE)); // Add days to this month $week[] = array($i, TRUE, $this->observed_data); $days++; } if (($w = (int) date('w', $last) - $this->week_start) < 0) { $w = 6; } if ($w >= 0) { // i = number of day, t = number of days to pad for ($i = 1, $t = 6 - $w; $t > 0; $t--, $i++) { // Notify the listeners $this->notify(array($this->month + 1, $i, $this->year, $week_number, FALSE)); // Add next month padding days $week[] = array($i, FALSE, $this->observed_data); } } if ( ! empty($week)) { // Append the remaining days $month[] = $week; } return $month; } /** * Adds new data from an observer. All event data contains and array of CSS * classes and an array of output messages. * * @param array observer data. * @return void */ public function add_data(array $data) { // Add new classes $this->observed_data['classes'] += $data['classes']; if ( ! empty($data['output'])) { // Only add output if it's not empty $this->observed_data['output'][] = $data['output']; } } /** * Resets the observed data and sends a notify to all attached events. * * @param array UNIX timestamp * @return void */ public function notify($data) { // Reset observed data $this->observed_data = array ( 'classes' => array(), 'output' => array(), ); // Send a notify parent::notify($data); } /** * Convert the calendar to HTML using the kohana_calendar view. * * @return string */ public function render() { $view = new View('kohana_calendar', array ( 'month' => $this->month, 'year' => $this->year, 'weeks' => $this->weeks(), )); return $view->render(); } /** * Magically convert this object to a string, the rendered calendar. * * @return string */ public function __toString() { return $this->render(); } } // End Calendar./kohana/system/libraries/Cache.php0000644000175000017500000001136711177443540017034 0ustar tokkeetokkeeconfig = $config; // Set driver name $driver = 'Cache_'.ucfirst($this->config['driver']).'_Driver'; // Load the driver if ( ! Kohana::auto_load($driver)) throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this)); // Initialize the driver $this->driver = new $driver($this->config['params']); // Validate the driver if ( ! ($this->driver instanceof Cache_Driver)) throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Cache_Driver'); Kohana::log('debug', 'Cache Library initialized'); if (Cache::$loaded !== TRUE) { $this->config['requests'] = (int) $this->config['requests']; if ($this->config['requests'] > 0 AND mt_rand(1, $this->config['requests']) === 1) { // Do garbage collection $this->driver->delete_expired(); Kohana::log('debug', 'Cache: Expired caches deleted.'); } // Cache has been loaded once Cache::$loaded = TRUE; } } /** * Fetches a cache by id. NULL is returned when a cache item is not found. * * @param string cache id * @return mixed cached data or NULL */ public function get($id) { // Sanitize the ID $id = $this->sanitize_id($id); return $this->driver->get($id); } /** * Fetches all of the caches for a given tag. An empty array will be * returned when no matching caches are found. * * @param string cache tag * @return array all cache items matching the tag */ public function find($tag) { return $this->driver->find($tag); } /** * Set a cache item by id. Tags may also be added and a custom lifetime * can be set. Non-string data is automatically serialized. * * @param string unique cache id * @param mixed data to cache * @param array|string tags for this item * @param integer number of seconds until the cache expires * @return boolean */ function set($id, $data, $tags = NULL, $lifetime = NULL) { if (is_resource($data)) throw new Kohana_Exception('cache.resources'); // Sanitize the ID $id = $this->sanitize_id($id); if ($lifetime === NULL) { // Get the default lifetime $lifetime = $this->config['lifetime']; } return $this->driver->set($id, $data, (array) $tags, $lifetime); } /** * Delete a cache item by id. * * @param string cache id * @return boolean */ public function delete($id) { // Sanitize the ID $id = $this->sanitize_id($id); return $this->driver->delete($id); } /** * Delete all cache items with a given tag. * * @param string cache tag name * @return boolean */ public function delete_tag($tag) { return $this->driver->delete($tag, TRUE); } /** * Delete ALL cache items items. * * @return boolean */ public function delete_all() { return $this->driver->delete(TRUE); } /** * Replaces troublesome characters with underscores. * * @param string cache id * @return string */ protected function sanitize_id($id) { // Change slashes and spaces to underscores return str_replace(array('/', '\\', ' '), '_', $id); } } // End Cache ./kohana/system/libraries/ORM_Iterator.php0000644000175000017500000000760511121324570020325 0ustar tokkeetokkeeclass_name = get_class($model); $this->primary_key = $model->primary_key; $this->primary_val = $model->primary_val; // Database result $this->result = $result->result(TRUE); } /** * Returns an array of the results as ORM objects. * * @return array */ public function as_array() { $array = array(); if ($results = $this->result->result_array()) { // Import class name $class = $this->class_name; foreach ($results as $obj) { $array[] = new $class($obj); } } return $array; } /** * Return an array of all of the primary keys for this object. * * @return array */ public function primary_key_array() { $ids = array(); foreach ($this->result as $row) { $ids[] = $row->{$this->primary_key}; } return $ids; } /** * Create a key/value array from the results. * * @param string key column * @param string value column * @return array */ public function select_list($key = NULL, $val = NULL) { if ($key === NULL) { // Use the default key $key = $this->primary_key; } if ($val === NULL) { // Use the default value $val = $this->primary_val; } $array = array(); foreach ($this->result->result_array() as $row) { $array[$row->$key] = $row->$val; } return $array; } /** * Return a range of offsets. * * @param integer start * @param integer end * @return array */ public function range($start, $end) { // Array of objects $array = array(); if ($this->result->offsetExists($start)) { // Import the class name $class = $this->class_name; // Set the end offset $end = $this->result->offsetExists($end) ? $end : $this->count(); for ($i = $start; $i < $end; $i++) { // Insert each object in the range $array[] = new $class($this->result->offsetGet($i)); } } return $array; } /** * Countable: count */ public function count() { return $this->result->count(); } /** * Iterator: current */ public function current() { if ($row = $this->result->current()) { // Import class name $class = $this->class_name; $row = new $class($row); } return $row; } /** * Iterator: key */ public function key() { return $this->result->key(); } /** * Iterator: next */ public function next() { return $this->result->next(); } /** * Iterator: rewind */ public function rewind() { $this->result->rewind(); } /** * Iterator: valid */ public function valid() { return $this->result->valid(); } /** * ArrayAccess: offsetExists */ public function offsetExists($offset) { return $this->result->offsetExists($offset); } /** * ArrayAccess: offsetGet */ public function offsetGet($offset) { if ($this->result->offsetExists($offset)) { // Import class name $class = $this->class_name; return new $class($this->result->offsetGet($offset)); } } /** * ArrayAccess: offsetSet * * @throws Kohana_Database_Exception */ public function offsetSet($offset, $value) { throw new Kohana_Database_Exception('database.result_read_only'); } /** * ArrayAccess: offsetUnset * * @throws Kohana_Database_Exception */ public function offsetUnset($offset) { throw new Kohana_Database_Exception('database.result_read_only'); } } // End ORM Iterator./kohana/system/libraries/URI.php0000644000175000017500000001431711156512746016470 0ustar tokkeetokkeebuild_array(URI::$segments, $offset, $associative); } /** * Returns an array containing all the re-routed URI segments. * * @param integer rsegment offset * @param boolean return an associative array * @return array */ public function rsegment_array($offset = 0, $associative = FALSE) { return $this->build_array(URI::$rsegments, $offset, $associative); } /** * Returns an array containing all the URI arguments. * * @param integer segment offset * @param boolean return an associative array * @return array */ public function argument_array($offset = 0, $associative = FALSE) { return $this->build_array(URI::$arguments, $offset, $associative); } /** * Creates a simple or associative array from an array and an offset. * Used as a helper for (r)segment_array and argument_array. * * @param array array to rebuild * @param integer offset to start from * @param boolean create an associative array * @return array */ public function build_array($array, $offset = 0, $associative = FALSE) { // Prevent the keys from being improperly indexed array_unshift($array, 0); // Slice the array, preserving the keys $array = array_slice($array, $offset + 1, count($array) - 1, TRUE); if ($associative === FALSE) return $array; $associative = array(); $pairs = array_chunk($array, 2); foreach ($pairs as $pair) { // Add the key/value pair to the associative array $associative[$pair[0]] = isset($pair[1]) ? $pair[1] : ''; } return $associative; } /** * Returns the complete URI as a string. * * @return string */ public function string() { return URI::$current_uri; } /** * Magic method for converting an object to a string. * * @return string */ public function __toString() { return URI::$current_uri; } /** * Returns the total number of URI segments. * * @return integer */ public function total_segments() { return count(URI::$segments); } /** * Returns the total number of re-routed URI segments. * * @return integer */ public function total_rsegments() { return count(URI::$rsegments); } /** * Returns the total number of URI arguments. * * @return integer */ public function total_arguments() { return count(URI::$arguments); } /** * Returns the last URI segment. * * @param mixed default value returned if segment does not exist * @return string */ public function last_segment($default = FALSE) { if (($end = $this->total_segments()) < 1) return $default; return URI::$segments[$end - 1]; } /** * Returns the last re-routed URI segment. * * @param mixed default value returned if segment does not exist * @return string */ public function last_rsegment($default = FALSE) { if (($end = $this->total_segments()) < 1) return $default; return URI::$rsegments[$end - 1]; } /** * Returns the path to the current controller (not including the actual * controller), as a web path. * * @param boolean return a full url, or only the path specifically * @return string */ public function controller_path($full = TRUE) { return ($full) ? url::site(URI::$controller_path) : URI::$controller_path; } /** * Returns the current controller, as a web path. * * @param boolean return a full url, or only the controller specifically * @return string */ public function controller($full = TRUE) { return ($full) ? url::site(URI::$controller_path.URI::$controller) : URI::$controller; } /** * Returns the current method, as a web path. * * @param boolean return a full url, or only the method specifically * @return string */ public function method($full = TRUE) { return ($full) ? url::site(URI::$controller_path.URI::$controller.'/'.URI::$method) : URI::$method; } } // End URI Class ./kohana/system/libraries/Validation.php0000644000175000017500000004164011162502167020113 0ustar tokkeetokkeesubmitted = ! empty($array); parent::__construct($array, ArrayObject::ARRAY_AS_PROPS | ArrayObject::STD_PROP_LIST); } /** * Magic clone method, clears errors and messages. * * @return void */ public function __clone() { $this->errors = array(); $this->messages = array(); } /** * Create a copy of the current validation rules and change the array. * * @chainable * @param array new array to validate * @return Validation */ public function copy(array $array) { $copy = clone $this; $copy->exchangeArray($array); return $copy; } /** * Test if the data has been submitted. * * @return boolean */ public function submitted($value = NULL) { if (is_bool($value)) { $this->submitted = $value; } return $this->submitted; } /** * Returns an array of all the field names that have filters, rules, or callbacks. * * @return array */ public function field_names() { // All the fields that are being validated $fields = array_keys(array_merge ( $this->pre_filters, $this->rules, $this->callbacks, $this->post_filters )); // Remove wildcard fields $fields = array_diff($fields, array('*')); return $fields; } /** * Returns the array values of the current object. * * @return array */ public function as_array() { return $this->getArrayCopy(); } /** * Returns the ArrayObject values, removing all inputs without rules. * To choose specific inputs, list the field name as arguments. * * @param boolean return only fields with filters, rules, and callbacks * @return array */ public function safe_array() { // Load choices $choices = func_get_args(); $choices = empty($choices) ? NULL : array_combine($choices, $choices); // Get field names $fields = $this->field_names(); $safe = array(); foreach ($fields as $field) { if ($choices === NULL OR isset($choices[$field])) { if (isset($this[$field])) { $value = $this[$field]; if (is_object($value)) { // Convert the value back into an array $value = $value->getArrayCopy(); } } else { // Even if the field is not in this array, it must be set $value = NULL; } // Add the field to the array $safe[$field] = $value; } } return $safe; } /** * Add additional rules that will forced, even for empty fields. All arguments * passed will be appended to the list. * * @chainable * @param string rule name * @return object */ public function allow_empty_rules($rules) { // Any number of args are supported $rules = func_get_args(); // Merge the allowed rules $this->empty_rules = array_merge($this->empty_rules, $rules); return $this; } /** * Converts a filter, rule, or callback into a fully-qualified callback array. * * @return mixed */ protected function callback($callback) { if (is_string($callback)) { if (strpos($callback, '::') !== FALSE) { $callback = explode('::', $callback); } elseif (function_exists($callback)) { // No need to check if the callback is a method $callback = $callback; } elseif (method_exists($this, $callback)) { // The callback exists in Validation $callback = array($this, $callback); } elseif (method_exists('valid', $callback)) { // The callback exists in valid:: $callback = array('valid', $callback); } } if ( ! is_callable($callback, FALSE)) { if (is_array($callback)) { if (is_object($callback[0])) { // Object instance syntax $name = get_class($callback[0]).'->'.$callback[1]; } else { // Static class syntax $name = $callback[0].'::'.$callback[1]; } } else { // Function syntax $name = $callback; } throw new Kohana_Exception('validation.not_callable', $name); } return $callback; } /** * Add a pre-filter to one or more inputs. Pre-filters are applied before * rules or callbacks are executed. * * @chainable * @param callback filter * @param string fields to apply filter to, use TRUE for all fields * @return object */ public function pre_filter($filter, $field = TRUE) { if ($field === TRUE OR $field === '*') { // Use wildcard $fields = array('*'); } else { // Add the filter to specific inputs $fields = func_get_args(); $fields = array_slice($fields, 1); } // Convert to a proper callback $filter = $this->callback($filter); foreach ($fields as $field) { // Add the filter to specified field $this->pre_filters[$field][] = $filter; } return $this; } /** * Add a post-filter to one or more inputs. Post-filters are applied after * rules and callbacks have been executed. * * @chainable * @param callback filter * @param string fields to apply filter to, use TRUE for all fields * @return object */ public function post_filter($filter, $field = TRUE) { if ($field === TRUE) { // Use wildcard $fields = array('*'); } else { // Add the filter to specific inputs $fields = func_get_args(); $fields = array_slice($fields, 1); } // Convert to a proper callback $filter = $this->callback($filter); foreach ($fields as $field) { // Add the filter to specified field $this->post_filters[$field][] = $filter; } return $this; } /** * Add rules to a field. Validation rules may only return TRUE or FALSE and * can not manipulate the value of a field. * * @chainable * @param string field name * @param callback rules (one or more arguments) * @return object */ public function add_rules($field, $rules) { // Get the rules $rules = func_get_args(); $rules = array_slice($rules, 1); if ($field === TRUE) { // Use wildcard $field = '*'; } foreach ($rules as $rule) { // Arguments for rule $args = NULL; if (is_string($rule)) { if (preg_match('/^([^\[]++)\[(.+)\]$/', $rule, $matches)) { // Split the rule into the function and args $rule = $matches[1]; $args = preg_split('/(?array_fields[$field] = $field; } // Convert to a proper callback $rule = $this->callback($rule); // Add the rule, with args, to the field $this->rules[$field][] = array($rule, $args); } return $this; } /** * Add callbacks to a field. Callbacks must accept the Validation object * and the input name. Callback returns are not processed. * * @chainable * @param string field name * @param callbacks callbacks (unlimited number) * @return object */ public function add_callbacks($field, $callbacks) { // Get all callbacks as an array $callbacks = func_get_args(); $callbacks = array_slice($callbacks, 1); if ($field === TRUE) { // Use wildcard $field = '*'; } foreach ($callbacks as $callback) { // Convert to a proper callback $callback = $this->callback($callback); // Add the callback to specified field $this->callbacks[$field][] = $callback; } return $this; } /** * Validate by processing pre-filters, rules, callbacks, and post-filters. * All fields that have filters, rules, or callbacks will be initialized if * they are undefined. Validation will only be run if there is data already * in the array. * * @param object Validation object, used only for recursion * @param object name of field for errors * @return bool */ public function validate($object = NULL, $field_name = NULL) { if ($object === NULL) { // Use the current object $object = $this; } // Get all field names $fields = $this->field_names(); // Copy the array from the object, to optimize multiple sets $array = $this->getArrayCopy(); foreach ($fields as $field) { if ($field === '*') { // Ignore wildcard continue; } if ( ! isset($array[$field])) { if (isset($this->array_fields[$field])) { // This field must be an array $array[$field] = array(); } else { $array[$field] = NULL; } } } // Swap the array back into the object $this->exchangeArray($array); // Get all defined field names $fields = array_keys($array); foreach ($this->pre_filters as $field => $callbacks) { foreach ($callbacks as $callback) { if ($field === '*') { foreach ($fields as $f) { $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]); } } else { $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]); } } } if ($this->submitted === FALSE) return FALSE; foreach ($this->rules as $field => $callbacks) { foreach ($callbacks as $callback) { // Separate the callback and arguments list ($callback, $args) = $callback; // Function or method name of the rule $rule = is_array($callback) ? $callback[1] : $callback; if ($field === '*') { foreach ($fields as $f) { // Note that continue, instead of break, is used when // applying rules using a wildcard, so that all fields // will be validated. if (isset($this->errors[$f])) { // Prevent other rules from being evaluated if an error has occurred continue; } if (empty($this[$f]) AND ! in_array($rule, $this->empty_rules)) { // This rule does not need to be processed on empty fields continue; } if ($args === NULL) { if ( ! call_user_func($callback, $this[$f])) { $this->errors[$f] = $rule; // Stop validating this field when an error is found continue; } } else { if ( ! call_user_func($callback, $this[$f], $args)) { $this->errors[$f] = $rule; // Stop validating this field when an error is found continue; } } } } else { if (isset($this->errors[$field])) { // Prevent other rules from being evaluated if an error has occurred break; } if ( ! in_array($rule, $this->empty_rules) AND ! $this->required($this[$field])) { // This rule does not need to be processed on empty fields continue; } if ($args === NULL) { if ( ! call_user_func($callback, $this[$field])) { $this->errors[$field] = $rule; // Stop validating this field when an error is found break; } } else { if ( ! call_user_func($callback, $this[$field], $args)) { $this->errors[$field] = $rule; // Stop validating this field when an error is found break; } } } } } foreach ($this->callbacks as $field => $callbacks) { foreach ($callbacks as $callback) { if ($field === '*') { foreach ($fields as $f) { // Note that continue, instead of break, is used when // applying rules using a wildcard, so that all fields // will be validated. if (isset($this->errors[$f])) { // Stop validating this field when an error is found continue; } call_user_func($callback, $this, $f); } } else { if (isset($this->errors[$field])) { // Stop validating this field when an error is found break; } call_user_func($callback, $this, $field); } } } foreach ($this->post_filters as $field => $callbacks) { foreach ($callbacks as $callback) { if ($field === '*') { foreach ($fields as $f) { $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]); } } else { $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]); } } } // Return TRUE if there are no errors return $this->errors === array(); } /** * Add an error to an input. * * @chainable * @param string input name * @param string unique error name * @return object */ public function add_error($field, $name) { $this->errors[$field] = $name; return $this; } /** * Sets or returns the message for an input. * * @chainable * @param string input key * @param string message to set * @return string|object */ public function message($input = NULL, $message = NULL) { if ($message === NULL) { if ($input === NULL) { $messages = array(); $keys = array_keys($this->messages); foreach ($keys as $input) { $messages[] = $this->message($input); } return implode("\n", $messages); } // Return nothing if no message exists if (empty($this->messages[$input])) return ''; // Return the HTML message string return $this->messages[$input]; } else { $this->messages[$input] = $message; } return $this; } /** * Return the errors array. * * @param boolean load errors from a lang file * @return array */ public function errors($file = NULL) { if ($file === NULL) { return $this->errors; } else { $errors = array(); foreach ($this->errors as $input => $error) { // Key for this input error $key = "$file.$input.$error"; if (($errors[$input] = Kohana::lang($key)) === $key) { // Get the default error message $errors[$input] = Kohana::lang("$file.$input.default"); } } return $errors; } } /** * Rule: required. Generates an error if the field has an empty value. * * @param mixed input value * @return bool */ public function required($str) { if (is_object($str) AND $str instanceof ArrayObject) { // Get the array from the ArrayObject $str = $str->getArrayCopy(); } if (is_array($str)) { return ! empty($str); } else { return ! ($str === '' OR $str === NULL OR $str === FALSE); } } /** * Rule: matches. Generates an error if the field does not match one or more * other fields. * * @param mixed input value * @param array input names to match against * @return bool */ public function matches($str, array $inputs) { foreach ($inputs as $key) { if ($str !== (isset($this[$key]) ? $this[$key] : NULL)) return FALSE; } return TRUE; } /** * Rule: length. Generates an error if the field is too long or too short. * * @param mixed input value * @param array minimum, maximum, or exact length to match * @return bool */ public function length($str, array $length) { if ( ! is_string($str)) return FALSE; $size = utf8::strlen($str); $status = FALSE; if (count($length) > 1) { list ($min, $max) = $length; if ($size >= $min AND $size <= $max) { $status = TRUE; } } else { $status = ($size === (int) $length[0]); } return $status; } /** * Rule: depends_on. Generates an error if the field does not depend on one * or more other fields. * * @param mixed field name * @param array field names to check dependency * @return bool */ public function depends_on($field, array $fields) { foreach ($fields as $depends_on) { if ( ! isset($this[$depends_on]) OR $this[$depends_on] == NULL) return FALSE; } return TRUE; } /** * Rule: chars. Generates an error if the field contains characters outside of the list. * * @param string field value * @param array allowed characters * @return bool */ public function chars($value, array $chars) { return ! preg_match('![^'.implode('', $chars).']!u', $value); } } // End Validation ./kohana/system/libraries/Profiler.php0000644000175000017500000001542411211340424017573 0ustar tokkeetokkeeshow OR (is_array($this->show) AND ! in_array($args[0], $this->show))) return FALSE; // Class name $class = 'Profiler_'.ucfirst($method); $class = new $class(); $this->profiles[$args[0]] = $class; return $class; } /** * Disables the profiler for this page only. * Best used when profiler is autoloaded. * * @return void */ public function disable() { // Removes itself from the event queue Event::clear('system.display', array($this, 'render')); } /** * Render the profiler. Output is added to the bottom of the page by default. * * @param boolean return the output if TRUE * @return void|string */ public function render($return = FALSE) { $start = microtime(TRUE); $get = isset($_GET['profiler']) ? explode(',', $_GET['profiler']) : array(); $this->show = empty($get) ? Kohana::config('profiler.show') : $get; Event::run('profiler.run', $this); $styles = ''; foreach ($this->profiles as $profile) { $styles .= $profile->styles(); } // Don't display if there's no profiles if (empty($this->profiles)) return; // Load the profiler view $data = array ( 'profiles' => $this->profiles, 'styles' => $styles, 'execution_time' => microtime(TRUE) - $start ); $view = new View('kohana_profiler', $data); // Return rendered view if $return is TRUE if ($return === TRUE) return $view->render(); // Add profiler data to the output if (stripos(Kohana::$output, '') !== FALSE) { // Closing body tag was found, insert the profiler data before it Kohana::$output = str_ireplace('', $view->render().'', Kohana::$output); } else { // Append the profiler data to the output Kohana::$output .= $view->render(); } } /** * Benchmark times and memory usage from the Benchmark library. * * @return void */ public function benchmarks() { if ( ! $table = $this->table('benchmarks')) return; $table->add_column(); $table->add_column('kp-column kp-data'); $table->add_column('kp-column kp-data'); $table->add_column('kp-column kp-data'); $table->add_row(array('Benchmarks', 'Time', 'Count', 'Memory'), 'kp-title', 'background-color: #FFE0E0'); $benchmarks = Benchmark::get(TRUE); // Moves the first benchmark (total execution time) to the end of the array $benchmarks = array_slice($benchmarks, 1) + array_slice($benchmarks, 0, 1); text::alternate(); foreach ($benchmarks as $name => $benchmark) { // Clean unique id from system benchmark names $name = ucwords(str_replace(array('_', '-'), ' ', str_replace(SYSTEM_BENCHMARK.'_', '', $name))); $data = array($name, number_format($benchmark['time'], 3), $benchmark['count'], number_format($benchmark['memory'] / 1024 / 1024, 2).'MB'); $class = text::alternate('', 'kp-altrow'); if ($name == 'Total Execution') $class = 'kp-totalrow'; $table->add_row($data, $class); } } /** * Database query benchmarks. * * @return void */ public function database() { if ( ! $table = $this->table('database')) return; $table->add_column(); $table->add_column('kp-column kp-data'); $table->add_column('kp-column kp-data'); $table->add_row(array('Queries', 'Time', 'Rows'), 'kp-title', 'background-color: #E0FFE0'); $queries = Database::$benchmarks; text::alternate(); $total_time = $total_rows = 0; foreach ($queries as $query) { $data = array($query['query'], number_format($query['time'], 3), $query['rows']); $class = text::alternate('', 'kp-altrow'); $table->add_row($data, $class); $total_time += $query['time']; $total_rows += $query['rows']; } $data = array('Total: ' . count($queries), number_format($total_time, 3), $total_rows); $table->add_row($data, 'kp-totalrow'); } /** * Session data. * * @return void */ public function session() { if (empty($_SESSION)) return; if ( ! $table = $this->table('session')) return; $table->add_column('kp-name'); $table->add_column(); $table->add_row(array('Session', 'Value'), 'kp-title', 'background-color: #CCE8FB'); text::alternate(); foreach($_SESSION as $name => $value) { if (is_object($value)) { $value = get_class($value).' [object]'; } $data = array($name, $value); $class = text::alternate('', 'kp-altrow'); $table->add_row($data, $class); } } /** * POST data. * * @return void */ public function post() { if (empty($_POST)) return; if ( ! $table = $this->table('post')) return; $table->add_column('kp-name'); $table->add_column(); $table->add_row(array('POST', 'Value'), 'kp-title', 'background-color: #E0E0FF'); text::alternate(); foreach($_POST as $name => $value) { $data = array($name, $value); $class = text::alternate('', 'kp-altrow'); $table->add_row($data, $class); } } /** * Cookie data. * * @return void */ public function cookies() { if (empty($_COOKIE)) return; if ( ! $table = $this->table('cookies')) return; $table->add_column('kp-name'); $table->add_column(); $table->add_row(array('Cookies', 'Value'), 'kp-title', 'background-color: #FFF4D7'); text::alternate(); foreach($_COOKIE as $name => $value) { $data = array($name, $value); $class = text::alternate('', 'kp-altrow'); $table->add_row($data, $class); } } }./kohana/system/libraries/Event_Observer.php0000644000175000017500000000305311121324570020740 0ustar tokkeetokkeeupdate($caller); } /** * Updates the observer subject with a new caller. * * @chainable * @param object Event_Subject * @return object */ public function update(SplSubject $caller) { if ( ! ($caller instanceof Event_Subject)) throw new Kohana_Exception('event.invalid_subject', get_class($caller), get_class($this)); // Update the caller $this->caller = $caller; return $this; } /** * Detaches this observer from the subject. * * @chainable * @return object */ public function remove() { // Detach this observer from the caller $this->caller->detach($this); return $this; } /** * Notify the observer of a new message. This function must be defined in * all observers and must take exactly one parameter of any type. * * @param mixed message string, object, or array * @return void */ abstract public function notify($message); } // End Event Observer./kohana/system/libraries/Database.php0000644000175000017500000010405511201062041017507 0ustar tokkeetokkee TRUE, 'persistent' => FALSE, 'connection' => '', 'character_set' => 'utf8', 'table_prefix' => '', 'object' => TRUE, 'cache' => FALSE, 'escape' => TRUE, ); // Database driver object protected $driver; protected $link; // Un-compiled parts of the SQL query protected $select = array(); protected $set = array(); protected $from = array(); protected $join = array(); protected $where = array(); protected $orderby = array(); protected $order = array(); protected $groupby = array(); protected $having = array(); protected $distinct = FALSE; protected $limit = FALSE; protected $offset = FALSE; protected $last_query = ''; // Stack of queries for push/pop protected $query_history = array(); /** * Returns a singleton instance of Database. * * @param mixed configuration array or DSN * @return Database_Core */ public static function & instance($name = 'default', $config = NULL) { if ( ! isset(Database::$instances[$name])) { // Create a new instance Database::$instances[$name] = new Database($config === NULL ? $name : $config); } return Database::$instances[$name]; } /** * Returns the name of a given database instance. * * @param Database instance of Database * @return string */ public static function instance_name(Database $db) { return array_search($db, Database::$instances, TRUE); } /** * Sets up the database configuration, loads the Database_Driver. * * @throws Kohana_Database_Exception */ public function __construct($config = array()) { if (empty($config)) { // Load the default group $config = Kohana::config('database.default'); } elseif (is_array($config) AND count($config) > 0) { if ( ! array_key_exists('connection', $config)) { $config = array('connection' => $config); } } elseif (is_string($config)) { // The config is a DSN string if (strpos($config, '://') !== FALSE) { $config = array('connection' => $config); } // The config is a group name else { $name = $config; // Test the config group name if (($config = Kohana::config('database.'.$config)) === NULL) throw new Kohana_Database_Exception('database.undefined_group', $name); } } // Merge the default config with the passed config $this->config = array_merge($this->config, $config); if (is_string($this->config['connection'])) { // Make sure the connection is valid if (strpos($this->config['connection'], '://') === FALSE) throw new Kohana_Database_Exception('database.invalid_dsn', $this->config['connection']); // Parse the DSN, creating an array to hold the connection parameters $db = array ( 'type' => FALSE, 'user' => FALSE, 'pass' => FALSE, 'host' => FALSE, 'port' => FALSE, 'socket' => FALSE, 'database' => FALSE ); // Get the protocol and arguments list ($db['type'], $connection) = explode('://', $this->config['connection'], 2); if (strpos($connection, '@') !== FALSE) { // Get the username and password list ($db['pass'], $connection) = explode('@', $connection, 2); // Check if a password is supplied $logindata = explode(':', $db['pass'], 2); $db['pass'] = (count($logindata) > 1) ? $logindata[1] : ''; $db['user'] = $logindata[0]; // Prepare for finding the database $connection = explode('/', $connection); // Find the database name $db['database'] = array_pop($connection); // Reset connection string $connection = implode('/', $connection); // Find the socket if (preg_match('/^unix\([^)]++\)/', $connection)) { // This one is a little hairy: we explode based on the end of // the socket, removing the 'unix(' from the connection string list ($db['socket'], $connection) = explode(')', substr($connection, 5), 2); } elseif (strpos($connection, ':') !== FALSE) { // Fetch the host and port name list ($db['host'], $db['port']) = explode(':', $connection, 2); } else { $db['host'] = $connection; } } else { // File connection $connection = explode('/', $connection); // Find database file name $db['database'] = array_pop($connection); // Find database directory name $db['socket'] = implode('/', $connection).'/'; } // Reset the connection array to the database config $this->config['connection'] = $db; } // Set driver name $driver = 'Database_'.ucfirst($this->config['connection']['type']).'_Driver'; // Load the driver if ( ! Kohana::auto_load($driver)) throw new Kohana_Database_Exception('core.driver_not_found', $this->config['connection']['type'], get_class($this)); // Initialize the driver $this->driver = new $driver($this->config); // Validate the driver if ( ! ($this->driver instanceof Database_Driver)) throw new Kohana_Database_Exception('core.driver_implements', $this->config['connection']['type'], get_class($this), 'Database_Driver'); Kohana::log('debug', 'Database Library initialized'); } /** * Simple connect method to get the database queries up and running. * * @return void */ public function connect() { // A link can be a resource or an object if ( ! is_resource($this->link) AND ! is_object($this->link)) { $this->link = $this->driver->connect(); if ( ! is_resource($this->link) AND ! is_object($this->link)) throw new Kohana_Database_Exception('database.connection', $this->driver->show_error()); // Clear password after successful connect $this->config['connection']['pass'] = NULL; } } /** * Runs a query into the driver and returns the result. * * @param string SQL query to execute * @return Database_Result */ public function query($sql = '') { if ($sql == '') return FALSE; // No link? Connect! $this->link or $this->connect(); // Start the benchmark $start = microtime(TRUE); if (func_num_args() > 1) //if we have more than one argument ($sql) { $argv = func_get_args(); $binds = (is_array(next($argv))) ? current($argv) : array_slice($argv, 1); } // Compile binds if needed if (isset($binds)) { $sql = $this->compile_binds($sql, $binds); } // Fetch the result $result = $this->driver->query($this->last_query = $sql); // Stop the benchmark $stop = microtime(TRUE); if ($this->config['benchmark'] == TRUE) { // Benchmark the query Database::$benchmarks[] = array('query' => $sql, 'time' => $stop - $start, 'rows' => count($result)); } return $result; } /** * Selects the column names for a database query. * * @param string string or array of column names to select * @return Database_Core This Database object. */ public function select($sql = '*') { if (func_num_args() > 1) { $sql = func_get_args(); } elseif (is_string($sql)) { $sql = explode(',', $sql); } else { $sql = (array) $sql; } foreach ($sql as $val) { if (($val = trim($val)) === '') continue; if (strpos($val, '(') === FALSE AND $val !== '*') { if (preg_match('/^DISTINCT\s++(.+)$/i', $val, $matches)) { // Only prepend with table prefix if table name is specified $val = (strpos($matches[1], '.') !== FALSE) ? $this->config['table_prefix'].$matches[1] : $matches[1]; $this->distinct = TRUE; } else { $val = (strpos($val, '.') !== FALSE) ? $this->config['table_prefix'].$val : $val; } $val = $this->driver->escape_column($val); } $this->select[] = $val; } return $this; } /** * Selects the from table(s) for a database query. * * @param string string or array of tables to select * @return Database_Core This Database object. */ public function from($sql) { if (func_num_args() > 1) { $sql = func_get_args(); } elseif (is_string($sql)) { $sql = explode(',', $sql); } else { $sql = array($sql); } foreach ($sql as $val) { if (is_string($val)) { if (($val = trim($val)) === '') continue; // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice) if (stripos($val, ' AS ') !== FALSE) { $val = str_ireplace(' AS ', ' AS ', $val); list($table, $alias) = explode(' AS ', $val); // Attach prefix to both sides of the AS $val = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias; } else { $val = $this->config['table_prefix'].$val; } } $this->from[] = $val; } return $this; } /** * Generates the JOIN portion of the query. * * @param string table name * @param string|array where key or array of key => value pairs * @param string where value * @param string type of join * @return Database_Core This Database object. */ public function join($table, $key, $value = NULL, $type = '') { $join = array(); if ( ! empty($type)) { $type = strtoupper(trim($type)); if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE)) { $type = ''; } else { $type .= ' '; } } $cond = array(); $keys = is_array($key) ? $key : array($key => $value); foreach ($keys as $key => $value) { $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; if (is_string($value)) { // Only escape if it's a string $value = $this->driver->escape_column($this->config['table_prefix'].$value); } $cond[] = $this->driver->where($key, $value, 'AND ', count($cond), FALSE); } if ( ! is_array($this->join)) { $this->join = array(); } if ( ! is_array($table)) { $table = array($table); } foreach ($table as $t) { if (is_string($t)) { // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice) if (stripos($t, ' AS ') !== FALSE) { $t = str_ireplace(' AS ', ' AS ', $t); list($table, $alias) = explode(' AS ', $t); // Attach prefix to both sides of the AS $t = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias; } else { $t = $this->config['table_prefix'].$t; } } $join['tables'][] = $this->driver->escape_column($t); } $join['conditions'] = '('.trim(implode(' ', $cond)).')'; $join['type'] = $type; $this->join[] = $join; return $this; } /** * Selects the where(s) for a database query. * * @param string|array key name or array of key => value pairs * @param string value to match with key * @param boolean disable quoting of WHERE clause * @return Database_Core This Database object. */ public function where($key, $value = NULL, $quote = TRUE) { $quote = (func_num_args() < 2 AND ! is_array($key)) ? -1 : $quote; if (is_object($key)) { $keys = array((string) $key => ''); } elseif ( ! is_array($key)) { $keys = array($key => $value); } else { $keys = $key; } foreach ($keys as $key => $value) { $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; $this->where[] = $this->driver->where($key, $value, 'AND ', count($this->where), $quote); } return $this; } /** * Selects the or where(s) for a database query. * * @param string|array key name or array of key => value pairs * @param string value to match with key * @param boolean disable quoting of WHERE clause * @return Database_Core This Database object. */ public function orwhere($key, $value = NULL, $quote = TRUE) { $quote = (func_num_args() < 2 AND ! is_array($key)) ? -1 : $quote; if (is_object($key)) { $keys = array((string) $key => ''); } elseif ( ! is_array($key)) { $keys = array($key => $value); } else { $keys = $key; } foreach ($keys as $key => $value) { $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; $this->where[] = $this->driver->where($key, $value, 'OR ', count($this->where), $quote); } return $this; } /** * Selects the like(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string like value to match with field * @param boolean automatically add starting and ending wildcards * @return Database_Core This Database object. */ public function like($field, $match = '', $auto = TRUE) { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->like($field, $match, $auto, 'AND ', count($this->where)); } return $this; } /** * Selects the or like(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string like value to match with field * @param boolean automatically add starting and ending wildcards * @return Database_Core This Database object. */ public function orlike($field, $match = '', $auto = TRUE) { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->like($field, $match, $auto, 'OR ', count($this->where)); } return $this; } /** * Selects the not like(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string like value to match with field * @param boolean automatically add starting and ending wildcards * @return Database_Core This Database object. */ public function notlike($field, $match = '', $auto = TRUE) { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->notlike($field, $match, $auto, 'AND ', count($this->where)); } return $this; } /** * Selects the or not like(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string like value to match with field * @return Database_Core This Database object. */ public function ornotlike($field, $match = '', $auto = TRUE) { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->notlike($field, $match, $auto, 'OR ', count($this->where)); } return $this; } /** * Selects the like(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string like value to match with field * @return Database_Core This Database object. */ public function regex($field, $match = '') { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->regex($field, $match, 'AND ', count($this->where)); } return $this; } /** * Selects the or like(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string like value to match with field * @return Database_Core This Database object. */ public function orregex($field, $match = '') { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->regex($field, $match, 'OR ', count($this->where)); } return $this; } /** * Selects the not regex(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string regex value to match with field * @return Database_Core This Database object. */ public function notregex($field, $match = '') { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->notregex($field, $match, 'AND ', count($this->where)); } return $this; } /** * Selects the or not regex(s) for a database query. * * @param string|array field name or array of field => match pairs * @param string regex value to match with field * @return Database_Core This Database object. */ public function ornotregex($field, $match = '') { $fields = is_array($field) ? $field : array($field => $match); foreach ($fields as $field => $match) { $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; $this->where[] = $this->driver->notregex($field, $match, 'OR ', count($this->where)); } return $this; } /** * Chooses the column to group by in a select query. * * @param string column name to group by * @return Database_Core This Database object. */ public function groupby($by) { if ( ! is_array($by)) { $by = explode(',', (string) $by); } foreach ($by as $val) { $val = trim($val); if ($val != '') { // Add the table prefix if we are using table.column names if(strpos($val, '.')) { $val = $this->config['table_prefix'].$val; } $this->groupby[] = $this->driver->escape_column($val); } } return $this; } /** * Selects the having(s) for a database query. * * @param string|array key name or array of key => value pairs * @param string value to match with key * @param boolean disable quoting of WHERE clause * @return Database_Core This Database object. */ public function having($key, $value = '', $quote = TRUE) { $this->having[] = $this->driver->where($key, $value, 'AND', count($this->having), TRUE); return $this; } /** * Selects the or having(s) for a database query. * * @param string|array key name or array of key => value pairs * @param string value to match with key * @param boolean disable quoting of WHERE clause * @return Database_Core This Database object. */ public function orhaving($key, $value = '', $quote = TRUE) { $this->having[] = $this->driver->where($key, $value, 'OR', count($this->having), TRUE); return $this; } /** * Chooses which column(s) to order the select query by. * * @param string|array column(s) to order on, can be an array, single column, or comma seperated list of columns * @param string direction of the order * @return Database_Core This Database object. */ public function orderby($orderby, $direction = NULL) { if ( ! is_array($orderby)) { $orderby = array($orderby => $direction); } foreach ($orderby as $column => $direction) { $direction = strtoupper(trim($direction)); // Add a direction if the provided one isn't valid if ( ! in_array($direction, array('ASC', 'DESC', 'RAND()', 'RANDOM()', 'NULL'))) { $direction = 'ASC'; } // Add the table prefix if a table.column was passed if (strpos($column, '.')) { $column = $this->config['table_prefix'].$column; } $this->orderby[] = $this->driver->escape_column($column).' '.$direction; } return $this; } /** * Selects the limit section of a query. * * @param integer number of rows to limit result to * @param integer offset in result to start returning rows from * @return Database_Core This Database object. */ public function limit($limit, $offset = NULL) { $this->limit = (int) $limit; if ($offset !== NULL OR ! is_int($this->offset)) { $this->offset($offset); } return $this; } /** * Sets the offset portion of a query. * * @param integer offset value * @return Database_Core This Database object. */ public function offset($value) { $this->offset = (int) $value; return $this; } /** * Allows key/value pairs to be set for inserting or updating. * * @param string|array key name or array of key => value pairs * @param string value to match with key * @return Database_Core This Database object. */ public function set($key, $value = '') { if ( ! is_array($key)) { $key = array($key => $value); } foreach ($key as $k => $v) { // Add a table prefix if the column includes the table. if (strpos($k, '.')) $k = $this->config['table_prefix'].$k; $this->set[$k] = $this->driver->escape($v); } return $this; } /** * Compiles the select statement based on the other functions called and runs the query. * * @param string table name * @param string limit clause * @param string offset clause * @return Database_Result */ public function get($table = '', $limit = NULL, $offset = NULL) { if ($table != '') { $this->from($table); } if ( ! is_null($limit)) { $this->limit($limit, $offset); } $sql = $this->driver->compile_select(get_object_vars($this)); $this->reset_select(); $result = $this->query($sql); $this->last_query = $sql; return $result; } /** * Compiles the select statement based on the other functions called and runs the query. * * @param string table name * @param array where clause * @param string limit clause * @param string offset clause * @return Database_Core This Database object. */ public function getwhere($table = '', $where = NULL, $limit = NULL, $offset = NULL) { if ($table != '') { $this->from($table); } if ( ! is_null($where)) { $this->where($where); } if ( ! is_null($limit)) { $this->limit($limit, $offset); } $sql = $this->driver->compile_select(get_object_vars($this)); $this->reset_select(); $result = $this->query($sql); return $result; } /** * Compiles the select statement based on the other functions called and returns the query string. * * @param string table name * @param string limit clause * @param string offset clause * @return string sql string */ public function compile($table = '', $limit = NULL, $offset = NULL) { if ($table != '') { $this->from($table); } if ( ! is_null($limit)) { $this->limit($limit, $offset); } $sql = $this->driver->compile_select(get_object_vars($this)); $this->reset_select(); return $sql; } /** * Compiles an insert string and runs the query. * * @param string table name * @param array array of key/value pairs to insert * @return Database_Result Query result */ public function insert($table = '', $set = NULL) { if ( ! is_null($set)) { $this->set($set); } if ($this->set == NULL) throw new Kohana_Database_Exception('database.must_use_set'); if ($table == '') { if ( ! isset($this->from[0])) throw new Kohana_Database_Exception('database.must_use_table'); $table = $this->from[0]; } // If caching is enabled, clear the cache before inserting ($this->config['cache'] === TRUE) and $this->clear_cache(); $sql = $this->driver->insert($this->config['table_prefix'].$table, array_keys($this->set), array_values($this->set)); $this->reset_write(); return $this->query($sql); } /** * Adds an "IN" condition to the where clause * * @param string Name of the column being examined * @param mixed An array or string to match against * @param bool Generate a NOT IN clause instead * @return Database_Core This Database object. */ public function in($field, $values, $not = FALSE) { if (is_array($values)) { $escaped_values = array(); foreach ($values as $v) { if (is_numeric($v)) { $escaped_values[] = $v; } else { $escaped_values[] = "'".$this->driver->escape_str($v)."'"; } } $values = implode(",", $escaped_values); } $where = $this->driver->escape_column(((strpos($field,'.') !== FALSE) ? $this->config['table_prefix'] : ''). $field).' '.($not === TRUE ? 'NOT ' : '').'IN ('.$values.')'; $this->where[] = $this->driver->where($where, '', 'AND ', count($this->where), -1); return $this; } /** * Adds a "NOT IN" condition to the where clause * * @param string Name of the column being examined * @param mixed An array or string to match against * @return Database_Core This Database object. */ public function notin($field, $values) { return $this->in($field, $values, TRUE); } /** * Compiles a merge string and runs the query. * * @param string table name * @param array array of key/value pairs to merge * @return Database_Result Query result */ public function merge($table = '', $set = NULL) { if ( ! is_null($set)) { $this->set($set); } if ($this->set == NULL) throw new Kohana_Database_Exception('database.must_use_set'); if ($table == '') { if ( ! isset($this->from[0])) throw new Kohana_Database_Exception('database.must_use_table'); $table = $this->from[0]; } $sql = $this->driver->merge($this->config['table_prefix'].$table, array_keys($this->set), array_values($this->set)); $this->reset_write(); return $this->query($sql); } /** * Compiles an update string and runs the query. * * @param string table name * @param array associative array of update values * @param array where clause * @return Database_Result Query result */ public function update($table = '', $set = NULL, $where = NULL) { if ( is_array($set)) { $this->set($set); } if ( ! is_null($where)) { $this->where($where); } if ($this->set == FALSE) throw new Kohana_Database_Exception('database.must_use_set'); if ($table == '') { if ( ! isset($this->from[0])) throw new Kohana_Database_Exception('database.must_use_table'); $table = $this->from[0]; } $sql = $this->driver->update($this->config['table_prefix'].$table, $this->set, $this->where); $this->reset_write(); return $this->query($sql); } /** * Compiles a delete string and runs the query. * * @param string table name * @param array where clause * @return Database_Result Query result */ public function delete($table = '', $where = NULL) { if ($table == '') { if ( ! isset($this->from[0])) throw new Kohana_Database_Exception('database.must_use_table'); $table = $this->from[0]; } else { $table = $this->config['table_prefix'].$table; } if (! is_null($where)) { $this->where($where); } if (count($this->where) < 1) throw new Kohana_Database_Exception('database.must_use_where'); $sql = $this->driver->delete($table, $this->where); $this->reset_write(); return $this->query($sql); } /** * Returns the last query run. * * @return string SQL */ public function last_query() { return $this->last_query; } /** * Count query records. * * @param string table name * @param array where clause * @return integer */ public function count_records($table = FALSE, $where = NULL) { if (count($this->from) < 1) { if ($table == FALSE) throw new Kohana_Database_Exception('database.must_use_table'); $this->from($table); } if ($where !== NULL) { $this->where($where); } $query = $this->select('COUNT(*) AS '.$this->escape_column('records_found'))->get()->result(TRUE); return (int) $query->current()->records_found; } /** * Resets all private select variables. * * @return void */ protected function reset_select() { $this->select = array(); $this->from = array(); $this->join = array(); $this->where = array(); $this->orderby = array(); $this->groupby = array(); $this->having = array(); $this->distinct = FALSE; $this->limit = FALSE; $this->offset = FALSE; } /** * Resets all private insert and update variables. * * @return void */ protected function reset_write() { $this->set = array(); $this->from = array(); $this->where = array(); } /** * Lists all the tables in the current database. * * @return array */ public function list_tables() { $this->link or $this->connect(); return $this->driver->list_tables(); } /** * See if a table exists in the database. * * @param string table name * @param boolean True to attach table prefix * @return boolean */ public function table_exists($table_name, $prefix = TRUE) { if ($prefix) return in_array($this->config['table_prefix'].$table_name, $this->list_tables()); else return in_array($table_name, $this->list_tables()); } /** * Combine a SQL statement with the bind values. Used for safe queries. * * @param string query to bind to the values * @param array array of values to bind to the query * @return string */ public function compile_binds($sql, $binds) { foreach ((array) $binds as $val) { // If the SQL contains no more bind marks ("?"), we're done. if (($next_bind_pos = strpos($sql, '?')) === FALSE) break; // Properly escape the bind value. $val = $this->driver->escape($val); // Temporarily replace possible bind marks ("?"), in the bind value itself, with a placeholder. $val = str_replace('?', '{%B%}', $val); // Replace the first bind mark ("?") with its corresponding value. $sql = substr($sql, 0, $next_bind_pos).$val.substr($sql, $next_bind_pos + 1); } // Restore placeholders. return str_replace('{%B%}', '?', $sql); } /** * Get the field data for a database table, along with the field's attributes. * * @param string table name * @return array */ public function field_data($table = '') { $this->link or $this->connect(); return $this->driver->field_data($this->config['table_prefix'].$table); } /** * Get the field data for a database table, along with the field's attributes. * * @param string table name * @return array */ public function list_fields($table = '') { $this->link or $this->connect(); return $this->driver->list_fields($this->config['table_prefix'].$table); } /** * Escapes a value for a query. * * @param mixed value to escape * @return string */ public function escape($value) { return $this->driver->escape($value); } /** * Escapes a string for a query. * * @param string string to escape * @return string */ public function escape_str($str) { return $this->driver->escape_str($str); } /** * Escapes a table name for a query. * * @param string string to escape * @return string */ public function escape_table($table) { return $this->driver->escape_table($table); } /** * Escapes a column name for a query. * * @param string string to escape * @return string */ public function escape_column($table) { return $this->driver->escape_column($table); } /** * Returns table prefix of current configuration. * * @return string */ public function table_prefix() { return $this->config['table_prefix']; } /** * Clears the query cache. * * @param string|TRUE clear cache by SQL statement or TRUE for last query * @return Database_Core This Database object. */ public function clear_cache($sql = NULL) { if ($sql === TRUE) { $this->driver->clear_cache($this->last_query); } elseif (is_string($sql)) { $this->driver->clear_cache($sql); } else { $this->driver->clear_cache(); } return $this; } /** * Pushes existing query space onto the query stack. Use push * and pop to prevent queries from clashing before they are * executed * * @return Database_Core This Databaes object */ public function push() { array_push($this->query_history, array( $this->select, $this->from, $this->join, $this->where, $this->orderby, $this->order, $this->groupby, $this->having, $this->distinct, $this->limit, $this->offset )); $this->reset_select(); return $this; } /** * Pops from query stack into the current query space. * * @return Database_Core This Databaes object */ public function pop() { if (count($this->query_history) == 0) { // No history return $this; } list( $this->select, $this->from, $this->join, $this->where, $this->orderby, $this->order, $this->groupby, $this->having, $this->distinct, $this->limit, $this->offset ) = array_pop($this->query_history); return $this; } /** * Count the number of records in the last query, without LIMIT or OFFSET applied. * * @return integer */ public function count_last_query() { if ($sql = $this->last_query()) { if (stripos($sql, 'LIMIT') !== FALSE) { // Remove LIMIT from the SQL $sql = preg_replace('/\sLIMIT\s+[^a-z]+/i', ' ', $sql); } if (stripos($sql, 'OFFSET') !== FALSE) { // Remove OFFSET from the SQL $sql = preg_replace('/\sOFFSET\s+\d+/i', '', $sql); } // Get the total rows from the last query executed $result = $this->query ( 'SELECT COUNT(*) AS '.$this->escape_column('total_rows').' '. 'FROM ('.trim($sql).') AS '.$this->escape_table('counted_results') ); // Return the total number of rows from the query return (int) $result->current()->total_rows; } return FALSE; } } // End Database Class /** * Sets the code for a Database exception. */ class Kohana_Database_Exception extends Kohana_Exception { protected $code = E_DATABASE_ERROR; } // End Kohana Database Exception ./kohana/system/libraries/ORM_Versioned.php0000644000175000017500000000550111122010320020445 0ustar tokkeetokkeelast_version = 1 + ($this->last_version === NULL ? $this->object['version'] : $this->last_version); $this->__set('version', $this->last_version); parent::save(); if ($this->saved) { $data = array(); foreach ($this->object as $key => $value) { if ($key === 'id') continue; $data[$key] = $value; } $data[$this->foreign_key()] = $this->id; $this->db->insert($this->table_name.'_versions', $data); } return $this; } /** * Loads previous version from current object * * @chainable * @return ORM */ public function previous() { if ( ! $this->loaded) return $this; $this->last_version = ($this->last_version === NULL) ? $this->object['version'] : $this->last_version; $version = $this->last_version - 1; $query = $this->db ->where($this->foreign_key(), $this->object[$this->primary_key]) ->where('version', $version) ->limit(1) ->get($this->table_name.'_versions'); if ($query->count()) { $this->load_values($query->result(FALSE)->current()); } return $this; } /** * Restores the object with data from stored version * * @param integer version number you want to restore * @return ORM */ public function restore($version) { if ( ! $this->loaded) return $this; $query = $this->db ->where($this->foreign_key(), $this->object[$this->primary_key]) ->where('version', $version) ->limit(1) ->get($this->table_name.'_versions'); if ($query->count()) { $row = $query->result(FALSE)->current(); foreach ($row as $key => $value) { if ($key === $this->primary_key OR $key === $this->foreign_key()) { // Do not overwrite the primary key continue; } if ($key === 'version') { // Always use the current version $value = $this->version; } $this->__set($key, $value); } $this->save(); } return $this; } /** * Overloads ORM::delete() to delete all versioned entries of current object * and the object itself * * @param integer id of the object you want to delete * @return ORM */ public function delete($id = NULL) { if ($id === NULL) { // Use the current object id $id = $this->object[$this->primary_key]; } if ($status = parent::delete($id)) { $this->db->where($this->foreign_key(), $id)->delete($this->table_name.'_versions'); } return $status; } }./kohana/system/libraries/Calendar_Event.php0000644000175000017500000001731311163210427020667 0ustar tokkeetokkeeconditions[$key]); } else { if ($key === 'callback') { // Do nothing } elseif (in_array($key, $this->booleans)) { // Make the value boolean $value = (bool) $value; } else { // Make the value an int $value = (int) $value; } $this->conditions[$key] = $value; } return $this; } /** * Add a CSS class for this event. This can be called multiple times. * * @chainable * @param string CSS class name * @return object */ public function add_class($class) { $this->classes[$class] = $class; return $this; } /** * Remove a CSS class for this event. This can be called multiple times. * * @chainable * @param string CSS class name * @return object */ public function remove_class($class) { unset($this->classes[$class]); return $this; } /** * Set HTML output for this event. * * @chainable * @param string HTML output * @return object */ public function output($str) { $this->output = $str; return $this; } /** * Add a CSS class for this event. This can be called multiple times. * * @chainable * @param string CSS class name * @return object */ public function notify($data) { // Split the date and current status list ($month, $day, $year, $week, $current) = $data; // Get a timestamp for the day $timestamp = mktime(0, 0, 0, $month, $day, $year); // Date conditionals $condition = array ( 'timestamp' => (int) $timestamp, 'day' => (int) date('j', $timestamp), 'week' => (int) $week, 'month' => (int) date('n', $timestamp), 'year' => (int) date('Y', $timestamp), 'day_of_week' => (int) date('w', $timestamp), 'current' => (bool) $current, ); // Tested conditions $tested = array(); foreach ($condition as $key => $value) { // Timestamps need to be handled carefully if($key === 'timestamp' AND isset($this->conditions['timestamp'])) { // This adds 23 hours, 59 minutes and 59 seconds to today's timestamp, as 24 hours // is classed as a new day $next_day = $timestamp + 86399; if($this->conditions['timestamp'] < $timestamp OR $this->conditions['timestamp'] > $next_day) return FALSE; } // Test basic conditions first elseif (isset($this->conditions[$key]) AND $this->conditions[$key] !== $value) return FALSE; // Condition has been tested $tested[$key] = TRUE; } if (isset($this->conditions['weekend'])) { // Weekday vs Weekend $condition['weekend'] = ($condition['day_of_week'] === 0 OR $condition['day_of_week'] === 6); } if (isset($this->conditions['first_day'])) { // First day of month $condition['first_day'] = ($condition['day'] === 1); } if (isset($this->conditions['last_day'])) { // Last day of month $condition['last_day'] = ($condition['day'] === (int) date('t', $timestamp)); } if (isset($this->conditions['occurrence'])) { // Get the occurance of the current day $condition['occurrence'] = $this->day_occurrence($timestamp); } if (isset($this->conditions['last_occurrence'])) { // Test if the next occurance of this date is next month $condition['last_occurrence'] = ((int) date('n', $timestamp + 604800) !== $condition['month']); } if (isset($this->conditions['easter'])) { if ($condition['month'] === 3 OR $condition['month'] === 4) { // This algorithm is from Practical Astronomy With Your Calculator, 2nd Edition by Peter // Duffett-Smith. It was originally from Butcher's Ecclesiastical Calendar, published in // 1876. This algorithm has also been published in the 1922 book General Astronomy by // Spencer Jones; in The Journal of the British Astronomical Association (Vol.88, page // 91, December 1977); and in Astronomical Algorithms (1991) by Jean Meeus. $a = $condition['year'] % 19; $b = (int) ($condition['year'] / 100); $c = $condition['year'] % 100; $d = (int) ($b / 4); $e = $b % 4; $f = (int) (($b + 8) / 25); $g = (int) (($b - $f + 1) / 3); $h = (19 * $a + $b - $d - $g + 15) % 30; $i = (int) ($c / 4); $k = $c % 4; $l = (32 + 2 * $e + 2 * $i - $h - $k) % 7; $m = (int) (($a + 11 * $h + 22 * $l) / 451); $p = ($h + $l - 7 * $m + 114) % 31; $month = (int) (($h + $l - 7 * $m + 114) / 31); $day = $p + 1; $condition['easter'] = ($condition['month'] === $month AND $condition['day'] === $day); } else { // Easter can only happen in March or April $condition['easter'] = FALSE; } } if (isset($this->conditions['callback'])) { // Use a callback to determine validity $condition['callback'] = call_user_func($this->conditions['callback'], $condition, $this); } $conditions = array_diff_key($this->conditions, $tested); foreach ($conditions as $key => $value) { if ($key === 'callback') { // Callbacks are tested on a TRUE/FALSE basis $value = TRUE; } // Test advanced conditions if ($condition[$key] !== $value) return FALSE; } $this->caller->add_data(array ( 'classes' => $this->classes, 'output' => $this->output, )); } /** * Find the week day occurrence for a specific timestamp. The occurrence is * relative to the current month. For example, the second Saturday of any * given month will return "2" as the occurrence. This is used in combination * with the "occurrence" condition. * * @param integer UNIX timestamp * @return integer */ protected function day_occurrence($timestamp) { // Get the current month for the timestamp $month = date('m', $timestamp); // Default occurrence is one $occurrence = 1; // Reduce the timestamp by one week for each loop. This has the added // benefit of preventing an infinite loop. while ($timestamp -= 604800) { if (date('m', $timestamp) !== $month) { // Once the timestamp has gone into the previous month, the // proper occurrence has been found. return $occurrence; } // Increment the occurrence $occurrence++; } } } // End Calendar Event ./kohana/system/libraries/Pagination.php0000644000175000017500000001514711121324570020110 0ustar tokkeetokkeeinitialize($config); Kohana::log('debug', 'Pagination Library initialized'); } /** * Sets config values. * * @throws Kohana_Exception * @param array configuration settings * @return void */ public function initialize($config = array()) { // Load config group if (isset($config['group'])) { // Load and validate config group if ( ! is_array($group_config = Kohana::config('pagination.'.$config['group']))) throw new Kohana_Exception('pagination.undefined_group', $config['group']); // All pagination config groups inherit default config group if ($config['group'] !== 'default') { // Load and validate default config group if ( ! is_array($default_config = Kohana::config('pagination.default'))) throw new Kohana_Exception('pagination.undefined_group', 'default'); // Merge config group with default config group $group_config += $default_config; } // Merge custom config items with config group $config += $group_config; } // Assign config values to the object foreach ($config as $key => $value) { if (property_exists($this, $key)) { $this->$key = $value; } } // Clean view directory $this->directory = trim($this->directory, '/').'/'; // Build generic URL with page in query string if ($this->query_string !== '') { // Extract current page $this->current_page = isset($_GET[$this->query_string]) ? (int) $_GET[$this->query_string] : 1; // Insert {page} placeholder $_GET[$this->query_string] = '{page}'; // Create full URL $base_url = ($this->base_url === '') ? Router::$current_uri : $this->base_url; $this->url = url::site($base_url).'?'.str_replace('%7Bpage%7D', '{page}', http_build_query($_GET)); // Reset page number $_GET[$this->query_string] = $this->current_page; } // Build generic URL with page as URI segment else { // Use current URI if no base_url set $this->url = ($this->base_url === '') ? Router::$segments : explode('/', trim($this->base_url, '/')); // Convert uri 'label' to corresponding integer if needed if (is_string($this->uri_segment)) { if (($key = array_search($this->uri_segment, $this->url)) === FALSE) { // If uri 'label' is not found, auto add it to base_url $this->url[] = $this->uri_segment; $this->uri_segment = count($this->url) + 1; } else { $this->uri_segment = $key + 2; } } // Insert {page} placeholder $this->url[$this->uri_segment - 1] = '{page}'; // Create full URL $this->url = url::site(implode('/', $this->url)).Router::$query_string; // Extract current page $this->current_page = URI::instance()->segment($this->uri_segment); } // Core pagination values $this->total_items = (int) max(0, $this->total_items); $this->items_per_page = (int) max(1, $this->items_per_page); $this->total_pages = (int) ceil($this->total_items / $this->items_per_page); $this->current_page = (int) min(max(1, $this->current_page), max(1, $this->total_pages)); $this->current_first_item = (int) min((($this->current_page - 1) * $this->items_per_page) + 1, $this->total_items); $this->current_last_item = (int) min($this->current_first_item + $this->items_per_page - 1, $this->total_items); // If there is no first/last/previous/next page, relative to the // current page, value is set to FALSE. Valid page number otherwise. $this->first_page = ($this->current_page === 1) ? FALSE : 1; $this->last_page = ($this->current_page >= $this->total_pages) ? FALSE : $this->total_pages; $this->previous_page = ($this->current_page > 1) ? $this->current_page - 1 : FALSE; $this->next_page = ($this->current_page < $this->total_pages) ? $this->current_page + 1 : FALSE; // SQL values $this->sql_offset = (int) ($this->current_page - 1) * $this->items_per_page; $this->sql_limit = sprintf(' LIMIT %d OFFSET %d ', $this->items_per_page, $this->sql_offset); } /** * Generates the HTML for the chosen pagination style. * * @param string pagination style * @return string pagination html */ public function render($style = NULL) { // Hide single page pagination if ($this->auto_hide === TRUE AND $this->total_pages <= 1) return ''; if ($style === NULL) { // Use default style $style = $this->style; } // Return rendered pagination view return View::factory($this->directory.$style, get_object_vars($this))->render(); } /** * Magically converts Pagination object to string. * * @return string pagination html */ public function __toString() { return $this->render(); } /** * Magically gets a pagination variable. * * @param string variable key * @return mixed variable value if the key is found * @return void if the key is not found */ public function __get($key) { if (isset($this->$key)) return $this->$key; } /** * Adds a secondary interface for accessing properties, e.g. $pagination->total_pages(). * Note that $pagination->total_pages is the recommended way to access properties. * * @param string function name * @return string */ public function __call($func, $args = NULL) { return $this->__get($func); } } // End Pagination Class./kohana/system/libraries/Database_Expression.php0000644000175000017500000000113711153611752021742 0ustar tokkeetokkeeexpression = $expression; } public function __toString() { return (string) $this->expression; } } // End Database Expr Class./kohana/system/libraries/Profiler_Table.php0000644000175000017500000000256711121324570020712 0ustar tokkeetokkeecolumns[] = array('class' => $class, 'style' => $style); } /** * Add row to table. * * @param array data to go in table cells * @param string CSS class * @param string CSS style */ public function add_row($data, $class = '', $style = '') { $this->rows[] = array('data' => $data, 'class' => $class, 'style' => $style); } /** * Render table. * * @return string */ public function render() { $data['rows'] = $this->rows; $data['columns'] = $this->columns; return View::factory('kohana_profiler_table', $data)->render(); } }./kohana/system/libraries/Router.php0000644000175000017500000001706411211635424017302 0ustar tokkeetokkee 1) { // Custom routing Router::$rsegments = Router::routed_uri(Router::$current_uri); } // The routed URI is now complete Router::$routed_uri = Router::$rsegments; // Routed segments will never be empty Router::$rsegments = explode('/', Router::$rsegments); // Prepare to find the controller $controller_path = ''; $method_segment = NULL; // Paths to search $paths = Kohana::include_paths(); foreach (Router::$rsegments as $key => $segment) { // Add the segment to the search path $controller_path .= $segment; $found = FALSE; foreach ($paths as $dir) { // Search within controllers only $dir .= 'controllers/'; if (is_dir($dir.$controller_path) OR is_file($dir.$controller_path.EXT)) { // Valid path $found = TRUE; // The controller must be a file that exists with the search path if ($c = str_replace('\\', '/', realpath($dir.$controller_path.EXT)) AND is_file($c) AND strpos($c, $dir) === 0) { // Set controller name Router::$controller = $segment; // Change controller path Router::$controller_path = $c; // Set the method segment $method_segment = $key + 1; // Stop searching break; } } } if ($found === FALSE) { // Maximum depth has been reached, stop searching break; } // Add another slash $controller_path .= '/'; } if ($method_segment !== NULL AND isset(Router::$rsegments[$method_segment])) { // Set method Router::$method = Router::$rsegments[$method_segment]; if (isset(Router::$rsegments[$method_segment + 1])) { // Set arguments Router::$arguments = array_slice(Router::$rsegments, $method_segment + 1); } } // Last chance to set routing before a 404 is triggered Event::run('system.post_routing'); if (Router::$controller === NULL) { // No controller was found, so no page can be rendered Event::run('system.404'); } } /** * Attempts to determine the current URI using CLI, GET, PATH_INFO, ORIG_PATH_INFO, or PHP_SELF. * * @return void */ public static function find_uri() { if (PHP_SAPI === 'cli') { // Command line requires a bit of hacking if (isset($_SERVER['argv'][1])) { Router::$current_uri = $_SERVER['argv'][1]; // Remove GET string from segments if (($query = strpos(Router::$current_uri, '?')) !== FALSE) { list (Router::$current_uri, $query) = explode('?', Router::$current_uri, 2); // Parse the query string into $_GET parse_str($query, $_GET); // Convert $_GET to UTF-8 $_GET = utf8::clean($_GET); } } } elseif (isset($_GET['kohana_uri'])) { // Use the URI defined in the query string Router::$current_uri = $_GET['kohana_uri']; // Remove the URI from $_GET unset($_GET['kohana_uri']); // Remove the URI from $_SERVER['QUERY_STRING'] $_SERVER['QUERY_STRING'] = preg_replace('~\bkohana_uri\b[^&]*+&?~', '', $_SERVER['QUERY_STRING']); } elseif (isset($_SERVER['PATH_INFO']) AND $_SERVER['PATH_INFO']) { Router::$current_uri = $_SERVER['PATH_INFO']; } elseif (isset($_SERVER['ORIG_PATH_INFO']) AND $_SERVER['ORIG_PATH_INFO']) { Router::$current_uri = $_SERVER['ORIG_PATH_INFO']; } elseif (isset($_SERVER['PHP_SELF']) AND $_SERVER['PHP_SELF']) { Router::$current_uri = $_SERVER['PHP_SELF']; } if (($strpos_fc = strpos(Router::$current_uri, KOHANA)) !== FALSE) { // Remove the front controller from the current uri Router::$current_uri = (string) substr(Router::$current_uri, $strpos_fc + strlen(KOHANA)); } // Remove slashes from the start and end of the URI Router::$current_uri = trim(Router::$current_uri, '/'); if (Router::$current_uri !== '') { if ($suffix = Kohana::config('core.url_suffix') AND strpos(Router::$current_uri, $suffix) !== FALSE) { // Remove the URL suffix Router::$current_uri = preg_replace('#'.preg_quote($suffix).'$#u', '', Router::$current_uri); // Set the URL suffix Router::$url_suffix = $suffix; } // Reduce multiple slashes into single slashes Router::$current_uri = preg_replace('#//+#', '/', Router::$current_uri); } } /** * Generates routed URI from given URI. * * @param string URI to convert * @return string Routed uri */ public static function routed_uri($uri) { if (Router::$routes === NULL) { // Load routes Router::$routes = Kohana::config('routes'); } // Prepare variables $routed_uri = $uri = trim($uri, '/'); if (isset(Router::$routes[$uri])) { // Literal match, no need for regex $routed_uri = Router::$routes[$uri]; } else { // Loop through the routes and see if anything matches foreach (Router::$routes as $key => $val) { if ($key === '_default') continue; // Trim slashes $key = trim($key, '/'); $val = trim($val, '/'); if (preg_match('#^'.$key.'$#u', $uri)) { if (strpos($val, '$') !== FALSE) { // Use regex routing $routed_uri = preg_replace('#^'.$key.'$#u', $val, $uri); } else { // Standard routing $routed_uri = $val; } // A valid route has been found break; } } } if (isset(Router::$routes[$routed_uri])) { // Check for double routing (without regex) $routed_uri = Router::$routes[$routed_uri]; } return trim($routed_uri, '/'); } } // End Router./kohana/system/libraries/Session.php0000644000175000017500000002374011156516666017461 0ustar tokkeetokkeeinput = Input::instance(); // This part only needs to be run once if (Session::$instance === NULL) { // Load config Session::$config = Kohana::config('session'); // Makes a mirrored array, eg: foo=foo Session::$protect = array_combine(Session::$protect, Session::$protect); // Configure garbage collection ini_set('session.gc_probability', (int) Session::$config['gc_probability']); ini_set('session.gc_divisor', 100); ini_set('session.gc_maxlifetime', (Session::$config['expiration'] == 0) ? 86400 : Session::$config['expiration']); // Create a new session $this->create(); if (Session::$config['regenerate'] > 0 AND ($_SESSION['total_hits'] % Session::$config['regenerate']) === 0) { // Regenerate session id and update session cookie $this->regenerate(); } else { // Always update session cookie to keep the session alive cookie::set(Session::$config['name'], $_SESSION['session_id'], Session::$config['expiration']); } // Close the session just before sending the headers, so that // the session cookie(s) can be written. Event::add('system.send_headers', array($this, 'write_close')); // Make sure that sessions are closed before exiting register_shutdown_function(array($this, 'write_close')); // Singleton instance Session::$instance = $this; } Kohana::log('debug', 'Session Library initialized'); } /** * Get the session id. * * @return string */ public function id() { return $_SESSION['session_id']; } /** * Create a new session. * * @param array variables to set after creation * @return void */ public function create($vars = NULL) { // Destroy any current sessions $this->destroy(); if (Session::$config['driver'] !== 'native') { // Set driver name $driver = 'Session_'.ucfirst(Session::$config['driver']).'_Driver'; // Load the driver if ( ! Kohana::auto_load($driver)) throw new Kohana_Exception('core.driver_not_found', Session::$config['driver'], get_class($this)); // Initialize the driver Session::$driver = new $driver(); // Validate the driver if ( ! (Session::$driver instanceof Session_Driver)) throw new Kohana_Exception('core.driver_implements', Session::$config['driver'], get_class($this), 'Session_Driver'); // Register non-native driver as the session handler session_set_save_handler ( array(Session::$driver, 'open'), array(Session::$driver, 'close'), array(Session::$driver, 'read'), array(Session::$driver, 'write'), array(Session::$driver, 'destroy'), array(Session::$driver, 'gc') ); } // Validate the session name if ( ! preg_match('~^(?=.*[a-z])[a-z0-9_]++$~iD', Session::$config['name'])) throw new Kohana_Exception('session.invalid_session_name', Session::$config['name']); // Name the session, this will also be the name of the cookie session_name(Session::$config['name']); // Set the session cookie parameters session_set_cookie_params ( Session::$config['expiration'], Kohana::config('cookie.path'), Kohana::config('cookie.domain'), Kohana::config('cookie.secure'), Kohana::config('cookie.httponly') ); // Start the session! session_start(); // Put session_id in the session variable $_SESSION['session_id'] = session_id(); // Set defaults if ( ! isset($_SESSION['_kf_flash_'])) { $_SESSION['total_hits'] = 0; $_SESSION['_kf_flash_'] = array(); $_SESSION['user_agent'] = Kohana::$user_agent; $_SESSION['ip_address'] = $this->input->ip_address(); } // Set up flash variables Session::$flash =& $_SESSION['_kf_flash_']; // Increase total hits $_SESSION['total_hits'] += 1; // Validate data only on hits after one if ($_SESSION['total_hits'] > 1) { // Validate the session foreach (Session::$config['validate'] as $valid) { switch ($valid) { // Check user agent for consistency case 'user_agent': if ($_SESSION[$valid] !== Kohana::$user_agent) return $this->create(); break; // Check ip address for consistency case 'ip_address': if ($_SESSION[$valid] !== $this->input->$valid()) return $this->create(); break; // Check expiration time to prevent users from manually modifying it case 'expiration': if (time() - $_SESSION['last_activity'] > ini_get('session.gc_maxlifetime')) return $this->create(); break; } } } // Expire flash keys $this->expire_flash(); // Update last activity $_SESSION['last_activity'] = time(); // Set the new data Session::set($vars); } /** * Regenerates the global session id. * * @return void */ public function regenerate() { if (Session::$config['driver'] === 'native') { // Generate a new session id // Note: also sets a new session cookie with the updated id session_regenerate_id(TRUE); // Update session with new id $_SESSION['session_id'] = session_id(); } else { // Pass the regenerating off to the driver in case it wants to do anything special $_SESSION['session_id'] = Session::$driver->regenerate(); } // Get the session name $name = session_name(); if (isset($_COOKIE[$name])) { // Change the cookie value to match the new session id to prevent "lag" $_COOKIE[$name] = $_SESSION['session_id']; } } /** * Destroys the current session. * * @return void */ public function destroy() { if (session_id() !== '') { // Get the session name $name = session_name(); // Destroy the session session_destroy(); // Re-initialize the array $_SESSION = array(); // Delete the session cookie cookie::delete($name); } } /** * Runs the system.session_write event, then calls session_write_close. * * @return void */ public function write_close() { static $run; if ($run === NULL) { $run = TRUE; // Run the events that depend on the session being open Event::run('system.session_write'); // Expire flash keys $this->expire_flash(); // Close the session session_write_close(); } } /** * Set a session variable. * * @param string|array key, or array of values * @param mixed value (if keys is not an array) * @return void */ public function set($keys, $val = FALSE) { if (empty($keys)) return FALSE; if ( ! is_array($keys)) { $keys = array($keys => $val); } foreach ($keys as $key => $val) { if (isset(Session::$protect[$key])) continue; // Set the key $_SESSION[$key] = $val; } } /** * Set a flash variable. * * @param string|array key, or array of values * @param mixed value (if keys is not an array) * @return void */ public function set_flash($keys, $val = FALSE) { if (empty($keys)) return FALSE; if ( ! is_array($keys)) { $keys = array($keys => $val); } foreach ($keys as $key => $val) { if ($key == FALSE) continue; Session::$flash[$key] = 'new'; Session::set($key, $val); } } /** * Freshen one, multiple or all flash variables. * * @param string variable key(s) * @return void */ public function keep_flash($keys = NULL) { $keys = ($keys === NULL) ? array_keys(Session::$flash) : func_get_args(); foreach ($keys as $key) { if (isset(Session::$flash[$key])) { Session::$flash[$key] = 'new'; } } } /** * Expires old flash data and removes it from the session. * * @return void */ public function expire_flash() { static $run; // Method can only be run once if ($run === TRUE) return; if ( ! empty(Session::$flash)) { foreach (Session::$flash as $key => $state) { if ($state === 'old') { // Flash has expired unset(Session::$flash[$key], $_SESSION[$key]); } else { // Flash will expire Session::$flash[$key] = 'old'; } } } // Method has been run $run = TRUE; } /** * Get a variable. Access to sub-arrays is supported with key.subkey. * * @param string variable key * @param mixed default value returned if variable does not exist * @return mixed Variable data if key specified, otherwise array containing all session data. */ public function get($key = FALSE, $default = FALSE) { if (empty($key)) return $_SESSION; $result = isset($_SESSION[$key]) ? $_SESSION[$key] : Kohana::key_string($_SESSION, $key); return ($result === NULL) ? $default : $result; } /** * Get a variable, and delete it. * * @param string variable key * @param mixed default value returned if variable does not exist * @return mixed */ public function get_once($key, $default = FALSE) { $return = Session::get($key, $default); Session::delete($key); return $return; } /** * Delete one or more variables. * * @param string variable key(s) * @return void */ public function delete($keys) { $args = func_get_args(); foreach ($args as $key) { if (isset(Session::$protect[$key])) continue; // Unset the key unset($_SESSION[$key]); } } } // End Session Class ./kohana/system/libraries/Event_Subject.php0000644000175000017500000000262111121324570020550 0ustar tokkeetokkeelisteners[spl_object_hash($obj)] = $obj; return $this; } /** * Detach an observer from the object. * * @chainable * @param object Event_Observer * @return object */ public function detach(SplObserver $obj) { // Remove the listener unset($this->listeners[spl_object_hash($obj)]); return $this; } /** * Notify all attached observers of a new message. * * @chainable * @param mixed message string, object, or array * @return object */ public function notify($message) { foreach ($this->listeners as $obj) { $obj->notify($message); } return $this; } } // End Event Subject./kohana/system/libraries/Image.php0000644000175000017500000002451511156512746017054 0ustar tokkeetokkee 'gif', IMAGETYPE_JPEG => 'jpg', IMAGETYPE_PNG => 'png', IMAGETYPE_TIFF_II => 'tiff', IMAGETYPE_TIFF_MM => 'tiff', ); // Driver instance protected $driver; // Driver actions protected $actions = array(); // Reference to the current image filename protected $image = ''; /** * Creates a new Image instance and returns it. * * @param string filename of image * @param array non-default configurations * @return object */ public static function factory($image, $config = NULL) { return new Image($image, $config); } /** * Creates a new image editor instance. * * @throws Kohana_Exception * @param string filename of image * @param array non-default configurations * @return void */ public function __construct($image, $config = NULL) { static $check; // Make the check exactly once ($check === NULL) and $check = function_exists('getimagesize'); if ($check === FALSE) throw new Kohana_Exception('image.getimagesize_missing'); // Check to make sure the image exists if ( ! is_file($image)) throw new Kohana_Exception('image.file_not_found', $image); // Disable error reporting, to prevent PHP warnings $ER = error_reporting(0); // Fetch the image size and mime type $image_info = getimagesize($image); // Turn on error reporting again error_reporting($ER); // Make sure that the image is readable and valid if ( ! is_array($image_info) OR count($image_info) < 3) throw new Kohana_Exception('image.file_unreadable', $image); // Check to make sure the image type is allowed if ( ! isset(Image::$allowed_types[$image_info[2]])) throw new Kohana_Exception('image.type_not_allowed', $image); // Image has been validated, load it $this->image = array ( 'file' => str_replace('\\', '/', realpath($image)), 'width' => $image_info[0], 'height' => $image_info[1], 'type' => $image_info[2], 'ext' => Image::$allowed_types[$image_info[2]], 'mime' => $image_info['mime'] ); // Load configuration $this->config = (array) $config + Kohana::config('image'); // Set driver class name $driver = 'Image_'.ucfirst($this->config['driver']).'_Driver'; // Load the driver if ( ! Kohana::auto_load($driver)) throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this)); // Initialize the driver $this->driver = new $driver($this->config['params']); // Validate the driver if ( ! ($this->driver instanceof Image_Driver)) throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Image_Driver'); } /** * Handles retrieval of pre-save image properties * * @param string property name * @return mixed */ public function __get($property) { if (isset($this->image[$property])) { return $this->image[$property]; } else { throw new Kohana_Exception('core.invalid_property', $property, get_class($this)); } } /** * Resize an image to a specific width and height. By default, Kohana will * maintain the aspect ratio using the width as the master dimension. If you * wish to use height as master dim, set $image->master_dim = Image::HEIGHT * This method is chainable. * * @throws Kohana_Exception * @param integer width * @param integer height * @param integer one of: Image::NONE, Image::AUTO, Image::WIDTH, Image::HEIGHT * @return object */ public function resize($width, $height, $master = NULL) { if ( ! $this->valid_size('width', $width)) throw new Kohana_Exception('image.invalid_width', $width); if ( ! $this->valid_size('height', $height)) throw new Kohana_Exception('image.invalid_height', $height); if (empty($width) AND empty($height)) throw new Kohana_Exception('image.invalid_dimensions', __FUNCTION__); if ($master === NULL) { // Maintain the aspect ratio by default $master = Image::AUTO; } elseif ( ! $this->valid_size('master', $master)) throw new Kohana_Exception('image.invalid_master'); $this->actions['resize'] = array ( 'width' => $width, 'height' => $height, 'master' => $master, ); return $this; } /** * Crop an image to a specific width and height. You may also set the top * and left offset. * This method is chainable. * * @throws Kohana_Exception * @param integer width * @param integer height * @param integer top offset, pixel value or one of: top, center, bottom * @param integer left offset, pixel value or one of: left, center, right * @return object */ public function crop($width, $height, $top = 'center', $left = 'center') { if ( ! $this->valid_size('width', $width)) throw new Kohana_Exception('image.invalid_width', $width); if ( ! $this->valid_size('height', $height)) throw new Kohana_Exception('image.invalid_height', $height); if ( ! $this->valid_size('top', $top)) throw new Kohana_Exception('image.invalid_top', $top); if ( ! $this->valid_size('left', $left)) throw new Kohana_Exception('image.invalid_left', $left); if (empty($width) AND empty($height)) throw new Kohana_Exception('image.invalid_dimensions', __FUNCTION__); $this->actions['crop'] = array ( 'width' => $width, 'height' => $height, 'top' => $top, 'left' => $left, ); return $this; } /** * Allows rotation of an image by 180 degrees clockwise or counter clockwise. * * @param integer degrees * @return object */ public function rotate($degrees) { $degrees = (int) $degrees; if ($degrees > 180) { do { // Keep subtracting full circles until the degrees have normalized $degrees -= 360; } while($degrees > 180); } if ($degrees < -180) { do { // Keep adding full circles until the degrees have normalized $degrees += 360; } while($degrees < -180); } $this->actions['rotate'] = $degrees; return $this; } /** * Flip an image horizontally or vertically. * * @throws Kohana_Exception * @param integer direction * @return object */ public function flip($direction) { if ($direction !== Image::HORIZONTAL AND $direction !== Image::VERTICAL) throw new Kohana_Exception('image.invalid_flip'); $this->actions['flip'] = $direction; return $this; } /** * Change the quality of an image. * * @param integer quality as a percentage * @return object */ public function quality($amount) { $this->actions['quality'] = max(1, min($amount, 100)); return $this; } /** * Sharpen an image. * * @param integer amount to sharpen, usually ~20 is ideal * @return object */ public function sharpen($amount) { $this->actions['sharpen'] = max(1, min($amount, 100)); return $this; } /** * Save the image to a new image or overwrite this image. * * @throws Kohana_Exception * @param string new image filename * @param integer permissions for new image * @param boolean keep or discard image process actions * @return object */ public function save($new_image = FALSE, $chmod = 0644, $keep_actions = FALSE) { // If no new image is defined, use the current image empty($new_image) and $new_image = $this->image['file']; // Separate the directory and filename $dir = pathinfo($new_image, PATHINFO_DIRNAME); $file = pathinfo($new_image, PATHINFO_BASENAME); // Normalize the path $dir = str_replace('\\', '/', realpath($dir)).'/'; if ( ! is_writable($dir)) throw new Kohana_Exception('image.directory_unwritable', $dir); if ($status = $this->driver->process($this->image, $this->actions, $dir, $file)) { if ($chmod !== FALSE) { // Set permissions chmod($new_image, $chmod); } } // Reset actions. Subsequent save() or render() will not apply previous actions. if ($keep_actions === FALSE) $this->actions = array(); return $status; } /** * Output the image to the browser. * * @param boolean keep or discard image process actions * @return object */ public function render($keep_actions = FALSE) { $new_image = $this->image['file']; // Separate the directory and filename $dir = pathinfo($new_image, PATHINFO_DIRNAME); $file = pathinfo($new_image, PATHINFO_BASENAME); // Normalize the path $dir = str_replace('\\', '/', realpath($dir)).'/'; // Process the image with the driver $status = $this->driver->process($this->image, $this->actions, $dir, $file, $render = TRUE); // Reset actions. Subsequent save() or render() will not apply previous actions. if ($keep_actions === FALSE) $this->actions = array(); return $status; } /** * Sanitize a given value type. * * @param string type of property * @param mixed property value * @return boolean */ protected function valid_size($type, & $value) { if (is_null($value)) return TRUE; if ( ! is_scalar($value)) return FALSE; switch ($type) { case 'width': case 'height': if (is_string($value) AND ! ctype_digit($value)) { // Only numbers and percent signs if ( ! preg_match('/^[0-9]++%$/D', $value)) return FALSE; } else { $value = (int) $value; } break; case 'top': if (is_string($value) AND ! ctype_digit($value)) { if ( ! in_array($value, array('top', 'bottom', 'center'))) return FALSE; } else { $value = (int) $value; } break; case 'left': if (is_string($value) AND ! ctype_digit($value)) { if ( ! in_array($value, array('left', 'right', 'center'))) return FALSE; } else { $value = (int) $value; } break; case 'master': if ($value !== Image::NONE AND $value !== Image::AUTO AND $value !== Image::WIDTH AND $value !== Image::HEIGHT) return FALSE; break; } return TRUE; } } // End Image./kohana/system/libraries/Tagcloud.php0000644000175000017500000000625511123223642017561 0ustar tokkeetokkee 'tag'); public $shuffle = FALSE; // Tag elements, biggest and smallest values protected $elements; protected $biggest; protected $smallest; /** * Construct a new tagcloud. The elements must be passed in as an array, * with each entry in the array having a "title" ,"link", and "count" key. * Font sizes will be applied via the "style" attribute as a percentage. * * @param array elements of the tagcloud * @param integer minimum font size * @param integer maximum font size * @return void */ public function __construct(array $elements, $min_size = NULL, $max_size = NULL, $shuffle = FALSE) { $this->elements = $elements; if($shuffle !== FALSE) { $this->shuffle = TRUE; } $counts = array(); foreach ($elements as $data) { $counts[] = $data['count']; } // Find the biggest and smallest values of the elements $this->biggest = max($counts); $this->smallest = min($counts); if ($min_size !== NULL) { $this->min_size = $min_size; } if ($max_size !== NULL) { $this->max_size = $max_size; } } /** * Magic __toString method. Returns all of the links as a single string. * * @return string */ public function __toString() { return implode("\n", $this->render()); } /** * Renders the elements of the tagcloud into an array of links. * * @return array */ public function render() { if ($this->shuffle === TRUE) { shuffle($this->elements); } // Minimum values must be 1 to prevent divide by zero errors $range = max($this->biggest - $this->smallest, 1); $scale = max($this->max_size - $this->min_size, 1); // Import the attributes locally to prevent overwrites $attr = $this->attributes; $output = array(); foreach ($this->elements as $data) { if (strpos($data['title'], ' ') !== FALSE) { // Replace spaces with non-breaking spaces to prevent line wrapping // in the middle of a link $data['title'] = str_replace(' ', ' ', $data['title']); } // Determine the size based on the min/max scale and the smallest/biggest range $size = ((($data['count'] - $this->smallest) * $scale) / $range) + $this->min_size; $attr['style'] = 'font-size: '.round($size, 0).'%'; $output[] = html::anchor($data['link'], $data['title'], $attr)."\n"; } return $output; } } // End Tagcloud./kohana/system/libraries/Captcha.php0000644000175000017500000001502411156512746017370 0ustar tokkeetokkee 'basic', 'width' => 150, 'height' => 50, 'complexity' => 4, 'background' => '', 'fontpath' => '', 'fonts' => array(), 'promote' => FALSE, ); /** * Singleton instance of Captcha. * * @return object */ public static function instance() { // Create the instance if it does not exist empty(Captcha::$instance) and new Captcha; return Captcha::$instance; } /** * Constructs and returns a new Captcha object. * * @param string config group name * @return object */ public static function factory($group = NULL) { return new Captcha($group); } /** * Constructs a new Captcha object. * * @throws Kohana_Exception * @param string config group name * @return void */ public function __construct($group = NULL) { // Create a singleton instance once empty(Captcha::$instance) and Captcha::$instance = $this; // No config group name given if ( ! is_string($group)) { $group = 'default'; } // Load and validate config group if ( ! is_array($config = Kohana::config('captcha.'.$group))) throw new Kohana_Exception('captcha.undefined_group', $group); // All captcha config groups inherit default config group if ($group !== 'default') { // Load and validate default config group if ( ! is_array($default = Kohana::config('captcha.default'))) throw new Kohana_Exception('captcha.undefined_group', 'default'); // Merge config group with default config group $config += $default; } // Assign config values to the object foreach ($config as $key => $value) { if (array_key_exists($key, Captcha::$config)) { Captcha::$config[$key] = $value; } } // Store the config group name as well, so the drivers can access it Captcha::$config['group'] = $group; // If using a background image, check if it exists if ( ! empty($config['background'])) { Captcha::$config['background'] = str_replace('\\', '/', realpath($config['background'])); if ( ! is_file(Captcha::$config['background'])) throw new Kohana_Exception('captcha.file_not_found', Captcha::$config['background']); } // If using any fonts, check if they exist if ( ! empty($config['fonts'])) { Captcha::$config['fontpath'] = str_replace('\\', '/', realpath($config['fontpath'])).'/'; foreach ($config['fonts'] as $font) { if ( ! is_file(Captcha::$config['fontpath'].$font)) throw new Kohana_Exception('captcha.file_not_found', Captcha::$config['fontpath'].$font); } } // Set driver name $driver = 'Captcha_'.ucfirst($config['style']).'_Driver'; // Load the driver if ( ! Kohana::auto_load($driver)) throw new Kohana_Exception('core.driver_not_found', $config['style'], get_class($this)); // Initialize the driver $this->driver = new $driver; // Validate the driver if ( ! ($this->driver instanceof Captcha_Driver)) throw new Kohana_Exception('core.driver_implements', $config['style'], get_class($this), 'Captcha_Driver'); Kohana::log('debug', 'Captcha Library initialized'); } /** * Validates a Captcha response and updates response counter. * * @param string captcha response * @return boolean */ public static function valid($response) { // Maximum one count per page load static $counted; // User has been promoted, always TRUE and don't count anymore if (Captcha::instance()->promoted()) return TRUE; // Challenge result $result = (bool) Captcha::instance()->driver->valid($response); // Increment response counter if ($counted !== TRUE) { $counted = TRUE; // Valid response if ($result === TRUE) { Captcha::instance()->valid_count(Session::instance()->get('captcha_valid_count') + 1); } // Invalid response else { Captcha::instance()->invalid_count(Session::instance()->get('captcha_invalid_count') + 1); } } return $result; } /** * Gets or sets the number of valid Captcha responses for this session. * * @param integer new counter value * @param boolean trigger invalid counter (for internal use only) * @return integer counter value */ public function valid_count($new_count = NULL, $invalid = FALSE) { // Pick the right session to use $session = ($invalid === TRUE) ? 'captcha_invalid_count' : 'captcha_valid_count'; // Update counter if ($new_count !== NULL) { $new_count = (int) $new_count; // Reset counter = delete session if ($new_count < 1) { Session::instance()->delete($session); } // Set counter to new value else { Session::instance()->set($session, (int) $new_count); } // Return new count return (int) $new_count; } // Return current count return (int) Session::instance()->get($session); } /** * Gets or sets the number of invalid Captcha responses for this session. * * @param integer new counter value * @return integer counter value */ public function invalid_count($new_count = NULL) { return $this->valid_count($new_count, TRUE); } /** * Resets the Captcha response counters and removes the count sessions. * * @return void */ public function reset_count() { $this->valid_count(0); $this->valid_count(0, TRUE); } /** * Checks whether user has been promoted after having given enough valid responses. * * @param integer valid response count threshold * @return boolean */ public function promoted($threshold = NULL) { // Promotion has been disabled if (Captcha::$config['promote'] === FALSE) return FALSE; // Use the config threshold if ($threshold === NULL) { $threshold = Captcha::$config['promote']; } // Compare the valid response count to the threshold return ($this->valid_count() >= $threshold); } /** * Returns or outputs the Captcha challenge. * * @param boolean TRUE to output html, e.g. * @return mixed html string or void */ public function render($html = TRUE) { return $this->driver->render($html); } /** * Magically outputs the Captcha challenge. * * @return mixed */ public function __toString() { return $this->render(); } } // End Captcha Class./kohana/system/libraries/Encrypt.php0000644000175000017500000001032011156512746017443 0ustar tokkeetokkee $size) { // Shorten the key to the maximum size $config['key'] = substr($config['key'], 0, $size); } // Find the initialization vector size $config['iv_size'] = mcrypt_get_iv_size($config['cipher'], $config['mode']); // Cache the config in the object $this->config = $config; Kohana::log('debug', 'Encrypt Library initialized'); } /** * Encrypts a string and returns an encrypted string that can be decoded. * * @param string data to be encrypted * @return string encrypted data */ public function encode($data) { // Set the rand type if it has not already been set if (Encrypt::$rand === NULL) { if (KOHANA_IS_WIN) { // Windows only supports the system random number generator Encrypt::$rand = MCRYPT_RAND; } else { if (defined('MCRYPT_DEV_URANDOM')) { // Use /dev/urandom Encrypt::$rand = MCRYPT_DEV_URANDOM; } elseif (defined('MCRYPT_DEV_RANDOM')) { // Use /dev/random Encrypt::$rand = MCRYPT_DEV_RANDOM; } else { // Use the system random number generator Encrypt::$rand = MCRYPT_RAND; } } } if (Encrypt::$rand === MCRYPT_RAND) { // The system random number generator must always be seeded each // time it is used, or it will not produce true random results mt_srand(); } // Create a random initialization vector of the proper size for the current cipher $iv = mcrypt_create_iv($this->config['iv_size'], Encrypt::$rand); // Encrypt the data using the configured options and generated iv $data = mcrypt_encrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv); // Use base64 encoding to convert to a string return base64_encode($iv.$data); } /** * Decrypts an encoded string back to its original value. * * @param string encoded string to be decrypted * @return string decrypted data */ public function decode($data) { // Convert the data back to binary $data = base64_decode($data); // Extract the initialization vector from the data $iv = substr($data, 0, $this->config['iv_size']); // Remove the iv from the data $data = substr($data, $this->config['iv_size']); // Return the decrypted data, trimming the \0 padding bytes from the end of the data return rtrim(mcrypt_decrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv), "\0"); } } // End Encrypt ./kohana/system/libraries/View.php0000644000175000017500000001626511156512746016747 0ustar tokkeetokkeeset_filename($name, $type); } if (is_array($data) AND ! empty($data)) { // Preload data using array_merge, to allow user extensions $this->kohana_local_data = array_merge($this->kohana_local_data, $data); } } /** * Magic method access to test for view property * * @param string View property to test for * @return boolean */ public function __isset($key = NULL) { return $this->is_set($key); } /** * Sets the view filename. * * @chainable * @param string view filename * @param string view file type * @return object */ public function set_filename($name, $type = NULL) { if ($type == NULL) { // Load the filename and set the content type $this->kohana_filename = Kohana::find_file('views', $name, TRUE); $this->kohana_filetype = EXT; } else { // Check if the filetype is allowed by the configuration if ( ! in_array($type, Kohana::config('view.allowed_filetypes'))) throw new Kohana_Exception('core.invalid_filetype', $type); // Load the filename and set the content type $this->kohana_filename = Kohana::find_file('views', $name, TRUE, $type); $this->kohana_filetype = Kohana::config('mimes.'.$type); if ($this->kohana_filetype == NULL) { // Use the specified type $this->kohana_filetype = $type; } } return $this; } /** * Sets a view variable. * * @param string|array name of variable or an array of variables * @param mixed value when using a named variable * @return object */ public function set($name, $value = NULL) { if (is_array($name)) { foreach ($name as $key => $value) { $this->__set($key, $value); } } else { $this->__set($name, $value); } return $this; } /** * Checks for a property existence in the view locally or globally. Unlike the built in __isset(), * this method can take an array of properties to test simultaneously. * * @param string $key property name to test for * @param array $key array of property names to test for * @return boolean property test result * @return array associative array of keys and boolean test result */ public function is_set( $key = FALSE ) { // Setup result; $result = FALSE; // If key is an array if (is_array($key)) { // Set the result to an array $result = array(); // Foreach key foreach ($key as $property) { // Set the result to an associative array $result[$property] = (array_key_exists($property, $this->kohana_local_data) OR array_key_exists($property, View::$kohana_global_data)) ? TRUE : FALSE; } } else { // Otherwise just check one property $result = (array_key_exists($key, $this->kohana_local_data) OR array_key_exists($key, View::$kohana_global_data)) ? TRUE : FALSE; } // Return the result return $result; } /** * Sets a bound variable by reference. * * @param string name of variable * @param mixed variable to assign by reference * @return object */ public function bind($name, & $var) { $this->kohana_local_data[$name] =& $var; return $this; } /** * Sets a view global variable. * * @param string|array name of variable or an array of variables * @param mixed value when using a named variable * @return void */ public static function set_global($name, $value = NULL) { if (is_array($name)) { foreach ($name as $key => $value) { View::$kohana_global_data[$key] = $value; } } else { View::$kohana_global_data[$name] = $value; } } /** * Magically sets a view variable. * * @param string variable key * @param string variable value * @return void */ public function __set($key, $value) { $this->kohana_local_data[$key] = $value; } /** * Magically gets a view variable. * * @param string variable key * @return mixed variable value if the key is found * @return void if the key is not found */ public function &__get($key) { if (isset($this->kohana_local_data[$key])) return $this->kohana_local_data[$key]; if (isset(View::$kohana_global_data[$key])) return View::$kohana_global_data[$key]; if (isset($this->$key)) return $this->$key; } /** * Magically converts view object to string. * * @return string */ public function __toString() { try { return $this->render(); } catch (Exception $e) { // Display the exception using its internal __toString method return (string) $e; } } /** * Renders a view. * * @param boolean set to TRUE to echo the output instead of returning it * @param callback special renderer to pass the output through * @return string if print is FALSE * @return void if print is TRUE */ public function render($print = FALSE, $renderer = FALSE) { if (empty($this->kohana_filename)) throw new Kohana_Exception('core.view_set_filename'); if (is_string($this->kohana_filetype)) { // Merge global and local data, local overrides global with the same name $data = array_merge(View::$kohana_global_data, $this->kohana_local_data); // Load the view in the controller for access to $this $output = Kohana::$instance->_kohana_load_view($this->kohana_filename, $data); if ($renderer !== FALSE AND is_callable($renderer, TRUE)) { // Pass the output through the user defined renderer $output = call_user_func($renderer, $output); } if ($print === TRUE) { // Display the output echo $output; return; } } else { // Set the content type and size header('Content-Type: '.$this->kohana_filetype[0]); if ($print === TRUE) { if ($file = fopen($this->kohana_filename, 'rb')) { // Display the output fpassthru($file); fclose($file); } return; } // Fetch the file contents $output = file_get_contents($this->kohana_filename); } return $output; } } // End View./kohana/system/libraries/ORM_Tree.php0000644000175000017500000000361111136111240017416 0ustar tokkeetokkeerelated[$column])) { // Load child model $model = ORM::factory(inflector::singular($this->ORM_Tree_children)); if (array_key_exists($this->ORM_Tree_parent_key, $this->object)) { // Find children of this parent $model->where($model->primary_key, $this->object[$this->ORM_Tree_parent_key])->find(); } $this->related[$column] = $model; } return $this->related[$column]; } elseif ($column === 'children') { if (empty($this->related[$column])) { $model = ORM::factory(inflector::singular($this->ORM_Tree_children)); if ($this->ORM_Tree_children === $this->table_name) { // Load children within this table $this->related[$column] = $model ->where($this->ORM_Tree_parent_key, $this->object[$this->primary_key]) ->find_all(); } else { // Find first selection of children $this->related[$column] = $model ->where($this->foreign_key(), $this->object[$this->primary_key]) ->where($this->ORM_Tree_parent_key, NULL) ->find_all(); } } return $this->related[$column]; } return parent::__get($column); } } // End ORM Tree./kohana/system/libraries/Input.php0000644000175000017500000003115011202055577017116 0ustar tokkeetokkeeuse_xss_clean = (bool) Kohana::config('core.global_xss_filtering'); if (Input::$instance === NULL) { // magic_quotes_runtime is enabled if (get_magic_quotes_runtime()) { set_magic_quotes_runtime(0); Kohana::log('debug', 'Disable magic_quotes_runtime! It is evil and deprecated: http://php.net/magic_quotes'); } // magic_quotes_gpc is enabled if (get_magic_quotes_gpc()) { $this->magic_quotes_gpc = TRUE; Kohana::log('debug', 'Disable magic_quotes_gpc! It is evil and deprecated: http://php.net/magic_quotes'); } // register_globals is enabled if (ini_get('register_globals')) { if (isset($_REQUEST['GLOBALS'])) { // Prevent GLOBALS override attacks exit('Global variable overload attack.'); } // Destroy the REQUEST global $_REQUEST = array(); // These globals are standard and should not be removed $preserve = array('GLOBALS', '_REQUEST', '_GET', '_POST', '_FILES', '_COOKIE', '_SERVER', '_ENV', '_SESSION'); // This loop has the same effect as disabling register_globals foreach (array_diff(array_keys($GLOBALS), $preserve) as $key) { global $$key; $$key = NULL; // Unset the global variable unset($GLOBALS[$key], $$key); } // Warn the developer about register globals Kohana::log('debug', 'Disable register_globals! It is evil and deprecated: http://php.net/register_globals'); } if (is_array($_GET)) { foreach ($_GET as $key => $val) { // Sanitize $_GET $_GET[$this->clean_input_keys($key)] = $this->clean_input_data($val); } } else { $_GET = array(); } if (is_array($_POST)) { foreach ($_POST as $key => $val) { // Sanitize $_POST $_POST[$this->clean_input_keys($key)] = $this->clean_input_data($val); } } else { $_POST = array(); } if (is_array($_COOKIE)) { foreach ($_COOKIE as $key => $val) { // Ignore special attributes in RFC2109 compliant cookies if ($key == '$Version' OR $key == '$Path' OR $key == '$Domain') continue; // Sanitize $_COOKIE $_COOKIE[$this->clean_input_keys($key)] = $this->clean_input_data($val); } } else { $_COOKIE = array(); } // Create a singleton Input::$instance = $this; Kohana::log('debug', 'Global GET, POST and COOKIE data sanitized'); } } /** * Fetch an item from the $_GET array. * * @param string key to find * @param mixed default value * @param boolean XSS clean the value * @return mixed */ public function get($key = array(), $default = NULL, $xss_clean = FALSE) { return $this->search_array($_GET, $key, $default, $xss_clean); } /** * Fetch an item from the $_POST array. * * @param string key to find * @param mixed default value * @param boolean XSS clean the value * @return mixed */ public function post($key = array(), $default = NULL, $xss_clean = FALSE) { return $this->search_array($_POST, $key, $default, $xss_clean); } /** * Fetch an item from the $_COOKIE array. * * @param string key to find * @param mixed default value * @param boolean XSS clean the value * @return mixed */ public function cookie($key = array(), $default = NULL, $xss_clean = FALSE) { return $this->search_array($_COOKIE, $key, $default, $xss_clean); } /** * Fetch an item from the $_SERVER array. * * @param string key to find * @param mixed default value * @param boolean XSS clean the value * @return mixed */ public function server($key = array(), $default = NULL, $xss_clean = FALSE) { return $this->search_array($_SERVER, $key, $default, $xss_clean); } /** * Fetch an item from a global array. * * @param array array to search * @param string key to find * @param mixed default value * @param boolean XSS clean the value * @return mixed */ protected function search_array($array, $key, $default = NULL, $xss_clean = FALSE) { if ($key === array()) return $array; if ( ! isset($array[$key])) return $default; // Get the value $value = $array[$key]; if ($this->use_xss_clean === FALSE AND $xss_clean === TRUE) { // XSS clean the value $value = $this->xss_clean($value); } return $value; } /** * Fetch the IP Address. * * @return string */ public function ip_address() { if ($this->ip_address !== NULL) return $this->ip_address; // Server keys that could contain the client IP address $keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'); foreach ($keys as $key) { if ($ip = $this->server($key)) { $this->ip_address = $ip; // An IP address has been found break; } } if ($comma = strrpos($this->ip_address, ',') !== FALSE) { $this->ip_address = substr($this->ip_address, $comma + 1); } if ( ! valid::ip($this->ip_address)) { // Use an empty IP $this->ip_address = '0.0.0.0'; } return $this->ip_address; } /** * Clean cross site scripting exploits from string. * HTMLPurifier may be used if installed, otherwise defaults to built in method. * Note - This function should only be used to deal with data upon submission. * It's not something that should be used for general runtime processing * since it requires a fair amount of processing overhead. * * @param string data to clean * @param string xss_clean method to use ('htmlpurifier' or defaults to built-in method) * @return string */ public function xss_clean($data, $tool = NULL) { if ($tool === NULL) { // Use the default tool $tool = Kohana::config('core.global_xss_filtering'); } if (is_array($data)) { foreach ($data as $key => $val) { $data[$key] = $this->xss_clean($val, $tool); } return $data; } // Do not clean empty strings if (trim($data) === '') return $data; if ($tool === TRUE) { // NOTE: This is necessary because switch is NOT type-sensative! $tool = 'default'; } switch ($tool) { case 'htmlpurifier': /** * @todo License should go here, http://htmlpurifier.org/ */ if ( ! class_exists('HTMLPurifier_Config', FALSE)) { // Load HTMLPurifier require Kohana::find_file('vendor', 'htmlpurifier/HTMLPurifier.auto', TRUE); require 'HTMLPurifier.func.php'; } // Set configuration $config = HTMLPurifier_Config::createDefault(); $config->set('HTML', 'TidyLevel', 'none'); // Only XSS cleaning now // Run HTMLPurifier $data = HTMLPurifier($data, $config); break; default: // http://svn.bitflux.ch/repos/public/popoon/trunk/classes/externalinput.php // +----------------------------------------------------------------------+ // | Copyright (c) 2001-2006 Bitflux GmbH | // +----------------------------------------------------------------------+ // | Licensed under the Apache License, Version 2.0 (the "License"); | // | you may not use this file except in compliance with the License. | // | You may obtain a copy of the License at | // | http://www.apache.org/licenses/LICENSE-2.0 | // | Unless required by applicable law or agreed to in writing, software | // | distributed under the License is distributed on an "AS IS" BASIS, | // | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | // | implied. See the License for the specific language governing | // | permissions and limitations under the License. | // +----------------------------------------------------------------------+ // | Author: Christian Stocker | // +----------------------------------------------------------------------+ // // Kohana Modifications: // * Changed double quotes to single quotes, changed indenting and spacing // * Removed magic_quotes stuff // * Increased regex readability: // * Used delimeters that aren't found in the pattern // * Removed all unneeded escapes // * Deleted U modifiers and swapped greediness where needed // * Increased regex speed: // * Made capturing parentheses non-capturing where possible // * Removed parentheses where possible // * Split up alternation alternatives // * Made some quantifiers possessive // Fix &entity\n; $data = str_replace(array('&','<','>'), array('&amp;','&lt;','&gt;'), $data); $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data); $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data); $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8'); // Remove any attribute starting with "on" or xmlns $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data); // Remove javascript: and vbscript: protocols $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data); $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data); $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data); // Only works in IE: $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data); $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data); $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data); // Remove namespaced elements (we do not need them) $data = preg_replace('#]*+>#i', '', $data); do { // Remove really unwanted tags $old_data = $data; $data = preg_replace('#]*+>#i', '', $data); } while ($old_data !== $data); break; } return $data; } /** * This is a helper method. It enforces W3C specifications for allowed * key name strings, to prevent malicious exploitation. * * @param string string to clean * @return string */ public function clean_input_keys($str) { $chars = PCRE_UNICODE_PROPERTIES ? '\pL' : 'a-zA-Z'; if ( ! preg_match('#^['.$chars.'0-9:_.-]++$#uD', $str)) { exit('Disallowed key characters in global data.'); } return $str; } /** * This is a helper method. It escapes data and forces all newline * characters to "\n". * * @param unknown_type string to clean * @return string */ public function clean_input_data($str) { if (is_array($str)) { $new_array = array(); foreach ($str as $key => $val) { // Recursion! $new_array[$this->clean_input_keys($key)] = $this->clean_input_data($val); } return $new_array; } if ($this->magic_quotes_gpc === TRUE) { // Remove annoying magic quotes $str = stripslashes($str); } if ($this->use_xss_clean === TRUE) { $str = $this->xss_clean($str); } if (strpos($str, "\r") !== FALSE) { // Standardize newlines $str = str_replace(array("\r\n", "\r"), "\n", $str); } return $str; } } // End Input Class ./kohana/system/libraries/ORM.php0000644000175000017500000010147211203316631016451 0ustar tokkeetokkeeobject_name = strtolower(substr(get_class($this), 0, -6)); $this->object_plural = inflector::plural($this->object_name); if (!isset($this->sorting)) { // Default sorting $this->sorting = array($this->primary_key => 'asc'); } // Initialize database $this->__initialize(); // Clear the object $this->clear(); if (is_object($id)) { // Load an object $this->load_values((array) $id); } elseif (!empty($id)) { // Find an object $this->find($id); } } /** * Prepares the model database connection, determines the table name, * and loads column information. * * @return void */ public function __initialize() { if ( ! is_object($this->db)) { // Get database instance $this->db = Database::instance($this->db); } if (empty($this->table_name)) { // Table name is the same as the object name $this->table_name = $this->object_name; if ($this->table_names_plural === TRUE) { // Make the table name plural $this->table_name = inflector::plural($this->table_name); } } if (is_array($this->ignored_columns)) { // Make the ignored columns mirrored = mirrored $this->ignored_columns = array_combine($this->ignored_columns, $this->ignored_columns); } // Load column information $this->reload_columns(); } /** * Allows serialization of only the object data and state, to prevent * "stale" objects being unserialized, which also requires less memory. * * @return array */ public function __sleep() { // Store only information about the object return array('object_name', 'object', 'changed', 'loaded', 'saved', 'sorting'); } /** * Prepares the database connection and reloads the object. * * @return void */ public function __wakeup() { // Initialize database $this->__initialize(); if ($this->reload_on_wakeup === TRUE) { // Reload the object $this->reload(); } } /** * Handles pass-through to database methods. Calls to query methods * (query, get, insert, update) are not allowed. Query builder methods * are chainable. * * @param string method name * @param array method arguments * @return mixed */ public function __call($method, array $args) { if (method_exists($this->db, $method)) { if (in_array($method, array('query', 'get', 'insert', 'update', 'delete'))) throw new Kohana_Exception('orm.query_methods_not_allowed'); // Method has been applied to the database $this->db_applied[$method] = $method; // Number of arguments passed $num_args = count($args); if ($method === 'select' AND $num_args > 3) { // Call select() manually to avoid call_user_func_array $this->db->select($args); } else { // We use switch here to manually call the database methods. This is // done for speed: call_user_func_array can take over 300% longer to // make calls. Most database methods are 4 arguments or less, so this // avoids almost any calls to call_user_func_array. switch ($num_args) { case 0: if (in_array($method, array('open_paren', 'close_paren', 'enable_cache', 'disable_cache'))) { // Should return ORM, not Database $this->db->$method(); } else { // Support for things like reset_select, reset_write, list_tables return $this->db->$method(); } break; case 1: $this->db->$method($args[0]); break; case 2: $this->db->$method($args[0], $args[1]); break; case 3: $this->db->$method($args[0], $args[1], $args[2]); break; case 4: $this->db->$method($args[0], $args[1], $args[2], $args[3]); break; default: // Here comes the snail... call_user_func_array(array($this->db, $method), $args); break; } } return $this; } else { throw new Kohana_Exception('core.invalid_method', $method, get_class($this)); } } /** * Handles retrieval of all model values, relationships, and metadata. * * @param string column name * @return mixed */ public function __get($column) { if (array_key_exists($column, $this->object)) { return $this->object[$column]; } elseif (isset($this->related[$column])) { return $this->related[$column]; } elseif ($column === 'primary_key_value') { return $this->object[$this->primary_key]; } elseif ($model = $this->related_object($column)) { // This handles the has_one and belongs_to relationships if (in_array($model->object_name, $this->belongs_to) OR ! array_key_exists($this->foreign_key($column), $model->object)) { // Foreign key lies in this table (this model belongs_to target model) OR an invalid has_one relationship $where = array($model->table_name.'.'.$model->primary_key => $this->object[$this->foreign_key($column)]); } else { // Foreign key lies in the target table (this model has_one target model) $where = array($this->foreign_key($column, $model->table_name) => $this->primary_key_value); } // one<>alias:one relationship return $this->related[$column] = $model->find($where); } elseif (isset($this->has_many[$column])) { // Load the "middle" model $through = ORM::factory(inflector::singular($this->has_many[$column])); // Load the "end" model $model = ORM::factory(inflector::singular($column)); // Join ON target model's primary key set to 'through' model's foreign key // User-defined foreign keys must be defined in the 'through' model $join_table = $through->table_name; $join_col1 = $through->foreign_key($model->object_name, $join_table); $join_col2 = $model->table_name.'.'.$model->primary_key; // one<>alias:many relationship return $this->related[$column] = $model ->join($join_table, $join_col1, $join_col2) ->where($through->foreign_key($this->object_name, $join_table), $this->object[$this->primary_key]) ->find_all(); } elseif (in_array($column, $this->has_many)) { // one<>many relationship $model = ORM::factory(inflector::singular($column)); return $this->related[$column] = $model ->where($this->foreign_key($column, $model->table_name), $this->object[$this->primary_key]) ->find_all(); } elseif (in_array($column, $this->has_and_belongs_to_many)) { // Load the remote model, always singular $model = ORM::factory(inflector::singular($column)); if ($this->has($model, TRUE)) { // many<>many relationship return $this->related[$column] = $model ->in($model->table_name.'.'.$model->primary_key, $this->changed_relations[$column]) ->find_all(); } else { // empty many<>many relationship return $this->related[$column] = $model ->where($model->table_name.'.'.$model->primary_key, NULL) ->find_all(); } } elseif (isset($this->ignored_columns[$column])) { return NULL; } elseif (in_array($column, array ( 'object_name', 'object_plural', // Object 'primary_key', 'primary_val', 'table_name', 'table_columns', // Table 'loaded', 'saved', // Status 'has_one', 'belongs_to', 'has_many', 'has_and_belongs_to_many', 'load_with' // Relationships ))) { // Model meta information return $this->$column; } else { throw new Kohana_Exception('core.invalid_property', $column, get_class($this)); } } /** * Handles setting of all model values, and tracks changes between values. * * @param string column name * @param mixed column value * @return void */ public function __set($column, $value) { if (isset($this->ignored_columns[$column])) { return NULL; } elseif (isset($this->object[$column]) OR array_key_exists($column, $this->object)) { if (isset($this->table_columns[$column])) { // Data has changed $this->changed[$column] = $column; // Object is no longer saved $this->saved = FALSE; } $this->object[$column] = $this->load_type($column, $value); } elseif (in_array($column, $this->has_and_belongs_to_many) AND is_array($value)) { // Load relations $model = ORM::factory(inflector::singular($column)); if ( ! isset($this->object_relations[$column])) { // Load relations $this->has($model); } // Change the relationships $this->changed_relations[$column] = $value; if (isset($this->related[$column])) { // Force a reload of the relationships unset($this->related[$column]); } } else { throw new Kohana_Exception('core.invalid_property', $column, get_class($this)); } } /** * Checks if object data is set. * * @param string column name * @return boolean */ public function __isset($column) { return (isset($this->object[$column]) OR isset($this->related[$column])); } /** * Unsets object data. * * @param string column name * @return void */ public function __unset($column) { unset($this->object[$column], $this->changed[$column], $this->related[$column]); } /** * Displays the primary key of a model when it is converted to a string. * * @return string */ public function __toString() { return (string) $this->object[$this->primary_key]; } /** * Returns the values of this object as an array. * * @return array */ public function as_array() { $object = array(); foreach ($this->object as $key => $val) { // Reconstruct the array (calls __get) $object[$key] = $this->$key; } return $object; } /** * Binds another one-to-one object to this model. One-to-one objects * can be nested using 'object1:object2' syntax * * @param string $target_path * @return void */ public function with($target_path) { if (isset($this->with_applied[$target_path])) { // Don't join anything already joined return $this; } // Split object parts $objects = explode(':', $target_path); $target = $this; foreach ($objects as $object) { // Go down the line of objects to find the given target $parent = $target; $target = $parent->related_object($object); if ( ! $target) { // Can't find related object return $this; } } $target_name = $object; // Pop-off top object to get the parent object (user:photo:tag becomes user:photo - the parent table prefix) array_pop($objects); $parent_path = implode(':', $objects); if (empty($parent_path)) { // Use this table name itself for the parent object $parent_path = $this->table_name; } else { if( ! isset($this->with_applied[$parent_path])) { // If the parent object hasn't been joined yet, do it first (otherwise LEFT JOINs fail) $this->with($parent_path); } } // Add to with_applied to prevent duplicate joins $this->with_applied[$target_path] = TRUE; // Use the keys of the empty object to determine the columns $select = array_keys($target->object); foreach ($select as $i => $column) { // Add the prefix so that load_result can determine the relationship $select[$i] = $target_path.'.'.$column.' AS '.$target_path.':'.$column; } // Select all of the prefixed keys in the object $this->db->select($select); if (in_array($target->object_name, $parent->belongs_to) OR ! isset($target->object[$parent->foreign_key($target_name)])) { // Parent belongs_to target, use target's primary key as join column $join_col1 = $target->foreign_key(TRUE, $target_path); $join_col2 = $parent->foreign_key($target_name, $parent_path); } else { // Parent has_one target, use parent's primary key as join column $join_col2 = $parent->foreign_key(TRUE, $parent_path); $join_col1 = $parent->foreign_key($target_name, $target_path); } // This allows for models to use different table prefixes (sharing the same database) $join_table = new Database_Expression($target->db->table_prefix().$target->table_name.' AS '.$this->db->table_prefix().$target_path); // Join the related object into the result $this->db->join($join_table, $join_col1, $join_col2, 'LEFT'); return $this; } /** * Finds and loads a single database row into the object. * * @chainable * @param mixed primary key or an array of clauses * @return ORM */ public function find($id = NULL) { if ($id !== NULL) { if (is_array($id)) { // Search for all clauses $this->db->where($id); } else { // Search for a specific column $this->db->where($this->table_name.'.'.$this->unique_key($id), $id); } } return $this->load_result(); } /** * Finds multiple database rows and returns an iterator of the rows found. * * @chainable * @param integer SQL limit * @param integer SQL offset * @return ORM_Iterator */ public function find_all($limit = NULL, $offset = NULL) { if ($limit !== NULL AND ! isset($this->db_applied['limit'])) { // Set limit $this->limit($limit); } if ($offset !== NULL AND ! isset($this->db_applied['offset'])) { // Set offset $this->offset($offset); } return $this->load_result(TRUE); } /** * Creates a key/value array from all of the objects available. Uses find_all * to find the objects. * * @param string key column * @param string value column * @return array */ public function select_list($key = NULL, $val = NULL) { if ($key === NULL) { $key = $this->primary_key; } if ($val === NULL) { $val = $this->primary_val; } // Return a select list from the results return $this->select($key, $val)->find_all()->select_list($key, $val); } /** * Validates the current object. This method should generally be called * via the model, after the $_POST Validation object has been created. * * @param object Validation array * @return boolean */ public function validate(Validation $array, $save = FALSE) { $safe_array = $array->safe_array(); if ( ! $array->submitted()) { foreach ($safe_array as $key => $value) { // Get the value from this object $value = $this->$key; if (is_object($value) AND $value instanceof ORM_Iterator) { // Convert the value to an array of primary keys $value = $value->primary_key_array(); } // Pre-fill data $array[$key] = $value; } } // Validate the array if ($status = $array->validate()) { // Grab only set fields (excludes missing data, unlike safe_array) $fields = $array->as_array(); foreach ($fields as $key => $value) { if (isset($safe_array[$key])) { // Set new data, ignoring any missing fields or fields without rules $this->$key = $value; } } if ($save === TRUE OR is_string($save)) { // Save this object $this->save(); if (is_string($save)) { // Redirect to the saved page url::redirect($save); } } } // Return validation status return $status; } /** * Saves the current object. * * @chainable * @return ORM */ public function save() { if ( ! empty($this->changed)) { $data = array(); foreach ($this->changed as $column) { // Compile changed data $data[$column] = $this->object[$column]; } if ($this->loaded === TRUE) { $query = $this->db ->where($this->primary_key, $this->object[$this->primary_key]) ->update($this->table_name, $data); // Object has been saved $this->saved = TRUE; } else { $query = $this->db ->insert($this->table_name, $data); if ($query->count() > 0) { if (empty($this->object[$this->primary_key])) { // Load the insert id as the primary key $this->object[$this->primary_key] = $query->insert_id(); } // Object is now loaded and saved $this->loaded = $this->saved = TRUE; } } if ($this->saved === TRUE) { // All changes have been saved $this->changed = array(); } } if ($this->saved === TRUE AND ! empty($this->changed_relations)) { foreach ($this->changed_relations as $column => $values) { // All values that were added $added = array_diff($values, $this->object_relations[$column]); // All values that were saved $removed = array_diff($this->object_relations[$column], $values); if (empty($added) AND empty($removed)) { // No need to bother continue; } // Clear related columns unset($this->related[$column]); // Load the model $model = ORM::factory(inflector::singular($column)); if (($join_table = array_search($column, $this->has_and_belongs_to_many)) === FALSE) continue; if (is_int($join_table)) { // No "through" table, load the default JOIN table $join_table = $model->join_table($this->table_name); } // Foreign keys for the join table $object_fk = $this->foreign_key(NULL); $related_fk = $model->foreign_key(NULL); if ( ! empty($added)) { foreach ($added as $id) { // Insert the new relationship $this->db->insert($join_table, array ( $object_fk => $this->object[$this->primary_key], $related_fk => $id, )); } } if ( ! empty($removed)) { $this->db ->where($object_fk, $this->object[$this->primary_key]) ->in($related_fk, $removed) ->delete($join_table); } // Clear all relations for this column unset($this->object_relations[$column], $this->changed_relations[$column]); } } return $this; } /** * Deletes the current object from the database. This does NOT destroy * relationships that have been created with other objects. * * @chainable * @return ORM */ public function delete($id = NULL) { if ($id === NULL AND $this->loaded) { // Use the the primary key value $id = $this->object[$this->primary_key]; } // Delete this object $this->db->where($this->primary_key, $id)->delete($this->table_name); return $this->clear(); } /** * Delete all objects in the associated table. This does NOT destroy * relationships that have been created with other objects. * * @chainable * @param array ids to delete * @return ORM */ public function delete_all($ids = NULL) { if (is_array($ids)) { // Delete only given ids $this->db->in($this->primary_key, $ids); } elseif (is_null($ids)) { // Delete all records $this->db->where('1=1'); } else { // Do nothing - safeguard return $this; } // Delete all objects $this->db->delete($this->table_name); return $this->clear(); } /** * Unloads the current object and clears the status. * * @chainable * @return ORM */ public function clear() { // Create an array with all the columns set to NULL $columns = array_keys($this->table_columns); $values = array_combine($columns, array_fill(0, count($columns), NULL)); // Replace the current object with an empty one $this->load_values($values); return $this; } /** * Reloads the current object from the database. * * @chainable * @return ORM */ public function reload() { return $this->find($this->object[$this->primary_key]); } /** * Reload column definitions. * * @chainable * @param boolean force reloading * @return ORM */ public function reload_columns($force = FALSE) { if ($force === TRUE OR empty($this->table_columns)) { if (isset(ORM::$column_cache[$this->object_name])) { // Use cached column information $this->table_columns = ORM::$column_cache[$this->object_name]; } else { // Load table columns ORM::$column_cache[$this->object_name] = $this->table_columns = $this->list_fields(); } } return $this; } /** * Tests if this object has a relationship to a different model. * * @param object related ORM model * @param boolean check for any relations to given model * @return boolean */ public function has(ORM $model, $any = FALSE) { // Determine plural or singular relation name $related = ($model->table_names_plural === TRUE) ? $model->object_plural : $model->object_name; if (($join_table = array_search($related, $this->has_and_belongs_to_many)) === FALSE) return FALSE; if (is_int($join_table)) { // No "through" table, load the default JOIN table $join_table = $model->join_table($this->table_name); } if ( ! isset($this->object_relations[$related])) { // Load the object relationships $this->changed_relations[$related] = $this->object_relations[$related] = $this->load_relations($join_table, $model); } if ( ! $model->empty_primary_key()) { // Check if a specific object exists return in_array($model->primary_key_value, $this->changed_relations[$related]); } elseif ($any) { // Check if any relations to given model exist return ! empty($this->changed_relations[$related]); } else { return FALSE; } } /** * Adds a new relationship to between this model and another. * * @param object related ORM model * @return boolean */ public function add(ORM $model) { if ($this->has($model)) return TRUE; // Get the faked column name $column = $model->object_plural; // Add the new relation to the update $this->changed_relations[$column][] = $model->primary_key_value; if (isset($this->related[$column])) { // Force a reload of the relationships unset($this->related[$column]); } return TRUE; } /** * Adds a new relationship to between this model and another. * * @param object related ORM model * @return boolean */ public function remove(ORM $model) { if ( ! $this->has($model)) return FALSE; // Get the faked column name $column = $model->object_plural; if (($key = array_search($model->primary_key_value, $this->changed_relations[$column])) === FALSE) return FALSE; // Remove the relationship unset($this->changed_relations[$column][$key]); if (isset($this->related[$column])) { // Force a reload of the relationships unset($this->related[$column]); } return TRUE; } /** * Count the number of records in the table. * * @return integer */ public function count_all() { // Return the total number of records in a table return $this->db->count_records($this->table_name); } /** * Proxy method to Database list_fields. * * @param string table name or NULL to use this table * @return array */ public function list_fields($table = NULL) { if ($table === NULL) { $table = $this->table_name; } // Proxy to database return $this->db->list_fields($table); } /** * Proxy method to Database field_data. * * @param string table name * @return array */ public function field_data($table) { // Proxy to database return $this->db->field_data($table); } /** * Proxy method to Database field_data. * * @chainable * @param string SQL query to clear * @return ORM */ public function clear_cache($sql = NULL) { // Proxy to database $this->db->clear_cache($sql); ORM::$column_cache = array(); return $this; } /** * Returns the unique key for a specific value. This method is expected * to be overloaded in models if the model has other unique columns. * * @param mixed unique value * @return string */ public function unique_key($id) { return $this->primary_key; } /** * Determines the name of a foreign key for a specific table. * * @param string related table name * @param string prefix table name (used for JOINs) * @return string */ public function foreign_key($table = NULL, $prefix_table = NULL) { if ($table === TRUE) { if (is_string($prefix_table)) { // Use prefix table name and this table's PK return $prefix_table.'.'.$this->primary_key; } else { // Return the name of this table's PK return $this->table_name.'.'.$this->primary_key; } } if (is_string($prefix_table)) { // Add a period for prefix_table.column support $prefix_table .= '.'; } if (isset($this->foreign_key[$table])) { // Use the defined foreign key name, no magic here! $foreign_key = $this->foreign_key[$table]; } else { if ( ! is_string($table) OR ! array_key_exists($table.'_'.$this->primary_key, $this->object)) { // Use this table $table = $this->table_name; if (strpos($table, '.') !== FALSE) { // Hack around support for PostgreSQL schemas list ($schema, $table) = explode('.', $table, 2); } if ($this->table_names_plural === TRUE) { // Make the key name singular $table = inflector::singular($table); } } $foreign_key = $table.'_'.$this->primary_key; } return $prefix_table.$foreign_key; } /** * This uses alphabetical comparison to choose the name of the table. * * Example: The joining table of users and roles would be roles_users, * because "r" comes before "u". Joining products and categories would * result in categories_products, because "c" comes before "p". * * Example: zoo > zebra > robber > ocean > angel > aardvark * * @param string table name * @return string */ public function join_table($table) { if ($this->table_name > $table) { $table = $table.'_'.$this->table_name; } else { $table = $this->table_name.'_'.$table; } return $table; } /** * Returns an ORM model for the given object name; * * @param string object name * @return ORM */ protected function related_object($object) { if (isset($this->has_one[$object])) { $object = ORM::factory($this->has_one[$object]); } elseif (isset($this->belongs_to[$object])) { $object = ORM::factory($this->belongs_to[$object]); } elseif (in_array($object, $this->has_one) OR in_array($object, $this->belongs_to)) { $object = ORM::factory($object); } else { return FALSE; } return $object; } /** * Loads an array of values into into the current object. * * @chainable * @param array values to load * @return ORM */ public function load_values(array $values) { if (array_key_exists($this->primary_key, $values)) { // Replace the object and reset the object status $this->object = $this->changed = $this->related = array(); // Set the loaded and saved object status based on the primary key $this->loaded = $this->saved = ($values[$this->primary_key] !== NULL); } // Related objects $related = array(); foreach ($values as $column => $value) { if (strpos($column, ':') === FALSE) { if (isset($this->table_columns[$column])) { // The type of the value can be determined, convert the value $value = $this->load_type($column, $value); } $this->object[$column] = $value; } else { list ($prefix, $column) = explode(':', $column, 2); $related[$prefix][$column] = $value; } } if ( ! empty($related)) { foreach ($related as $object => $values) { // Load the related objects with the values in the result $this->related[$object] = $this->related_object($object)->load_values($values); } } return $this; } /** * Loads a value according to the types defined by the column metadata. * * @param string column name * @param mixed value to load * @return mixed */ protected function load_type($column, $value) { $type = gettype($value); if ($type == 'object' OR $type == 'array' OR ! isset($this->table_columns[$column])) return $value; // Load column data $column = $this->table_columns[$column]; if ($value === NULL AND ! empty($column['null'])) return $value; if ( ! empty($column['binary']) AND ! empty($column['exact']) AND (int) $column['length'] === 1) { // Use boolean for BINARY(1) fields $column['type'] = 'boolean'; } switch ($column['type']) { case 'int': if ($value === '' AND ! empty($column['null'])) { // Forms will only submit strings, so empty integer values must be null $value = NULL; } elseif ((float) $value > PHP_INT_MAX) { // This number cannot be represented by a PHP integer, so we convert it to a string $value = (string) $value; } else { $value = (int) $value; } break; case 'float': $value = (float) $value; break; case 'boolean': $value = (bool) $value; break; case 'string': $value = (string) $value; break; } return $value; } /** * Loads a database result, either as a new object for this model, or as * an iterator for multiple rows. * * @chainable * @param boolean return an iterator or load a single row * @return ORM for single rows * @return ORM_Iterator for multiple rows */ protected function load_result($array = FALSE) { if ($array === FALSE) { // Only fetch 1 record $this->db->limit(1); } if ( ! isset($this->db_applied['select'])) { // Select all columns by default $this->db->select($this->table_name.'.*'); } if ( ! empty($this->load_with)) { foreach ($this->load_with as $alias => $object) { // Join each object into the results if (is_string($alias)) { // Use alias $this->with($alias); } else { // Use object $this->with($object); } } } if ( ! isset($this->db_applied['orderby']) AND ! empty($this->sorting)) { $sorting = array(); foreach ($this->sorting as $column => $direction) { if (strpos($column, '.') === FALSE) { // Keeps sorting working properly when using JOINs on // tables with columns of the same name $column = $this->table_name.'.'.$column; } $sorting[$column] = $direction; } // Apply the user-defined sorting $this->db->orderby($sorting); } // Load the result $result = $this->db->get($this->table_name); if ($array === TRUE) { // Return an iterated result return new ORM_Iterator($this, $result); } if ($result->count() === 1) { // Load object values $this->load_values($result->result(FALSE)->current()); } else { // Clear the object, nothing was found $this->clear(); } return $this; } /** * Return an array of all the primary keys of the related table. * * @param string table name * @param object ORM model to find relations of * @return array */ protected function load_relations($table, ORM $model) { // Save the current query chain (otherwise the next call will clash) $this->db->push(); $query = $this->db ->select($model->foreign_key(NULL).' AS id') ->from($table) ->where($this->foreign_key(NULL, $table), $this->object[$this->primary_key]) ->get() ->result(TRUE); $this->db->pop(); $relations = array(); foreach ($query as $row) { $relations[] = $row->id; } return $relations; } /** * Returns whether or not primary key is empty * * @return bool */ protected function empty_primary_key() { return (empty($this->object[$this->primary_key]) AND $this->object[$this->primary_key] !== '0'); } } // End ORM ./kohana/system/i18n/0000755000175000017500000000000011263472435014114 5ustar tokkeetokkee./kohana/system/i18n/it_IT/0000755000175000017500000000000011263472435015124 5ustar tokkeetokkee./kohana/system/i18n/it_IT/encrypt.php0000644000175000017500000000057711121324570017317 0ustar tokkeetokkee 'Il gruppo %s non è definito nel file di configurazione.', 'requires_mcrypt' => 'L\'uso della libreria Encrypt richiede l\'abilitazione di mcrypt.', 'no_encryption_key' => 'Per usare la libreria Encrypt bisogna definire una chiave di codifica nel file di configurazione.' ); ./kohana/system/i18n/it_IT/database.php0000644000175000017500000000160111121324570017364 0ustar tokkeetokkee 'Il gruppo %s non è stato definito nel file di configurazione.', 'error' => 'Si è verificato un errore SQL: %s', 'connection' => 'Si è verificato un errore durante la connessione al database: %s', 'invalid_dsn' => 'Il DSN fornito non è valido: %s', 'must_use_set' => 'È necessario definire una clausola SET per la query.', 'must_use_where' => 'È necessario definire una clausola WHERE per la query.', 'must_use_table' => 'È necessario definire una tabella per la query.', 'table_not_found' => 'La tabella %s non esiste nella base di dati.', 'not_implemented' => 'Il metodo chiamato, %s, non è supportato da questo driver.', 'result_read_only' => 'Il risultato della query è in sola lettura.', );./kohana/system/i18n/it_IT/profiler.php0000644000175000017500000000101411121324570017440 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Dati postati', 'no_post' => 'Non ci sono dati postati', 'session_data' => 'Dati di sessione', 'no_session' => 'Non ci sono dati di sessione', 'queries' => 'Query al database', 'no_queries' => 'Non ci sono query al database', 'no_database' => 'Database non caricato', 'cookie_data' => 'Dati del cookie', 'no_cookie' => 'I dati del cookie non sono stati trovati', ); ./kohana/system/i18n/it_IT/errors.php0000644000175000017500000000227711121324570017146 0ustar tokkeetokkee array( 1, 'Errore del Framework', 'Controlla la documentazione di Kohana per informazioni circa il seguente errore.'), E_PAGE_NOT_FOUND => array( 1, 'Pagina non trovata', 'La pagina richiesta non è stata trovata. Potrebbe essere stata spostata, rimossa o archiviata.'), E_DATABASE_ERROR => array( 1, 'Errore del Database', 'Si è verificato un errore durante l\'esecuzione della procedura richiesta. Per maggiori informazioni fare riferimento al messaggio sottostante.'), E_RECOVERABLE_ERROR => array( 1, 'Errore Recuperabile', 'Un errore ha impedito il caricamento della pagina. Se l\'errore persiste contattare l\'amministratore del sito.'), E_ERROR => array( 1, 'Errore Fatale', ''), E_USER_ERROR => array( 1, 'Errore Fatale', ''), E_PARSE => array( 1, 'Errore di Sintassi', ''), E_WARNING => array( 1, 'Avviso', ''), E_USER_WARNING => array( 1, 'Avviso', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/it_IT/cache.php0000644000175000017500000000075111121324570016670 0ustar tokkeetokkee 'Il gruppo %s non è stato definito in configurazione.', 'extension_not_loaded' => 'L\'estensione di PHP %s deve essere caricata per poter usare questo driver.', 'unwritable' => 'La cartella di deposito, %s, non ha i permessi in scrittura.', 'resources' => 'Risorsa non serializzabile. Impossibile immagazzinare.', 'driver_error' => '%s', );./kohana/system/i18n/it_IT/swift.php0000644000175000017500000000026711121324570016763 0ustar tokkeetokkee 'Si è verificato un errore durante l\'invio del messaggio di posta elettronica.' );./kohana/system/i18n/it_IT/core.php0000644000175000017500000000405611121324570016557 0ustar tokkeetokkee 'Ci può essere una sola istanza di Kohana per ogni pagina richiesta.', 'uncaught_exception' => 'Uncaught %s: %s in %s, linea %s', 'invalid_method' => 'Metodo non valido %s chiamato in %s.', 'invalid_property' => 'La proprietà %s non esiste nella classe %s.', 'log_dir_unwritable' => 'Il parametro di configurazione log.directory non punta ad una cartella con permesso di scrittura.', 'resource_not_found' => 'Il %s richiesto, %s, non è stato trovato.', 'invalid_filetype' => 'Il tipo di file richiesto, .%s, non è presente nel file di configurazione.', 'view_set_filename' => 'Bisogna definire il nome di una vista prima di chiamare il metodo render', 'no_default_route' => 'Non è stato definito il default route in config/routes.php.', 'no_controller' => 'Kohana non è in grado di determinare a quale controller inoltrare la richiesta: %s', 'page_not_found' => 'La pagina richiesta, %s, non è stata trovata.', 'stats_footer' => 'Caricato in {execution_time} secondi, usando {memory_usage} di memoria. Generato da Kohana v{kohana_version}.', 'error_file_line' => 'Errore in %s linea: %s.', 'stack_trace' => 'Tracciato', 'generic_error' => 'Impossibile completare la richiesta', 'errors_disabled' => 'Puoi andare alla pagina iniziale o ritentare.', // Drivers 'driver_implements' => 'Il driver %s per la libreria %s non implementa l\'interfaccia %s', 'driver_not_found' => 'Il driver %s per la libreria %s non è stato trovato', // Resource names 'config' => 'file di configurazione', 'controller' => 'controller', 'helper' => 'helper', 'library' => 'libreria', 'driver' => 'driver', 'model' => 'modello', 'view' => 'vista', ); ./kohana/system/i18n/it_IT/captcha.php0000644000175000017500000000262011121324570017225 0ustar tokkeetokkee 'Il file specificato, %s, non è stato trovato. Verificarne l\'esistenza con file_exists prima di usarlo.', 'requires_GD2' => 'La libreria Captcha richiede GD2 con supporto FreeType. Leggere http://php.net/gd_info per maggiori informazioni.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Detesti lo spam? (si o no)', 'si'), array('Sei un robot? (si o no)', 'no'), array('Il fuoco è... (caldo o freddo)', 'caldo'), array('La stagione che viene dopo l\'autunno è...', 'inverno'), array('Che giorno della settimana è oggi?', strftime('%A')), array('In quale mese dell\'anno siamo?', strftime('%B')), ), ); ./kohana/system/i18n/it_IT/validation.php0000644000175000017500000000433211121324570017756 0ustar tokkeetokkee 'Regola di validazione usata non valida: %s', 'i18n_array' => 'Il parametro i18n %s deve essere un array per essere utilizzato con la regola in_lang', 'not_callable' => 'La callback %s usata per la Validation non puo essere richiamata', // Errori generici 'unknown_error' => 'Errore sconosciuto durante la validazione del campo %s.', 'required' => 'Il campo %s è obbligatorio.', 'min_length' => 'Il campo %s deve essere lungo almeno %d caratteri.', 'max_length' => 'Il campo %s non deve superare i %d caratteri.', 'exact_length' => 'Il campo %s deve contenere esattamente %d caratteri.', 'in_array' => 'Il campo %s deve essere selezionato dalla lista delle opzioni.', 'matches' => 'Il campo %s deve coincidere con il campo %s.', 'valid_url' => 'Il campo %s deve contenere un URL valido.', 'valid_email' => 'Il campo %s deve contenere un indirizzo email valido.', 'valid_ip' => 'Il campo %s deve contenere un indirizzo IP valido.', 'valid_type' => 'Il campo %s deve contenere solo i caratteri %s.', 'range' => 'Il campo %s deve trovarsi negli intervalli specificati.', 'regex' => 'Il campo %s non coincide con i dati accettati.', 'depends_on' => 'Il campo %s dipende dal campo %s.', // Errori di upload 'user_aborted' => 'Il caricamento del file %s è stato interrotto.', 'invalid_type' => 'Il file %s non è un tipo di file permesso.', 'max_size' => 'Il file %s inviato è troppo grande. La dimensone massima consentita è %s.', 'max_width' => 'Il file %s inviato è troppo grande. La larghezza massima consentita è %spx.', 'max_height' => 'Il file %s inviato è troppo grande. L\'altezza massima consentita è %spx.', 'min_width' => 'Il file %s inviato è troppo piccolo. La larghezza minima consentita è %spx.', 'min_height' => 'Il file %s inviato è troppo piccolo. L\'altezza minima consentita è %spx.', // Tipi di valore dei campi 'alpha' => 'alfabetico', 'alpha_numeric' => 'alfanumerico', 'alpha_dash' => 'alfabetico, trattino e sottolineato', 'digit' => 'cifra', 'numeric' => 'numerico', ); ./kohana/system/i18n/it_IT/pagination.php0000644000175000017500000000074411121324570017760 0ustar tokkeetokkee 'Il gruppo %s non è stato definito nel file di configurazione per la paginazione.', 'page' => 'pagina', 'pages' => 'pagine', 'item' => 'elemento', 'items' => 'elementi', 'of' => 'di', 'first' => 'primo', 'last' => 'ultimo', 'previous' => 'precedente', 'next' => 'successivo', ); ./kohana/system/i18n/it_IT/calendar.php0000644000175000017500000000241611121324570017376 0ustar tokkeetokkee 'Do', 'mo' => 'Lu', 'tu' => 'Ma', 'we' => 'Me', 'th' => 'Gi', 'fr' => 'Ve', 'sa' => 'Sa', // Short day names 'sun' => 'Dom', 'mon' => 'Lun', 'tue' => 'Mar', 'wed' => 'Mer', 'thu' => 'Gio', 'fri' => 'Ven', 'sat' => 'Sab', // Long day names 'sunday' => 'Domenica', 'monday' => 'Lunedì', 'tuesday' => 'Martedì', 'wednesday' => 'Mercoledì', 'thursday' => 'Giovedì', 'friday' => 'Venerdì', 'saturday' => 'Sabato', // Short month names 'jan' => 'Gen', 'feb' => 'Feb', 'mar' => 'Mar', 'apr' => 'Apr', 'may' => 'Mag', 'jun' => 'Giu', 'jul' => 'Lug', 'aug' => 'Ago', 'sep' => 'Set', 'oct' => 'Ott', 'nov' => 'Nov', 'dec' => 'Dic', // Long month names 'january' => 'Gennaio', 'february' => 'Febbraio', 'march' => 'Marzo', 'april' => 'Aprile', 'mayl' => 'Maggio', 'june' => 'Giugno', 'july' => 'Luglio', 'august' => 'Agosto', 'september' => 'Settembre', 'october' => 'Ottobre', 'november' => 'Novembre', 'december' => 'Dicembre' );./kohana/system/i18n/it_IT/orm.php0000644000175000017500000000024211121324570016415 0ustar tokkeetokkee 'La cartella di destinazione, %s, non sembra avere i permessi in scrittura.', ); ./kohana/system/i18n/it_IT/event.php0000644000175000017500000000063111121324570016743 0ustar tokkeetokkee 'Fallito il tentativo di aggiungere il soggetto %s a %s. I soggetti devono estendere la classe Event_Subject.', 'invalid_observer' => 'Fallito il tentativo di aggiungere l\'observer %s a %s. Gli observer devono estendere la classe Event_Observer.', ); ./kohana/system/i18n/it_IT/session.php0000644000175000017500000000040711121324570017306 0ustar tokkeetokkee 'Il parametro session_name, %s, non è valido. Può contenere solo caratteri alfanumerici o il trattino basso. Almeno una lettera deve essere presente.', ); ./kohana/system/i18n/it_IT/image.php0000644000175000017500000000310011121324570016676 0ustar tokkeetokkee 'La libreria Image richiede la funzione PHP getimagesize, che non è disponibile nella tua intallazione.', 'unsupported_method' => 'Il driver impostato in configurazione non supporta il tipo di trasformazione %s.', 'file_not_found' => 'L\'immagine specificata, %s, non è stata trovata. Verificarne l\'esistenza con file_exists prima di manipolarla.', 'type_not_allowed' => 'Il tipo d\'immagine specificato, %s, non è permesso.', 'invalid_width' => 'La larghezza specificata, %s, non è valida.', 'invalid_height' => 'L\'altezza specificata, %s, non è valida.', 'invalid_dimensions' => 'Le dimensioni specificate per %s non sono valide.', 'invalid_master' => 'Master dimension specificato non valido.', 'invalid_flip' => 'La direzione di rotazione specificata non è valida.', 'directory_unwritable' => 'La directory specificata, %s, non consente la scrittura.', // Messaggi specifici per ImageMagick 'imagemagick' => array ( 'not_found' => 'La cartella di ImageMagick specificata non contiene il programma richiesto, %s.', ), // Messaggi specifici per GraphicsMagick 'graphicsmagick' => array ( 'not_found' => 'La cartella di GraphicsMagick specificata non contiene il programma richiesto, %s.', ), // Messaggi specifici per GD 'gd' => array ( 'requires_v2' => 'La libreria Image richiede GD2. Leggere http://php.net/gd_info per maggiori informazioni.', ), ); ./kohana/system/i18n/zh_CN/0000755000175000017500000000000011263472434015114 5ustar tokkeetokkee./kohana/system/i18n/zh_CN/encrypt.php0000644000175000017500000000051111177434177017314 0ustar tokkeetokkee '配置没有定义 %s 组。', 'requires_mcrypt' => '使用加密(Encrypt)库,必须在 PHP 中开启 mcrypt', 'no_encryption_key' => '使用加密(Encrypt)库, 必须在配置文件中设定加密关键字' ); ./kohana/system/i18n/zh_CN/database.php0000644000175000017500000000121311177434177017374 0ustar tokkeetokkee '配置未定义 %s 组。', 'error' => 'SQL 错误:%s', 'connection' => '连接数据库失败:%s', 'invalid_dsn' => 'DSN 不是有效的:%s', 'must_use_set' => '缺少 SET 语句。', 'must_use_where' => '缺少 WHERE 语句。', 'must_use_table' => '数据库表未赋值。', 'table_not_found' => '数据库不存在表 %s。', 'not_implemented' => '驱动不支持你调用的方法,%s。', 'result_read_only' => '查询结果仅为只读。' );./kohana/system/i18n/zh_CN/profiler.php0000644000175000017500000000071411177434177017457 0ustar tokkeetokkee '基准测试', 'post_data' => 'Post 数据', 'no_post' => '无 Post 数据', 'session_data' => 'Session 数据', 'no_session' => '无 Session 数据', 'queries' => '数据库查询', 'no_queries' => '无查询语句', 'no_database' => '数据库未加载', 'cookie_data' => 'Cookie 数据', 'no_cookie' => '无 Cookie 数据', ); ./kohana/system/i18n/zh_CN/errors.php0000644000175000017500000000204411177434177017147 0ustar tokkeetokkee array( 1, '框架错误', '请根据下面的相关错误查阅 Kohana 文档。'), E_PAGE_NOT_FOUND => array( 1, '页面不存在', '请求页面不存在。或许它被转移,删除或存档。'), E_DATABASE_ERROR => array( 1, '数据库错误', '数据库在执行程序时出现错误。请从下面的错误信息检查数据库错误。'), E_RECOVERABLE_ERROR => array( 1, '可回收错误', '发生错误在加载此页面时。如果这个问题仍然存在,请联系网站管理员。'), E_ERROR => array( 1, '致命错误', ''), E_USER_ERROR => array( 1, '致命错误', ''), E_PARSE => array( 1, '语法错误', ''), E_WARNING => array( 1, '警告消息', ''), E_USER_WARNING => array( 1, '警告消息', ''), E_STRICT => array( 2, '严格(标准)模式错误', ''), E_NOTICE => array( 2, '运行信息', ''), );./kohana/system/i18n/zh_CN/cache.php0000644000175000017500000000053111177434177016675 0ustar tokkeetokkee '配置未定义 %s 组。', 'extension_not_loaded' => 'PHP %s 扩展必须使用这个驱动加载。', 'unwritable' => '配置的储存地址不可写:%s。', 'resources' => '资源无法缓存,因为资源没有被序列化。', 'driver_error' => '%s', );./kohana/system/i18n/zh_CN/swift.php0000644000175000017500000000012411177434177016764 0ustar tokkeetokkee '发送邮件过程中发生错误。' );./kohana/system/i18n/zh_CN/core.php0000644000175000017500000000335111177434177016565 0ustar tokkeetokkee '每个请求页面只允许一个 Kohana 的实例化', 'uncaught_exception' => '未捕获 %s 异常:%s 于文件 %s 的行 %s', 'invalid_method' => '无效方法 %s 调用于 %s', 'invalid_property' => '属性 %s 不存在于 %s 类中。', 'log_dir_unwritable' => '日志目录不可写:%s', 'resource_not_found' => '请求的 %s,%s,不存在', 'invalid_filetype' => '在视图配置文件内请求的文件类型,.%s,不允许', 'view_set_filename' => '在调用 render 之前您必须设置视图文件名', 'no_default_route' => '请在 config/routes.php 文件设置默认的路由参数值', 'no_controller' => 'Kohana 没有找到处理该请求的控制器:%s', 'page_not_found' => '您请求的页面 %s,不存在。', 'stats_footer' => '页面加载 {execution_time} 秒,使用内存 {memory_usage}。程序生成 Kohana v{kohana_version}。', 'error_file_line' => '%s [%s]:', 'stack_trace' => '堆栈跟踪', 'generic_error' => '无法完成请求', 'errors_disabled' => '您可以返回首页或者重新尝试。', // 驱动 'driver_implements' => '类 %s 的 %s 驱动必须继承 %s 接口', 'driver_not_found' => '类 %s 的 %s 驱动没有发现', // 资源名称 'config' => '配置文件', 'controller' => '控制器', 'helper' => '辅助函数', 'library' => '库', 'driver' => '驱动', 'model' => '模型', 'view' => '视图', );./kohana/system/i18n/zh_CN/captcha.php0000644000175000017500000000247411177434177017245 0ustar tokkeetokkee '指定文件 %s 不存在。请在使用之前使用 file_exists() 方法确认文件是否存在。', 'requires_GD2' => '验证码(Captcha)库需要带 FreeType 的 GD2 支持。详情请看 http://php.net/gd_info 。', // 为 Captcha_Word_Driver 选择不同长度的字符 // 注意:仅使用字母字符时 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // 为 Captcha_Word_Driver 选择不同的谜语 // 注意:仅使用字母字符时 'riddles' => array ( array('请问你是否讨厌垃圾留言(SPAM)吗?(是或否)', '是'), array('你是机器人吗?(是或否)', '否'), array('火是... (热的 还是 冷的)', '热'), array('秋季之后是什么季节?', '冬季'), array('今天是这周的哪一天?', strftime('%A')), array('现在是几月份?', strftime('%B')), ), ); ./kohana/system/i18n/zh_CN/validation.php0000644000175000017500000000346311177434177017773 0ustar tokkeetokkee '无效的规则:%s', 'i18n_array' => 'i18n 键 %s 必须遵循 in_lang 规则且为数组形式', 'not_callable' => '校验(Validation)的回调 %s 不可调用', // 通常错误 'unknown_error' => '验证字段 %s 时,发生未知错误。', 'required' => '字段 %s 必填。', 'min_length' => '字段 %s 最少 %d 字符。', 'max_length' => '字段 %s 最多 %d 字符。', 'exact_length' => '字段 %s 必须包含 %d 字符。', 'in_array' => '字段 %s 必须选中下拉列表的选项。', 'matches' => '字段 %s 必须与 %s 字段一致。', 'valid_url' => '字段 %s 必须包含有效的 URL。', 'valid_email' => '字段 %s 无效 Email 地址格式。', 'valid_ip' => '字段 %s 无效 IP 地址。', 'valid_type' => '字段 %s 只可以包含 %s 字符。', 'range' => '字段 %s 越界指定范围。', 'regex' => '字段 %s 与给定输入模式不匹配。', 'depends_on' => '字段 %s 依赖于 %s 栏位。', // 上传错误 'user_aborted' => '文件 %s 上传过程中被中断。', 'invalid_type' => '文件 %s 非法文件格式。', 'max_size' => '文件 %s 超出最大允许范围. 最大文件大小 %s。', 'max_width' => '文件 %s 的最大允许宽度 %s 是 %spx。', 'max_height' => '文件 %s 的最大允许高度 %s 是 %spx。', 'min_width' => '文件 %s 太小,最小文件宽度大小 %spx。', 'min_height' => '文件 %s 太小,最小文件高度大小 %spx。', // 字段类型 'alpha' => '字母', 'alpha_numeric' => '字母和数字', 'alpha_dash' => '字母,破折号和下划线', 'digit' => '数字', 'numeric' => '数字', ); ./kohana/system/i18n/zh_CN/pagination.php0000644000175000017500000000054111177434177017764 0ustar tokkeetokkee '分页配置中未定义组:%s。', 'page' => '页', 'pages' => '页', 'item' => '条', 'items' => '条', 'of' => ' / ', 'first' => '首页', 'last' => '末页', 'previous' => '前页', 'next' => '后页', ); ./kohana/system/i18n/zh_CN/calendar.php0000644000175000017500000000265511177434177017414 0ustar tokkeetokkee '日', 'mo' => '一', 'tu' => '二', 'we' => '三', 'th' => '四', 'fr' => '五', 'sa' => '六', // 相对英文来说显示短字母天数名 'sun' => '日', 'mon' => '一', 'tue' => '二', 'wed' => '三', 'thu' => '四', 'fri' => '五', 'sat' => '六', // 相对英文来说显示长字母的天数名 'sunday' => '星期天', 'monday' => '星期一', 'tuesday' => '星期二', 'wednesday' => '星期三', 'thursday' => '星期四', 'friday' => '星期五', 'saturday' => '星期六', // 相对英文来说显示短字母的月份名 'jan' => '一', 'feb' => '二', 'mar' => '三', 'apr' => '四', 'may' => '五', 'jun' => '六', 'jul' => '七', 'aug' => '八', 'sep' => '九', 'oct' => '十', 'nov' => '十一', 'dec' => '十二', // 相对英文来说显示长字母的月份名 'january' => '一月', 'february' => '二月', 'march' => '三月', 'april' => '四月', 'mayl' => '五月', 'june' => '六月', 'july' => '七月', 'august' => '八月', 'september' => '九月', 'october' => '十月', 'november' => '十一', 'december' => '十二' );./kohana/system/i18n/zh_CN/orm.php0000644000175000017500000000011711177434177016427 0ustar tokkeetokkee '上传的目标文件夹似乎没有写入权限:%s。', );./kohana/system/i18n/zh_CN/event.php0000644000175000017500000000040311177434177016751 0ustar tokkeetokkee '尝试加入无效的 subject %s 到 %s 失败:Subjects 必须继承 Event_Subject 类', 'invalid_observer' => '尝试加入无效的 observer %s 到 %s 失败:Observers 必须继承 Event_Observer 类', ); ./kohana/system/i18n/zh_CN/session.php0000644000175000017500000000034411177434177017317 0ustar tokkeetokkee '无效的 Session 名:%s。只能包含字母,数字和下划线。此外,至少还需要一个字母存在。', );./kohana/system/i18n/zh_CN/image.php0000644000175000017500000000226011177434177016715 0ustar tokkeetokkee '图像库需求 getimagesize() PHP 函数且在 PHP 配置文件没有激活。', 'unsupported_method' => '配置驱动不支持 %s 图片转变。', 'file_not_found' => '指定图片 %s 没有发现。在使用之前请使用 file_exists() 确认文件是否存在。', 'type_not_allowed' => '指定图片 %s 为不允许图片类型。', 'invalid_width' => '无效的宽度,%s。', 'invalid_height' => '无效的高度,%s。', 'invalid_dimensions' => '无效的 dimensions,%s。', 'invalid_master' => '无效的 master dimension。', 'invalid_flip' => '无效的 flip direction。', 'directory_unwritable' => '指定的目录(文件夹)不可写,%s。', // ImageMagick 信息 'imagemagick' => array ( 'not_found' => '指定的 ImageMagick 目录不包含在程序中,%s。', ), // GraphicsMagick 信息 'graphicsmagick' => array ( 'not_found' => '指定的 GraphicsMagick 目录不包含在程序中,%s。', ), // GD 信息 'gd' => array ( 'requires_v2' => '图片库需求 GD2。详情请看 http://php.net/gd_info 。', ), ); ./kohana/system/i18n/mk_MK/0000755000175000017500000000000011263472435015112 5ustar tokkeetokkee./kohana/system/i18n/mk_MK/encrypt.php0000644000175000017500000000057011121324570017276 0ustar tokkeetokkee 'За користење на библиотеката Encrypt, mcrypt мора да постои.', 'no_encryption_key' => 'За користење на библиотеката Encrypt, мора да напишете encryption key во config датотеката.' ); ./kohana/system/i18n/mk_MK/database.php0000644000175000017500000000220511121324570017353 0ustar tokkeetokkee 'Групата %s не е дефинирана во оваа конфигурација.', 'error' => 'Се појави SQL грешка: %s', 'connection' => 'Грешка при конектирање со датабазата: %s', 'invalid_dsn' => 'DSN-от кој го имате напишано не е валиден: %s', 'must_use_set' => 'Мора да напишете SET услов во ова query.', 'must_use_where' => 'Мора да напишете WHERE услов во ова query.', 'must_use_table' => 'Мора да ја напишете табелата во датабазата во ова query.', 'table_not_found' => 'Табелата %s не постои во базата на податоци.', 'not_implemented' => 'Повиканата метода, %s, не е поддржана од овој драјвер.', 'result_read_only' => 'Query резултатите можат само да се читаат (read only).' );./kohana/system/i18n/mk_MK/profiler.php0000644000175000017500000000072611121324570017437 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Post Data', 'no_post' => 'No post data', 'session_data' => 'Session Data', 'no_session' => 'No session data', 'queries' => 'Database Queries', 'no_queries' => 'No queries', 'no_database' => 'Датабазата не е вчитана', 'cookie_data' => 'Cookie Data', 'no_cookie' => 'Нема cookie data', ); ./kohana/system/i18n/mk_MK/errors.php0000644000175000017500000000272011121324570017125 0ustar tokkeetokkee array( 1, 'Framework Error', 'Проверете во документацијата на Kohana во врска со следната грешка.'), E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'Страната не е пронајдена. Можеби е преместена, избришана или архивирана.'), E_DATABASE_ERROR => array( 1, 'Database Error', 'Се појави грешка во базата на податоци при извршување на побараната процедура. За повеќе информации, прегледајте ја грешката опишана доле.'), E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Се појави грешка кое го прекина вчитувањето на оваа страна. Ако овој проблем перзистира, контактирајте со веб администраторот.'), E_ERROR => array( 1, 'Fatal Error', ''), E_USER_ERROR => array( 1, 'Fatal Error', ''), E_PARSE => array( 1, 'Syntax Error', ''), E_WARNING => array( 1, 'Warning Message', ''), E_USER_WARNING => array( 1, 'Warning Message', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/mk_MK/cache.php0000644000175000017500000000133311121324570016653 0ustar tokkeetokkee 'Групата %s не е дефинирана во конфигурацијата.', 'extension_not_loaded' => 'PHP екстензијата %s мора да биде вчитана ако го користите овој драјвер.', 'unwritable' => 'Во конфигурираната локација за кеширање, %s, не може да се запишува.', 'resources' => 'Кеширање на ресурсите е невозможно, бидејќи ресурсите не можат да се серијализираат.', 'driver_error' => '%s', );./kohana/system/i18n/mk_MK/swift.php0000644000175000017500000000030211121324570016737 0ustar tokkeetokkee 'Се појави грешка при испраќање на емаил пораката.' );./kohana/system/i18n/mk_MK/core.php0000644000175000017500000000464511121324570016551 0ustar tokkeetokkee 'Може да има само една инстанца на Kohana при еден циклус.', 'uncaught_exception' => 'Uncaught %s: %s во датотека %s, линија %s', 'invalid_method' => 'Повикана е погрешна метода %s во %s.', 'log_dir_unwritable' => 'Твојот log.directory config елемент не поинтира во директориум во кој може да се пишува.', 'resource_not_found' => 'Побараниот %s, %s, не е пронајден.', 'invalid_filetype' => 'Побараниот тип на датотека, .%s, не е дозволен во view конфигурационата датотека.', 'no_default_route' => 'Подесете ја default рутата во config/routes.php.', 'view_set_filename' => 'Мора да се сетира view датотеката пред са се повикува render', 'no_controller' => 'Kohana не пронајде контролер за да го процесира ова барање: %s', 'page_not_found' => 'Страната која ја побаравте, %s, не е пронајдена.', 'stats_footer' => 'Вчитано за {execution_time} секунди, употребено {memory_usage} меморија. Креирано со Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Барањето Не Може Да Биде Извршено', 'errors_disabled' => 'Можете да отидете на почетната страница или да пробате повторно.', // Drivers 'driver_implements' => 'Драјверот %s за библиотеката %s мора да го имплементира интерфејсот %s', 'driver_not_found' => 'Драјверот %s за библиотеката %s не е пронајден', // Resource names 'controller' => 'controller', 'helper' => 'helper', 'library' => 'library', 'driver' => 'driver', 'model' => 'model', 'view' => 'view', );./kohana/system/i18n/mk_MK/captcha.php0000644000175000017500000000105511121324570017214 0ustar tokkeetokkee 'Назначената датотека, %s, не е пронајдена. Потврдете дека датотеките постојат користејќи file_exists пред да ги користите.', 'requires_GD2' => 'За библиотеката Captcha задолжителен е GD2 со FreeType поддршка. Молиме погледнете на http://php.net/gd_info за повеќе информации.', ); ./kohana/system/i18n/mk_MK/validation.php0000644000175000017500000000523211121324570017744 0ustar tokkeetokkee 'Користено е невалидно правило за валидирање: %s', // General errors 'unknown_error' => 'Непозната грешка при валидирање на полето: %s.', 'required' => 'Полето %s е задолжително.', 'min_length' => 'Полето %s мора да е долго најмалку %d карактера.', 'max_length' => 'Полето %s мора да е долго %d карактера или помалку.', 'exact_length' => 'Полето %s мора да е точно %d карактера.', 'in_array' => 'Полето %s мора да е селектирано од листата со опции.', 'matches' => 'Полето %s мора да е исто со полето %s.', 'valid_url' => 'Полето %s мора да содржи валидно URL.', 'valid_email' => 'Полето %s мора да содржи валидна емаил адреса.', 'valid_ip' => 'Полето %s мора да содржи валидна IP адреса.', 'valid_type' => 'Полето %s мора да содржи само %s карактери.', 'range' => 'Полето %s мора да е помеѓу дефинираниот опсег.', 'regex' => 'Полето %s не содржи прифатлива вредност.', 'depends_on' => 'Полето %s е зависно од полето %s.', // Upload errors 'user_aborted' => 'Датотеката %s е прекината при испраќање.', 'invalid_type' => 'Датотеката %s не е од валиден тип.', 'max_size' => 'Датотеката %s која е испратена е преголема. Максимум дозволена големина е %s.', 'max_width' => 'Датотеката %s има максимум дозволена ширина од %s и е %spx.', 'max_height' => 'Датотеката %s има максимум дозволена висина од %s и е %spx.', 'min_width' => 'Качената датотеката %s е премногу мала. Минимум дозволената ширина е %spx.', 'min_height' => 'Качената датотеката %s е премногу мала. Минимум дозволената висина е %spx.', // Field types 'alpha' => 'alphabetical', 'alpha_numeric' => 'alphabetical and numeric', 'alpha_dash' => 'alphabetical, dash, and underscore', 'digit' => 'digit', 'numeric' => 'numeric', );./kohana/system/i18n/mk_MK/pagination.php0000644000175000017500000000053011121324570017737 0ustar tokkeetokkee 'страна', 'pages' => 'страни', 'item' => 'item', 'items' => 'items', 'of' => 'од', 'first' => 'прва', 'last' => 'последна', 'previous' => 'претходна', 'next' => 'следна', ); ./kohana/system/i18n/mk_MK/calendar.php0000644000175000017500000000267411121324570017372 0ustar tokkeetokkee 'Не', 'mo' => 'По', 'tu' => 'Вт', 'we' => 'Ср', 'th' => 'Че', 'fr' => 'Пе', 'sa' => 'Са', // Short day names 'sun' => 'Нед', 'mon' => 'Пон', 'tue' => 'Вто', 'wed' => 'Сре', 'thu' => 'Чет', 'fri' => 'Пет', 'sat' => 'Саб', // Long day names 'sunday' => 'Недела', 'monday' => 'Понеделник', 'tuesday' => 'Вторник', 'wednesday' => 'Среда', 'thursday' => 'Четврток', 'friday' => 'Петок', 'saturday' => 'Сабота', // Short month names 'jan' => 'Јан', 'feb' => 'Феб', 'mar' => 'Мар', 'apr' => 'Апр', 'may' => 'Мај', 'jun' => 'Јун', 'jul' => 'Јул', 'aug' => 'Авг', 'sep' => 'Сеп', 'oct' => 'Окт', 'nov' => 'Ное', 'dec' => 'Дек', // Long month names 'january' => 'Јануари', 'february' => 'Фебруари', 'march' => 'Март', 'april' => 'Април', 'mayl' => 'Мај', 'june' => 'Јуни', 'july' => 'Јули', 'august' => 'Август', 'september' => 'Септрмври', 'october' => 'Октомври', 'november' => 'Ноември', 'december' => 'Декември' );./kohana/system/i18n/mk_MK/orm.php0000644000175000017500000000027111121324570016405 0ustar tokkeetokkee 'Не е пронајдена post променлива со име %s.', 'file_exceeds_limit' => 'Испратената слика ја надминува максимум дозволената големина во PHP конфигурационата датотека', 'file_partial' => 'Датотеката само делумно е испратена', 'no_file_selected' => 'Немате изберено датотека за качување', 'invalid_filetype' => 'Типот на датотеката која сакате да ја испратете, не е дозволен.', 'invalid_filesize' => 'Датотеката која сакате да ја испратите е поголема од дозволената големина (%s)', 'invalid_dimensions' => 'Датотеката која сакате да ја испратите ја преминува дозволената висина или ширина (%s)', 'destination_error' => 'Се појави проблем при процесот на преместување на качената датотека до крајната дестинација.', 'no_filepath' => 'Патеката за качување, не е валидна.', 'no_file_types' => 'Немате дефинирано кои типови на датотеки се дозволени.', 'bad_filename' => 'Испратената датотека веќе постои на серверот.', 'not_writable' => 'Во фолдерот во кој треба да се испраќа, %s, не може да се запишува.', 'error_on_file' => 'Грешка при испраќање на %s:', // Error code responses 'set_allowed' => 'Поради сигурност, мора да ги подесете типовите на датотеки кои ќе се дозволени за качување.', 'max_file_size' => 'Поради сигурност, немојте да го користете MAX_FILE_SIZE за контрола на максималната големина за качување.', 'no_tmp_dir' => 'Не е пронајден привремен директориум во кој може да се запишува.', 'tmp_unwritable' => 'Не може да се запишува во конфигурираниот директориум за качување, %s.' ); ./kohana/system/i18n/mk_MK/event.php0000644000175000017500000000115311121324570016731 0ustar tokkeetokkee 'Намерата да прикачете невалиден субјект %s на %s е неуспешна. Субјектите мора да бидат екстензии на класата Event_Subject.', 'invalid_observer' => 'Намерата да прикачете невалиден набљудувач %s на %s е неуспешна. Набљудувачите мора да бидат екстензии на класата Event_Observer.', ); ./kohana/system/i18n/mk_MK/session.php0000644000175000017500000000046111121324570017274 0ustar tokkeetokkee 'session_name, %s, е грешка. Треба да содржи само алфанумерички карактери и мора да е напишана најмалку една буква.', );./kohana/system/i18n/mk_MK/image.php0000644000175000017500000000356211121324570016700 0ustar tokkeetokkee 'Библиотеката Image задолжително ја бара PHP функцијата getimagesize, која не е достапна во оваа инсталација.', 'unsupported_method' => 'Конфигурираниот драјвер не поддржува %s сликовни трансформации.', 'file_not_found' => 'Назначената слика, %s, не е пронајдена. Потврдете дека сликите постојат користејќи file_exists пред да вршите манипулација со нив.', 'type_not_allowed' => 'Назначената слика, %s, е тип на слика кој не е дозволен.', 'invalid_width' => 'Ширината која ја имате назначено, %s, не е валидна.', 'invalid_height' => 'Висината која ја имате назначено, %s, не е валидна.', 'invalid_dimensions' => 'Назначените димензии за %s не се валидни.', 'invalid_master' => 'Главните назначени димензии не се валидни.', 'invalid_flip' => 'Flip насоката која ја имате назначено не е валидна.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'Назначениот директориум на ImageMagick не го содржи задолжителниот програм, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'За библиотеката Image задолжителен е GD2. Молиме погледнете на http://php.net/gd_info за повеќе информации.', ), ); ./kohana/system/i18n/fi_FI/0000755000175000017500000000000011263472435015070 5ustar tokkeetokkee./kohana/system/i18n/fi_FI/encrypt.php0000644000175000017500000000046211121324570017254 0ustar tokkeetokkee 'Käyttääksesi Encrypt-kirjastoa, mcrypt tulee olla kytkettynä PHP-asennukessasi.', 'no_encryption_key' => 'Käyttääksesi Encrypt-kirjastoa, tulee salausavain olla määriteltynä asetuksissa.' ); ./kohana/system/i18n/fi_FI/database.php0000644000175000017500000000140611121324570017333 0ustar tokkeetokkee 'Ryhmää %s ei ole määritelty asetuksissa.', 'error' => 'SQL-virhe: %s', 'connection' => 'Virhe yhdistettäessä tietokantaan: %s', 'invalid_dsn' => 'Antamasi DSN ei ole hyväksyttävä: %s', 'must_use_set' => 'SET tulee olla annettu kyselyssä.', 'must_use_where' => 'WHERE tulee olla annettu kyselyssä.', 'must_use_table' => 'Tietokantataulu tulee olla annettu kyselyssä.', 'table_not_found' => 'Taulua %s ei löydy tietokannassa.', 'not_implemented' => 'Kutsumasi metodi, %s, ei ole tuettu tällä ajurilla.', 'result_read_only' => 'Kyselyn tuloksia voidaan vain lukea.' );./kohana/system/i18n/fi_FI/profiler.php0000644000175000017500000000071511121324570017413 0ustar tokkeetokkee 'Suoritustestit', 'post_data' => 'POST-tiedot', 'no_post' => 'Ei POST-tietoa', 'session_data' => 'Sessio-tiedot', 'no_session' => 'Ei sessio-tietoa', 'queries' => 'Tietokantakyselyt', 'no_queries' => 'Ei kyselyitä', 'no_database' => 'Tietokantaa ei ladattu', 'cookie_data' => 'Cookie-tiedot', 'no_cookie' => 'Ei cookie-tietoa', ); ./kohana/system/i18n/fi_FI/errors.php0000644000175000017500000000223611121324570017105 0ustar tokkeetokkee array( 1, 'Framework-virhe', 'Please check the Kohana documentation for information about the following error.'), E_PAGE_NOT_FOUND => array( 1, 'Sivua ei löydy', 'The requested page was not found. It may have moved, been deleted, or archived.'), E_DATABASE_ERROR => array( 1, 'Tietokantavirhe', 'A database error occurred while performing the requested procedure. Please review the database error below for more information.'), E_RECOVERABLE_ERROR => array( 1, 'Palautuva virhe', 'An error was detected which prevented the loading of this page. If this problem persists, please contact the website administrator.'), E_ERROR => array( 1, 'Vakava virhe', ''), E_USER_ERROR => array( 1, 'Vakava virhe', ''), E_PARSE => array( 1, 'Syntaksivirhe', ''), E_WARNING => array( 1, 'Varoitus', ''), E_USER_WARNING => array( 1, 'Varoitus', ''), E_STRICT => array( 2, 'Strict Mode -virhe', ''), E_NOTICE => array( 2, 'Huomautus', ''), );./kohana/system/i18n/fi_FI/cache.php0000644000175000017500000000077211121324570016637 0ustar tokkeetokkee 'Ryhmää %s ei ole määritelty asetuksissasi.', 'extension_not_loaded' => 'PHP laajennus %s tulee olla ladattu käyttääksesi tätä ajuria.', 'unwritable' => 'Asetuksissa määriteltyyn tallennushakemistoon %s ei voida kirjoittaa.', 'resources' => 'Resurssin lisääminen välimuistiin ei onnistu, koska resurssia ei voi serialisoida.', 'driver_error' => '%s', );./kohana/system/i18n/fi_FI/swift.php0000644000175000017500000000021311121324570016716 0ustar tokkeetokkee 'Virhe sähköpostin lähetyksessä.' );./kohana/system/i18n/fi_FI/core.php0000644000175000017500000000337511121324570016526 0ustar tokkeetokkee 'Yhdellä sivulla voi olla vain yksi Kohana-instanssi.', 'uncaught_exception' => 'Käsittelemätön virhe %s: %s tiedostossa %s rivillä %s', 'invalid_method' => 'Tuntematon metodi %s kutsuttu %s', 'invalid_property' => 'Ominaisuutta %s ei löydy luokasta %s.', 'log_dir_unwritable' => 'Lokihakemistoon ei voida kirjoittaa: %s', 'resource_not_found' => 'Pyydettyä %s, %s, ei löydy', 'invalid_filetype' => 'Pyydetty tiedostotyyppi, .%s, ei ole sallittu näkymäasetuksissa', 'view_set_filename' => 'Anna näkymän tiedostonimi ennen kuin kutsut render', 'no_default_route' => 'Anna oletusreititys tiedostossa config/routes.php', 'no_controller' => 'Kohana ei pystynyt päätellä kontrolleria käsittelemään pyyntöä: %s', 'page_not_found' => 'Pyytämääsi sivua, %s, ei löydy.', 'stats_footer' => 'Ladattu {execution_time} sekunnissa, käyttäen {memory_usage} muistia. Loi Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Pyyntä ei voitu suorittaa', 'errors_disabled' => 'Voit mennä etusivulle tai yrittää uudelleen.', // Drivers 'driver_implements' => 'Ajurin %s kirjastolle %s täytyy soveltaa rajapintaa %s', 'driver_not_found' => 'Ajuria %s kirjastolle %s ei löydy', // Resource names 'controller' => 'kontrolleri', 'helper' => 'apuri', 'library' => 'kirjasto', 'driver' => 'ajuri', 'model' => 'malli', 'view' => 'näkymä', ); ./kohana/system/i18n/fi_FI/captcha.php0000644000175000017500000000261611121324570017176 0ustar tokkeetokkee 'Määriteltyä tiedostoa %s ei löydy. Varmista, että tiedostot ovat olemassa käyttämällä file_exists() ennen niiden käyttöä.', 'requires_GD2' => 'Captcha-kirjasto vaatii GD2-kirjaston FreeType-tuella. Lisätietoja: http://php.net/gd_info', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'se', 'ja', 'ei', 'on', 'vai', 'oli', 'ilo', 'voi', 'maa', 'kuu', 'auto', 'yksi', 'vesi', 'talo', 'valo', 'peli', 'ankka', 'kirja', 'hiiri', 'kissa', 'peili', 'polvi', 'salkku', 'ikkuna', 'nikama', 'pensas', 'paperi', 'kaunis', 'ranneke', 'sininen', 'alainen', 'karisma', 'iloinen', 'pehmeys', 'aikuinen', 'punainen', 'kymmenen', 'rakennus', 'menestys', 'laatikko', 'suurennus', 'valkoinen', 'rohkeasti', 'paljastaa', 'sylinteri', 'seuraamus', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Onko lumi mustaa? (kyllä tai ei)', 'ei'), array('Oletko sinä robotti? (kyllä tai en)', 'en'), array('Aurinko on... (kuuma tai kylmä)', 'kuuma'), array('Syksyn jälkeen tulee...', 'talvi'), array('Mikä on ensimmäinen viikonpäivä?', 'maanantai'), array('Mikä on vuoden viimeinen kuukausi?', 'joulukuu'), ), ); ./kohana/system/i18n/fi_FI/validation.php0000644000175000017500000000351111121324570017720 0ustar tokkeetokkee 'Viallinen validointisääntö: %s', // General errors 'unknown_error' => 'Tuntematon validointivirhe tarkastettaessa kenttää %s.', 'required' => '%s on pakollinen.', 'min_length' => '%s pitää olla vähintään %d merkkiä pitkä.', 'max_length' => '%s saa olla korkeintaan %d merkkiä pitkä.', 'exact_length' => '%s pitää olla tasan %d merkkiä pitkä.', 'in_array' => '%s pitää olla valittuna listasta.', 'matches' => '%s pitää olla sama kuin %s.', 'valid_url' => '%s pitää olla oikea URL.', 'valid_email' => '%s pitää olla oikea email-osoite.', 'valid_ip' => '%s pitää olla oikea IP-osoite.', 'valid_type' => '%s saa sisältää vain %s -merkkejä.', 'range' => '%s pitää olla annettujen arvojen välillä.', 'regex' => '%s ei täsmää hyväksyttyyn sisältöön.', 'depends_on' => '%s riippuu kentästä %s.', // Upload errors 'user_aborted' => 'Tiedoston %s lähetys keskeytettiin.', 'invalid_type' => 'Tiedosto %s ei ole sallittua tyyppiä.', 'max_size' => 'Lähettämäsi tiedosto %s oli liian suuri. Suurin sallittu koko on %s.', 'max_width' => 'Lähettämäsi tiedosto %s oli liian suuri. Suurin sallittu leveys on %spx.', 'max_height' => 'Lähettämäsi tiedosto %s oli liian suuri. Suurin sallittu korkeus on %spx.', 'min_width' => 'Lähettämäsi tiedosto %s oli liian pieni. Pienin sallittu leveys on %spx.', 'min_height' => 'Lähettämäsi tiedosto %s oli liian pieni. Pienin sallittu korkeus on %spx.', // Field types 'alpha' => 'aakkoset', 'alpha_numeric' => 'aakkoset ja numerot', 'alpha_dash' => 'aakkoset, väli- ja alaviivat', 'digit' => 'numero', 'numeric' => 'numerot', ); ./kohana/system/i18n/fi_FI/pagination.php0000644000175000017500000000063711121324570017725 0ustar tokkeetokkee 'Ryhmää %s ei ole määritetty sivutusasetuksissa.', 'page' => 'sivu', 'pages' => 'sivua', 'item' => 'juttu', // horrible translation 'items' => 'juttua', 'of' => ' / ', 'first' => 'ensimmäinen', 'last' => 'viimeinen', 'previous' => 'edellinen', 'next' => 'seuraava', ); ./kohana/system/i18n/fi_FI/calendar.php0000644000175000017500000000244011121324570017337 0ustar tokkeetokkee 'Su', 'mo' => 'Ma', 'tu' => 'Ti', 'we' => 'Ke', 'th' => 'To', 'fr' => 'Pe', 'sa' => 'La', // Short day names 'sun' => 'Sun', 'mon' => 'Maa', 'tue' => 'Tii', 'wed' => 'Kes', 'thu' => 'Tor', 'fri' => 'Per', 'sat' => 'Lau', // Long day names 'sunday' => 'Sunnuntai', 'monday' => 'Maanantai', 'tuesday' => 'Tiistai', 'wednesday' => 'Keskiviikko', 'thursday' => 'Torstai', 'friday' => 'Perjantai', 'saturday' => 'Lauantai', // Short month names 'jan' => 'Tam', 'feb' => 'Hel', 'mar' => 'Maa', 'apr' => 'Huh', 'may' => 'Tou', 'jun' => 'Kes', 'jul' => 'Hei', 'aug' => 'Elo', 'sep' => 'Syy', 'oct' => 'Lok', 'nov' => 'Mar', 'dec' => 'Jou', // Long month names 'january' => 'Tammikuu', 'february' => 'Helmikuu', 'march' => 'Maaliskuu', 'april' => 'Huhtikuu', 'mayl' => 'Toukokuu', 'june' => 'Kesäkuu', 'july' => 'Heinäkuu', 'august' => 'Elokuu', 'september' => 'Syyskuu', 'october' => 'Lokakuu', 'november' => 'Marraskuu', 'december' => 'Joulukuu' );./kohana/system/i18n/fi_FI/orm.php0000644000175000017500000000023211121324570016360 0ustar tokkeetokkee 'Ei löydy lomakkeen kenttää %s.', 'file_exceeds_limit' => 'Lähetetyn tiedoston koko ylittää PHP-asetuksissa määritellyn suurimman tiedostokoon.', 'file_partial' => 'Vain osa tiedostosta lähetettiin', 'no_file_selected' => 'Et valinnut tiedostoa lähetettäväksi', 'invalid_filetype' => 'Lähettämäsi tiedoston tyyppi ei ole sallittu.', 'invalid_filesize' => 'Lähettämäsi tiedosto ylittää suurimman sallitun koon (%s)', 'invalid_dimensions' => 'Lähettämäsi kuva ylittää suurimman sallitun leveyden tai korkeuden (%s)', 'destination_error' => 'Virhe siirrettäessä lähetettyä tiedostoa lopulliseen kohteeseen.', 'no_filepath' => 'Lähetysten tallennushakemisto on viallinen.', 'no_file_types' => 'Et ole määritellyt yhtään sallittua tiedostotyyppiä.', 'bad_filename' => 'Palvelimella on jo lähettämäsi tiedoston niminen tiedosto.', 'not_writable' => 'Lähetyksen kohdehakemistoon %s ei voida kirjoittaa.', 'error_on_file' => 'Virhe lähettäessä %s:', // Error code responses 'set_allowed' => 'Turvallisuussyistä sinun tulee määritellä hyväksytyt tiedostotyypit.', 'max_file_size' => 'Turvallisuussyistä MAX_FILE_SIZE ei ole riittävä tiedostokoon rajoittamiseen.', 'no_tmp_dir' => 'Väliaikaishakemistoa johon voi kirjoittaa ei löydy.', 'tmp_unwritable' => 'Määriteltyyn lähetyshakemistoon %s ei voida kirjoittaa.' ); ./kohana/system/i18n/fi_FI/event.php0000644000175000017500000000055111121324570016710 0ustar tokkeetokkee 'Yritys liittää epäkelpo kohde %s -> %s epäonnistui: Kohteiden täytyy laajentaa Event_Subject -luokkaa', 'invalid_observer' => 'Yritys liittää epäkelpo tarkkailija %s -> %s epäonnistui: Tarkkailijoiden täytyy laajentaa Event_Observer -luokkaa', ); ./kohana/system/i18n/fi_FI/session.php0000644000175000017500000000036411121324570017254 0ustar tokkeetokkee 'session_name, %s, ei kelpaa. Se tulee sisältää vähintään yhden kirjaimen, sekä vain aakkosnumeerisia merkkejä ja alaviivoja.', );./kohana/system/i18n/fi_FI/image.php0000644000175000017500000000245011121324570016651 0ustar tokkeetokkee 'Image-kirjasto tarvitsee getimagesize() PHP-funktion jota ei ole saatavilla.', 'unsupported_method' => 'Määrittelemäsi ajuri ei tue kuvamuunnosta %s.', 'file_not_found' => 'Määriteltyä kuvaa %s ei löydy. Varmista, että tiedostot ovat olemassa käyttämällä file_exists() ennen niiden käyttöä.', 'type_not_allowed' => 'Määritelty kuva %s ei ole sallittua tyyppiä.', 'invalid_width' => 'Antamasi leveys %s ei ole hyväksyttävä.', 'invalid_height' => 'Antamasi korkeus %s ei ole hyväksyttävä.', 'invalid_dimensions' => 'Kuvalle %s antamasi mitat eivät ole hyväksyttäviä.', 'invalid_master' => 'Määritellyt päämitat eivät ole hyväksyttäviä.', 'invalid_flip' => 'Määritelty kääntösuunta ei ole hyväksyttävä.', 'directory_unwritable' => 'Määriteltyyn hakemistoon %s ei voida kirjoittaa.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'Määritelty ImageMagick -hakemisto ei sisällä vaadittua ohjelmaa, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'Image-kirjasto vaatii GD2-kirjaston. Lisätietoja: http://php.net/gd_info', ), ); ./kohana/system/i18n/nl_NL/0000755000175000017500000000000011263472434015115 5ustar tokkeetokkee./kohana/system/i18n/nl_NL/encrypt.php0000644000175000017500000000061511121324570017302 0ustar tokkeetokkee 'De %s groep is niet gedefinieerd in je configuratie.', 'requires_mcrypt' => 'Om de Encrypt library te gebruiken, moet mcrypt ingeschakeld zijn in je PHP installatie.', 'no_encryption_key' => 'Om de Encrypt library te gebruiken, moet je een encryption key zetten in je config bestand.', ); ./kohana/system/i18n/nl_NL/database.php0000644000175000017500000000152311121324570017361 0ustar tokkeetokkee 'De %s groep is niet opgegeven in je configuratie.', 'error' => 'Er was een SQL fout: %s', 'connection' => 'Fout bij het verbinden met de database: %s', 'invalid_dsn' => 'De DSN die je opgaf is ongeldig: %s', 'must_use_set' => 'Je moet een SET clause opgeven voor je query.', 'must_use_where' => 'Je moet een WHERE clause opgeven voor je query.', 'must_use_table' => 'Je moet een database tabel opgeven voor je query.', 'table_not_found' => 'De tabel %s bestaat niet in je database.', 'not_implemented' => 'De method die je opriep, %s, wordt niet ondersteund door deze driver.', 'result_read_only' => 'Query resultaten kunnen alleen maar gelezen worden.', );./kohana/system/i18n/nl_NL/profiler.php0000644000175000017500000000070211121324570017435 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Post Data', 'no_post' => 'Geen post data', 'session_data' => 'Session Data', 'no_session' => 'Geen session data', 'queries' => 'Database Queries', 'no_queries' => 'Geen queries', 'no_database' => 'Database niet geladen', 'cookie_data' => 'Cookie Data', 'no_cookie' => 'Geen cookie data', ); ./kohana/system/i18n/nl_NL/errors.php0000644000175000017500000000227411121324570017135 0ustar tokkeetokkee array( 1, 'Framework Error', 'Bekijk de Kohana documentatie voor meer informatie over deze fout.'), E_PAGE_NOT_FOUND => array( 1, 'Pagina Niet Gevonden', 'De opgevraagde pagina werd niet gevonden. Mogelijk werd deze verplaatst of verwijderd.'), E_DATABASE_ERROR => array( 1, 'Database Error', 'Er vond een database fout plaats bij het verwerken van de opgeroepen procedure. Bekijk het errorbericht hieronder voor meer informatie.'), E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Er vond een fout plaats waardoor deze pagina niet geladen kon worden. Als dit probleem aanhoudt, contacteer dan a.u.b. de website beheerder.'), E_ERROR => array( 1, 'Fatal Error', ''), E_USER_ERROR => array( 1, 'Fatal Error', ''), E_PARSE => array( 1, 'Syntax Error', ''), E_WARNING => array( 1, 'Warning Message', ''), E_USER_WARNING => array( 1, 'Warning Message', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/nl_NL/cache.php0000644000175000017500000000076411121324570016666 0ustar tokkeetokkee 'De %s groep is niet gedefinieerd in uw configuratie.', 'extension_not_loaded' => 'De %s PHP extensie moet geladen zijn om deze driver te gebruiken.', 'unwritable' => 'De geconfigureerde opslaglocatie, %s, is niet schrijfbaar.', 'resources' => 'Het cachen van resources is onmogelijk omdat resources niet geserialized kunnen worden.', 'driver_error' => '%s', );./kohana/system/i18n/nl_NL/swift.php0000644000175000017500000000024111121324570016745 0ustar tokkeetokkee 'Er vond een fout plaats bij het verzenden van de e-mail.', );./kohana/system/i18n/nl_NL/core.php0000644000175000017500000000363711121324570016555 0ustar tokkeetokkee 'Er kan maar één instantie van Kohana zijn per pagina oproep.', 'uncaught_exception' => 'Uncaught %s: %s in bestand %s op lijn %s', 'invalid_method' => 'Ongeldige method %s opgeroepen in %s.', 'invalid_property' => 'De %s property bestaat niet in de %s class.', 'log_dir_unwritable' => 'De log directory is niet schrijfbaar: %s', 'resource_not_found' => 'De opgevraagde %s, %s, kon niet gevonden worden.', 'invalid_filetype' => 'Het opgevraagde bestandstype, .%s, wordt niet toegestaan door het view configuratiebestand.', 'view_set_filename' => 'Je moet de view bestandsnaam opgeven voordat je render aanroept.', 'no_default_route' => 'Zet een default route in config/routes.php.', 'no_controller' => 'Kohana kon geen controller aanduiden om deze pagina te verwerken: %s', 'page_not_found' => 'De opgevraagde pagina, %s, kon niet gevonden worden.', 'stats_footer' => 'Geladen in {execution_time} seconden, met een geheugengebruik van {memory_usage}. Aangedreven door Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Oproep kon niet afgewerkt worden', 'errors_disabled' => 'Ga naar de homepage of probeer opnieuw.', // Drivers 'driver_implements' => 'De %s driver voor de %s library moet de %s interface implementeren.', 'driver_not_found' => 'De %s driver voor de %s library werd niet gevonden.', // Resource names 'config' => 'configuratiebestand', 'controller' => 'controller', 'helper' => 'helper', 'library' => 'library', 'driver' => 'driver', 'model' => 'model', 'view' => 'view', );./kohana/system/i18n/nl_NL/captcha.php0000644000175000017500000000261211121324570017220 0ustar tokkeetokkee 'Het opgegeven bestand, %s, werd niet gevonden. Controleer met file_exists() of bestanden bestaan, voordat je ze gebruikt.', 'requires_GD2' => 'De Captcha library vereist GD2 met FreeType ondersteuning. Zie http://php.net/gd_info voor meer informatie.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'ok', 'pc', 'nu', 'ik', 'zon', 'kar', 'kat', 'bed', 'tof', 'hoi', 'puin', 'hoop', 'mens', 'roof', 'auto', 'haar', 'water', 'beter', 'aarde', 'appel', 'mango', 'liter', 'ananas', 'bakker', 'wekker', 'kroket', 'zingen', 'dansen', 'fietsen', 'zwemmen', 'kolonel', 'potlood', 'kookpot', 'voetbal', 'barbecue', 'computer', 'generaal', 'koelkast', 'fietsers', 'spelling', 'appelmoes', 'president', 'kangoeroe', 'frankrijk', 'luxemburg', 'apartheid', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Haat jij spam? (ja of nee)', 'ja'), array('Ben jij een robot? (ja of nee)', 'nee'), array('Vuur is... (heet of koud)', 'heet'), array('Het seizoen na herfst is...', 'winter'), array('Welke dag van de week is het vandaag?', strftime('%A')), array('In welke maand van het jaar zijn we?', strftime('%B')), ), ); ./kohana/system/i18n/nl_NL/validation.php0000644000175000017500000000376111121324570017755 0ustar tokkeetokkee 'Ongeldige validatieregel gebruikt: %s', // Algemene errors 'unknown_error' => 'Onbekende validatiefout bij het valideren van het %s veld.', 'required' => 'Het %s veld is verplicht.', 'min_length' => 'Het %s veld moet minstens %s karakters lang zijn.', 'max_length' => 'Het %s veld mag maximum %s karakters lang zijn.', 'exact_length' => 'Het %s veld moet exact %s karakters lang zijn.', 'in_array' => 'Het %s veld moet geselecteerd worden uit de gegeven opties.', 'matches' => 'Het %s veld moet overeenkomen met het %s veld.', 'valid_url' => 'Het %s veld moet een geldige URL zijn.', 'valid_email' => 'Het %s veld moet een geldig e-mailadres zijn.', 'valid_ip' => 'Het %s veld moet een geldig IP-adres zijn.', 'valid_type' => 'Het %s veld mag alleen maar %s karakters bevatten.', 'range' => 'Het %s veld moet tussen bepaalde waardes liggen.', 'regex' => 'Het %s veld valideert niet als geldige invoer.', 'depends_on' => 'Het %s veld is afhankelijk van het %s veld.', // Upload errors 'user_aborted' => 'Het uploaden van het %s bestand werd afgebroken.', 'invalid_type' => 'Het bestandstype van het %s bestand is niet toegestaan.', 'max_size' => 'Het %s bestand dat je wilde uploaden is te groot. De maximum toegelaten grootte is %s.', 'max_width' => 'Het %s upgeloade bestand is te groot: maximum toegelaten breedte is %spx.', 'max_height' => 'Het %s upgeloade bestand is te groot: maximum toegelaten hoogte is %spx.', 'min_width' => 'Het %s upgeloade bestand is te klein: minimum toegelaten breedte is %spx.', 'min_height' => 'Het %s upgeloade bestand is te klein: minimum toegelaten breedte is %spx.', // Field types 'alpha' => 'alfabetisch', 'alpha_numeric' => 'alfanumeriek', 'alpha_dash' => 'alfabetisch, streepje, en underscore', 'digit' => 'cijfers', 'numeric' => 'getal', );./kohana/system/i18n/nl_NL/pagination.php0000644000175000017500000000061611121324570017750 0ustar tokkeetokkee 'De %s groep werd niet gedefinieerd in uw pagination configuratie.', 'page' => 'pagina', 'pages' => 'pagina\'s', 'item' => 'item', 'items' => 'items', 'of' => 'van', 'first' => 'eerste', 'last' => 'laatste', 'previous' => 'vorige', 'next' => 'volgende', ); ./kohana/system/i18n/nl_NL/calendar.php0000644000175000017500000000240611121324570017367 0ustar tokkeetokkee 'zo', 'mo' => 'ma', 'tu' => 'di', 'we' => 'wo', 'th' => 'do', 'fr' => 'vr', 'sa' => 'za', // Short day names 'sun' => 'zon', 'mon' => 'maa', 'tue' => 'din', 'wed' => 'woe', 'thu' => 'don', 'fri' => 'vri', 'sat' => 'zat', // Long day names 'sunday' => 'zondag', 'monday' => 'maandag', 'tuesday' => 'dinsdag', 'wednesday' => 'woensdag', 'thursday' => 'donderdag', 'friday' => 'vrijdag', 'saturday' => 'zaterdag', // Short month names 'jan' => 'jan', 'feb' => 'feb', 'mar' => 'maa', 'apr' => 'apr', 'may' => 'mei', 'jun' => 'jun', 'jul' => 'jul', 'aug' => 'aug', 'sep' => 'sep', 'oct' => 'okt', 'nov' => 'nov', 'dec' => 'dec', // Long month names 'january' => 'januari', 'february' => 'februari', 'march' => 'maart', 'april' => 'april', 'mayl' => 'mei', 'june' => 'juni', 'july' => 'juli', 'august' => 'augustus', 'september' => 'september', 'october' => 'oktober', 'november' => 'november', 'december' => 'december', );./kohana/system/i18n/nl_NL/orm.php0000644000175000017500000000023011121324570016404 0ustar tokkeetokkee 'De upload doelmap, %s, is niet schrijfbaar.', );./kohana/system/i18n/nl_NL/event.php0000644000175000017500000000053311121324570016736 0ustar tokkeetokkee 'Poging om ongeldig subject %s te binden aan %s mislukt. Subjects moeten de Event_Subject class extenden.', 'invalid_observer' => 'Poging om ongeldige observer %s te binden aan %s mislukt. Observers moeten de Event_Subject class extenden.', ); ./kohana/system/i18n/nl_NL/session.php0000644000175000017500000000040111121324570017272 0ustar tokkeetokkee 'De sessienaam, %s, is ongeldig. Hij mag alleen maar bestaan uit alfanumerieke tekens en underscores. Hij moet ook minstens één letter bevatten.', );./kohana/system/i18n/nl_NL/image.php0000644000175000017500000000255211121324570016702 0ustar tokkeetokkee 'De Image library vereist de getimagesize() functie en die is niet beschikbaar op dit systeem.', 'unsupported_method' => 'De huidige Image driver ondersteunt volgende transformatie niet: %s.', 'file_not_found' => 'De opgegeven afbeelding, %s, werd niet gevonden. Controleer a.u.b. eerst of afbeeldingen bestaan via de file_exists() functie voordat je ze begint te bewerken.', 'type_not_allowed' => 'De opgegeven afbeelding, %s, is geen toegestaan afbeeldingstype.', 'invalid_width' => 'De breedte die je opgaf, %s, is ongeldig.', 'invalid_height' => 'De hoogte die je opgaf, %s, is ongeldig.', 'invalid_dimensions' => 'De afmetingen die je opgaf voor %s zijn ongeldig.', 'invalid_master' => 'De master afmeting die je opgaf, is ongeldig.', 'invalid_flip' => 'De spiegelrichting die je opgaf, is ongeldig.', 'directory_unwritable' => 'De opgegeven directory, %s, is niet schrijfbaar.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'De opgegeven ImageMagick directory bevat een vereist programma niet: %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'De Image library vereist GD2. Kijk op http://php.net/gd_info voor meer informatie.', ), ); ./kohana/system/i18n/en_US/0000755000175000017500000000000011263472435015125 5ustar tokkeetokkee./kohana/system/i18n/en_US/encrypt.php0000644000175000017500000000056011121324570017310 0ustar tokkeetokkee 'The %s group is not defined in your configuration.', 'requires_mcrypt' => 'To use the Encrypt library, mcrypt must be enabled in your PHP installation', 'no_encryption_key' => 'To use the Encrypt library, you must set an encryption key in your config file' ); ./kohana/system/i18n/en_US/database.php0000644000175000017500000000146311121324570017373 0ustar tokkeetokkee 'The %s group is not defined in your configuration.', 'error' => 'There was an SQL error: %s', 'connection' => 'There was an error connecting to the database: %s', 'invalid_dsn' => 'The DSN you supplied is not valid: %s', 'must_use_set' => 'You must set a SET clause for your query.', 'must_use_where' => 'You must set a WHERE clause for your query.', 'must_use_table' => 'You must set a database table for your query.', 'table_not_found' => 'Table %s does not exist in your database.', 'not_implemented' => 'The method you called, %s, is not supported by this driver.', 'result_read_only' => 'Query results are read only.' );./kohana/system/i18n/en_US/profiler.php0000644000175000017500000000067011121324570017450 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Post Data', 'no_post' => 'No post data', 'session_data' => 'Session Data', 'no_session' => 'No session data', 'queries' => 'Database Queries', 'no_queries' => 'No queries', 'no_database' => 'Database not loaded', 'cookie_data' => 'Cookie Data', 'no_cookie' => 'No cookie data', ); ./kohana/system/i18n/en_US/errors.php0000644000175000017500000000222211121324570017135 0ustar tokkeetokkee array( 1, 'Framework Error', 'Please check the Kohana documentation for information about the following error.'), E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'The requested page was not found. It may have moved, been deleted, or archived.'), E_DATABASE_ERROR => array( 1, 'Database Error', 'A database error occurred while performing the requested procedure. Please review the database error below for more information.'), E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'An error was detected which prevented the loading of this page. If this problem persists, please contact the website administrator.'), E_ERROR => array( 1, 'Fatal Error', ''), E_USER_ERROR => array( 1, 'Fatal Error', ''), E_PARSE => array( 1, 'Syntax Error', ''), E_WARNING => array( 1, 'Warning Message', ''), E_USER_WARNING => array( 1, 'Warning Message', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/en_US/cache.php0000644000175000017500000000072711121324570016674 0ustar tokkeetokkee 'The %s group is not defined in your configuration.', 'extension_not_loaded' => 'The %s PHP extension must be loaded to use this driver.', 'unwritable' => 'The configured storage location, %s, is not writable.', 'resources' => 'Caching of resources is impossible, because resources cannot be serialized.', 'driver_error' => '%s', );./kohana/system/i18n/en_US/swift.php0000644000175000017500000000023211121324570016754 0ustar tokkeetokkee 'An error occurred while sending the email message.' );./kohana/system/i18n/en_US/core.php0000644000175000017500000000352511121324570016560 0ustar tokkeetokkee 'There can be only one instance of Kohana per page request', 'uncaught_exception' => 'Uncaught %s: %s in file %s on line %s', 'invalid_method' => 'Invalid method %s called in %s', 'invalid_property' => 'The %s property does not exist in the %s class.', 'log_dir_unwritable' => 'The log directory is not writable: %s', 'resource_not_found' => 'The requested %s, %s, could not be found', 'invalid_filetype' => 'The requested filetype, .%s, is not allowed in your view configuration file', 'view_set_filename' => 'You must set the the view filename before calling render', 'no_default_route' => 'Please set a default route in config/routes.php', 'no_controller' => 'Kohana was not able to determine a controller to process this request: %s', 'page_not_found' => 'The page you requested, %s, could not be found.', 'stats_footer' => 'Loaded in {execution_time} seconds, using {memory_usage} of memory. Generated by Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Unable to Complete Request', 'errors_disabled' => 'You can go to the home page or try again.', // Drivers 'driver_implements' => 'The %s driver for the %s library must implement the %s interface', 'driver_not_found' => 'The %s driver for the %s library could not be found', // Resource names 'config' => 'config file', 'controller' => 'controller', 'helper' => 'helper', 'library' => 'library', 'driver' => 'driver', 'model' => 'model', 'view' => 'view', ); ./kohana/system/i18n/en_US/captcha.php0000644000175000017500000000257611121324570017240 0ustar tokkeetokkee 'The specified file, %s, was not found. Please verify that files exist by using file_exists() before using them.', 'requires_GD2' => 'The Captcha library requires GD2 with FreeType support. Please see http://php.net/gd_info for more information.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Do you hate spam? (yes or no)', 'yes'), array('Are you a robot? (yes or no)', 'no'), array('Fire is... (hot or cold)', 'hot'), array('The season after fall is...', 'winter'), array('Which day of the week is it today?', strftime('%A')), array('Which month of the year are we in?', strftime('%B')), ), ); ./kohana/system/i18n/en_US/validation.php0000644000175000017500000000412111121324570017753 0ustar tokkeetokkee 'Invalid validation rule used: %s', 'i18n_array' => 'The %s i18n key must be an array to be used with the in_lang rule', 'not_callable' => 'Callback %s used for Validation is not callable', // General errors 'unknown_error' => 'Unknown validation error while validating the %s field.', 'required' => 'The %s field is required.', 'min_length' => 'The %s field must be at least %d characters long.', 'max_length' => 'The %s field must be %d characters or fewer.', 'exact_length' => 'The %s field must be exactly %d characters.', 'in_array' => 'The %s field must be selected from the options listed.', 'matches' => 'The %s field must match the %s field.', 'valid_url' => 'The %s field must contain a valid URL.', 'valid_email' => 'The %s field must contain a valid email address.', 'valid_ip' => 'The %s field must contain a valid IP address.', 'valid_type' => 'The %s field must only contain %s characters.', 'range' => 'The %s field must be between specified ranges.', 'regex' => 'The %s field does not match accepted input.', 'depends_on' => 'The %s field depends on the %s field.', // Upload errors 'user_aborted' => 'The %s file was aborted during upload.', 'invalid_type' => 'The %s file is not an allowed file type.', 'max_size' => 'The %s file you uploaded was too large. The maximum size allowed is %s.', 'max_width' => 'The %s file you uploaded was too big. The maximum allowed width is %spx.', 'max_height' => 'The %s file you uploaded was too big. The maximum allowed height is %spx.', 'min_width' => 'The %s file you uploaded was too small. The minimum allowed width is %spx.', 'min_height' => 'The %s file you uploaded was too small. The minimum allowed height is %spx.', // Field types 'alpha' => 'alphabetical', 'alpha_numeric' => 'alphabetical and numeric', 'alpha_dash' => 'alphabetical, dash, and underscore', 'digit' => 'digit', 'numeric' => 'numeric', ); ./kohana/system/i18n/en_US/pagination.php0000644000175000017500000000057511121324570017763 0ustar tokkeetokkee 'The %s group is not defined in your pagination configuration.', 'page' => 'page', 'pages' => 'pages', 'item' => 'item', 'items' => 'items', 'of' => 'of', 'first' => 'first', 'last' => 'last', 'previous' => 'previous', 'next' => 'next', ); ./kohana/system/i18n/en_US/calendar.php0000644000175000017500000000240111121324570017371 0ustar tokkeetokkee 'Su', 'mo' => 'Mo', 'tu' => 'Tu', 'we' => 'We', 'th' => 'Th', 'fr' => 'Fr', 'sa' => 'Sa', // Short day names 'sun' => 'Sun', 'mon' => 'Mon', 'tue' => 'Tue', 'wed' => 'Wed', 'thu' => 'Thu', 'fri' => 'Fri', 'sat' => 'Sat', // Long day names 'sunday' => 'Sunday', 'monday' => 'Monday', 'tuesday' => 'Tuesday', 'wednesday' => 'Wednesday', 'thursday' => 'Thursday', 'friday' => 'Friday', 'saturday' => 'Saturday', // Short month names 'jan' => 'Jan', 'feb' => 'Feb', 'mar' => 'Mar', 'apr' => 'Apr', 'may' => 'May', 'jun' => 'Jun', 'jul' => 'Jul', 'aug' => 'Aug', 'sep' => 'Sep', 'oct' => 'Oct', 'nov' => 'Nov', 'dec' => 'Dec', // Long month names 'january' => 'January', 'february' => 'February', 'march' => 'March', 'april' => 'April', 'mayl' => 'May', 'june' => 'June', 'july' => 'July', 'august' => 'August', 'september' => 'September', 'october' => 'October', 'november' => 'November', 'december' => 'December' );./kohana/system/i18n/en_US/orm.php0000644000175000017500000000021711121324570016420 0ustar tokkeetokkee 'The upload destination folder, %s, does not appear to be writable.', );./kohana/system/i18n/en_US/event.php0000644000175000017500000000051111121324570016741 0ustar tokkeetokkee 'Attempt to attach invalid subject %s to %s failed: Subjects must extend the Event_Subject class', 'invalid_observer' => 'Attempt to attach invalid observer %s to %s failed: Observers must extend the Event_Observer class', ); ./kohana/system/i18n/en_US/session.php0000644000175000017500000000037111121324570017307 0ustar tokkeetokkee 'The session_name, %s, is invalid. It must contain only alphanumeric characters and underscores. Also at least one letter must be present.', );./kohana/system/i18n/en_US/image.php0000644000175000017500000000276511121324570016717 0ustar tokkeetokkee 'The Image library requires the getimagesize() PHP function, which is not available in your installation.', 'unsupported_method' => 'Your configured driver does not support the %s image transformation.', 'file_not_found' => 'The specified image, %s, was not found. Please verify that images exist by using file_exists() before manipulating them.', 'type_not_allowed' => 'The specified image, %s, is not an allowed image type.', 'invalid_width' => 'The width you specified, %s, is not valid.', 'invalid_height' => 'The height you specified, %s, is not valid.', 'invalid_dimensions' => 'The dimensions specified for %s are not valid.', 'invalid_master' => 'The master dimension specified is not valid.', 'invalid_flip' => 'The flip direction specified is not valid.', 'directory_unwritable' => 'The specified directory, %s, is not writable.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'The ImageMagick directory specified does not contain a required program, %s.', ), // GraphicsMagick specific messages 'graphicsmagick' => array ( 'not_found' => 'The GraphicsMagick directory specified does not contain a required program, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'The Image library requires GD2. Please see http://php.net/gd_info for more information.', ), ); ./kohana/system/i18n/el_GR/0000755000175000017500000000000011263472434015103 5ustar tokkeetokkee./kohana/system/i18n/fr_FR/0000755000175000017500000000000011263472435015112 5ustar tokkeetokkee./kohana/system/i18n/fr_FR/encrypt.php0000644000175000017500000000076411121324570017303 0ustar tokkeetokkee 'Le groupe %s n\'est pas défini dans votre configuration.', 'requires_mcrypt' => 'Afin de pouvoir utiliser la librairie de chiffrement (Encrypt library), mcrypt doit être activé dans votre installation PHP.', 'no_encryption_key' => 'Afin de pouvoir utiliser la librairie de chiffrement (Encrypt library), vous devez définir une clé de chiffrement dans votre fichier de configuration.' ); ./kohana/system/i18n/fr_FR/database.php0000644000175000017500000000201511121324570017352 0ustar tokkeetokkee 'Le groupe de base de données %s n\'existe pas dans votre fichier de configuration.', 'error' => 'L\'erreur SQL suivante est survenue: %s', 'connection' => 'Il y a eu une erreur lors de la connexion à la base de données: %s', 'invalid_dsn' => 'Le DSN que vous avez spécifié n\'est pas valide: %s', 'must_use_set' => 'Vous devez spécifier une clause SET pour votre requête.', 'must_use_where' => 'Vous devez spécifier une clause WHERE pour votre requête.', 'must_use_table' => 'Vous devez spécifier une table de la base de données pour votre requête.', 'table_not_found' => 'La table %s n\'existe pas dans votre base de données.', 'not_implemented' => 'La méthode %s que vous avez appelée n\'est pas supportée par le driver de base de données.', 'result_read_only' => 'Les résultats de la requête sont en lecture seule.' ); ./kohana/system/i18n/fr_FR/profiler.php0000644000175000017500000000075411121324570017440 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Données POST', 'no_post' => 'Aucune donnée POST', 'session_data' => 'Données de session', 'no_session' => 'Aucune donnée de session', 'queries' => 'Requêtes', 'no_queries' => 'Aucune requête', 'no_database' => 'Base de données non chargée', 'cookie_data' => 'Données du Cookie', 'no_cookie' => 'Aucune donnée de Cookie', );./kohana/system/i18n/fr_FR/errors.php0000644000175000017500000000235211121324570017126 0ustar tokkeetokkee array( 1, 'Framework Error', 'Veuillez vous référer à la documentation de Kohana pour plus d\'informations sur l\'erreur suivante.'), E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'La page demandée n\'a pas été trouvée. Elle a peut-être été déplacée, supprimée, ou archivée.'), E_DATABASE_ERROR => array( 1, 'Database Error', 'Une erreur de base de données est survenue lors de l\'exécution de la procèdure demandée. Veuillez vous référer à l\'erreur renvoyée ci-dessous pour plus d\'informations.'), E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Une erreur a empêché le chargement de la page. Si le problème persiste, veuillez contacter l\'administrateur du site.'), E_ERROR => array( 1, 'Fatal Error', ''), E_USER_ERROR => array( 1, 'Fatal Error', ''), E_PARSE => array( 1, 'Syntax Error', ''), E_WARNING => array( 1, 'Warning Message', ''), E_USER_WARNING => array( 1, 'Warning Message', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), ); ./kohana/system/i18n/fr_FR/cache.php0000644000175000017500000000102411121324570016650 0ustar tokkeetokkee 'Le groupe %s n\'est pas défini dans votre configuration.', 'extension_not_loaded' => 'l\'extension PHP %s doit être chargée pour utiliser ce driver.', 'unwritable' => 'Le chemin %s configuré pour le cache n\'est pas accessible en écriture.', 'resources' => 'La mise en cache des ressources est impossible car elles n\'ont pas pu être sérialisées.', 'driver_error' => '%s' ); ./kohana/system/i18n/fr_FR/swift.php0000644000175000017500000000023511121324570016744 0ustar tokkeetokkee 'Une erreur est survenue lors de l\'envoi du message.' ); ./kohana/system/i18n/fr_FR/core.php0000644000175000017500000000421011132220312016524 0ustar tokkeetokkee 'Il ne peut y avoir qu\'une instance de Kohana par page.', 'uncaught_exception' => 'Uncaught %s: %s dans le fichier %s à la ligne %s', 'invalid_method' => 'La méthode %s appelée dans %s est invalide.', 'invalid_property' => 'La propriété %s n\'existe pas dans la classe %s.', 'log_dir_unwritable' => 'Le répertoire spécifié dans votre fichier de configuration pour le fichier de log ne pointe pas vers un répertoire accessible en écriture.', 'resource_not_found' => 'La ressource %s, %s, n\'a pas été trouvée.', 'invalid_filetype' => 'Le type de ficher demandé, .%s, n\'est pas autorisé dans le fichier de configuration des vues (view configuration file).', 'view_set_filename' => 'Vous devez renseigner le nom de la vue avant d\'appeller la méthode render', 'no_default_route' => 'Aucune route par défaut n\a été définie. Veuillez la spécifer dans le fichier config/routes.php.', 'no_controller' => 'Kohana n\'a pu déterminer aucun controlleur pour effectuer la requête: %s.', 'page_not_found' => 'La page demandée %s n\'a pu être trouvée.', 'stats_footer' => 'Chargé en {execution_time} secondes, {memory_usage} de mémoire utilisée. Généré par Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Impossible de terminer la requête.', 'errors_disabled' => 'Vous pouvez aller sur la page d\'accueil ou essayer encore.', // Drivers 'driver_implements' => 'Le driver %s de la librairie %s doit implémenter l\'interface %s.', 'driver_not_found' => 'Le driver %s de la librairie %s est introuvable.', // Resource names 'config' => 'fichier de configuration', 'controller' => 'contrôleur', 'helper' => 'helper', 'library' => 'librairie', 'driver' => 'driver', 'model' => 'modèle', 'view' => 'vue', ); ./kohana/system/i18n/fr_FR/captcha.php0000644000175000017500000000272211121324570017216 0ustar tokkeetokkee 'Le fichier spécifié, %s, est introuvable. Merci de vérifier que les fichiers existent, grâce à la fontion file_exists, avant de les utiliser.', 'requires_GD2' => 'La librairie Captcha requiert GD2 avec le support FreeType installé. Voir http://php.net/gd_info pour de plus amples renseignements, merci.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'le', 'il', 'ou', 'an', 'moi', 'age', 'coq', 'ici', 'bob', 'eau', 'cake', 'agir', 'bain', 'dodo', 'elle', 'faux', 'hello', 'monde', 'terre', 'adore', 'baton', 'chats', 'absent', 'cendre', 'banane', 'cirque', 'violet', 'disque', 'abricot', 'billets', 'cendres', 'frisson', 'nations', 'respect', 'accepter', 'batterie', 'collines', 'desserts', 'feuilles', 'sandwich', 'acheteurs', 'tellement', 'renverser', 'histoires', 'dimanches', 'cinquante', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Détestez-vous le spam? (oui ou non)', 'oui'), array('Etes vous un robot? (oui ou non)', 'non'), array('Le feu est... (chaud ou froid)', 'chaud'), array('La saison après l\'automne est l\'...', 'hiver'), array('Quel jour est-il?', strftime('%A')), array('Quel est le mois en cours?', strftime('%B')), ) ); ./kohana/system/i18n/fr_FR/validation.php0000644000175000017500000000471111132220312017734 0ustar tokkeetokkee 'La règle de validation %s utilisée est invalide', 'i18n_array' => 'La clé i18n %s doit être un tableau pour pouvoir être utilisée avec la règle in_lang', 'not_callable' => 'La callback %s utilisé pour la Validation n\'est pas appellable', // General errors 'unknown_error' => 'Erreur de validation inconnue lors de la validation du champ %s.', 'required' => 'Le champ %s est requis.', 'min_length' => 'Le champ %s doit contenir au minimum %d caractères.', 'max_length' => 'Le champ %s ne peut contenir plus de %d caractères.', 'exact_length' => 'Le champ %s doit contenir exactement %d caractères.', 'in_array' => 'Le champ %s doit être sélectionné dans parmi les options listées.', 'matches' => 'Le champ %s doit correspondre au champ %s.', 'valid_url' => 'Le champ %s doit contenir une URL valide.', 'valid_email' => 'Le champ %s doit contenir une adresse email valide.', 'valid_ip' => 'Le champ %s doit contenir une adresse IP valide.', 'valid_type' => 'Le champ %s doit contenir uniquement %s caractères', 'range' => 'Le champ %s doit être situé dans la plage de valeurs spécifiée.', 'regex' => 'Le champ %s ne correspond pas aux valeurs acceptées.', 'depends_on' => 'Le champ %s est dépendant du champ %s.', // Upload errors 'user_aborted' => 'L\'envoi du fichier %s sur le serveur a échoué.', 'invalid_type' => 'Le type du fichier %s n\'est pas autorisé.', 'max_size' => 'La taille du fichier %s que vous tentez d\'envoyer est trop volumineuse. La taille maximale autorisée est de %s', 'max_width' => 'La largeur de l\'image %s que vous envoyez est trop grande. La largeur maximale autorisée est de %spx', 'max_height' => 'La hauteur de l\'image %s que vous envoyez est trop grande. La hauteur maximale autorisée est de %spx', 'min_width' => 'La largeur de l\'image %s que vous envoyez n\'est pas assez grande. La largeur minimale demandée est de %spx', 'min_height' => 'La hauteur de l\'image %s que vous envoyez n\'est pas assez grande. La hauteur minimale demandée est de %spx', // Field types 'alpha' => 'alphabétiques', 'alpha_numeric' => 'alphabétiques et numériques', 'alpha_dash' => 'alphabétiques, tirets haut ou tirets bas (underscore)', 'digit' => 'digitaux', 'numeric' => 'numériques', );./kohana/system/i18n/fr_FR/pagination.php0000644000175000017500000000064111200534242017737 0ustar tokkeetokkee 'Le groupe %s n\'est pas défini dans votre configuration de la pagination.', 'page' => 'page', 'pages' => 'pages', 'item' => 'résultat', 'items' => 'résultats', 'of' => 'sur', 'first' => 'premier', 'last' => 'dernier', 'previous' => 'précédent', 'next' => 'suivant', ); ./kohana/system/i18n/fr_FR/calendar.php0000644000175000017500000000240211121324570017357 0ustar tokkeetokkee 'Di', 'mo' => 'Lu', 'tu' => 'Ma', 'we' => 'Me', 'th' => 'Je', 'fr' => 'Ve', 'sa' => 'Sa', // Short day names 'sun' => 'Dim', 'mon' => 'Lun', 'tue' => 'Mar', 'wed' => 'Mer', 'thu' => 'Jeu', 'fri' => 'Ven', 'sat' => 'Sam', // Long day names 'sunday' => 'Dimanche', 'monday' => 'Lundi', 'tuesday' => 'Mardi', 'wednesday' => 'Mercredi', 'thursday' => 'Jeudi', 'friday' => 'Vendredi', 'saturday' => 'Samedi', // Short month names 'jan' => 'Jan', 'feb' => 'Fév', 'mar' => 'Mar', 'apr' => 'Avr', 'may' => 'Mai', 'jun' => 'Jui', 'jul' => 'Juil', 'aug' => 'Aoû', 'sep' => 'Sep', 'oct' => 'Oct', 'nov' => 'Nov', 'dec' => 'Déc', // Long month names 'january' => 'Janvier', 'february' => 'Février', 'march' => 'Mars', 'april' => 'Avril', 'mayl' => 'Mai', 'june' => 'Juin', 'july' => 'Juillet', 'august' => 'Août', 'september' => 'Septembre', 'october' => 'Octobre', 'november' => 'Novembre', 'december' => 'Décembre' );./kohana/system/i18n/fr_FR/orm.php0000644000175000017500000000025411121324570016406 0ustar tokkeetokkee 'Le répertoire de destination pour l\'upload, %s, ne semble pas être accessible en écriture.', ); ./kohana/system/i18n/fr_FR/event.php0000644000175000017500000000053711121324570016736 0ustar tokkeetokkee 'Le sujet %s n\'a pas pu peut être attaché à %s. Les sujets doivent étendre la classe Event_Subject.', 'invalid_observer' => 'L\'observeur %s n\'a pas pu peut être attaché à %s. Les observeurs doivent étendre la classe Event_Observer.', ); ./kohana/system/i18n/fr_FR/session.php0000644000175000017500000000041611121324570017274 0ustar tokkeetokkee 'Le nom de session "session_name", %s, est invalide. Il doit contenir uniquement des caractères alphanumériques et au moins une lettre doit être présente.', ); ./kohana/system/i18n/fr_FR/image.php0000644000175000017500000000320211132220312016656 0ustar tokkeetokkee 'Le répertoire %s spécifié n\'est pas accessible en écriture.', 'getimagesize_missing' => 'La librairie d\'image requiert la function PHP getimagesize. Celle-ci n\'est pas disponible dans votre installation.', 'unsupported_method' => 'Le pilote configuré ne supporte pas la transformation d\'image %s.', 'file_not_found' => 'L\'image spécifié %s n\'a pas été trouvée. Merci de vérifier que l\'image existe bien avec la fonction file_exists avant sa manipulation.', 'type_not_allowed' => 'L\'image spécifié %s n\'est pas d\'un type autorisé.', 'invalid_width' => 'La largeur que vous avez spécifiée, %s, est invalide.', 'invalid_height' => 'La hauteur que vous avez spécifiée, %s, est invalide.', 'invalid_dimensions' => 'Les dimensions spécifiées pour %s ne sont pas valides.', 'invalid_master' => 'La dimension principale (master dim) n\'est pas valide.', 'invalid_flip' => 'La direction de rotation spécifiée n\'est pas valide.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'Le répertoire ImageMagick spécifié ne contient pas le programme requis %s.', ), // GraphicsMagick specific messages 'graphicsmagick' => array ( 'not_found' => 'Le répertoire GraphicsMagick spécifié ne contient pas le programme requis %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'La librairie d\'image requiert GD2. Veuillez consulter http://php.net/gd_info pour de plus amples informations.', ), );./kohana/system/i18n/de_DE/0000755000175000017500000000000011263472434015053 5ustar tokkeetokkee./kohana/system/i18n/de_DE/encrypt.php0000644000175000017500000000063711121324570017244 0ustar tokkeetokkee 'Die Gruppe %s ist nicht in Ihrer Konfiguration enthalten.', 'requires_mcrypt' => 'Um die Bibliothek Encrypt zu benutzen, muss mcrypt in Ihrer PHP-Installation aktiviert werden', 'no_encryption_key' => 'Um die Bibliothek Encrypt zu benutzen, müssen Sie einen Schlüssel in Ihrer Konfiguration eintragen' ); ./kohana/system/i18n/de_DE/database.php0000644000175000017500000000161411121324570017320 0ustar tokkeetokkee 'Die Gruppe %s ist in Ihrer Konfiguration nicht definiert worden.', 'error' => 'Es gab einen SQL-Fehler: %s', 'connection' => 'Es gab einen Fehler bei der Verbindung mit der Datenbank: %s', 'invalid_dsn' => 'Die von Ihnen angegebene DSN ist ungültig: %s', 'must_use_set' => 'Sie müssen SET in Ihrem Query benutzen.', 'must_use_where' => 'Sie müssen WHERE in Ihrem Query benutzen.', 'must_use_table' => 'Sie müssen eine Tabelle für Ihren Query angeben.', 'table_not_found' => 'Die Tabelle %s konnte in der Datenbank nicht gefunden werden.', 'not_implemented' => 'Die Methode %s wird von diesem Datenbanktreiber nicht unterstützt.', 'result_read_only' => 'Ergebnisse der Anfrage können nur gelesen werden.', );./kohana/system/i18n/de_DE/profiler.php0000644000175000017500000000072711121324570017402 0ustar tokkeetokkee 'Benchmark-Tests', 'post_data' => 'POST-Daten:', 'no_post' => 'Keine POST-Daten', 'session_data' => 'Session-Daten', 'no_session' => 'Keine Session-Daten', 'queries' => 'Datenbank-Anfragen', 'no_queries' => 'Keine Anfragen', 'no_database' => 'Datenbank nicht geladen', 'cookie_data' => 'Cookie-Daten', 'no_cookie' => 'Keine Cookie-Daten', ); ./kohana/system/i18n/de_DE/errors.php0000644000175000017500000000236311121324570017072 0ustar tokkeetokkee array( 1, 'Framework-Fehler', 'Lesen Sie bitte in der Kohana-Dokumentation, um mehr über den folgenden Fehler zu erfahren.'), E_PAGE_NOT_FOUND => array( 1, 'Seite Nicht Gefunden', 'Die aufgerufene Seite wurde nicht gefunden. Sie wurde entweder verschoben, gelöscht oder archiviert.'), E_DATABASE_ERROR => array( 1, 'Datenbank-Fehler', 'Ein Datenbankfehler ist während des Aufrufs aufgetreten. Überprüfen Sie bitte den unten stehenden Fehler für mehr Informationen.'), E_RECOVERABLE_ERROR => array( 1, 'Behebbarer Fehler', 'Es ist ein Fehler aufgetreten, der das Laden der Seite verhindert hat. Wenn der Fehler weiterhin besteht, kontaktieren Sie bitte den Administrator der Seite.'), E_ERROR => array( 1, 'Fataler Fehler', ''), E_USER_ERROR => array( 1, 'Fataler Fehler', ''), E_PARSE => array( 1, 'Syntax-Fehler', ''), E_WARNING => array( 1, 'Warnung', ''), E_USER_WARNING => array( 1, 'Warnung', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Laufzeitfehler', ''), );./kohana/system/i18n/de_DE/cache.php0000644000175000017500000000100611121324570016612 0ustar tokkeetokkee 'Die Gruppe %s ist in Ihrer Konfiguration nicht definiert.', 'extension_not_loaded' => 'Die PHP-Erweiterung %s muss geladen sein, um diesen Treiber benutzen zu können.', 'unwritable' => 'Der eingestellte Speicherort %s ist nicht beschreibbar.', 'resources' => 'Das Cachen von Ressourcen ist nicht möglich, da diese nicht serialisiert werden können.', 'driver_error' => '%s' );./kohana/system/i18n/de_DE/swift.php0000644000175000017500000000022411121324570016704 0ustar tokkeetokkee 'Fehler beim Senden einer E-Mail aufgetreten.' );./kohana/system/i18n/de_DE/core.php0000644000175000017500000000400411121324570016500 0ustar tokkeetokkee 'Pro Seitenaufruf kann es nur eine Instanz von Kohana geben', 'uncaught_exception' => 'Unerwarteter Fehler vom Typ %s: %s in %s in Zeile %s', 'invalid_method' => 'Ungültige Methode %s aufgerufen in %s', 'invalid_property' => '%s ist keine Eigenschaft der Klasse %s.', 'log_dir_unwritable' => 'Das Log-Verzeichnis ist nicht beschreibbar: %s', 'resource_not_found' => '%s %s konnte nicht gefunden werden', 'invalid_filetype' => 'Die Dateiendung .%s ist in Ihrer View-Konfiguration nicht vorhanden', 'view_set_filename' => 'Sie müssen den Dateinamen der Ansicht festlegen, bevor render aufgerufen wird', 'no_default_route' => 'Erstellen Sie bitte eine Standardroute config/routes.php', 'no_controller' => 'Kohana gelang es nicht einen Controller zu finden, um diesen Aufruf zu verarbeiten: %s', 'page_not_found' => 'Die Seite %s konnte nicht gefunden werden.', 'stats_footer' => 'Seite geladen in {execution_time} Sekunden bei {memory_usage} Speichernutzung. Generiert von Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Die Abfrage konnte nicht abgeschlossen werden', 'errors_disabled' => 'Sie können zur Startseite zurück kehren oder es erneut versuchen.', // Drivers 'driver_implements' => 'Der Treiber %s für die Bibliothek %s muss das Interface %s implementieren', 'driver_not_found' => 'Der Treiber %s für die Bibliothek %s konnte nicht gefunden werden', // Resource names 'config' => 'Die Konfigurationsdatei', 'controller' => 'Der Controller', 'helper' => 'Der Helfer', 'library' => 'Die Bibliothek', 'driver' => 'Der Treiber', 'model' => 'Das Modell', 'view' => 'Die Ansicht', );./kohana/system/i18n/de_DE/captcha.php0000644000175000017500000000303511121324570017156 0ustar tokkeetokkee 'Die eingestellte Datei %s konnte nicht gefunden werden. Kontrollieren Sie bitte, bevor Sie Dateien benutzen, ob diese existieren. Sie können dafür die Funktion file_exists() benutzen.', 'requires_GD2' => 'Die Captcha-Bibliothek erfordert GD2 mit FreeType-Unterstützung. Sehen Sie sich die Seite http://php.net/gd_info an, um weitere Informationen zu erhalten.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Hasst du Spam? (ja oder nein)', 'ja'), array('Bist du ein Roboter? (ja oder nein)', 'nein'), array('Feuer ist ... (heiß or kalt)', 'heiß'), array('Die Jahreszeit, die nach Herbst kommt ist ...', 'Winter'), array('Welcher Wochentag ist heute?', strftime('%A')), array('In welchem Monat befinden wir uns gerade?', strftime('%B')), ), ); ./kohana/system/i18n/de_DE/validation.php0000644000175000017500000000435011121525176017713 0ustar tokkeetokkee 'Ungültige Validierungsregel benutzt: %s', 'i18n_array' => 'Der i18n-Schlüssel %s muss ein Array sein, um diesen in der in_array-Regel benutzen zu können', 'not_callable' => 'Die Callback-Funktion %s, die zur Validierung benutzt wird, ist nicht aufrufbar', // General errors 'unknown_error' => 'Unbekannter Fehler bei der Validierungsregel von dem Feld %s aufgetreten.', 'required' => 'Das Feld %s ist erforderlich.', 'min_length' => 'Das Feld %s muss mindestens %d Zeichen lang sein.', 'max_length' => 'Das Feld %s darf höchstens %d Zeichen lang sein.', 'exact_length' => 'Das Feld %s muss genau %d Zeichen enthalten.', 'in_array' => 'Das Feld %s muss ausgewählt werden.', 'matches' => 'Das Feld %s muss mit dem Feld %s übereinstimmen.', 'valid_url' => 'Das Feld %s muss eine gültige URL beinhalten.', 'valid_email' => 'Das Feld %s muss eine gültige E-Mailadresse beinhalten.', 'valid_ip' => 'Das Feld %s muss eine gültige IP-Adresse beinhalten.', 'valid_type' => 'Das Feld %s darf nur %s beinhalten.', 'range' => 'Das Feld %s muss zwischen festgelegten Bereichen sein.', 'regex' => 'Das Feld %s entspricht nicht einer akzeptierten Eingabe.', 'depends_on' => 'Das Feld %s hängt vom Feld %s ab.', // Upload errors 'user_aborted' => 'Das Hochladen der Datei %s wurde abgebrochen.', 'invalid_type' => 'Die Datei %s entspricht nicht den erlaubten Dateitypen.', 'max_size' => 'Die Datei %s ist zu groß. Die maximale Größe beträgt %s.', 'max_width' => 'Die Datei %s ist zu groß. Die maximal erlaubte Breite betägt %spx.', 'max_height' => 'Die Datei %s ist zu groß. Die maximal erlaubte Höhe betägt %spx.', 'min_width' => 'Die Datei %s ist zu klein. Die minimal erlaubte Breite betägt %spx.', 'min_height' => 'Die Datei %s ist zu klein. Die minimal erlaubte Höhe betägt %spx.', // Field types 'alpha' => 'alphabetische Zeichen', 'alpha_numeric' => 'alphabetische und numerische Zeichen', 'alpha_dash' => 'alphabetische Zeichen, Trennstriche und Unterstriche', 'digit' => 'Zahlen', 'numeric' => 'Nummern', ); ./kohana/system/i18n/de_DE/pagination.php0000644000175000017500000000063111121324570017703 0ustar tokkeetokkee 'Die Gruppe %s ist nicht in der Pagination-Konfiguration definiert worden.', 'page' => 'Seite', 'pages' => 'Seiten', 'item' => 'Element', 'items' => 'Elemente', 'of' => 'von', 'first' => 'Erste', 'last' => 'Letzte', 'previous' => 'Vorherige', 'next' => 'Nächste', ); ./kohana/system/i18n/de_DE/calendar.php0000644000175000017500000000240311121324570017322 0ustar tokkeetokkee 'So', 'mo' => 'Mo', 'tu' => 'Di', 'we' => 'Mi', 'th' => 'Do', 'fr' => 'Fr', 'sa' => 'Sa', // Short day names 'sun' => 'Son', 'mon' => 'Mon', 'tue' => 'Die', 'wed' => 'Mit', 'thu' => 'Don', 'fri' => 'Fre', 'sat' => 'Sam', // Long day names 'sunday' => 'Sonntag', 'monday' => 'Montag', 'tuesday' => 'Dienstag', 'wednesday' => 'Mittwoch', 'thursday' => 'Donnerstag', 'friday' => 'Freitag', 'saturday' => 'Samstag', // Short month names 'jan' => 'Jan', 'feb' => 'Feb', 'mar' => 'Mär', 'apr' => 'Apr', 'may' => 'Mai', 'jun' => 'Jun', 'jul' => 'Jul', 'aug' => 'Aug', 'sep' => 'Sep', 'oct' => 'Okt', 'nov' => 'Nov', 'dec' => 'Dez', // Long month names 'january' => 'Januar', 'february' => 'Februar', 'march' => 'März', 'april' => 'April', 'mayl' => 'Mai', 'june' => 'Juni', 'july' => 'Juli', 'august' => 'August', 'september' => 'September', 'october' => 'Oktober', 'november' => 'November', 'december' => 'Dezember' );./kohana/system/i18n/de_DE/orm.php0000644000175000017500000000024111121324570016344 0ustar tokkeetokkee 'Das Verzeichnis für hochgeladene Dateien, %s, ist nicht beschreibbar.', );./kohana/system/i18n/de_DE/event.php0000644000175000017500000000062311121324570016674 0ustar tokkeetokkee 'Der Versuch, das ungültige Subjekt %s an %s anzuhängen, ist fehlgeschlagen. Subjekte müssen die Klasse Event_Subject erweitern.', 'invalid_observer' => 'Der Versuch, den ungültigen Beobachter %s an %s anzuhängen, ist fehlgeschlagen. Beobachter müssen die Klasse Event_Observer erweitern.', ); ./kohana/system/i18n/de_DE/session.php0000644000175000017500000000035011121324570017233 0ustar tokkeetokkee 'Der Sessionname %s ist ungültig. Dieser darf nur aus alphanumerischen Zeichen und mindestens einem Buchstaben bestehen.', );./kohana/system/i18n/de_DE/image.php0000644000175000017500000000314711171102623016637 0ustar tokkeetokkee 'Die Bildbibliothek versucht die PHP-Funktion getimagesize() zu benutzen, die aber nicht Bestandteil ihrer PHP-Installation ist.', 'unsupported_method' => 'Der Bildtreiber, den Sie benutzen, unterstützt nicht die %s-Bildtransformation.', 'file_not_found' => 'Das angegebene Bild %s konnte nicht gefunden werden. Stellen Sie bitte sicher, dass das Bild existiert. Benutzen Sie hierzu die Funktion file_exists().', 'type_not_allowed' => 'Das angegebene Bild %s ist kein erlaubter Bildtyp.', 'invalid_width' => 'Die von Ihnen festgelegte Bildbreite, %s, ist ungültig.', 'invalid_height' => 'Die von Ihnen festgelegte Bildhöhe, %s, ist ungültig.', 'invalid_dimensions' => 'Das festgelegte Format für %s ist ungültig.', 'invalid_master' => 'Die festgelegte Master-Dimension ist ungültig.', 'invalid_flip' => 'Die festgelegte Richtung der Spiegelung ist ungültig.', 'directory_unwritable' => 'Das Verzeichnis %s ist nicht beschreibbar.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'Das festgelegte ImageMagic-Verzeichnis enthält nicht das benötigte Programm %s.', ), // GraphicsMagick specific messages 'graphicsmagick' => array ( 'not_found' => 'Das festgelegte GraphicsMagick-Verzeichnis enthält nicht das benötigte Programm %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'Die Bildbibliothek erfordert GD2. Sehen Sie sich die Seite http://php.net/gd_info an, um weitere Informationen zu erhalten.', ), ); ./kohana/system/i18n/pt_BR/0000755000175000017500000000000011263472434015121 5ustar tokkeetokkee./kohana/system/i18n/pt_BR/encrypt.php0000644000175000017500000000064411121324570017310 0ustar tokkeetokkee 'O grupo %s não esta definido na sua configuração.', 'requires_mcrypt' => 'Para usar a biblioteca Encrypt, mcrypt deve estar habilitada em sua configuação PHP.', 'no_encryption_key' => 'Para usar a biblioteca Encrypt, você precisa configurar um chave de criptografia no seu arquivo de configuracão.' ); ./kohana/system/i18n/pt_BR/database.php0000644000175000017500000000164311121324570017370 0ustar tokkeetokkee 'O grupo %s não está definido na sua configuracão.', 'error' => 'Houve um erro no seguinte comando SQL: %s', 'connection' => 'Houve um erro durante a conexão com o banco de dados: %s', 'invalid_dsn' => 'O DSN informado não é válido: %s', 'must_use_set' => 'Você deve fornecer uma cláusula SET para a sua consulta.', 'must_use_where' => 'Você deve fornecer uma cláusula WHERE para a sua consulta.', 'must_use_table' => 'Você deve fornecer um nome de tabela para a sua consulta.', 'table_not_found' => 'A tabela %s não existe em seu banco de dados.', 'not_implemented' => 'O método que você chamou, %s, não é suportado pelo driver.', 'result_read_only' => 'Resultados de consultas são apenas para leitura.', );./kohana/system/i18n/pt_BR/profiler.php0000644000175000017500000000101711121324570017441 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Dados de Post', 'no_post' => 'Não existem dados de Post', 'session_data' => 'Dados de Sessão', 'no_session' => 'Nao existem dados de Sessão', 'queries' => 'Consultas ao Banco de Dados', 'no_queries' => 'Não existem consultas', 'no_database' => 'Banco de dados não foi carregado', 'cookie_data' => 'Dados de cookie', 'no_cookie' => 'Sem dados de cookie', ); ./kohana/system/i18n/pt_BR/errors.php0000644000175000017500000000234211121324570017135 0ustar tokkeetokkee array( 1, 'Framework Error', 'Por favor, verifique a documentacão do Kohana para maiores informacões sobre o seguinte erro.'), E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'Não foi possível encontrar a página requisitada, em virtude de remocão, renomeacão, ou arquivamento.'), E_DATABASE_ERROR => array( 1, 'Database Error', 'Ocorreu um erro de banco de dados enquanto se processava o procedimento requisitado. Por favor, revise o erro de banco de dados abaixo para maiores informacões.'), E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Um erro foi detectado, prevenindo o carregamento desta página. Caso o problema persista, por favor, contacte o administrador do website.'), E_ERROR => array( 1, 'Fatal Error', ''), E_USER_ERROR => array( 1, 'Fatal Error', ''), E_PARSE => array( 1, 'Syntax Error', ''), E_WARNING => array( 1, 'Warning Message', ''), E_USER_WARNING => array( 1, 'Warning Message', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/pt_BR/cache.php0000644000175000017500000000075611121324570016673 0ustar tokkeetokkee 'O grupo %s não esta definido em sua configuação.', 'extension_not_loaded' => 'A extenção %s do PHP deve estar carregada para usar este driver.', 'unwritable' => 'O local configurado para guardar, %s, não é gravável.', 'resources' => 'O cache de recursos é impossível, porque recursos não podem ser serializados.', 'driver_error' => '%s', );./kohana/system/i18n/pt_BR/swift.php0000644000175000017500000000024011121324570016750 0ustar tokkeetokkee 'Um erro ocorreu enquanto a imagem estava sendo enviada.' ); ./kohana/system/i18n/pt_BR/core.php0000644000175000017500000000365611122714624016566 0ustar tokkeetokkee 'Apenas uma instância do Kohana é permitida para cada página requisitada.', 'uncaught_exception' => 'Não foi possível capturar %s: %s no arquivo %s, linha %s', 'invalid_method' => 'Método %s inválido, chamado por %s.', 'invalid_property' => 'A propriedade %s não existe na classe %s.', 'log_dir_unwritable' => 'A diretiva de configuracao do seu log.directory nao esta apontando para um diretorio com permissao de escrita disponivel.', 'resource_not_found' => 'Nao foi possivel executar a requisicao %s, %s,.', 'invalid_filetype' => 'O tipo de arquivo solicitado, .%s, não é permitido em seu arquivo de configuração do view.', 'no_default_route' => 'Por favor, selecione uma rota padrão em config/routes.php.', 'no_controller' => 'Não foi possível determinar um controlador para processar a requisicao: %s', 'page_not_found' => 'A página %s requisitada, não foi encontrada.', 'stats_footer' => 'Carregado em {execution_time} segundo(s), utilizando {memory_usage} de memória. Gerado por Kohana v{kohana_version}.', 'error_message' => 'Erro ocorrido na linha %s de %s.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Incapaz de completar a solicitação', 'errors_disabled' => 'Você pode ir para home page ou tentar novamente.', // Resource names 'config' => 'arquivo de configuração', 'controller' => 'controlador', 'helper' => 'ajudante', 'library' => 'biblioteca', 'driver' => 'driver', 'model' => 'modelo', 'view' => 'vista', );./kohana/system/i18n/pt_BR/captcha.php0000644000175000017500000000263211121324570017226 0ustar tokkeetokkee 'O arquivo especificado, %s, não foi encontrado. Por favor verifique se o arquivo existe usando file_exists() antes de utiliza-lo.', 'requires_GD2' => 'A biblioteca Captcha necessita do GD2 com suporte FreeType. Por favor veja http://php.net/gd_info para maiores informações.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Você odeia spam? (sim ou não)', 'sim'), array('Você é um robo?', 'não'), array('Fogo é... (quente ou frio)', 'quente'), array('A estação após o outono é...', 'inverno'), array('Que dia da semana é hoje?', strftime('%A')), array('Em que mês do ano nós estamos?', strftime('%B')), ), ); ./kohana/system/i18n/pt_BR/validation.php0000644000175000017500000000403111121324570017750 0ustar tokkeetokkee 'Regra de validação inválida usada: %s', // General errors 'unknown_error' => 'Erro desconhecido de validação ao validar o campo %s.', 'required' => 'O campo %s é requerido.', 'min_length' => 'O campo %s deve ter ao menos %d caracteres de tamanho.', 'max_length' => 'O campo %s deve ter %d caracteres ou menos.', 'exact_length' => 'O campo %s deve ser de exatamente %d caracteres.', 'in_array' => 'O campo %s deve ser selecionado entre as opções listadas.', 'matches' => 'O campo %s deve ser igual ao campo %s.', 'valid_url' => 'O campo %s deve conter um URL válido.', 'valid_email' => 'O campo %s deve conter um endereço de email válido.', 'valid_ip' => 'O campo %s deve conter um endereço de IP válido.', 'valid_type' => 'O campo %s deve conter apenas caracteres %s.', 'range' => 'O campo %s deve estar entre os intervalos especificados.', 'regex' => 'O campo %s não combina com a entrada aceita.', 'depends_on' => 'O campo %s depende do campo %s.', // Upload errors 'user_aborted' => 'O arquivo %s foi abortado durante o envio.', 'invalid_type' => 'O arquivo %s não é de um tipo de arquivo permitido.', 'max_size' => 'O arquivo %s que você enviou é muito grande. O tamanho máximo permitido é %s.', 'max_width' => 'O arquivo %s que você enviou é muito grande. A largura máxima permitida é %spx.', 'max_height' => 'O arquivo %s que você enviou é muito grande. A altura máxima permitida é %spx.', 'min_width' => 'O arquivo %s que você enviou é muito pequeno. A largura mínima permitida é %spx.', 'min_height' => 'O arquivo %s que você enviou é muito pequeno. A altura mínima permitida é %spx.', // Field types 'alpha' => 'alfabético', 'alpha_numeric' => 'alfabético e numérico', 'alpha_dash' => 'alfabético, hífen e sublinhado', 'digit' => 'digito', 'numeric' => 'numérico', ); ./kohana/system/i18n/pt_BR/pagination.php0000644000175000017500000000062611121324570017755 0ustar tokkeetokkee 'O grupo %s não esta definido na sua configuração de paginação.', 'page' => 'página', 'pages' => 'páginas', 'item' => 'item', 'items' => 'itens', 'of' => 'de', 'first' => 'primeiro', 'last' => 'último', 'previous' => 'anterior', 'next' => 'próximo', ); ./kohana/system/i18n/pt_BR/calendar.php0000644000175000017500000000243411121324570017374 0ustar tokkeetokkee 'Do', 'mo' => 'Se', 'tu' => 'Te', 'we' => 'Qa', 'th' => 'Qi', 'fr' => 'Se', 'sa' => 'Sa', // Short day names 'sun' => 'Dom', 'mon' => 'Seg', 'tue' => 'Ter', 'wed' => 'Qua', 'thu' => 'Qui', 'fri' => 'Sex', 'sat' => 'Sab', // Long day names 'sunday' => 'Domingo', 'monday' => 'Segunda-Feira', 'tuesday' => 'Terca-Feira', 'wednesday' => 'Quarta-Feira', 'thursday' => 'Quinta-Feira', 'friday' => 'Sexta-Feira', 'saturday' => 'Sábado', // Short month names 'jan' => 'Jan', 'feb' => 'Fev', 'mar' => 'Mar', 'apr' => 'Abr', 'may' => 'Mai', 'jun' => 'Jun', 'jul' => 'Jul', 'aug' => 'Ago', 'sep' => 'Set', 'oct' => 'Out', 'nov' => 'Nov', 'dec' => 'Dez', // Long month names 'january' => 'Janeiro', 'february' => 'Fevereiro', 'march' => 'Marco', 'april' => 'Abril', 'mayl' => 'Maio', 'june' => 'Junho', 'july' => 'Julho', 'august' => 'Agosto', 'september' => 'Setembro', 'october' => 'Outubro', 'november' => 'Novembro', 'december' => 'Dezembro' ); ./kohana/system/i18n/pt_BR/orm.php0000644000175000017500000000024111121324570016412 0ustar tokkeetokkee 'O diretório de destino, %s, parece não ter permissão de escrita.', ); ./kohana/system/i18n/pt_BR/event.php0000644000175000017500000000053611121324570016745 0ustar tokkeetokkee 'Tentativa de anexar um sujeito inválido %s a %s falhou: Sujeitos devem extender a classe Event_Subject', 'invalid_observer' => 'Tentativa de anexar um observador inválido %s a %s falhou: Observadores devem extender a classe Event_Observer', ); ./kohana/system/i18n/pt_BR/session.php0000644000175000017500000000035011121324570017301 0ustar tokkeetokkee 'O session_name, %s, é inválido. Deve conter apenas caracteres alfanuméricos e ao menos uma letra deve estar presente.', );./kohana/system/i18n/pt_BR/image.php0000644000175000017500000000266511121324570016713 0ustar tokkeetokkee 'A biblioteca de imagem precisa da função getimagesize() do PHP, a qual não esta disponível na sua instalação.', 'unsupported_method' => 'O seu driver que esta configurado não suporta a transformação de imagem %s.', 'file_not_found' => 'A imagem especificada, %s, não foi encontrada. Por Favor verifique se a imagem existe usando file_exists() antes de manipula-la.', 'type_not_allowed' => 'A imagem especificada, %s, não é um tipo permitido de imagem.', 'invalid_width' => 'A largura que você especificou, %s, não é valida.', 'invalid_height' => 'A altura que você especificou, %s, não é valida.', 'invalid_dimensions' => 'As dimensões especificadas para %s não são validas.', 'invalid_master' => 'A dimenção principal especificada não é valida.', 'invalid_flip' => 'A direção de rotação especificada não é valida.', 'directory_unwritable' => 'O diretório especificado, %s, não pode ser escrito.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'O diretório ImageMagick especificado não contém um programa necessário, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'A biblioteca de imagem requer GD2. Por favor veja http://php.net/gd_info para maiores informações.', ), ); ./kohana/system/i18n/ru_RU/0000755000175000017500000000000011263472435015150 5ustar tokkeetokkee./kohana/system/i18n/ru_RU/encrypt.php0000644000175000017500000000110611121324570017330 0ustar tokkeetokkee 'Группа %s не определена вашей конфигурацией.', 'requires_mcrypt' => 'Для использования библиотеки Encrypt необходимо включить расширение "mcrypt" в конфигурации PHP.', 'no_encryption_key' => 'Для использования библиотеки Encrypt необходимо задать ключ шифрования в конфигурационном файле.' ); ./kohana/system/i18n/ru_RU/database.php0000644000175000017500000000223411121324570017413 0ustar tokkeetokkee 'Группа %s не определена Вашей конфигурацией.', 'error' => 'Ошибка SQL: %s', 'connection' => 'Не удалось подключиться к базе данных: %s', 'invalid_dsn' => 'Переданный DSN некорректен: %s', 'must_use_set' => 'Необходимо использовать оператор SET в этом запросе.', 'must_use_where' => 'Необходимо использовать оператор WHERE в этом запросе.', 'must_use_table' => 'Необходимо указать таблицу базы данных в этом запросе.', 'table_not_found' => 'Таблица %s не существует в Вашей базе данных.', 'not_implemented' => 'Запрошенный метод, %s, не поддерживается этим драйвером.', 'result_read_only' => 'Результат запроса доступен только для чтения.' ); ./kohana/system/i18n/ru_RU/profiler.php0000644000175000017500000000107611121324570017474 0ustar tokkeetokkee 'Производительность', 'post_data' => 'Данные POST', 'no_post' => 'Нет данных POST', 'session_data' => 'Данные сессии', 'no_session' => 'Нет данных сессии', 'queries' => 'Запросов к БД', 'no_queries' => 'Нет запросов к БД', 'no_database' => 'БД не загружена', 'cookie_data' => 'Данные cookie', 'no_cookie' => 'Нет данных cookie', ); ./kohana/system/i18n/ru_RU/errors.php0000644000175000017500000000307511121324570017167 0ustar tokkeetokkee array( 1, 'Ошибка фреймворка', 'Информация об этой ошибке доступна в документации Kohana.'), E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'Запрошенная страница не найдена. Возможно, она была перемещена, удалена, или архивирована.'), E_DATABASE_ERROR => array( 1, 'Database Error', 'При обработке запроса произошла ошибка в базе данных. Пожалуйста, уточните причину ошибки ниже'), E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Обнаружена ошибка, препятствующая загрузке этой страницы. Если это повторится, пожалуйста, уведомите администрацию сайта.'), E_ERROR => array( 1, 'Фатальная ошибка', ''), E_USER_ERROR => array( 1, 'Фатальная ошибка', ''), E_PARSE => array( 1, 'Синтаксическая ошибка', ''), E_WARNING => array( 1, 'Предупреждение', ''), E_USER_WARNING => array( 1, 'Предупреждение', ''), E_STRICT => array( 2, 'Стилистическая ошибка', ''), E_NOTICE => array( 2, 'Уведомление', ''), ); ./kohana/system/i18n/ru_RU/cache.php0000644000175000017500000000130211121324570016705 0ustar tokkeetokkee 'Группа "%s" не определена Вашей конфигурацией.', 'extension_not_loaded' => 'Расширение PHP "%s" должно быть загружено для использования этого драйвера.', 'unwritable' => 'Целевая директория хранения кеша, %s, не доступна для записи.', 'resources' => 'Кеширование ресурсов невозможно, так как ресурсы не могут быть сериализованы.', 'driver_error' => '%s', ); ./kohana/system/i18n/ru_RU/swift.php0000644000175000017500000000023311121324570017000 0ustar tokkeetokkee 'Отправка письма не удалась.' ); ./kohana/system/i18n/ru_RU/core.php0000644000175000017500000000501311121324570016575 0ustar tokkeetokkee 'Наличие более, чем одного экземпляра Kohana, в пределах одного запроса страницы, невозможно', 'uncaught_exception' => 'Не пойманное %s: %s в файле %s, на строке %s', 'invalid_method' => 'Вызов метода %s из файла %s невозможен', 'invalid_property' => 'Свойство %s не входит в состав класса %s.', 'log_dir_unwritable' => 'Директория для хранения журналов, %s, не доступна для записи', 'resource_not_found' => 'Запрошенный %s, %s, не найден', 'invalid_filetype' => 'Запрошенный тип файла, .%s, не разрешён конфигурацией видов', 'view_set_filename' => 'Необходимо задать файл вида перед вызовом render()', 'no_default_route' => 'Установите путь по умолчанию в файле config/routes.php.', 'no_controller' => 'Kohana не удалось найти контроллер для обработки этого запроса: %s', 'page_not_found' => 'Запрошенная страница, %s, не найдена.', 'stats_footer' => 'Загружено за {execution_time} секунд, используя {memory_usage} памяти. Сгенерировано Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Стек вызовов', 'generic_error' => 'Не удалось обработать запрос', 'errors_disabled' => 'Вы можете вернуться на начальную страницу или повторить попытку.', // Drivers 'driver_implements' => 'Драйвер %s библиотеки %s не реализует интерфейс %s', 'driver_not_found' => 'Драйвер %s библиотеки %s не найден', // Resource names 'config' => 'конфигурация', 'controller' => 'контроллер', 'helper' => 'помощник', 'library' => 'библиотека', 'driver' => 'драйвер', 'model' => 'модель', 'view' => 'вид', ); ./kohana/system/i18n/ru_RU/captcha.php0000644000175000017500000000274311121324570017257 0ustar tokkeetokkee 'Файл "%s" не найден. Убедитесь в наличии файлов функцией file_exists() перед их использованием.', 'requires_GD2' => 'Библиотека Captcha нуждается в расширении GD2 с поддержкой FreeType. Подробности на http://php.net/gd_info .', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Do you hate spam? (yes or no)', 'yes'), array('Are you a robot? (yes or no)', 'no'), array('Fire is... (hot or cold)', 'hot'), array('The season after fall is...', 'winter'), array('Which day of the week is it today?', strftime('%A')), array('Which month of the year are we in?', strftime('%B')), ), ); ./kohana/system/i18n/ru_RU/validation.php0000644000175000017500000000561211121324570020004 0ustar tokkeetokkee 'Некорректное правило валидации: %s', // General errors 'unknown_error' => 'Неизвестная ошибка при валидации поля %s.', 'required' => 'Поле %s обязательно для заполнения.', 'min_length' => 'Поле %s должно быть не короче %d символов.', 'max_length' => 'Поле %s должно быть не длиннее %d символов.', 'exact_length' => 'Поле %s должно быть длиной в %d символов.', 'in_array' => 'Поле %s должно содержать одно из перечисленных значений.', 'matches' => 'Поле %s должно совпадать с полем %s.', 'valid_url' => 'Поле %s должно содержать корректный URL.', 'valid_email' => 'Поле %s должно содержать корректный email.', 'valid_ip' => 'Поле %s должно содержать корректный IP-адрес.', 'valid_type' => 'Поле %s должно содержать только символы %s.', 'range' => 'Поле %s должно сожержать значение из заданных пределов.', 'regex' => 'Поле %s не является принимаемым значением.', 'depends_on' => 'Поле %s зависит от поля %s.', // Upload errors 'user_aborted' => 'Загрузка файла %s отменена пользователем.', 'invalid_type' => 'Загруженный файл, %s, не является файлом разрешённого типа.', 'max_size' => 'Загруженный файл, %s, слишком велик. Максимальный разрешённый размер файла: %s.', 'max_width' => 'Загруженный файл, %s, слишком велик. Максимальная разрешённая ширина: %s пикселей.', 'max_height' => 'Загруженный файл, %s, слишком велик. Максимальная разрешённая высота: %s пикселей.', 'min_width' => 'Загруженный файл, %s, слишком мал. Минимальная разрешённая ширина: %s пикселей.', 'min_height' => 'Загруженный файл, %s, слишком мал. Минимальная разрешённая высота: %s пикселей.', // Field types 'alpha' => 'буквенное', 'alpha_numeric' => 'буквенно-цифровое', 'alpha_dash' => 'буквенное, c дефисом и символом подчёркивания', 'digit' => 'цифровое', 'numeric' => 'числовое', ); ./kohana/system/i18n/ru_RU/pagination.php0000644000175000017500000000100011121324570017766 0ustar tokkeetokkee 'Группа %s не определена конфигурацией нумератора страниц.', 'page' => 'страница', 'pages' => 'страницы', 'item' => 'пункт', 'items' => 'пунктов', 'of' => 'из', 'first' => 'первая', 'last' => 'последняя', 'previous' => 'предыдущая', 'next' => 'следующая', ); ./kohana/system/i18n/ru_RU/calendar.php0000644000175000017500000000270311121324570017421 0ustar tokkeetokkee 'Пн', 'tu' => 'Вт', 'we' => 'Ср', 'th' => 'Чт', 'fr' => 'Пт', 'sa' => 'Сб', 'su' => 'Вс', // Short day names 'mon' => 'Пнд', 'tue' => 'Втр', 'wed' => 'Срд', 'thu' => 'Чтв', 'fri' => 'Птн', 'sat' => 'Сбт', 'sun' => 'Вск', // Long day names 'monday' => 'Понедельник', 'tuesday' => 'Вторник', 'wednesday' => 'Среда', 'thursday' => 'Четверг', 'friday' => 'Пятница', 'saturday' => 'Суббота', 'sunday' => 'Воскресенье', // Short month names 'jan' => 'Янв', 'feb' => 'Фев', 'mar' => 'Мар', 'apr' => 'Апр', 'may' => 'Май', 'jun' => 'Июн', 'jul' => 'Июл', 'aug' => 'Авг', 'sep' => 'Сен', 'oct' => 'Окт', 'nov' => 'Ноя', 'dec' => 'Дек', // Long month names 'january' => 'Январь', 'february' => 'Февраль', 'march' => 'Март', 'april' => 'Апрель', 'mayl' => 'Май', 'june' => 'Июнь', 'july' => 'Июль', 'august' => 'Август', 'september' => 'Сентябрь', 'october' => 'Октябрь', 'november' => 'Ноябрь', 'december' => 'Декабрь' ); ./kohana/system/i18n/ru_RU/orm.php0000644000175000017500000000030611121324570016442 0ustar tokkeetokkee 'POST-переменная %s не найдена.', 'file_exceeds_limit' => 'Размер закачанного файла превышает максимальный разрешённый конфигурацией PHP', 'file_partial' => 'Файл закачан не полностью', 'no_file_selected' => 'Вы не выбрали файл для закачивания', 'invalid_filetype' => 'Тип файла, который вы пытаетесь закачать, не разрешён.', 'invalid_filesize' => 'Размер файла, который вы пытаетесь закачать, превышает максимальный разрешённый (%s)', 'invalid_dimensions' => 'Разрешение картинки, которую вы пытаетесь закачать, превышает максимальное разрешённое (%s)', 'destination_error' => 'Не удалось переместить закачанный файл в пункт назначения.', 'no_filepath' => 'Путь для закачивания некорректен.', 'no_file_types' => 'Вы не разрешили ни один тип файлов.', 'bad_filename' => 'Файл с таким именем уже существует на сервере.', 'not_writable' => 'Запись в целевой каталог, %s, не возможна.', 'error_on_file' => 'Ошибка при закачивании %s:', // Error code responses 'set_allowed' => 'В целях безопасности, установите разрешённые для закачивания типы файлов.', 'max_file_size' => 'В целях безопасности, не используйте MAX_FILE_SIZE для ограничения размера закачиваемых файлов.', 'no_tmp_dir' => 'Временная директория для закачивания файлов не найдена.', 'tmp_unwritable' => 'Нет прав записи во временную директорию для закачивания файлов, %s.' ); ./kohana/system/i18n/ru_RU/event.php0000644000175000017500000000102511121324570016765 0ustar tokkeetokkee 'Попытка привязать некорректный субъект %s к %s не удалась: Субъект должен быть наследником класса Event_Subject', 'invalid_observer' => 'Попытка привязать некорректный наблюдатель %s к %s не удалась: Наблюдатель должен быть наследником класса Event_Observer', ); ./kohana/system/i18n/ru_RU/session.php0000644000175000017500000000047611121324570017340 0ustar tokkeetokkee 'Имя сессии, %s, некорректно. Оно должно состоять только из буквенно-цифровых символов, и, как минимум, одной буквы.', ); ./kohana/system/i18n/ru_RU/image.php0000644000175000017500000000334511121324570016735 0ustar tokkeetokkee 'Библиотеке Image необходима функция getimagesize(), недоступная в вашей инсталляции PHP.', 'unsupported_method' => 'Указанный драйвер не поддерживает операцию %s.', 'file_not_found' => 'Заданное изображение, %s, не найдено. Удостоверьтесь в наличии изображения функцией file_exists() перед его обработкой.', 'type_not_allowed' => 'Заданное изображение, %s, не является разрешённым типом изображений.', 'invalid_width' => 'Заданная ширина, %s, некорректна.', 'invalid_height' => 'Заданная высота, %s, некорректна.', 'invalid_dimensions' => 'Заданный размер для %s некорректен.', 'invalid_master' => 'Заданная основная сторона некорректна.', 'invalid_flip' => 'Направление разворота некорректно.', 'directory_unwritable' => 'Заданная директория, %s, недоступна для записи.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'Директория ImageMagick не содержит запрошенную программу, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'Библиотеке Image необходимо расширение GD2. Подробности на http://php.net/gd_info .', ), ); ./kohana/system/i18n/es_ES/0000755000175000017500000000000011263472435015112 5ustar tokkeetokkee./kohana/system/i18n/es_ES/encrypt.php0000644000175000017500000000063111121324570017274 0ustar tokkeetokkee 'El grupo %s no esta definidp en la configuración.', 'requires_mcrypt' => 'Para usar la librería de Encriptación, mcrypt debe estar habilitado.', 'no_encryption_key' => 'Para usar la librería de Encriptación, tienes que especificar una llave de encriptación en tu archivo de configuración.', ); ./kohana/system/i18n/es_ES/database.php0000644000175000017500000000152211121324570017354 0ustar tokkeetokkee 'El grupo %s no esta definido en tu configuración.', 'error' => 'Ocurrió un error de SQL: %s', 'connection' => 'Ocurrió un error conectando a la base de datos: %s', 'invalid_dsn' => 'El DSN que pusiste no es válido: %s', 'must_use_set' => 'Necesitas una clausula SET para tu consulta.', 'must_use_where' => 'Necesitas una clausula WHERE para tu consulta.', 'must_use_table' => 'Necesitas especificar la tabla para tu consulta.', 'table_not_found' => 'La tabla %s no existe en tu base de datos.', 'not_implemented' => 'El método requerido, %s, no esta soportado por este driver.', 'result_read_only' => 'Los resultados del query son de solo lectura.' );./kohana/system/i18n/es_ES/profiler.php0000644000175000017500000000104611121324570017433 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Datos Posteados', 'no_post' => 'No hay datos posteados', 'session_data' => 'Datos de sesión', 'no_session' => 'No hay datos de sesión', 'queries' => 'Consultas a la base de datos', 'no_queries' => 'No hay consultas a la base de datos', 'no_database' => 'No se encuentra la base de datos', 'cookie_data' => 'Datos de la cookie', 'no_cookie' => 'No se encuentran los datos de la cookie', ); ./kohana/system/i18n/es_ES/errors.php0000644000175000017500000000224111121324570017123 0ustar tokkeetokkee array( 1, 'Error del Framework', 'Revisa la documentación de Kohana para información sobre el siguiente error.'), E_PAGE_NOT_FOUND => array( 1, 'No se encuentra la página', 'No se encontró la página solicitada. Puede ser que haya sido movida, borrada o archivada.'), E_DATABASE_ERROR => array( 1, 'Error de Base de Datos', 'Ocurrió un error en la base de datos mientras se ejecutaba el procedimiento requerido. Para más información, revisa el error que aparece más abajo.'), E_RECOVERABLE_ERROR => array( 1, 'Error Recuperable', 'Se detectó un error que evitó que esta página cargara. Si el problema persiste, contacta con el administrador de la web.'), E_ERROR => array( 1, 'Error Fatal', ''), E_USER_ERROR => array( 1, 'Error Fatal', ''), E_PARSE => array( 1, 'Error de Syntaxis', ''), E_WARNING => array( 1, 'Advertencia', ''), E_USER_WARNING => array( 1, 'Advertencia', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/es_ES/cache.php0000644000175000017500000000077311121324570016662 0ustar tokkeetokkee 'El grupo %s no esta definido en la configuracion.', 'extension_not_loaded' => 'La extensión PHP %s tiene que estar cargada para poder utilizar este driver.', 'unwritable' => 'El directorio seleccionado, %s, no tiene permisos de escritura.', 'resources' => 'No es posible guardar el contenido en la cache, el contenido no es serializable.', 'driver_error' => '%s', );./kohana/system/i18n/es_ES/swift.php0000644000175000017500000000026011121324570016742 0ustar tokkeetokkee 'Ocurrió un error mientras se realizaba el envio del mensaje de correo.', );./kohana/system/i18n/es_ES/core.php0000644000175000017500000000351711121324570016546 0ustar tokkeetokkee 'Solo puede haber una instancia de Kohana por cada página.', 'uncaught_exception' => '%s no capturada: %s en el archivo %s, linea %s', 'invalid_method' => 'Método inválido %s llamado en %s.', 'invalid_property' => 'La propiedad %s no existe en la clase %s.', 'log_dir_unwritable' => 'Tu configuración del &8220;log.directory&8221; no apunta a un directorio con permiso de escritura.', 'resource_not_found' => 'El fichero de %s con nombre %s, no pudo ser encontrado.', 'invalid_filetype' => 'El tipo de fichero solicitado, .%s, no esta permitido en la configuración de tus vistas.', 'view_set_filename' => 'Tienes que definir el nombre de la vista antes de llamar al metodo render', 'no_default_route' => 'Por favor, especifica la ruta en config/routes.php.', 'no_controller' => 'Kohana no pudo determinar un controlador para procesar: %s', 'page_not_found' => 'La página que solicitase, %s, no se encuentra.', 'stats_footer' => 'Cargado en {execution_time} segundos, usando {memory_usage} de memoria. Generado con Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Imposible completar la solicitud', 'errors_disabled' => 'Puedes volver a la página de inico o volver a intentarlo.', // Drivers 'driver_implements' => 'El driver %s para la libreria %s debe implementar el interface %s', 'driver_not_found' => 'No se ha encontrado el driver %s para la libreria %s', // Resource names 'config' => 'fichero de configuración', 'controller' => 'controlador', 'helper' => 'helper', 'library' => 'librería', 'driver' => 'driver', 'model' => 'modelo', 'view' => 'vista', ); ./kohana/system/i18n/es_ES/captcha.php0000644000175000017500000000270711121324570017221 0ustar tokkeetokkee 'El archivo especificado, %s, no ha sido encontrado. Por favor, verifica que el fichero existe utilizando file_exists() antes de intentar utilizarlo.', 'requires_GD2' => 'La libreria Captcha requiere GD2 con soporte FreeType. Lea lo siguiente http://php.net/gd_info para ampliar la informacion.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('¿Odias el spam? (si o no)', 'si'), array('¿Eres un robot? (si o no)', 'no'), array('El fuego es... (caliente o frio)', 'caliente'), array('La estación que viene despues del otoño es...', 'invierno'), array('¿Qué día de la semana es hoy?', strftime('%A')), array('¿En qué mes del año estamos?', strftime('%B')), ), ); ./kohana/system/i18n/es_ES/validation.php0000644000175000017500000000467011174030662017755 0ustar tokkeetokkee 'La regla de validación usada es invalida: %s', 'i18n_array' => 'La clave %s i18n debe de ser un array para ser utilizado en la regla in_lang', 'not_callable' => 'La llamada de retorno %s utilizada para la validación no puede ser llamada', // General errors 'unknown_error' => 'Error de validación desconocido al comprobar el campo %s.', 'required' => 'El campo %s es obligatorio.', 'min_length' => 'El campo %s debe tener un mínimo de %d caracteres.', 'max_length' => 'El campo %s debe tener un máximo de %d caracteres.', 'exact_length' => 'El campo %s debe tener exactamente %d caracteres.', 'in_array' => 'El campo %s debe ser seleccionado de las opciones listadas.', 'matches' => 'El campo %s debe conincidir con el campo %s.', 'valid_url' => 'El campo %s debe contener una url valida, empezando con %s://.', 'valid_email' => 'El campo %s debe contener una dirección de email valida.', 'valid_ip' => 'El campo %s debe contener una dirección IP valida.', 'valid_type' => 'El campo %s debe contener unicamente %s.', 'range' => 'El campo %s debe estar entre los rangos especificados.', 'regex' => 'El campo %s no coincide con los datos aceptados.', 'depends_on' => 'El campo %s depende del campo %s.', // Upload errors 'user_aborted' => 'El envio del archivo %s fue abortado antes de completarse.', 'invalid_type' => 'El archivo %s no es un tipo de archivo permitido.', 'max_size' => 'El archivo %s que estas enviando es muy grande. El tamaño máximo es de %s.', 'max_width' => 'El archivo %s debe tener como ancho máximo %s, y tiene %spx.', 'max_height' => 'El archivo %s debe tener como alto máximo %s, y tiene %spx.', 'min_width' => 'El archivo %s que estas enviando es muy pequeño. El ancho mínimo permitido es de %spx.', 'min_height' => 'El archivo %s que estas enviando es muy pequeño. El alto mínimo permitido es de %spx.', // Field types 'alpha' => 'caracteres del alfabeto', 'alpha_numeric' => 'caracteres del alfabeto y numericos', 'alpha_dash' => 'caracteres del alfabeto, guiones y subrayado', 'digit' => 'digitos', 'numeric' => 'caracteres numéricos', );./kohana/system/i18n/es_ES/pagination.php0000644000175000017500000000063311121324570017743 0ustar tokkeetokkee 'El grupo %s no esta definido en la configuracion de la paginacion.', 'page' => 'página', 'pages' => 'páginas', 'item' => 'elemento', 'items' => 'elementos', 'of' => 'de', 'first' => 'primero', 'last' => 'último', 'previous' => 'anterior', 'next' => 'siguiente', ); ./kohana/system/i18n/es_ES/calendar.php0000644000175000017500000000237711121324570017372 0ustar tokkeetokkee 'Do', 'mo' => 'Lu', 'tu' => 'Ma', 'we' => 'Mi', 'th' => 'Ju', 'fr' => 'Vi', 'sa' => 'Sa', // Short day names 'sun' => 'Dom', 'mon' => 'Lun', 'tue' => 'Mar', 'wed' => 'Mie', 'thu' => 'Jue', 'fri' => 'Vie', 'sat' => 'Sab', // Long day names 'sunday' => 'Domingo', 'monday' => 'Lunes', 'tuesday' => 'Martes', 'wednesday' => 'Miércoles', 'thursday' => 'Jueves', 'friday' => 'Viernes', 'saturday' => 'Sábado', // Short month names 'jan' => 'Ene', 'feb' => 'Feb', 'mar' => 'Mar', 'apr' => 'Abr', 'may' => 'May', 'jun' => 'Jun', 'jul' => 'Jul', 'aug' => 'Ago', 'sep' => 'Sep', 'oct' => 'Oct', 'nov' => 'Nov', 'dec' => 'Dic', // Long month names 'january' => 'Enero', 'february' => 'Febrero', 'march' => 'Marzo', 'april' => 'Abril', 'mayl' => 'Mayo', 'june' => 'Junio', 'july' => 'Julio', 'august' => 'Agosto', 'september' => 'Septiembre', 'october' => 'Octubre', 'november' => 'Noviembre', 'december' => 'Diciembre', );./kohana/system/i18n/es_ES/orm.php0000644000175000017500000000024111121324570016402 0ustar tokkeetokkee 'El directorio seleccionado, %s, no tiene permisos de escritura.', );./kohana/system/i18n/es_ES/event.php0000644000175000017500000000052311121324570016731 0ustar tokkeetokkee 'Fallo el intento de añadir el sujeto %s a %s. Los sujetos deben extender la clase Event_Subject.', 'invalid_observer' => 'Fallo el intento de añadir el observador %s a %s. Los observadores deben extender la clase Event_Observer.', ); ./kohana/system/i18n/es_ES/session.php0000644000175000017500000000040511121324570017272 0ustar tokkeetokkee 'El parametro session_name, %s, no es valido. Solo debe contener caracteres alfanumericos y guiones bajos. Tambien al menos uno debe de ser una letra.', );./kohana/system/i18n/es_ES/image.php0000644000175000017500000000311711176456336016714 0ustar tokkeetokkee 'La librería &8220;Image&8221; requiere la función PHP getimagesize, que no parece estar disponible en tu instalación.', 'unsupported_method' => 'El driver que has elegido en la configuración no soporta el tipo de transformación %s.', 'file_not_found' => 'La imagen especificada, %s no se ha encontrado. Por favor, verifica que existe utilizando file_exists() antes de manipularla.', 'type_not_allowed' => 'El tipo de imagen especificado, %s, no es un tipo de imagen permitido.', 'invalid_width' => 'El ancho que has especificado, %s, no es valido.', 'invalid_height' => 'El alto que has especificado, %s, no es valido.', 'invalid_dimensions' => 'Las dimensiones que has especificado para %s no son validas.', 'invalid_master' => 'The master dim specified is not valid.', 'invalid_flip' => 'La dirección de rotación especificada no es valida.', 'directory_unwritable' => 'El directorio especificado, %s, no tiene permisos de escritura.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'El directorio de ImageMagick especificado, no contiene el programa requerido, %s.', ), // GraphicsMagick specific messages 'graphicsmagick' => array ( 'not_found' => 'El directorio de GraphicsMagick especificado, no contiene el programa requerido, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'La librería &8220;Image&8221; requiere GD2. Por favor, lee http://php.net/gd_info para más información.', ), ); ./kohana/system/i18n/es_AR/0000755000175000017500000000000011263472435015105 5ustar tokkeetokkee./kohana/system/i18n/es_AR/encrypt.php0000644000175000017500000000063111121324570017267 0ustar tokkeetokkee 'El grupo %s no esta definidp en la configuración.', 'requires_mcrypt' => 'Para usar la librería de Encriptación, mcrypt debe estar habilitado.', 'no_encryption_key' => 'Para usar la librería de Encriptación, tienes que especificar una llave de encriptación en tu archivo de configuración.', ); ./kohana/system/i18n/es_AR/database.php0000644000175000017500000000152211121324570017347 0ustar tokkeetokkee 'El grupo %s no esta definido en tu configuración.', 'error' => 'Ocurrió un error de SQL: %s', 'connection' => 'Ocurrió un error conectando a la base de datos: %s', 'invalid_dsn' => 'El DSN que pusiste no es válido: %s', 'must_use_set' => 'Necesitas una clausula SET para tu consulta.', 'must_use_where' => 'Necesitas una clausula WHERE para tu consulta.', 'must_use_table' => 'Necesitas especificar la tabla para tu consulta.', 'table_not_found' => 'La tabla %s no existe en tu base de datos.', 'not_implemented' => 'El método requerido, %s, no esta soportado por este driver.', 'result_read_only' => 'Los resultados del query son de solo lectura.' );./kohana/system/i18n/es_AR/profiler.php0000644000175000017500000000104611121324570017426 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Datos Posteados', 'no_post' => 'No hay datos posteados', 'session_data' => 'Datos de sesión', 'no_session' => 'No hay datos de sesión', 'queries' => 'Consultas a la base de datos', 'no_queries' => 'No hay consultas a la base de datos', 'no_database' => 'No se encuentra la base de datos', 'cookie_data' => 'Datos de la cookie', 'no_cookie' => 'No se encuentran los datos de la cookie', ); ./kohana/system/i18n/es_AR/errors.php0000644000175000017500000000224111121324570017116 0ustar tokkeetokkee array( 1, 'Error del Framework', 'Revisa la documentación de Kohana para información sobre el siguiente error.'), E_PAGE_NOT_FOUND => array( 1, 'No se encuentra la página', 'No se encontró la página solicitada. Puede ser que haya sido movida, borrada o archivada.'), E_DATABASE_ERROR => array( 1, 'Error de Base de Datos', 'Ocurrió un error en la base de datos mientras se ejecutaba el procedimiento requerido. Para más información, revisa el error que aparece más abajo.'), E_RECOVERABLE_ERROR => array( 1, 'Error Recuperable', 'Se detectó un error que evitó que esta página cargara. Si el problema persiste, contacta con el administrador de la web.'), E_ERROR => array( 1, 'Error Fatal', ''), E_USER_ERROR => array( 1, 'Error Fatal', ''), E_PARSE => array( 1, 'Error de Syntaxis', ''), E_WARNING => array( 1, 'Advertencia', ''), E_USER_WARNING => array( 1, 'Advertencia', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/es_AR/cache.php0000644000175000017500000000077311121324570016655 0ustar tokkeetokkee 'El grupo %s no esta definido en la configuracion.', 'extension_not_loaded' => 'La extensión PHP %s tiene que estar cargada para poder utilizar este driver.', 'unwritable' => 'El directorio seleccionado, %s, no tiene permisos de escritura.', 'resources' => 'No es posible guardar el contenido en la cache, el contenido no es serializable.', 'driver_error' => '%s', );./kohana/system/i18n/es_AR/swift.php0000644000175000017500000000026011121324570016735 0ustar tokkeetokkee 'Ocurrió un error mientras se realizaba el envio del mensaje de correo.', );./kohana/system/i18n/es_AR/core.php0000644000175000017500000000351611121324570016540 0ustar tokkeetokkee 'Solo puede haber una instancia de Kohana por cada página.', 'uncaught_exception' => '%s no capturada: %s en el archivo %s, linea %s', 'invalid_method' => 'Método inválido %s llamado en %s.', 'invalid_property' => 'La propiedad %s no existe en la clase %s.', 'log_dir_unwritable' => 'Tu configuración del &8220;log.directory&8221; no apunta a un directorio con permiso de escritura.', 'resource_not_found' => 'El archivo de %s con nombre %s, no pudo ser encontrado.', 'invalid_filetype' => 'El tipo de archivo solicitado, .%s, no esta permitido en la configuración de tus vistas.', 'view_set_filename' => 'Tienes que definir el nombre de la vista antes de llamar al metodo render', 'no_default_route' => 'Por favor, especifica la ruta en config/routes.php.', 'no_controller' => 'Kohana no pudo determinar un controlador para procesar: %s', 'page_not_found' => 'La página que solicitase, %s, no se encuentra.', 'stats_footer' => 'Cargado en {execution_time} segundos, usando {memory_usage} de memoria. Generado con Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Imposible completar la solicitud', 'errors_disabled' => 'Puedes volver a la página de inico o volver a intentarlo.', // Drivers 'driver_implements' => 'El driver %s para la libreria %s debe implementar el interface %s', 'driver_not_found' => 'No se ha encontrado el driver %s para la libreria %s', // Resource names 'config' => 'archivo de configuración', 'controller' => 'controlador', 'helper' => 'helper', 'library' => 'librería', 'driver' => 'driver', 'model' => 'modelo', 'view' => 'vista', );./kohana/system/i18n/es_AR/captcha.php0000644000175000017500000000270711121324570017214 0ustar tokkeetokkee 'El archivo especificado, %s, no ha sido encontrado. Por favor, verifica que el fichero existe utilizando file_exists() antes de intentar utilizarlo.', 'requires_GD2' => 'La libreria Captcha requiere GD2 con soporte FreeType. Lea lo siguiente http://php.net/gd_info para ampliar la informacion.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'america', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('¿Odias el spam? (si o no)', 'si'), array('¿Eres un robot? (si o no)', 'no'), array('El fuego es... (caliente o frio)', 'caliente'), array('La estación que viene despues del otoño es...', 'invierno'), array('¿Qué día de la semana es hoy?', strftime('%A')), array('¿En qué mes del año estamos?', strftime('%B')), ), ); ./kohana/system/i18n/es_AR/validation.php0000644000175000017500000000436211121324570017742 0ustar tokkeetokkee 'La regla de validación usada es invalida: %s', // General errors 'unknown_error' => 'Error de validación desconocido al comprobar el campo %s.', 'required' => 'El campo %s es obligatorio.', 'min_length' => 'El campo %s debe tener un mínimo de %d caracteres.', 'max_length' => 'El campo %s debe tener un máximo de %d caracteres.', 'exact_length' => 'El campo %s debe tener exactamente %d caracteres.', 'in_array' => 'El campo %s debe ser seleccionado de las opciones listadas.', 'matches' => 'El campo %s debe conincidir con el campo %s.', 'valid_url' => 'El campo %s debe contener una url valida, empezando con %s://.', 'valid_email' => 'El campo %s debe contener una dirección de email valida.', 'valid_ip' => 'El campo %s debe contener una dirección IP valida.', 'valid_type' => 'El campo %s debe contener unicamente %s.', 'range' => 'El campo %s debe estar entre los rangos especificados.', 'regex' => 'El campo %s no coincide con los datos aceptados.', 'depends_on' => 'El campo %s depende del campo %s.', // Upload errors 'user_aborted' => 'El envio del archivo %s fue abortado antes de completarse.', 'invalid_type' => 'El archivo %s no es un tipo de archivo permitido.', 'max_size' => 'El archivo %s que estas enviando es muy grande. El tamaño máximo es de %s.', 'max_width' => 'El archivo %s debe tener como ancho máximo %s, y tiene %spx.', 'max_height' => 'El archivo %s debe tener como alto máximo %s, y tiene %spx.', 'min_width' => 'El archivo %s que estas enviando es muy pequeño. El ancho mínimo permitido es de %spx.', 'min_height' => 'El archivo %s que estas enviando es muy pequeño. El alto mínimo permitido es de %spx.', // Field types 'alpha' => 'caracteres del alfabeto', 'alpha_numeric' => 'caracteres del alfabeto y numericos', 'alpha_dash' => 'caracteres del alfabeto, guiones y subrayado', 'digit' => 'digitos', 'numeric' => 'caracteres numéricos', ); ./kohana/system/i18n/es_AR/pagination.php0000644000175000017500000000063411121324570017737 0ustar tokkeetokkee 'El grupo %s no esta definido en la configuracion de la paginación.', 'page' => 'página', 'pages' => 'páginas', 'item' => 'elemento', 'items' => 'elementos', 'of' => 'de', 'first' => 'primero', 'last' => 'último', 'previous' => 'Anterior', 'next' => 'Siguiente', ); ./kohana/system/i18n/es_AR/calendar.php0000644000175000017500000000237511121324570017363 0ustar tokkeetokkee 'Do', 'mo' => 'Lu', 'tu' => 'Ma', 'we' => 'Mi', 'th' => 'Ju', 'fr' => 'Vi', 'sa' => 'Sa', // Short day names 'sun' => 'Dom', 'mon' => 'Lun', 'tue' => 'Mar', 'wed' => 'Mie', 'thu' => 'Jue', 'fri' => 'Vie', 'sat' => 'Sab', // Long day names 'sunday' => 'Domingo', 'monday' => 'Lunes', 'tuesday' => 'Martes', 'wednesday' => 'Miercoles', 'thursday' => 'Jueves', 'friday' => 'Viernes', 'saturday' => 'Sabado', // Short month names 'jan' => 'Ene', 'feb' => 'Feb', 'mar' => 'Mar', 'apr' => 'Abr', 'may' => 'May', 'jun' => 'Jun', 'jul' => 'Jul', 'aug' => 'Ago', 'sep' => 'Sep', 'oct' => 'Oct', 'nov' => 'Nov', 'dec' => 'Dic', // Long month names 'january' => 'Enero', 'february' => 'Febrero', 'march' => 'Marzo', 'april' => 'Abril', 'mayl' => 'Mayo', 'june' => 'Junio', 'july' => 'Julio', 'august' => 'Agosto', 'september' => 'Septiembere', 'october' => 'Octubre', 'november' => 'Noviembre', 'december' => 'diciembre' );./kohana/system/i18n/es_AR/orm.php0000644000175000017500000000024111121324570016375 0ustar tokkeetokkee 'El directorio seleccionado, %s, no tiene permisos de escritura.', );./kohana/system/i18n/es_AR/event.php0000644000175000017500000000052311121324570016724 0ustar tokkeetokkee 'Fallo el intento de añadir el sujeto %s a %s. Los sujetos deben extender la clase Event_Subject.', 'invalid_observer' => 'Fallo el intento de añadir el observador %s a %s. Los observadores deben extender la clase Event_Observer.', ); ./kohana/system/i18n/es_AR/session.php0000644000175000017500000000040611121324570017266 0ustar tokkeetokkee 'El parametro session_name, %s, no es valido. Solo debe contener caracteres alfanumericos y guiones bajos. También al menos uno debe de ser una letra.', );./kohana/system/i18n/es_AR/es_ar.patch0000644000175000017500000004460711116223755017226 0ustar tokkeetokkeeIndex: cache.php =================================================================== --- cache.php (revision 0) +++ cache.php (revision 0) @@ -0,0 +1,10 @@ + 'El grupo %s no esta definido en la configuracion.', + 'extension_not_loaded' => 'La extensión PHP %s tiene que estar cargada para poder utilizar este driver.', + 'unwritable' => 'El directorio seleccionado, %s, no tiene permisos de escritura.', + 'resources' => 'No es posible guardar el contenido en la cache, el contenido no es serializable.', + 'driver_error' => '%s', +); \ No newline at end of file Index: calendar.php =================================================================== --- calendar.php (revision 3284) +++ calendar.php (working copy) @@ -10,7 +10,6 @@ 'th' => 'Ju', 'fr' => 'Vi', 'sa' => 'Sa', - // Short day names 'sun' => 'Dom', 'mon' => 'Lun', @@ -19,16 +18,14 @@ 'thu' => 'Jue', 'fri' => 'Vie', 'sat' => 'Sab', - // Long day names - 'sunday' => 'Dominfo', + 'sunday' => 'Domingo', 'monday' => 'Lunes', 'tuesday' => 'Martes', 'wednesday' => 'Miercoles', 'thursday' => 'Jueves', 'friday' => 'Viernes', 'saturday' => 'Sabado', - // Short month names 'jan' => 'Ene', 'feb' => 'Feb', @@ -42,7 +39,6 @@ 'oct' => 'Oct', 'nov' => 'Nov', 'dec' => 'Dic', - // Long month names 'january' => 'Enero', 'february' => 'Febrero', Index: captcha.php =================================================================== --- captcha.php (revision 0) +++ captcha.php (revision 0) @@ -0,0 +1,33 @@ + 'El archivo especificado, %s, no ha sido encontrado. Por favor, verifica que el fichero existe utilizando file_exists() antes de intentar utilizarlo.', + 'requires_GD2' => 'La libreria Captcha requiere GD2 con soporte FreeType. Lea lo siguiente http://php.net/gd_info para ampliar la informacion.', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'it', 'to', 'be', 'or', + 'sun', 'car', 'dog', 'bed', 'kid', 'egg', + 'bike', 'tree', 'bath', 'roof', 'road', 'hair', + 'hello', 'world', 'earth', 'beard', 'chess', 'water', + 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', + 'america', 'release', 'playing', 'working', 'foreign', 'general', + 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', + 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('¿Odias el spam? (si o no)', 'si'), + array('¿Eres un robot? (si o no)', 'no'), + array('El fuego es... (caliente o frio)', 'caliente'), + array('La estación que viene despues del otoño es...', 'invierno'), + array('¿Qué día de la semana es hoy?', strftime('%A')), + array('¿En qué mes del año estamos?', strftime('%B')), + ), +); Index: core.php =================================================================== --- core.php (revision 3284) +++ core.php (working copy) @@ -3,13 +3,32 @@ $lang = array ( 'there_can_be_only_one' => 'Solo puede haber una instancia de Kohana por cada página.', - 'uncaught_exception' => 'Uncaught %s: %s en el archivo %s en la linea %s', - 'invalid_method' => 'Método Inváliudo %s llamado en %s.', - 'log_dir_unwritable' => 'Tu configuración del log.directory no apunta a un directorio con permiso de escritura.', - 'resource_not_found' => 'El llamado %s, %s, no pudo ser encontrado.', - 'no_default_route' => 'Por favor, especificá la ruta en config/routes.php.', - 'no_controller' => 'Kohana no pudo determinar un controlador para procesar: %s', - 'page_not_found' => 'La página que solicitase, %s, no pudo ser encontrada.', - 'stats_footer' => 'Cargado en {execution_time} segundos, usando {memory_usage} memoria. Generado con Kohana v{kohana_version}.', - 'error_message' => 'Ocurrio un error en la linea line %s de %s.' + 'uncaught_exception' => '%s no capturada: %s en el archivo %s, linea %s', + 'invalid_method' => 'Método inválido %s llamado en %s.', + 'invalid_property' => 'La propiedad %s no existe en la clase %s.', + 'log_dir_unwritable' => 'Tu configuración del &8220;log.directory&8221; no apunta a un directorio con permiso de escritura.', + 'resource_not_found' => 'El archivo de %s con nombre %s, no pudo ser encontrado.', + 'invalid_filetype' => 'El tipo de archivo solicitado, .%s, no esta permitido en la configuración de tus vistas.', + 'view_set_filename' => 'Tienes que definir el nombre de la vista antes de llamar al metodo render', + 'no_default_route' => 'Por favor, especifica la ruta en config/routes.php.', + 'no_controller' => 'Kohana no pudo determinar un controlador para procesar: %s', + 'page_not_found' => 'La página que solicitase, %s, no se encuentra.', + 'stats_footer' => 'Cargado en {execution_time} segundos, usando {memory_usage} de memoria. Generado con Kohana v{kohana_version}.', + 'error_file_line' => '%s [%s]:', + 'stack_trace' => 'Stack Trace', + 'generic_error' => 'Imposible completar la solicitud', + 'errors_disabled' => 'Puedes volver a la página de inico o volver a intentarlo.', + + // Drivers + 'driver_implements' => 'El driver %s para la libreria %s debe implementar el interface %s', + 'driver_not_found' => 'No se ha encontrado el driver %s para la libreria %s', + + // Resource names + 'config' => 'archivo de configuración', + 'controller' => 'controlador', + 'helper' => 'helper', + 'library' => 'librería', + 'driver' => 'driver', + 'model' => 'modelo', + 'view' => 'vista', ); \ No newline at end of file Index: database.php =================================================================== --- database.php (revision 3284) +++ database.php (working copy) @@ -3,11 +3,13 @@ $lang = array ( 'undefined_group' => 'El grupo %s no esta definido en tu configuración.', - 'error' => 'Hubo un error de SQL: %s', - 'connection' => 'Hubo un error conectando a la base de datos: %s', - 'driver_not_supported' => 'El driver de base de datos %s no existe.', + 'error' => 'Ocurrió un error de SQL: %s', + 'connection' => 'Ocurrió un error conectando a la base de datos: %s', 'invalid_dsn' => 'El DSN que pusiste no es válido: %s', 'must_use_set' => 'Necesitas una clausula SET para tu consulta.', 'must_use_where' => 'Necesitas una clausula WHERE para tu consulta.', - 'must_use_table' => 'Necesitas especificar la tabla para tu consulta.' + 'must_use_table' => 'Necesitas especificar la tabla para tu consulta.', + 'table_not_found' => 'La tabla %s no existe en tu base de datos.', + 'not_implemented' => 'El método requerido, %s, no esta soportado por este driver.', + 'result_read_only' => 'Los resultados del query son de solo lectura.' ); \ No newline at end of file Index: encrypt.php =================================================================== --- encrypt.php (revision 3284) +++ encrypt.php (working copy) @@ -2,6 +2,7 @@ $lang = array ( - 'requires_mcrypt' => 'Para usar la libreria de Encriptación, mcrypt debe estar habilitado.', - 'no_encryption_key' => 'Para usar la libreria de Encriptación, tenes que especificar una llave de encriptación en tu archivo de configuración.' + 'undefined_group' => 'El grupo %s no esta definidp en la configuración.', + 'requires_mcrypt' => 'Para usar la librería de Encriptación, mcrypt debe estar habilitado.', + 'no_encryption_key' => 'Para usar la librería de Encriptación, tienes que especificar una llave de encriptación en tu archivo de configuración.', ); Index: errors.php =================================================================== --- errors.php (revision 3284) +++ errors.php (working copy) @@ -2,15 +2,15 @@ $lang = array ( - E_KOHANA => array( 1, 'Error del Framework', 'Revisa la documentación de Kohana para información sobre el siguiente error.'), - E_PAGE_NOT_FOUND => array( 1, 'No se encuentra la página', 'No se encontró la página solicitada. Puede ser que haya sido movida, borrada o archivada.'), - E_DATABASE_ERROR => array( 1, 'Error de Base de Datos', 'Ocurrio un error en la base de datos mientras se ejecutaba el procedimiento requerido. Para más información, revisa el error de abajo.'), + E_KOHANA => array( 1, 'Error del Framework', 'Revisa la documentación de Kohana para información sobre el siguiente error.'), + E_PAGE_NOT_FOUND => array( 1, 'No se encuentra la página', 'No se encontró la página solicitada. Puede ser que haya sido movida, borrada o archivada.'), + E_DATABASE_ERROR => array( 1, 'Error de Base de Datos', 'Ocurrió un error en la base de datos mientras se ejecutaba el procedimiento requerido. Para más información, revisa el error que aparece más abajo.'), E_RECOVERABLE_ERROR => array( 1, 'Error Recuperable', 'Se detectó un error que evitó que esta página cargara. Si el problema persiste, contacta con el administrador de la web.'), - E_ERROR => array( 1, 'Error Fatal', ''), - E_USER_ERROR => array( 1, 'Error Fatal', ''), - E_PARSE => array( 1, 'Error de Syntax', ''), - E_WARNING => array( 1, 'Advertencia', ''), - E_USER_WARNING => array( 1, 'Advertencia', ''), + E_ERROR => array( 1, 'Error Fatal', ''), + E_USER_ERROR => array( 1, 'Error Fatal', ''), + E_PARSE => array( 1, 'Error de Syntaxis', ''), + E_WARNING => array( 1, 'Advertencia', ''), + E_USER_WARNING => array( 1, 'Advertencia', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), - E_NOTICE => array( 2, 'Runtime Message', ''), + E_NOTICE => array( 2, 'Runtime Message', ''), ); \ No newline at end of file Index: event.php =================================================================== --- event.php (revision 0) +++ event.php (revision 0) @@ -0,0 +1,7 @@ + 'Fallo el intento de añadir el sujeto %s a %s. Los sujetos deben extender la clase Event_Subject.', + 'invalid_observer' => 'Fallo el intento de añadir el observador %s a %s. Los observadores deben extender la clase Event_Observer.', +); Index: image.php =================================================================== --- image.php (revision 0) +++ image.php (revision 0) @@ -0,0 +1,27 @@ + 'La librería &8220;Image&8221; requiere la función PHP getimagesize, que no parece estar disponible en tu instalación.', + 'unsupported_method' => 'El driver que has elegido en la configuración no soporta el tipo de transformación %s.', + 'file_not_found' => 'La imagen especificada, %s no se ha encontrado. Por favor, verifica que existe utilizando file_exists() antes de manipularla.', + 'type_not_allowed' => 'El tipo de imagen especificado, %s, no es un tipo de imagen permitido.', + 'invalid_width' => 'El ancho que has especificado, %s, no es valido.', + 'invalid_height' => 'El alto que has especificado, %s, no es valido.', + 'invalid_dimensions' => 'Las dimensiones que has especificado para %s no son validas.', + 'invalid_master' => 'The master dim specified is not valid.', + 'invalid_flip' => 'La dirección de rotación especificada no es valida.', + 'directory_unwritable' => 'El directorio especificado, %s, no tiene permisos de escritura.', + + // ImageMagick specific messages + 'imagemagick' => array + ( + 'not_found' => 'El directorio de ImageMagick especificado, no contiene el programa requrido, %s.', + ), + + // GD specific messages + 'gd' => array + ( + 'requires_v2' => 'La librería &8220;Image&8221; requiere GD2. Por favor, lee http://php.net/gd_info para más información.', + ), +); Index: orm.php =================================================================== --- orm.php (revision 0) +++ orm.php (revision 0) @@ -0,0 +1,3 @@ + 'El grupo %s no esta definido en la configuracion de la paginación.', 'page' => 'página', 'pages' => 'páginas', - 'item' => 'item', - 'items' => 'items', + 'item' => 'elemento', + 'items' => 'elementos', 'of' => 'de', 'first' => 'primero', - 'last' => 'ultimo', - 'previous' => 'anterior', - 'next' => 'siguiente', + 'last' => 'último', + 'previous' => 'Anterior', + 'next' => 'Siguiente', ); Index: profiler.php =================================================================== --- profiler.php (revision 3284) +++ profiler.php (working copy) @@ -5,9 +5,11 @@ 'benchmarks' => 'Benchmarks', 'post_data' => 'Datos Posteados', 'no_post' => 'No hay datos posteados', - 'session_data' => 'Datos de Session', - 'no_session' => 'No hay datos de session', - 'queries' => 'Consultas a la Base de Datos', - 'no_queries' => 'No hay Consultas a la Base de Datos', - 'no_database' => 'No se encuentra la Base de Datos', + 'session_data' => 'Datos de sesión', + 'no_session' => 'No hay datos de sesión', + 'queries' => 'Consultas a la base de datos', + 'no_queries' => 'No hay consultas a la base de datos', + 'no_database' => 'No se encuentra la base de datos', + 'cookie_data' => 'Datos de la cookie', + 'no_cookie' => 'No se encuentran los datos de la cookie', ); Index: session.php =================================================================== --- session.php (revision 3284) +++ session.php (working copy) @@ -2,6 +2,5 @@ $lang = array ( - 'driver_not_supported' => 'El driver de sessiones, %s, no fue encontrado.', - 'driver_implements' => 'Los driver de sessiones deben implementar la interfase Session_Driver.' + 'invalid_session_name' => 'El parametro session_name, %s, no es valido. Solo debe contener caracteres alfanumericos y guiones bajos. También al menos uno debe de ser una letra.', ); \ No newline at end of file Index: swift.php =================================================================== --- swift.php (revision 0) +++ swift.php (revision 0) @@ -0,0 +1,6 @@ + 'Ocurrió un error mientras se realizaba el envio del mensaje de correo.', +); \ No newline at end of file Index: upload.php =================================================================== --- upload.php (revision 0) +++ upload.php (revision 0) @@ -0,0 +1,6 @@ + 'El directorio seleccionado, %s, no tiene permisos de escritura.', +); \ No newline at end of file Index: validation.php =================================================================== --- validation.php (revision 3284) +++ validation.php (working copy) @@ -3,29 +3,37 @@ $lang = array ( // Class errors - 'error_format' => 'Tu cadena de mensaje de error, debe contener la cadena {message} .', 'invalid_rule' => 'La regla de validación usada es invalida: %s', // General errors - 'unknown_error' => 'Error de validación desconocido mientras se validaba el %s field.', + 'unknown_error' => 'Error de validación desconocido al comprobar el campo %s.', 'required' => 'El campo %s es obligatorio.', - 'min_length' => 'El campo %s debe tener al menos %d caracteres.', - 'max_length' => 'El campo %s debe tener %d caracteres o menos.', + 'min_length' => 'El campo %s debe tener un mínimo de %d caracteres.', + 'max_length' => 'El campo %s debe tener un máximo de %d caracteres.', 'exact_length' => 'El campo %s debe tener exactamente %d caracteres.', 'in_array' => 'El campo %s debe ser seleccionado de las opciones listadas.', 'matches' => 'El campo %s debe conincidir con el campo %s.', - 'valid_url' => 'El campo %s debe contener una url válida, empezando con %s://.', - 'valid_email' => 'El campo %s debe contener una dirección de email válida.', - 'valid_ip' => 'El campo %s debe contener una direcicón IP válida.', - 'valid_type' => 'El campo %s debe contener unicamente %s caracteres.', + 'valid_url' => 'El campo %s debe contener una url valida, empezando con %s://.', + 'valid_email' => 'El campo %s debe contener una dirección de email valida.', + 'valid_ip' => 'El campo %s debe contener una dirección IP valida.', + 'valid_type' => 'El campo %s debe contener unicamente %s.', 'range' => 'El campo %s debe estar entre los rangos especificados.', 'regex' => 'El campo %s no coincide con los datos aceptados.', 'depends_on' => 'El campo %s depende del campo %s.', // Upload errors - 'user_aborted' => 'El archivo %s fue abortado mientras estaba subiendo.', + 'user_aborted' => 'El envio del archivo %s fue abortado antes de completarse.', 'invalid_type' => 'El archivo %s no es un tipo de archivo permitido.', - 'max_size' => 'El archivo %s que estabas subiendo es muy grande. El tamaño maximo es %s.', - 'max_width' => 'El archivo %s debe tener como ancho maximo %s, y tiene %spx.', - 'max_height' => 'El archivo %s debe tener como alto maximo %s, y tiene %spx.', + 'max_size' => 'El archivo %s que estas enviando es muy grande. El tamaño máximo es de %s.', + 'max_width' => 'El archivo %s debe tener como ancho máximo %s, y tiene %spx.', + 'max_height' => 'El archivo %s debe tener como alto máximo %s, y tiene %spx.', + 'min_width' => 'El archivo %s que estas enviando es muy pequeño. El ancho mínimo permitido es de %spx.', + 'min_height' => 'El archivo %s que estas enviando es muy pequeño. El alto mínimo permitido es de %spx.', + + // Field types + 'alpha' => 'caracteres del alfabeto', + 'alpha_numeric' => 'caracteres del alfabeto y numericos', + 'alpha_dash' => 'caracteres del alfabeto, guiones y subrayado', + 'digit' => 'digitos', + 'numeric' => 'caracteres numéricos', ); ./kohana/system/i18n/es_AR/image.php0000644000175000017500000000263511121324570016673 0ustar tokkeetokkee 'La librería &8220;Image&8221; requiere la función PHP getimagesize, que no parece estar disponible en tu instalación.', 'unsupported_method' => 'El driver que has elegido en la configuración no soporta el tipo de transformación %s.', 'file_not_found' => 'La imagen especificada, %s no se ha encontrado. Por favor, verifica que existe utilizando file_exists() antes de manipularla.', 'type_not_allowed' => 'El tipo de imagen especificado, %s, no es un tipo de imagen permitido.', 'invalid_width' => 'El ancho que has especificado, %s, no es valido.', 'invalid_height' => 'El alto que has especificado, %s, no es valido.', 'invalid_dimensions' => 'Las dimensiones que has especificado para %s no son validas.', 'invalid_master' => 'The master dim specified is not valid.', 'invalid_flip' => 'La dirección de rotación especificada no es valida.', 'directory_unwritable' => 'El directorio especificado, %s, no tiene permisos de escritura.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'El directorio de ImageMagick especificado, no contiene el programa requrido, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'La librería &8220;Image&8221; requiere GD2. Por favor, lee http://php.net/gd_info para más información.', ), ); ./kohana/system/i18n/pl_PL/0000755000175000017500000000000011263472434015121 5ustar tokkeetokkee./kohana/system/i18n/pl_PL/encrypt.php0000644000175000017500000000057411121324570017312 0ustar tokkeetokkee 'Brak definicji grupy %s w konfiguracji.', 'requires_mcrypt' => 'Aby użyć biblioteki szyfrowania, należy włączyć mcrypt w konfiguracji PHP.', 'no_encryption_key' => 'Aby użyć biblioteki szyfrowania, należy zdefiniować klucz szyfrujący w pliku konfiguracji.', ); ./kohana/system/i18n/pl_PL/database.php0000644000175000017500000000145511121324570017371 0ustar tokkeetokkee 'Brak definicji grupy % w konfiguracji.', 'error' => 'Wystąpił błąd SQL: %s', 'connection' => 'Wystąpił błąd podczas połączenia do bazy danych: %s', 'invalid_dsn' => 'Ustawiony DSN jest nieprawidłowy: %s', 'must_use_set' => 'Proszę ustawić sekcję SET dla zapytania.', 'must_use_where' => 'Proszę ustawić sekcję WHERE dla zapytania.', 'must_use_table' => 'Proszę wybrać tabelę dla zapytania.', 'table_not_found' => 'Tabeli %s nie ma w bazie danych.', 'not_implemented' => 'Wywołana metoda, %s, nie jest obsługiwana przez sterownik.', 'result_read_only' => 'Wynik zapytania jest tylko do odczytu.' );./kohana/system/i18n/pl_PL/profiler.php0000644000175000017500000000075411121324570017450 0ustar tokkeetokkee 'Pomiar wydajności', 'post_data' => 'Dane typu POST', 'no_post' => 'Brak danych typu POST', 'session_data' => 'Dane sesji', 'no_session' => 'Brak danych sesji', 'queries' => 'Zapytania do bazy danych', 'no_queries' => 'Brak zapytań', 'no_database' => 'Baza danych nie jest załadowana', 'cookie_data' => 'Dane Ciasteczka', 'no_cookie' => 'Brak Ciasteczka', ); ./kohana/system/i18n/pl_PL/errors.php0000644000175000017500000000232511121324570017136 0ustar tokkeetokkee array( 1, 'Błąd aplikacji', 'Proszę sprawdzić w dokumentacji Kohana informacje o tym błędzie.'), E_PAGE_NOT_FOUND => array( 1, 'Strony nie znaleziono', 'Nie znaleziono wybranej strony. Mogła zostać przeniesiona, usunięta lub zarchiwizowana.'), E_DATABASE_ERROR => array( 1, 'Błąd Bazy Danych', 'W bazie danych wystąpił błąd podczas próby wywołania zapytania. Proszę zapoznać się z opisem błędu poniżej.'), E_RECOVERABLE_ERROR => array( 1, 'Nieoczekiwany błąd', 'Wystąpił błąd który uniemożliwił załadowanie strony. Jeśli problem się utrzymuje prosimy skontaktować się z administratorem strony.'), E_ERROR => array( 1, 'Błąd krytyczny', ''), E_USER_ERROR => array( 1, 'Błąd krytyczny', ''), E_PARSE => array( 1, 'Błąd składni', ''), E_WARNING => array( 1, 'Ostrzeżenie', ''), E_USER_WARNING => array( 1, 'Ostrzeżenie', ''), E_STRICT => array( 2, 'Błąd ścisłej notacji', ''), E_NOTICE => array( 2, 'Błąd wykonania', ''), );./kohana/system/i18n/pl_PL/cache.php0000644000175000017500000000100511121324570016657 0ustar tokkeetokkee 'Grupa %s nie została zdefiniowana w konfiguracji.', 'extension_not_loaded' => 'Aby użyć tego sterownika musi zostać załadowane rozszerzenie PHP %s.', 'unwritable' => 'Wybrane w konfiguracji miejsce, %s, jest tylko do odczytu.', 'resources' => 'Zachowanie danych w pamięci podręcznej jest niemożliwe z powodu braku możliwości serializacji.', 'driver_error' => '%s', );./kohana/system/i18n/pl_PL/swift.php0000644000175000017500000000024311121324570016753 0ustar tokkeetokkee 'Wystąpił nieznany błąd podczas wysyłania wiadomości.', );./kohana/system/i18n/pl_PL/core.php0000644000175000017500000000400611121324570016550 0ustar tokkeetokkee 'Na jedno wywołanie strony można powołać tylko jedną instancję Kohany.', 'uncaught_exception' => 'Nieobsługiwany %s: %s w pliku %s w lini %s', 'invalid_method' => 'Nieprawidłowa metoda %s wywołana w %s.', 'invalid_property' => 'Właściwość %s w klasie %s nie istnieje.', 'log_dir_unwritable' => 'Katalog zapisu dziennika w konfiguracji, wskazuje na położenie tylko do odczytu.', 'resource_not_found' => 'Żądany %s, %s, Nie może zostać znaleziony.', 'invalid_filetype' => 'Żądany typ pliku, .%s, w konfiguracji widoków nie jest podany jako dozwolony.', 'view_set_filename' => 'Musisz podać plik widoku przed wywołaniem funkcji render', 'no_default_route' => 'Proszę ustawić domyślny adres wywołania w config/routes.php.', 'no_controller' => 'Kohana nie była w stanie określić kontrolera obsługującego wywołanie: %s', 'page_not_found' => 'Wywołana strona, %s, nie może zostać znaleziona.', 'stats_footer' => 'Czas wywołania: {execution_time} sekund, użyto {memory_usage} MB pamięci. Wygenerowano przez Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Zrzut stosu (Stack Trace)', 'generic_error' => 'Nie można zakończyć żądania', 'errors_disabled' => 'Przejdź na stronę główną lub spróbuj znowu.', // Drivers 'driver_implements' => 'Sterownik %s dla biblioteki %s musi posiadać implementację interfejsu %s', 'driver_not_found' => 'Nie znaleziono sterownika %s dla biblioteki %s', // Resource names 'config' => 'plik konfiguracyjny', 'controller' => 'kontroler', 'helper' => 'pomocnik', 'library' => 'biblioteka', 'driver' => 'sterownik', 'model' => 'model', 'view' => 'widok', );./kohana/system/i18n/pl_PL/captcha.php0000644000175000017500000000055311121324570017226 0ustar tokkeetokkee 'Podany plik %s, nie został znaleziony. Sprawdź czy plik istnieje używając file_exists() przed wywołaniem.', 'requires_GD2' => 'Biblioteka Captcha wymaga biblioteki graficznej GD2 z obsługą FreeType. Więcej informacji pod: http://php.net/gd_info.', ); ./kohana/system/i18n/pl_PL/validation.php0000644000175000017500000000432111127703575017766 0ustar tokkeetokkee 'Użyto niepoprawnej reguły walidacji: %s', 'i18n_array' => 'Klucz %s z i18n musi być tablicą do użycia z zasadami in_lang.', 'not_callable' => 'Funkcja callback %s uzyta w walidacji nie może zostać wywołana.', // General errors 'unknown_error' => 'Nieznany błąd walidacji podczas walidowania pola %s.', 'required' => 'Pole %s jest wymagane.', 'min_length' => 'Minimalna wymagana ilość znaków dla pola %s to %d.', 'max_length' => 'Maksymalana wymagana ilość znaków dla pola %s to %d.', 'exact_length' => 'Wymagana ilość znaków dla pola %s to dokładnie %d.', 'in_array' => 'Wartość pola %s musi zostać wybrana z listy.', 'matches' => 'Pole %s musi być identyczne z polem %s.', 'valid_url' => 'Pole %s musi zawierać poprawny adres URL, zaczynający się od %s://.', 'valid_email' => 'Pole %s musi zawierać poprawny adres email.', 'valid_ip' => 'Pole %s musi zawierać poprawny numer IP.', 'valid_type' => 'Pole %s może zawierać wyłącznie znaki typu %s.', 'range' => 'Pole %s musi się zawierać w określonym zakresie.', 'regex' => 'Pole %s nie odpowiada zdefiniowanej masce wprowadzania.', 'depends_on' => 'Pole %s jest zależne od pola %s.', // Upload errors 'user_aborted' => 'Przerwano podczas wysyłania pliku %s.', 'invalid_type' => 'Plik %s ma nieprawidłowy typ.', 'max_size' => 'Rozmiar pliku %s przekracza dozwoloną wartość. Maksymalna wielkość to %s.', 'max_width' => 'Szerokość pliku %s przekracza dozwoloną wartość. Maksymalna szerokość to %spx.', 'max_height' => 'Wysokość pliku %s przekracza dozwoloną wartość. Maksymalna wysokość to %spx.', 'min_width' => 'Plik %s który próbujesz wysłać, jest zbyt mały. Minimalna dozwolona szerokość to %spx.', 'min_height' => 'Plik %s który próbujesz wysłać, jest zbyt mały. Minimalna dozwolona wysokość to %spx.', // Field types 'alpha' => 'litera', 'alpha_numeric' => 'litera i/lub cyfra', 'alpha_dash' => 'litera, podkreślenie i myślnik', 'digit' => 'cyfra', 'numeric' => 'liczba', );./kohana/system/i18n/pl_PL/pagination.php0000644000175000017500000000062311121324570017752 0ustar tokkeetokkee 'Grupa %s nie została zdefiniowana w konfiguracji paginacji.', 'page' => 'strona', 'pages' => 'stron', 'item' => 'element', 'items' => 'elementów', 'of' => 'z', 'first' => 'pierwsza', 'last' => 'ostatnia', 'previous' => 'poprzednia', 'next' => 'następna', ); ./kohana/system/i18n/pl_PL/calendar.php0000644000175000017500000000243311121324570017373 0ustar tokkeetokkee 'Nd', 'mo' => 'Pn', 'tu' => 'Wt', 'we' => 'Śr', 'th' => 'Cz', 'fr' => 'Pt', 'sa' => 'So', // Short day names 'sun' => 'Nie', 'mon' => 'Pon', 'tue' => 'Wto', 'wed' => 'Śro', 'thu' => 'Czw', 'fri' => 'Pią', 'sat' => 'Sob', // Long day names 'sunday' => 'Niedziela', 'monday' => 'Poniedziałek', 'tuesday' => 'Wtorek', 'wednesday' => 'Środa', 'thursday' => 'Czwartek', 'friday' => 'Piątek', 'saturday' => 'Sobota', // Short month names 'jan' => 'Sty', 'feb' => 'Lut', 'mar' => 'Mar', 'apr' => 'Kwi', 'may' => 'Maj', 'jun' => 'Cze', 'jul' => 'Lip', 'aug' => 'Sie', 'sep' => 'Wrz', 'oct' => 'Paź', 'nov' => 'Lis', 'dec' => 'Gru', // Long month names 'january' => 'Styczeń', 'february' => 'Luty', 'march' => 'Marzec', 'april' => 'Kwiecień', 'mayl' => 'Maj', 'june' => 'Czerwiec', 'july' => 'Lipiec', 'august' => 'Sierpień', 'september' => 'Wrzesień', 'october' => 'Październik', 'november' => 'Listopad', 'december' => 'Grudzień' );./kohana/system/i18n/pl_PL/orm.php0000644000175000017500000000023011121324570016410 0ustar tokkeetokkee 'Nie posiadasz prawa zapisu do docelowego katalogu %s.', ); ./kohana/system/i18n/pl_PL/event.php0000644000175000017500000000056411121324570016746 0ustar tokkeetokkee 'Nieudana próba podłączenia niewłaściwego podmiotu %s do %s. Podmiot musi dziedziczyć po klasie Event_Subject.', 'invalid_observer' => 'Nieudana próba podłączenia niewłaściwego obserwatora %s do %s. Obserwator musi dziedziczyć po klasie Event_Observer.', );./kohana/system/i18n/pl_PL/session.php0000644000175000017500000000034211121324570017302 0ustar tokkeetokkee 'Nieprawidłowa session_name, %s. Powinna zawierać wyłącznie znaki alfanumeryczne i przynajmniej jedną literę.', );./kohana/system/i18n/pl_PL/image.php0000644000175000017500000000276011127703575016723 0ustar tokkeetokkee 'Biblioteka edycji grafiki wymaga funkcji PHP getimagesize(), która nie jest dostępna dla obecnej instalacji.', 'unsupported_method' => 'Biblioteka edycji grafiki nie posiada opcji: %s.', 'file_not_found' => 'Podana grafika %s, nie została znaleziona. Sprawdź proszę czy plik grafiki istnieje używając funkcji file_exists przed próbą transformacji.', 'type_not_allowed' => 'Podana grafika, %s, jest niedozwolonego typu.', 'invalid_width' => 'Podana szerokość, %s, jest nieprawidłowa.', 'invalid_height' => 'Podana wysokość, %s, jest nieprawidłowa.', 'invalid_dimensions' => 'Podane rozmiary dla %s są nieprawidłowe.', 'invalid_master' => 'Nadrzędne podane wymiary, nie są prawidłowe.', 'invalid_flip' => 'Podany kierunek obrotu jest nieprawidłowy.', 'directory_unwritable' => 'W podanym folderze, %s, zapis jest niedozwolony.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'Podany katalog ImageMagick nie zawiera wymaganego programu, %s.', ), // GraphicsMagick specific messages 'graphicsmagick' => array ( 'not_found' => 'Podany katalog GraphicsMagick nie zawiera wymaganego programu, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'Biblioteka manipulacji obrazem wymaga GD2. Zobacz http://php.net/gd_info aby dowiedzieć się więcej.', ), ); ./kohana/system/i18n/en_GB/0000755000175000017500000000000011263472435015066 5ustar tokkeetokkee./kohana/system/i18n/en_GB/encrypt.php0000755000175000017500000000056011121324570017254 0ustar tokkeetokkee 'The %s group is not defined in your configuration.', 'requires_mcrypt' => 'To use the Encrypt library, mcrypt must be enabled in your PHP installation', 'no_encryption_key' => 'To use the Encrypt library, you must set an encryption key in your config file' ); ./kohana/system/i18n/en_GB/database.php0000755000175000017500000000146311121324570017337 0ustar tokkeetokkee 'The %s group is not defined in your configuration.', 'error' => 'There was an SQL error: %s', 'connection' => 'There was an error connecting to the database: %s', 'invalid_dsn' => 'The DSN you supplied is not valid: %s', 'must_use_set' => 'You must set a SET clause for your query.', 'must_use_where' => 'You must set a WHERE clause for your query.', 'must_use_table' => 'You must set a database table for your query.', 'table_not_found' => 'Table %s does not exist in your database.', 'not_implemented' => 'The method you called, %s, is not supported by this driver.', 'result_read_only' => 'Query results are read only.' );./kohana/system/i18n/en_GB/profiler.php0000755000175000017500000000067011121324570017414 0ustar tokkeetokkee 'Benchmarks', 'post_data' => 'Post Data', 'no_post' => 'No post data', 'session_data' => 'Session Data', 'no_session' => 'No session data', 'queries' => 'Database Queries', 'no_queries' => 'No queries', 'no_database' => 'Database not loaded', 'cookie_data' => 'Cookie Data', 'no_cookie' => 'No cookie data', ); ./kohana/system/i18n/en_GB/errors.php0000755000175000017500000000222211121324570017101 0ustar tokkeetokkee array( 1, 'Framework Error', 'Please check the Kohana documentation for information about the following error.'), E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'The requested page was not found. It may have moved, been deleted, or archived.'), E_DATABASE_ERROR => array( 1, 'Database Error', 'A database error occurred while performing the requested procedure. Please review the database error below for more information.'), E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'An error was detected which prevented the loading of this page. If this problem persists, please contact the website administrator.'), E_ERROR => array( 1, 'Fatal Error', ''), E_USER_ERROR => array( 1, 'Fatal Error', ''), E_PARSE => array( 1, 'Syntax Error', ''), E_WARNING => array( 1, 'Warning Message', ''), E_USER_WARNING => array( 1, 'Warning Message', ''), E_STRICT => array( 2, 'Strict Mode Error', ''), E_NOTICE => array( 2, 'Runtime Message', ''), );./kohana/system/i18n/en_GB/cache.php0000755000175000017500000000072711121324570016640 0ustar tokkeetokkee 'The %s group is not defined in your configuration.', 'extension_not_loaded' => 'The %s PHP extension must be loaded to use this driver.', 'unwritable' => 'The configured storage location, %s, is not writable.', 'resources' => 'Caching of resources is impossible, because resources cannot be serialised.', 'driver_error' => '%s', );./kohana/system/i18n/en_GB/swift.php0000755000175000017500000000023211121324570016720 0ustar tokkeetokkee 'An error occurred while sending the email message.' );./kohana/system/i18n/en_GB/core.php0000755000175000017500000000352511121324570016524 0ustar tokkeetokkee 'There can be only one instance of Kohana per page request', 'uncaught_exception' => 'Uncaught %s: %s in file %s on line %s', 'invalid_method' => 'Invalid method %s called in %s', 'invalid_property' => 'The %s property does not exist in the %s class.', 'log_dir_unwritable' => 'The log directory is not writable: %s', 'resource_not_found' => 'The requested %s, %s, could not be found', 'invalid_filetype' => 'The requested filetype, .%s, is not allowed in your view configuration file', 'view_set_filename' => 'You must set the the view filename before calling render', 'no_default_route' => 'Please set a default route in config/routes.php', 'no_controller' => 'Kohana was not able to determine a controller to process this request: %s', 'page_not_found' => 'The page you requested, %s, could not be found.', 'stats_footer' => 'Loaded in {execution_time} seconds, using {memory_usage} of memory. Generated by Kohana v{kohana_version}.', 'error_file_line' => '%s [%s]:', 'stack_trace' => 'Stack Trace', 'generic_error' => 'Unable to Complete Request', 'errors_disabled' => 'You can go to the home page or try again.', // Drivers 'driver_implements' => 'The %s driver for the %s library must implement the %s interface', 'driver_not_found' => 'The %s driver for the %s library could not be found', // Resource names 'config' => 'config file', 'controller' => 'controller', 'helper' => 'helper', 'library' => 'library', 'driver' => 'driver', 'model' => 'model', 'view' => 'view', ); ./kohana/system/i18n/en_GB/captcha.php0000644000175000017500000000260011121324570017165 0ustar tokkeetokkee 'The specified file, %s, was not found. Please verify that files exist by using file_exists() before using them.', 'requires_GD2' => 'The Captcha library requires GD2 with FreeType support. Please see http://php.net/gd_info for more information.', // Words of varying length for the Captcha_Word_Driver to pick from // Note: use only alphanumeric characters 'words' => array ( 'cd', 'tv', 'it', 'to', 'be', 'or', 'sun', 'car', 'dog', 'bed', 'kid', 'egg', 'bike', 'tree', 'bath', 'roof', 'road', 'hair', 'hello', 'world', 'earth', 'beard', 'chess', 'water', 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', 'britain', 'release', 'playing', 'working', 'foreign', 'general', 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', ), // Riddles for the Captcha_Riddle_Driver to pick from // Note: use only alphanumeric characters 'riddles' => array ( array('Do you hate spam? (yes or no)', 'yes'), array('Are you a robot? (yes or no)', 'no'), array('Fire is... (hot or cold)', 'hot'), array('The season after autumn is...', 'winter'), array('Which day of the week is it today?', strftime('%A')), array('Which month of the year are we in?', strftime('%B')), ), ); ./kohana/system/i18n/en_GB/validation.php0000755000175000017500000000402511121324570017722 0ustar tokkeetokkee 'Invalid validation rule used: %s', 'i18n_array' => 'The %s i18n key must be an array to be used with the in_lang validation rule', // General errors 'unknown_error' => 'Unknown validation error while validating the %s field.', 'required' => 'The %s field is required.', 'min_length' => 'The %s field must be at least %d characters long.', 'max_length' => 'The %s field must be %d characters or fewer.', 'exact_length' => 'The %s field must be exactly %d characters.', 'in_array' => 'The %s field must be selected from the options listed.', 'matches' => 'The %s field must match the %s field.', 'valid_url' => 'The %s field must contain a valid URL.', 'valid_email' => 'The %s field must contain a valid email address.', 'valid_ip' => 'The %s field must contain a valid IP address.', 'valid_type' => 'The %s field must only contain %s characters.', 'range' => 'The %s field must be between specified ranges.', 'regex' => 'The %s field does not match accepted input.', 'depends_on' => 'The %s field depends on the %s field.', // Upload errors 'user_aborted' => 'The %s file was aborted during upload.', 'invalid_type' => 'The %s file is not an allowed file type.', 'max_size' => 'The %s file you uploaded was too large. The maximum size allowed is %s.', 'max_width' => 'The %s file you uploaded was too big. The maximum allowed width is %spx.', 'max_height' => 'The %s file you uploaded was too big. The maximum allowed height is %spx.', 'min_width' => 'The %s file you uploaded was too small. The minimum allowed width is %spx.', 'min_height' => 'The %s file you uploaded was too small. The minimum allowed height is %spx.', // Field types 'alpha' => 'alphabetical', 'alpha_numeric' => 'alphabetical and numeric', 'alpha_dash' => 'alphabetical, dash, and underscore', 'digit' => 'digit', 'numeric' => 'numeric', ); ./kohana/system/i18n/en_GB/pagination.php0000755000175000017500000000057511121324570017727 0ustar tokkeetokkee 'The %s group is not defined in your pagination configuration.', 'page' => 'page', 'pages' => 'pages', 'item' => 'item', 'items' => 'items', 'of' => 'of', 'first' => 'first', 'last' => 'last', 'previous' => 'previous', 'next' => 'next', ); ./kohana/system/i18n/en_GB/calendar.php0000755000175000017500000000240111121324570017335 0ustar tokkeetokkee 'Su', 'mo' => 'Mo', 'tu' => 'Tu', 'we' => 'We', 'th' => 'Th', 'fr' => 'Fr', 'sa' => 'Sa', // Short day names 'sun' => 'Sun', 'mon' => 'Mon', 'tue' => 'Tue', 'wed' => 'Wed', 'thu' => 'Thu', 'fri' => 'Fri', 'sat' => 'Sat', // Long day names 'sunday' => 'Sunday', 'monday' => 'Monday', 'tuesday' => 'Tuesday', 'wednesday' => 'Wednesday', 'thursday' => 'Thursday', 'friday' => 'Friday', 'saturday' => 'Saturday', // Short month names 'jan' => 'Jan', 'feb' => 'Feb', 'mar' => 'Mar', 'apr' => 'Apr', 'may' => 'May', 'jun' => 'Jun', 'jul' => 'Jul', 'aug' => 'Aug', 'sep' => 'Sep', 'oct' => 'Oct', 'nov' => 'Nov', 'dec' => 'Dec', // Long month names 'january' => 'January', 'february' => 'February', 'march' => 'March', 'april' => 'April', 'mayl' => 'May', 'june' => 'June', 'july' => 'July', 'august' => 'August', 'september' => 'September', 'october' => 'October', 'november' => 'November', 'december' => 'December' );./kohana/system/i18n/en_GB/orm.php0000644000175000017500000000021711121324570016361 0ustar tokkeetokkee 'The upload destination folder, %s, does not appear to be writable.', );./kohana/system/i18n/en_GB/event.php0000644000175000017500000000051111121324570016702 0ustar tokkeetokkee 'Attempt to attach invalid subject %s to %s failed: Subjects must extend the Event_Subject class', 'invalid_observer' => 'Attempt to attach invalid observer %s to %s failed: Observers must extend the Event_Observer class', ); ./kohana/system/i18n/en_GB/session.php0000755000175000017500000000037111121324570017253 0ustar tokkeetokkee 'The session_name, %s, is invalid. It must contain only alphanumeric characters and underscores. Also at least one letter must be present.', );./kohana/system/i18n/en_GB/image.php0000755000175000017500000000250711121324570016655 0ustar tokkeetokkee 'The Image library requires the getimagesize() PHP function, which is not available in your installation.', 'unsupported_method' => 'Your configured driver does not support the %s image transformation.', 'file_not_found' => 'The specified image, %s, was not found. Please verify that images exist by using file_exists() before manipulating them.', 'type_not_allowed' => 'The specified image, %s, is not an allowed image type.', 'invalid_width' => 'The width you specified, %s, is not valid.', 'invalid_height' => 'The height you specified, %s, is not valid.', 'invalid_dimensions' => 'The dimensions specified for %s are not valid.', 'invalid_master' => 'The master dimension specified is not valid.', 'invalid_flip' => 'The flip direction specified is not valid.', 'directory_unwritable' => 'The specified directory, %s, is not writable.', // ImageMagick specific messages 'imagemagick' => array ( 'not_found' => 'The ImageMagick directory specified does not contain a required program, %s.', ), // GD specific messages 'gd' => array ( 'requires_v2' => 'The Image library requires GD2. Please see http://php.net/gd_info for more information.', ), ); ./kohana/system/vendor/0000755000175000017500000000000011263472452014631 5ustar tokkeetokkee./kohana/system/vendor/swift/0000755000175000017500000000000011263472452015765 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/0000755000175000017500000000000011263472453017062 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Connection/0000755000175000017500000000000011263472453021161 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Connection/Sendmail.php0000644000175000017500000002225610660421612023424 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_ConnectionBase"); /** * Swift Sendmail Connection * @package Swift_Connection * @author Chris Corbyn */ class Swift_Connection_Sendmail extends Swift_ConnectionBase { /** * Constant for auto-detection of paths */ const AUTO_DETECT = -2; /** * Flags for the MTA (options such as bs or t) * @var string */ protected $flags = null; /** * The full path to the MTA * @var string */ protected $path = null; /** * The type of last request sent * For example MAIL, RCPT, DATA * @var string */ protected $request = null; /** * The process handle * @var resource */ protected $proc; /** * I/O pipes for the process * @var array */ protected $pipes; /** * Switches to true for just one command when DATA has been issued * @var boolean */ protected $send = false; /** * The timeout in seconds before giving up * @var int Seconds */ protected $timeout = 10; /** * Constructor * @param string The command to execute * @param int The timeout in seconds before giving up */ public function __construct($command="/usr/sbin/sendmail -bs", $timeout=10) { $this->setCommand($command); $this->setTimeout($timeout); } /** * Set the timeout on the process * @param int The number of seconds */ public function setTimeout($secs) { $this->timeout = (int)$secs; } /** * Get the timeout on the process * @return int */ public function getTimeout() { return $this->timeout; } /** * Set the operating flags for the MTA * @param string */ public function setFlags($flags) { $this->flags = $flags; } /** * Get the operating flags for the MTA * @return string */ public function getFlags() { return $this->flags; } /** * Set the path to the binary * @param string The path (must be absolute!) */ public function setPath($path) { if ($path == self::AUTO_DETECT) $path = $this->findSendmail(); $this->path = $path; } /** * Get the path to the binary * @return string */ public function getPath() { return $this->path; } /** * For auto-detection of sendmail path * Thanks to "Joe Cotroneo" for providing the enhancement * @return string */ public function findSendmail() { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Sendmail path auto-detection in progress. Trying `which sendmail`"); } $path = @trim(shell_exec('which sendmail')); if (!is_executable($path)) { if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("No luck so far, trying some common paths..."); } $common_locations = array( '/usr/bin/sendmail', '/usr/lib/sendmail', '/var/qmail/bin/sendmail', '/bin/sendmail', '/usr/sbin/sendmail', '/sbin/sendmail' ); foreach ($common_locations as $path) { if (is_executable($path)) return $path; } if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Falling back to /usr/sbin/sendmail (but it doesn't look good)!"); } //Fallback (swift will still throw an error) return "/usr/sbin/sendmail"; } else return $path; } /** * Set the sendmail command (path + flags) * @param string Command * @throws Swift_ConnectionException If the command is not correctly structured */ public function setCommand($command) { if ($command == self::AUTO_DETECT) $command = $this->findSendmail() . " -bs"; if (!strrpos($command, " -")) { throw new Swift_ConnectionException("Cannot set sendmail command with no command line flags. e.g. /usr/sbin/sendmail -t"); } $path = substr($command, 0, strrpos($command, " -")); $flags = substr($command, strrpos($command, " -")+2); $this->setPath($path); $this->setFlags($flags); } /** * Get the sendmail command (path + flags) * @return string */ public function getCommand() { return $this->getPath() . " -" . $this->getFlags(); } /** * Write a command to the open pipe * @param string The command to write * @throws Swift_ConnectionException If the pipe cannot be written to */ protected function pipeIn($command, $end="\r\n") { if (!$this->isAlive()) throw new Swift_ConnectionException("The sendmail process is not alive and cannot be written to."); if (!@fwrite($this->pipes[0], $command . $end) && !empty($command)) throw new Swift_ConnectionException("The sendmail process did not allow the command '" . $command . "' to be sent."); fflush($this->pipes[0]); } /** * Read data from the open pipe * @return string * @throws Swift_ConnectionException If the pipe is not operating as expected */ protected function pipeOut() { if (strpos($this->getFlags(), "t") !== false) return; if (!$this->isAlive()) throw new Swift_ConnectionException("The sendmail process is not alive and cannot be read from."); $ret = ""; $line = 0; while (true) { $line++; stream_set_timeout($this->pipes[1], $this->timeout); $tmp = @fgets($this->pipes[1]); if ($tmp === false) { throw new Swift_ConnectionException("There was a problem reading line " . $line . " of a sendmail SMTP response. The response so far was:
    [" . $ret . "]. It appears the process has died."); } $ret .= trim($tmp) . "\r\n"; if ($tmp{3} == " ") break; } fflush($this->pipes[1]); return $ret = substr($ret, 0, -2); } /** * Read a full response from the buffer (this is spoofed if running in -t mode) * @return string * @throws Swift_ConnectionException Upon failure to read */ public function read() { if (strpos($this->getFlags(), "t") !== false) { switch (strtolower($this->request)) { case null: return "220 Greetings"; case "helo": case "ehlo": return "250 hello"; case "mail": case "rcpt": case "rset": return "250 ok"; case "quit": return "221 bye"; case "data": $this->send = true; return "354 go ahead"; default: return "250 ok"; } } else return $this->pipeOut(); } /** * Write a command to the process (leave off trailing CRLF) * @param string The command to send * @throws Swift_ConnectionException Upon failure to write */ public function write($command, $end="\r\n") { if (strpos($this->getFlags(), "t") !== false) { if (!$this->send && strpos($command, " ")) $command = substr($command, strpos($command, " ")+1); elseif ($this->send) { $this->pipeIn($command); } $this->request = $command; $this->send = (strtolower($command) == "data"); } else $this->pipeIn($command, $end); } /** * Try to start the connection * @throws Swift_ConnectionException Upon failure to start */ public function start() { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Trying to start a sendmail process."); } if (!$this->getPath() || !$this->getFlags()) { throw new Swift_ConnectionException("Sendmail cannot be started without a path to the binary including flags."); } if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Trying to stat the executable '" . $this->getPath() . "'."); } if (!@lstat($this->getPath())) { throw new Swift_ConnectionException( "Sendmail cannot be seen with lstat(). The command given [" . $this->getCommand() . "] does not appear to be valid."); } $pipes_spec = array( array("pipe", "r"), array("pipe", "w"), array("pipe", "w") ); $this->proc = proc_open($this->getCommand(), $pipes_spec, $this->pipes); if (!$this->isAlive()) { throw new Swift_ConnectionException( "The sendmail process failed to start. Please verify that the path exists and PHP has permission to execute it."); } } /** * Try to close the connection */ public function stop() { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Terminating sendmail process."); } foreach ((array)$this->pipes as $pipe) { @fclose($pipe); } if ($this->proc) { proc_close($this->proc); $this->pipes = null; $this->proc = null; } } /** * Check if the process is still alive * @return boolean */ public function isAlive() { return ($this->proc !== false && is_resource($this->proc) && is_resource($this->pipes[0]) && is_resource($this->pipes[1]) && $this->proc !== null); } /** * Destructor. * Cleans up by stopping any running processes. */ public function __destruct() { $this->stop(); } } ./kohana/system/vendor/swift/Swift/Connection/Rotator.php0000644000175000017500000001253510660421612023321 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_ConnectionBase"); /** * Swift Rotator Connection * Switches through each connection in turn after sending each message * @package Swift_Connection * @author Chris Corbyn */ class Swift_Connection_Rotator extends Swift_ConnectionBase { /** * The list of available connections * @var array */ protected $connections = array(); /** * The id of the active connection * @var int */ protected $active = null; /** * Contains a list of any connections which were tried but found to be dead * @var array */ protected $dead = array(); /** * Constructor */ public function __construct($connections=array()) { foreach ($connections as $id => $conn) { $this->addConnection($connections[$id], $id); } } /** * Add a connection to the list of options * @param Swift_Connection An instance of the connection */ public function addConnection(Swift_Connection $connection) { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Adding new connection of type '" . get_class($connection) . "' to rotator."); } $this->connections[] = $connection; } /** * Rotate to the next working connection * @throws Swift_ConnectionException If no connections are available */ public function nextConnection() { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add(" <==> Rotating connection."); } $total = count($this->connections); $start = $this->active === null ? 0 : ($this->active + 1); if ($start >= $total) $start = 0; $fail_messages = array(); for ($id = $start; $id < $total; $id++) { if (in_array($id, $this->dead)) continue; //The connection was previously found to be useless try { if (!$this->connections[$id]->isAlive()) $this->connections[$id]->start(); if ($this->connections[$id]->isAlive()) { $this->active = $id; return true; } else { $this->dead[] = $id; $this->connections[$id]->stop(); throw new Swift_ConnectionException("The connection started but reported that it was not active"); } } catch (Swift_ConnectionException $e) { $fail_messages[] = $id . ": " . $e->getMessage(); } } $failure = implode("
    ", $fail_messages); throw new Swift_ConnectionException("No connections were started.
    " . $failure); } /** * Read a full response from the buffer * @return string * @throws Swift_ConnectionException Upon failure to read */ public function read() { if ($this->active === null) { throw new Swift_ConnectionException("None of the connections set have been started"); } return $this->connections[$this->active]->read(); } /** * Write a command to the server (leave off trailing CRLF) * @param string The command to send * @throws Swift_ConnectionException Upon failure to write */ public function write($command, $end="\r\n") { if ($this->active === null) { throw new Swift_ConnectionException("None of the connections set have been started"); } return $this->connections[$this->active]->write($command, $end); } /** * Try to start the connection * @throws Swift_ConnectionException Upon failure to start */ public function start() { if ($this->active === null) $this->nextConnection(); } /** * Try to close the connection * @throws Swift_ConnectionException Upon failure to close */ public function stop() { foreach ($this->connections as $id => $conn) { if ($this->connections[$id]->isAlive()) $this->connections[$id]->stop(); } $this->active = null; } /** * Check if the current connection is alive * @return boolean */ public function isAlive() { return (($this->active !== null) && $this->connections[$this->active]->isAlive()); } /** * Get the ID of the active connection * @return int */ public function getActive() { return $this->active; } /** * Call the current connection's postConnect() method */ public function postConnect(Swift $instance) { Swift_ClassLoader::load("Swift_Plugin_ConnectionRotator"); if (!$instance->getPlugin("_ROTATOR")) $instance->attachPlugin(new Swift_Plugin_ConnectionRotator(), "_ROTATOR"); $this->connections[$this->active]->postConnect($instance); } /** * Call the current connection's setExtension() method */ public function setExtension($extension, $attributes=array()) { $this->connections[$this->active]->setExtension($extension, $attributes); } /** * Call the current connection's hasExtension() method */ public function hasExtension($name) { return $this->connections[$this->active]->hasExtension($name); } /** * Call the current connection's getAttributes() method */ public function getAttributes($name) { return $this->connections[$this->active]->getAttributes($name); } } ./kohana/system/vendor/swift/Swift/Connection/NativeMail.php0000644000175000017500000000706110655670311023724 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_ConnectionBase"); Swift_ClassLoader::load("Swift_Plugin_MailSend"); /** * Swift mail() Connection * NOTE: This class is nothing more than a stub. The MailSend plugin does the actual sending. * @package Swift_Connection * @author Chris Corbyn */ class Swift_Connection_NativeMail extends Swift_ConnectionBase { /** * The response the stub will be giving next * @var string Response */ protected $response = "220 Stubbed"; /** * The 5th parameter in mail() is a sprintf() formatted string. * @var string */ protected $pluginParams; /** * An instance of the MailSend plugin. * @var Swift_Plugin_MailSend */ protected $plugin = null; /** * Ctor. * @param string The 5th parameter in mail() as a sprintf() formatted string where %s is the sender address. This only comes into effect if safe_mode is OFF. */ public function __construct($additional_params="-oi -f %s") { $this->setAdditionalMailParams($additional_params); } /** * Sets the MailSend plugin in Swift once Swift has connected * @param Swift The current instance of Swift */ public function postConnect(Swift $instance) { $this->plugin = new Swift_Plugin_MailSend($this->getAdditionalMailParams()); $instance->attachPlugin($this->plugin, "_MAIL_SEND"); } /** * Set the 5th parameter in mail() as a sprintf() formatted string. Only used if safe_mode is off. * @param string */ public function setAdditionalMailParams($params) { $this->pluginParams = $params; if ($this->plugin !== null) { $this->plugin->setAdditionalParams($params); } } /** * Get the 5th parameter in mail() as a sprintf() formatted string. * @return string */ public function getAdditionalMailParams() { return $this->pluginParams; } /** * Read a full response from the buffer (this is spoofed if running in -t mode) * @return string * @throws Swift_ConnectionException Upon failure to read */ public function read() { return $this->response; } /** * Set the response this stub will return * @param string The response to send */ public function setResponse($int) { $this->response = $int . " Stubbed"; } /** * Write a command to the process (leave off trailing CRLF) * @param string The command to send * @throws Swift_ConnectionException Upon failure to write */ public function write($command, $end="\r\n") { $command = strtoupper($command); if (strpos($command, " ")) $command = substr($command, 0, strpos($command, " ")); switch ($command) { case "DATA": $this->setResponse(354); break; case "EHLO": case "MAIL": case "RCPT": case "QUIT": case "RSET": default: $this->setResponse(250); break; } } /** * Try to start the connection * @throws Swift_ConnectionException Upon failure to start */ public function start() { $this->response = "220 Stubbed"; } /** * Try to close the connection * @throws Swift_ConnectionException Upon failure to close */ public function stop() { $this->response = "220 Stubbed"; } /** * Check if the process is still alive * @return boolean */ public function isAlive() { return function_exists("mail"); } } ./kohana/system/vendor/swift/Swift/Connection/Multi.php0000644000175000017500000001067410660421612022763 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_ConnectionBase"); /** * Swift Multi Connection * Tries to connect to a number of connections until one works successfully * @package Swift_Connection * @author Chris Corbyn */ class Swift_Connection_Multi extends Swift_ConnectionBase { /** * The list of available connections * @var array */ protected $connections = array(); /** * The id of the active connection * @var string */ protected $active = null; /** * Constructor */ public function __construct($connections=array()) { foreach ($connections as $id => $conn) { $this->addConnection($connections[$id], $id); } } /** * Add a connection to the list of options * @param Swift_Connection An instance of the connection * @param string An ID to assign to the connection */ public function addConnection(Swift_Connection $connection, $id=null) { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Adding new connection of type '" . get_class($connection) . "' to the multi-redundant connection."); } if ($id !== null) $this->connections[$id] = $connection; else $this->connections[] = $connection; } /** * Read a full response from the buffer * @return string * @throws Swift_ConnectionException Upon failure to read */ public function read() { if ($this->active === null) { throw new Swift_ConnectionException("None of the connections set have been started"); } return $this->connections[$this->active]->read(); } /** * Write a command to the server (leave off trailing CRLF) * @param string The command to send * @throws Swift_ConnectionException Upon failure to write */ public function write($command, $end="\r\n") { if ($this->active === null) { throw new Swift_ConnectionException("None of the connections set have been started"); } return $this->connections[$this->active]->write($command, $end); } /** * Try to start the connection * @throws Swift_ConnectionException Upon failure to start */ public function start() { $log = Swift_LogContainer::getLog(); $fail_messages = array(); foreach ($this->connections as $id => $conn) { try { $this->connections[$id]->start(); if ($this->connections[$id]->isAlive()) { $this->active = $id; return true; } else { if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Connection (" . $id . ") failed. Will try next connection if available."); } throw new Swift_ConnectionException("The connection started but reported that it was not active"); } } catch (Swift_ConnectionException $e) { $fail_messages[] = $id . ": " . $e->getMessage(); } } $failure = implode("
    ", $fail_messages); throw new Swift_ConnectionException($failure); } /** * Try to close the connection * @throws Swift_ConnectionException Upon failure to close */ public function stop() { if ($this->active !== null) $this->connections[$this->active]->stop(); $this->active = null; } /** * Check if the current connection is alive * @return boolean */ public function isAlive() { return (($this->active !== null) && $this->connections[$this->active]->isAlive()); } /** * Call the current connection's postConnect() method */ public function postConnect(Swift $instance) { $this->connections[$this->active]->postConnect($instance); } /** * Call the current connection's setExtension() method */ public function setExtension($extension, $attributes=array()) { $this->connections[$this->active]->setExtension($extension, $attributes); } /** * Call the current connection's hasExtension() method */ public function hasExtension($name) { return $this->connections[$this->active]->hasExtension($name); } /** * Call the current connection's getAttributes() method */ public function getAttributes($name) { return $this->connections[$this->active]->getAttributes($name); } } ./kohana/system/vendor/swift/Swift/Connection/SMTP.php0000644000175000017500000003031710660421612022450 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_ConnectionBase"); Swift_ClassLoader::load("Swift_Authenticator"); /** * Swift SMTP Connection * @package Swift_Connection * @author Chris Corbyn */ class Swift_Connection_SMTP extends Swift_ConnectionBase { /** * Constant for TLS connections */ const ENC_TLS = 2; /** * Constant for SSL connections */ const ENC_SSL = 4; /** * Constant for unencrypted connections */ const ENC_OFF = 8; /** * Constant for the default SMTP port */ const PORT_DEFAULT = 25; /** * Constant for the default secure SMTP port */ const PORT_SECURE = 465; /** * Constant for auto-detection of paramters */ const AUTO_DETECT = -2; /** * A connection handle * @var resource */ protected $handle = null; /** * The remote port number * @var int */ protected $port = null; /** * Encryption type to use * @var int */ protected $encryption = null; /** * A connection timeout * @var int */ protected $timeout = 15; /** * A username to authenticate with * @var string */ protected $username = false; /** * A password to authenticate with * @var string */ protected $password = false; /** * Loaded authentication mechanisms * @var array */ protected $authenticators = array(); /** * Fsockopen() error codes. * @var int */ protected $errno; /** * Fsockopen() error codes. * @var string */ protected $errstr; /** * Constructor * @param string The remote server to connect to * @param int The remote port to connect to * @param int The encryption level to use */ public function __construct($server="localhost", $port=null, $encryption=null) { $this->setServer($server); $this->setEncryption($encryption); $this->setPort($port); } /** * Set the timeout to connect in seconds * @param int Timeout to use */ public function setTimeout($time) { $this->timeout = (int) $time; } /** * Get the timeout currently set for connecting * @return int */ public function getTimeout() { return $this->timeout; } /** * Set the remote server to connect to as a FQDN * @param string Server name */ public function setServer($server) { if ($server == self::AUTO_DETECT) { $server = @ini_get("SMTP"); if (!$server) $server = "localhost"; } $this->server = (string) $server; } /** * Get the remote server name * @return string */ public function getServer() { return $this->server; } /** * Set the remote port number to connect to * @param int Port number */ public function setPort($port) { if ($port == self::AUTO_DETECT) { $port = @ini_get("SMTP_PORT"); } if (!$port) $port = ($this->getEncryption() == self::ENC_OFF) ? self::PORT_DEFAULT : self::PORT_SECURE; $this->port = (int) $port; } /** * Get the remote port number currently used to connect * @return int */ public function getPort() { return $this->port; } /** * Provide a username for authentication * @param string The username */ public function setUsername($user) { $this->setRequiresEHLO(true); $this->username = $user; } /** * Get the username for authentication * @return string */ public function getUsername() { return $this->username; } /** * Set the password for SMTP authentication * @param string Password to use */ public function setPassword($pass) { $this->setRequiresEHLO(true); $this->password = $pass; } /** * Get the password for authentication * @return string */ public function getPassword() { return $this->password; } /** * Add an authentication mechanism to authenticate with * @param Swift_Authenticator */ public function attachAuthenticator(Swift_Authenticator $auth) { $this->authenticators[$auth->getAuthExtensionName()] = $auth; $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Authentication mechanism '" . $auth->getAuthExtensionName() . "' attached."); } } /** * Set the encryption level to use on the connection * See the constants ENC_TLS, ENC_SSL and ENC_OFF * NOTE: PHP needs to have been compiled with OpenSSL for SSL and TLS to work * NOTE: Some PHP installations will not have the TLS stream wrapper * @param int Level of encryption */ public function setEncryption($enc) { if (!$enc) $enc = self::ENC_OFF; $this->encryption = (int) $enc; } /** * Get the current encryption level used * This method returns an integer corresponding to one of the constants ENC_TLS, ENC_SSL or ENC_OFF * @return int */ public function getEncryption() { return $this->encryption; } /** * Read a full response from the buffer * inner !feof() patch provided by Christian Rodriguez: * www.flyspray.org * @return string * @throws Swift_ConnectionException Upon failure to read */ public function read() { if (!$this->handle) throw new Swift_ConnectionException( "The SMTP connection is not alive and cannot be read from." . $this->smtpErrors()); $ret = ""; $line = 0; while (!feof($this->handle)) { $line++; stream_set_timeout($this->handle, $this->timeout); $tmp = @fgets($this->handle); if ($tmp === false && !feof($this->handle)) { throw new Swift_ConnectionException( "There was a problem reading line " . $line . " of an SMTP response. The response so far was:
    [" . $ret . "]. It appears the connection has died without saying goodbye to us! Too many emails in one go perhaps?" . $this->smtpErrors()); } $ret .= trim($tmp) . "\r\n"; if ($tmp{3} == " ") break; } return $ret = substr($ret, 0, -2); } /** * Write a command to the server (leave off trailing CRLF) * @param string The command to send * @throws Swift_ConnectionException Upon failure to write */ public function write($command, $end="\r\n") { if (!$this->handle) throw new Swift_ConnectionException( "The SMTP connection is not alive and cannot be written to." . $this->smtpErrors()); if (!@fwrite($this->handle, $command . $end) && !empty($command)) throw new Swift_ConnectionException("The SMTP connection did not allow the command '" . $command . "' to be sent." . $this->smtpErrors()); } /** * Try to start the connection * @throws Swift_ConnectionException Upon failure to start */ public function start() { if ($this->port === null) { switch ($this->encryption) { case self::ENC_TLS: case self::ENC_SSL: $this->port = 465; break; case null: default: $this->port = 25; break; } } $server = $this->server; if ($this->encryption == self::ENC_TLS) $server = "tls://" . $server; elseif ($this->encryption == self::ENC_SSL) $server = "ssl://" . $server; $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_log::LOG_EVERYTHING)) { $log->add("Trying to connect to SMTP server at '" . $server . ":" . $this->port); } if (!$this->handle = @fsockopen($server, $this->port, $errno, $errstr, $this->timeout)) { $error_msg = "The SMTP connection failed to start [" . $server . ":" . $this->port . "]: fsockopen returned Error Number " . $errno . " and Error String '" . $errstr . "'"; if ($log->isEnabled()) { $log->add($error_msg, Swift_Log::ERROR); } $this->handle = null; throw new Swift_ConnectionException($error_msg); } $this->errno =& $errno; $this->errstr =& $errstr; } /** * Get the smtp error string as recorded by fsockopen() * @return string */ public function smtpErrors() { return " (fsockopen: " . $this->errstr . "#" . $this->errno . ") "; } /** * Authenticate if required to do so * @param Swift An instance of Swift * @throws Swift_ConnectionException If authentication fails */ public function postConnect(Swift $instance) { if ($this->getUsername() && $this->getPassword()) { $this->runAuthenticators($this->getUsername(), $this->getPassword(), $instance); } } /** * Run each authenticator in turn an try for a successful login * If none works, throw an exception * @param string Username * @param string Password * @param Swift An instance of swift * @throws Swift_ConnectionException Upon failure to authenticate */ public function runAuthenticators($user, $pass, Swift $swift) { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Trying to authenticate with username '" . $user . "'."); } //Load in defaults if (empty($this->authenticators)) { if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("No authenticators loaded; looking for defaults."); } $dir = dirname(__FILE__) . "/../Authenticator"; $handle = opendir($dir); while (false !== $file = readdir($handle)) { if (preg_match("/^[A-Za-z0-9-]+\\.php\$/", $file)) { $name = preg_replace('/[^a-zA-Z0-9]+/', '', substr($file, 0, -4)); require_once $dir . "/" . $file; $class = "Swift_Authenticator_" . $name; $this->attachAuthenticator(new $class()); } } closedir($handle); } $tried = 0; $looks_supported = true; //Allow everything we have if the server has the audacity not to help us out. if (!$this->hasExtension("AUTH")) { if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Server (perhaps wrongly) is not advertising AUTH... manually overriding."); } $looks_supported = false; $this->setExtension("AUTH", array_keys($this->authenticators)); } foreach ($this->authenticators as $name => $obj) { //Server supports this authentication mechanism if (in_array($name, $this->getAttributes("AUTH")) || $name{0} == "*") { $tried++; if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Trying '" . $name . "' authentication..."); } if ($this->authenticators[$name]->isAuthenticated($user, $pass, $swift)) { if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Success! Authentication accepted."); } return true; } } } //Server doesn't support authentication if (!$looks_supported && $tried == 0) throw new Swift_ConnectionException("Authentication is not supported by the server but a username and password was given."); if ($tried == 0) throw new Swift_ConnectionException("No authentication mechanisms were tried since the server did not support any of the ones loaded. " . "Loaded authenticators: [" . implode(", ", array_keys($this->authenticators)) . "]"); else throw new Swift_ConnectionException("Authentication failed using username '" . $user . "' and password '". str_repeat("*", strlen($pass)) . "'"); } /** * Try to close the connection * @throws Swift_ConnectionException Upon failure to close */ public function stop() { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Closing down SMTP connection."); } if ($this->handle) { if (!fclose($this->handle)) { throw new Swift_ConnectionException("The SMTP connection could not be closed for an unknown reason." . $this->smtpErrors()); } $this->handle = null; } } /** * Check if the SMTP connection is alive * @return boolean */ public function isAlive() { return ($this->handle !== null); } /** * Destructor. * Cleans up any open connections. */ public function __destruct() { $this->stop(); } } ./kohana/system/vendor/swift/Swift/Events.php0000644000175000017500000000147710607101013021026 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Provides core functionality for Swift generated events for plugins * @package Swift_Events * @author Chris Corbyn */ abstract class Swift_Events { /** * An instance of Swift * @var Swift */ protected $swift = null; /** * Provide a reference to te currently running Swift this event was generated from * @param Swift */ public function setSwift(Swift $swift) { $this->swift = $swift; } /** * Get the current instance of swift * @return Swift */ public function getSwift() { return $this->swift; } } ./kohana/system/vendor/swift/Swift/BadResponseException.php0000644000175000017500000000104510660421612023646 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_ConnectionException"); /** * Swift Bad Response Exception * @package Swift_Connection * @author Chris Corbyn */ class Swift_BadResponseException extends Swift_ConnectionException { } ./kohana/system/vendor/swift/Swift/Cache.php0000644000175000017500000000300410607101013020551 0ustar tokkeetokkee * @package Swift_Cache * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; /** * The interface for any cache mechanisms to follow * @package Swift_Cache * @author Chris Corbyn */ abstract class Swift_Cache { /** * Append bytes to the cache buffer identified by $key * @param string The Cache key * @param string The bytes to append */ abstract public function write($key, $data); /** * Clear out the buffer for $key * @param string The cache key */ abstract public function clear($key); /** * Check if there is something in the cache for $key * @param string The cache key * @return boolean */ abstract public function has($key); /** * Read bytes from the cached buffer and seek forward in the buffer * Returns false once no more bytes are left to read * @param int The number of bytes to read (may be ignored) * @return string */ abstract public function read($key, $size=null); /** * A factory method to return an output stream object for the relevant location in the cache * @param string The cache key to fetch the stream for * @return Swift_Cache_OutputStream */ public function getOutputStream($key) { Swift_ClassLoader::load("Swift_Cache_OutputStream"); $os = new Swift_Cache_OutputStream($this, $key); return $os; } } ./kohana/system/vendor/swift/Swift/RecipientList.php0000644000175000017500000001311510620303200022325 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_Address"); Swift_ClassLoader::load("Swift_Iterator_Array"); /** * Swift's Recipient List container. Contains To, Cc, Bcc * @package Swift * @author Chris Corbyn */ class Swift_RecipientList extends Swift_AddressContainer { /** * The recipients in the To: header * @var array */ protected $to = array(); /** * The recipients in the Cc: header * @var array */ protected $cc = array(); /** * The recipients in the Bcc: header * @var array */ protected $bcc = array(); /** * Iterators to use when getting lists back out. * If any iterators are present here, their relevant "addXX()" methods will be useless. * As per the last note, any iterators need to be pre-configured before Swift::send() is called. * @var array,Swift_Iterator */ protected $iterators = array("to" => null, "cc" => null, "bcc" => null); /** * Add a recipient. * @param string The address * @param string The name * @param string The field (to, cc or bcc) */ public function add($address, $name="", $where="to") { if ($address instanceof Swift_Address) { $address_str = trim(strtolower($address->getAddress())); } elseif (is_array($address)) { foreach ($address as $a) $this->add($a, $name, $where); return; } else { $address_str = (string) $address; $address_str = trim(strtolower($address_str)); $address = new Swift_Address($address_str, $name); } if (in_array($where, array("to", "cc", "bcc"))) { $container =& $this->$where; $container[$address_str] = $address; } } /** * Remove a recipient. * @param string The address * @param string The field (to, cc or bcc) */ public function remove($address, $where="to") { if ($address instanceof Swift_Address) { $key = trim(strtolower($address->getAddress())); } else $key = trim(strtolower((string) $address)); if (in_array($where, array("to", "cc", "bcc"))) { if (array_key_exists($key, $this->$where)) unset($this->{$where}[$key]); } } /** * Get an iterator object for all the recipients in the given field. * @param string The field name (to, cc or bcc) * @return Swift_Iterator */ public function getIterator($where) { if (!empty($this->iterators[$where])) { return $this->iterators[$where]; } elseif (in_array($where, array("to", "cc", "bcc"))) { $it = new Swift_Iterator_Array($this->$where); return $it; } } /** * Override the loading of the default iterator (Swift_ArrayIterator) and use the one given here. * @param Swift_Iterator The iterator to use. It must be populated already. */ public function setIterator(Swift_Iterator $it, $where) { if (in_array($where, array("to", "cc", "bcc"))) { $this->iterators[$where] = $it; } } /** * Add a To: recipient * @param mixed The address to add. Can be a string or Swift_Address * @param string The personal name, optional */ public function addTo($address, $name=null) { $this->add($address, $name, "to"); } /** * Get an array of addresses in the To: field * The array contains Swift_Address objects * @return array */ public function getTo() { return $this->to; } /** * Remove a To: recipient from the list * @param mixed The address to remove. Can be Swift_Address or a string */ public function removeTo($address) { $this->remove($address, "to"); } /** * Empty all To: addresses */ public function flushTo() { $this->to = null; $this->to = array(); } /** * Add a Cc: recipient * @param mixed The address to add. Can be a string or Swift_Address * @param string The personal name, optional */ public function addCc($address, $name=null) { $this->add($address, $name, "cc"); } /** * Get an array of addresses in the Cc: field * The array contains Swift_Address objects * @return array */ public function getCc() { return $this->cc; } /** * Remove a Cc: recipient from the list * @param mixed The address to remove. Can be Swift_Address or a string */ public function removeCc($address) { $this->remove($address, "cc"); } /** * Empty all Cc: addresses */ public function flushCc() { $this->cc = null; $this->cc = array(); } /** * Add a Bcc: recipient * @param mixed The address to add. Can be a string or Swift_Address * @param string The personal name, optional */ public function addBcc($address, $name=null) { $this->add($address, $name, "bcc"); } /** * Get an array of addresses in the Bcc: field * The array contains Swift_Address objects * @return array */ public function getBcc() { return $this->bcc; } /** * Remove a Bcc: recipient from the list * @param mixed The address to remove. Can be Swift_Address or a string */ public function removeBcc($address) { $this->remove($address, "bcc"); } /** * Empty all Bcc: addresses */ public function flushBcc() { $this->bcc = null; $this->bcc = array(); } /** * Empty the entire list */ public function flush() { $this->flushTo(); $this->flushCc(); $this->flushBcc(); } } ./kohana/system/vendor/swift/Swift/Connection.php0000644000175000017500000000432510635210315021663 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ /** * Swift Connection Interface * Lists methods which are required by any connections * @package Swift_Connection * @author Chris Corbyn */ interface Swift_Connection { /** * Try to start the connection * @throws Swift_ConnectionException If the connection cannot be started */ public function start(); /** * Return the contents of the buffer * @return string * @throws Swift_ConnectionException If the buffer cannot be read */ public function read(); /** * Write a command to the buffer * @param string The command to send * @throws Swift_ConnectionException If the write fails */ public function write($command, $end="\r\n"); /** * Try to stop the connection * @throws Swift_ConnectionException If the connection cannot be closed/stopped */ public function stop(); /** * Check if the connection is up or not * @return boolean */ public function isAlive(); /** * Add an extension which is available on this connection * @param string The name of the extension * @param array The list of attributes for the extension */ public function setExtension($name, $list=array()); /** * Check if an extension exists by the name $name * @param string The name of the extension * @return boolean */ public function hasExtension($name); /** * Get the list of attributes for the extension $name * @param string The name of the extension * @return array * @throws Swift_ConnectionException If no such extension can be found */ public function getAttributes($name); /** * Execute logic needed after SMTP greetings * @param Swift An instance of Swift */ public function postConnect(Swift $instance); /** * Returns TRUE if the connection needs a EHLO greeting. * @return boolean */ public function getRequiresEHLO(); /** * Set if the connection needs a EHLO greeting. * @param boolean */ public function setRequiresEHLO($set); } ./kohana/system/vendor/swift/Swift/Message.php0000644000175000017500000006325210652115214021155 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_Address"); Swift_ClassLoader::load("Swift_Message_Mime"); Swift_ClassLoader::load("Swift_Message_Image"); Swift_ClassLoader::load("Swift_Message_Part"); /** * Swift Message class * @package Swift_Message * @author Chris Corbyn */ class Swift_Message extends Swift_Message_Mime { /** * Constant from a high priority message (pretty meaningless) */ const PRIORITY_HIGH = 1; /** * Constant for a low priority message */ const PRIORITY_LOW = 5; /** * Constant for a normal priority message */ const PRIORITY_NORMAL = 3; /** * The MIME warning for client not supporting multipart content * @var string */ protected $mimeWarning = null; /** * The version of the library (Swift) if known. * @var string */ protected $libVersion = ""; /** * A container for references to other objects. * This is used in some very complex logic when sub-parts get shifted around. * @var array */ protected $references = array( "parent" => array("alternative" => null, "mixed" => null, "related" => null), "alternative" => array(), "mixed" => array(), "related" => array() ); /** * Ctor. * @param string Message subject * @param string Body * @param string Content-type * @param string Encoding * @param string Charset */ public function __construct($subject="", $body=null, $type="text/plain", $encoding=null, $charset=null) { parent::__construct(); if (function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get")) { date_default_timezone_set(@date_default_timezone_get()); } $this->setReturnPath(null); $this->setTo(""); $this->setFrom(""); $this->setCc(null); $this->setBcc(null); $this->setReplyTo(null); $this->setSubject($subject); $this->setDate(time()); if (defined("Swift::VERSION")) { $this->libVersion = Swift::VERSION; $this->headers->set("X-LibVersion", $this->libVersion); } $this->headers->set("MIME-Version", "1.0"); $this->setContentType($type); $this->setCharset($charset); $this->setFlowed(true); $this->setEncoding($encoding); foreach (array_keys($this->references["parent"]) as $key) { $this->setReference("parent", $key, $this); } $this->setMimeWarning( "This is a message in multipart MIME format. Your mail client should not be displaying this. " . "Consider upgrading your mail client to view this message correctly." ); if ($body !== null) { $this->setData($body); if ($charset === null) { Swift_ClassLoader::load("Swift_Message_Encoder"); if (Swift_Message_Encoder::instance()->isUTF8($body)) $this->setCharset("utf-8"); else $this->setCharset("iso-8859-1"); } } } /** * Sets a reference so when nodes are nested, operations can be redirected. * This really should be refactored to use just one array rather than dynamic variables. * @param string Key 1 * @param string Key 2 * @param Object Reference */ protected function setReference($where, $key, $ref) { if ($ref === $this) $this->references[$where][$key] = false; else $this->references[$where][$key] = $ref; } /** * Get a reference to an object (for complex reasons). * @param string Key 1 * @param string Key 2 * @return Object */ protected function getReference($where, $key) { if (!$this->references[$where][$key]) return $this; else return $this->references[$where][$key]; } /** * Get the level in the MIME hierarchy at which this section should appear. * @return string */ public function getLevel() { return Swift_Message_Mime::LEVEL_TOP; } /** * Set the message id literally. * Unless you know what you are doing you should be using generateId() rather than this method, * otherwise you may break compliancy with RFC 2822. * @param string The message ID string. */ public function setId($id) { $this->headers->set("Message-ID", $id); } /** * Create a RFC 2822 compliant message id, optionally based upon $idstring. * The message ID includes information about the current time, the server and some random characters. * @param string An optional string the base the ID on * @return string The generated message ID, including the <> quotes. * @author Cristian Rodriguez */ public function generateId($idstring=null) { $midparams = array( "utctime" => gmstrftime("%Y%m%d%H%M%S"), "pid" => getmypid(), "randint" => mt_rand(), "customstr" => (preg_match("/^(? (isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : php_uname("n")), ); $this->setId(vsprintf("<%s.%d.%d.%s@%s>", $midparams)); return $this->getId(); } /** * Get the generated message ID for this message, including the <> quotes. * If generated automatically, or using generateId() this method returns a RFC2822 compliant Message-ID. * @return string * @author Cristian Rodriguez */ public function getId() { return $this->headers->has("Message-ID") ? $this->headers->get("Message-ID") : null; } /** * Set the address in the Return-Path: header * @param string The bounce-detect address */ public function setReturnPath($address) { if ($address instanceof Swift_Address) $address = $address->build(true); $this->headers->set("Return-Path", $address); } /** * Return the address used in the Return-Path: header * @return string * @param boolean Return the address for SMTP command */ public function getReturnPath($smtp=false) { if ($this->headers->has("Return-Path")) { if (!$smtp) return $this->headers->get("Return-Path"); else { $path = $this->headers->get("Return-Path"); if (strpos($path, ">") > strpos($path, "<")) return substr($path, ($start = strpos($path, "<")), ($start + strrpos($path, ">") + 1)); else return "<" . $path . ">"; } } } /** * Set the address in the From: header * @param string The address to set as From */ public function setFrom($from) { if ($from instanceof Swift_Address) $from = $from->build(); $this->headers->set("From", $from); } /** * Get the address used in the From: header * @return string */ public function getFrom() { if ($this->headers->has("From")) return $this->headers->get("From"); } /** * Set the list of recipients in the To: header * @param mixed An array or a string */ public function setTo($to) { if ($to) { if (!is_array($to)) $to = array($to); foreach ($to as $key => $value) { if ($value instanceof Swift_Address) $to[$key] = $value->build(); } } $this->headers->set("To", $to); } /** * Return the list of recipients in the To: header * @return array */ public function getTo() { if ($this->headers->has("To")) { $to = $this->headers->get("To"); if ($to == "") return array(); else return (array) $to; } } /** * Set the list of recipients in the Reply-To: header * @param mixed An array or a string */ public function setReplyTo($replyto) { if ($replyto) { if (!is_array($replyto)) $replyto = array($replyto); foreach ($replyto as $key => $value) { if ($value instanceof Swift_Address) $replyto[$key] = $value->build(); } } $this->headers->set("Reply-To", $replyto); } /** * Return the list of recipients in the Reply-To: header * @return array */ public function getReplyTo() { if ($this->headers->has("Reply-To")) { $reply_to = $this->headers->get("Reply-To"); if ($reply_to == "") return array(); else return (array) $reply_to; } } /** * Set the list of recipients in the Cc: header * @param mixed An array or a string */ public function setCc($cc) { if ($cc) { if (!is_array($cc)) $cc = array($cc); foreach ($cc as $key => $value) { if ($value instanceof Swift_Address) $cc[$key] = $value->build(); } } $this->headers->set("Cc", $cc); } /** * Return the list of recipients in the Cc: header * @return array */ public function getCc() { if ($this->headers->has("Cc")) { $cc = $this->headers->get("Cc"); if ($cc == "") return array(); else return (array) $cc; } } /** * Set the list of recipients in the Bcc: header * @param mixed An array or a string */ public function setBcc($bcc) { if ($bcc) { if (!is_array($bcc)) $bcc = array($bcc); foreach ($bcc as $key => $value) { if ($value instanceof Swift_Address) $bcc[$key] = $value->build(); } } $this->headers->set("Bcc", $bcc); } /** * Return the list of recipients in the Bcc: header * @return array */ public function getBcc() { if ($this->headers->has("Bcc")) { $bcc = $this->headers->get("Bcc"); if ($bcc == "") return array(); else return (array) $bcc; } } /** * Set the subject in the headers * @param string The subject of the email */ public function setSubject($subject) { $this->headers->set("Subject", $subject); } /** * Get the current subject used in the headers * @return string */ public function getSubject() { return $this->headers->get("Subject"); } /** * Set the date in the headers in RFC 2822 format * @param int The time as a UNIX timestamp */ public function setDate($date) { $this->headers->set("Date", date("r", $date)); } /** * Get the date as it looks in the headers * @return string */ public function getDate() { return strtotime($this->headers->get("Date")); } /** * Set the charset of the document * @param string The charset used */ public function setCharset($charset) { $this->headers->setAttribute("Content-Type", "charset", $charset); if (($this->getEncoding() == "7bit") && (strtolower($charset) == "utf-8" || strtolower($charset) == "utf8")) $this->setEncoding("8bit"); } /** * Get the charset used in the document * Returns null if none is set * @return string */ public function getCharset() { if ($this->headers->hasAttribute("Content-Type", "charset")) { return $this->headers->getAttribute("Content-Type", "charset"); } else { return null; } } /** * Set the "format" attribute to flowed * @param boolean On or Off */ public function setFlowed($flowed=true) { $value = null; if ($flowed) $value = "flowed"; $this->headers->setAttribute("Content-Type", "format", $value); } /** * Check if the message format is set as flowed * @return boolean */ public function isFlowed() { if ($this->headers->hasAttribute("Content-Type", "format") && $this->headers->getAttribute("Content-Type", "format") == "flowed") { return true; } else return false; } /** * Set the message prioirty in the mail client (don't rely on this) * @param int The priority as a value between 1 (high) and 5 (low) */ public function setPriority($priority) { $priority = (int) $priority; if ($priority > self::PRIORITY_LOW) $priority = self::PRIORITY_LOW; if ($priority < self::PRIORITY_HIGH) $priority = self::PRIORITY_HIGH; $label = array(1 => "High", 2 => "High", 3 => "Normal", 4 => "Low", 5 => "Low"); $this->headers->set("X-Priority", $priority); $this->headers->set("X-MSMail-Priority", $label[$priority]); $this->headers->set("X-MimeOLE", "Produced by SwiftMailer " . $this->libVersion); } /** * Request that the client send back a read-receipt (don't rely on this!) * @param string Request address */ public function requestReadReceipt($request) { if ($request instanceof Swift_Address) $request = $request->build(); if (!$request) { $this->headers->set("Disposition-Notification-To", null); $this->headers->set("X-Confirm-Reading-To", null); $this->headers->set("Return-Receipt-To", null); } else { $this->headers->set("Disposition-Notification-To", $request); $this->headers->set("X-Confirm-Reading-To", $request); $this->headers->set("Return-Receipt-To", $request); } } /** * Check if a read receipt has been requested for this message * @return boolean */ public function wantsReadReceipt() { return $this->headers->has("Disposition-Notification-To"); } /** * Get the current message priority * Returns NULL if none set * @return int */ public function getPriority() { if ($this->headers->has("X-Priority")) return $this->headers->get("X-Priority"); else return null; } /** * Alias for setData() * @param mixed Body */ public function setBody($body) { $this->setData($body); } /** * Alias for getData() * @return mixed The document body */ public function getBody() { return $this->getData(); } /** * Set the MIME warning message which is displayed to old clients * @var string The full warning message (in 7bit ascii) */ public function setMimeWarning($text) { $this->mimeWarning = (string) $text; } /** * Get the MIME warning which is displayed to old clients * @return string */ public function getMimeWarning() { return $this->mimeWarning; } /** * Attach a mime part or an attachment of some sort * Any descendant of Swift_Message_Mime can be added safely (including other Swift_Message objects for mail forwarding!!) * @param Swift_Message_Mime The document to attach * @param string An identifier to use (one is returned otherwise) * @return string The identifier for the part */ public function attach(Swift_Message_Mime $child, $id=null) { try { switch ($child->getLevel()) { case Swift_Message_Mime::LEVEL_ALTERNATIVE: $sign = (strtolower($child->getContentType()) == "text/plain") ? -1 : 1; $id = $this->getReference("parent", "alternative")->addChild($child, $id, $sign); $this->setReference("alternative", $id, $child); break; case Swift_Message_Mime::LEVEL_RELATED: $id = "cid:" . $child->getContentId(); $id = $this->getReference("parent", "related")->addChild($child, $id, 1); $this->setReference("related", $id, $child); break; case Swift_Message_Mime::LEVEL_MIXED: default: $id = $this->getReference("parent", "mixed")->addChild($child, $id, 1); $this->setReference("mixed", $id, $child); break; } $this->postAttachFixStructure(); $this->fixContentType(); return $id; } catch (Swift_Message_MimeException $e) { throw new Swift_Message_MimeException("Something went wrong whilst trying to move some MIME parts during an attach(). " . "The MIME component threw an exception:
    " . $e->getMessage()); } } /** * Remove a nested MIME part * @param string The ID of the attached part * @throws Swift_Message_MimeException If no such part exists */ public function detach($id) { try { switch (true) { case array_key_exists($id, $this->references["alternative"]): $this->getReference("parent", "alternative")->removeChild($id); unset($this->references["alternative"][$id]); break; case array_key_exists($id, $this->references["related"]): $this->getReference("parent", "related")->removeChild($id); unset($this->references["related"][$id]); break; case array_key_exists($id, $this->references["mixed"]): $this->getReference("parent", "mixed")->removeChild($id); unset($this->references["mixed"][$id]); break; default: throw new Swift_Message_MimeException("Unable to detach part identified by ID '" . $id . "' since it's not registered."); break; } $this->postDetachFixStructure(); $this->fixContentType(); } catch (Swift_Message_MimeException $e) { throw new Swift_Message_MimeException("Something went wrong whilst trying to move some MIME parts during a detach(). " . "The MIME component threw an exception:
    " . $e->getMessage()); } } /** * Sets the correct content type header by looking at what types of data we have set */ protected function fixContentType() { if (!empty($this->references["mixed"])) $this->setContentType("multipart/mixed"); elseif (!empty($this->references["related"])) $this->setContentType("multipart/related"); elseif (!empty($this->references["alternative"])) $this->setContentType("multipart/alternative"); } /** * Move a branch of the tree, containing all it's MIME parts onto another branch * @param string The content type on the branch itself * @param string The content type which may exist in the branch's parent * @param array The array containing all the nodes presently * @param string The location of the branch now * @param string The location of the branch after moving * @param string The key to identify the branch by in it's new location */ protected function moveBranchIn($type, $nested_type, $from, $old_branch, $new_branch, $tag) { $new = new Swift_Message_Part(); $new->setContentType($type); $this->getReference("parent", $new_branch)->addChild($new, $tag, -1); switch ($new_branch) { case "related": $this->setReference("related", $tag, $new);//relatedRefs[$tag] = $new; break; case "mixed": $this->setReference("mixed", $tag, $new);//mixedRefs[$tag] = $new; break; } foreach ($from as $id => $ref) { if (!$ref) $ref = $this; $sign = (strtolower($ref->getContentType()) == "text/plain" || strtolower($ref->getContentType()) == $nested_type) ? -1 : 1; switch ($new_branch) { case "related": $this->getReference("related", $tag)->addChild($ref, $id, $sign); break; case "mixed": $this->getReference("mixed", $tag)->addChild($ref, $id, $sign); break; } $this->getReference("parent", $old_branch)->removeChild($id); } $this->setReference("parent", $old_branch, $new); //parentRefs[$old_branch] = $new; } /** * Analyzes the mixing of MIME types in a mulitpart message an re-arranges if needed * It looks complicated and long winded but the concept is pretty simple, even if putting it * in code does me make want to cry! */ protected function postAttachFixStructure() { switch (true) { case (!empty($this->references["mixed"]) && !empty($this->references["related"]) && !empty($this->references["alternative"])): if (!isset($this->references["related"]["_alternative"])) { $this->moveBranchIn( "multipart/alternative", "multipart/alternative", $this->references["alternative"], "alternative", "related", "_alternative"); } if (!isset($this->references["mixed"]["_related"])) { $this->moveBranchIn( "multipart/related", "multipart/alternative", $this->references["related"], "related", "mixed", "_related"); } break; case (!empty($this->references["mixed"]) && !empty($this->references["related"])): if (!isset($this->references["mixed"]["_related"])) { $this->moveBranchIn( "multipart/related", "multipart/related", $this->references["related"], "related", "mixed", "_related"); } break; case (!empty($this->references["mixed"]) && !empty($this->references["alternative"])): if (!isset($this->references["mixed"]["_alternative"])) { $this->moveBranchIn( "multipart/alternative", null, $this->references["alternative"], "alternative", "mixed", "_alternative"); } break; case (!empty($this->references["related"]) && !empty($this->references["alternative"])): if (!isset($this->references["related"]["_alternative"])) { $this->moveBranchIn( "multipart/alternative", "multipart/alternative", $this->references["alternative"], "alternative", "related", "_alternative"); } break; } } /** * Move a branch further toward the top of the tree * @param array The array containing MIME parts from the old branch * @param string The name of the old branch * @param string The name of the new branch * @param string The key of the branch being moved */ protected function moveBranchOut($from, $old_branch, $new_branch, $tag) { foreach ($from as $id => $ref) { if (!$ref) $ref = $this; $sign = (strtolower($ref->getContentType()) == "text/html" || strtolower($ref->getContentType()) == "multipart/alternative") ? -1 : 1; $this->getReference("parent", $new_branch)->addChild($ref, $id, $sign); switch ($new_branch) { case "related": $this->getReference("related", $tag)->removeChild($id); break; case "mixed": $this->getReference("parent", $old_branch)->removeChild($id); break; } } $this->getReference("parent", $new_branch)->removeChild($tag); $mixed = $this->getReference("parent", $new_branch);//parentRefs[$new_branch]; $this->setReference("parent", $old_branch, $mixed);//parentRefs[$old_branch] = $mixed; switch ($new_branch) { case "related": unset($this->references["related"][$tag]); break; case "mixed": unset($this->references["mixed"][$tag]); break; } } /** * Analyzes the mixing of MIME types in a mulitpart message an re-arranges if needed * It looks complicated and long winded but the concept is pretty simple, even if putting it * in code does me make want to cry! */ protected function postDetachFixStructure() { switch (true) { case (!empty($this->references["mixed"]) && !empty($this->references["related"]) && !empty($this->references["alternative"])): if (array_keys($this->references["related"]) == array("_alternative")) { $alt = $this->getReference("parent", "related")->getChild("_alternative"); $this->getReference("parent", "mixed")->addChild($alt, "_alternative", -1); $this->setReference("mixed", "_alternative", $alt);//mixedRefs["_alternative"] = $alt; $this->getReference("parent", "related")->removeChild("_alternative"); unset($this->references["related"]["_alternative"]); $this->getReference("parent", "mixed")->removeChild("_related"); unset($this->references["mixed"]["_related"]); } if (array_keys($this->references["mixed"]) == array("_related")) { $this->moveBranchOut($this->references["related"], "related", "mixed", "_related"); } break; case (!empty($this->references["mixed"]) && !empty($this->references["related"])): if (array_keys($this->references["mixed"]) == array("_related")) { $this->moveBranchOut($this->references["related"], "related", "mixed", "_related"); } if (isset($this->references["related"]["_alternative"])) { $this->detach("_alternative"); } break; case (!empty($this->references["mixed"]) && !empty($this->references["alternative"])): if (array_keys($this->references["mixed"]) == array("_alternative")) { $this->moveBranchOut($this->references["alternative"], "alternative", "mixed", "_alternative"); } break; case (!empty($this->references["related"]) && !empty($this->references["alternative"])): if (array_keys($this->references["related"]) == array("_alternative")) { $this->moveBranchOut($this->references["alternative"], "alternative", "related", "_alternative"); } break; case (!empty($this->references["mixed"])): if (isset($this->references["mixed"]["_related"])) $this->detach("_related"); case (!empty($this->references["related"])): if (isset($this->references["related"]["_alternative"]) || isset($this->references["mixed"]["_alternative"])) $this->detach("_alternative"); break; } } /** * Execute needed logic prior to compilation */ public function preBuild() { $data = $this->getData(); if (!($enc = $this->getEncoding())) { $this->setEncoding("8bit"); } if ($this->getCharset() === null && !$this->numChildren()) { Swift_ClassLoader::load("Swift_Message_Encoder"); if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data)) { $this->setCharset("utf-8"); } elseif(is_string($data) && Swift_Message_Encoder::instance()->is7BitAscii($data)) { $this->setCharset("us-ascii"); if (!$enc) $this->setEncoding("7bit"); } else $this->setCharset("iso-8859-1"); } elseif ($this->numChildren()) { if (!$this->getData()) { $this->setData($this->getMimeWarning()); $this->setLineWrap(76); } if ($this->getCharset() !== null) $this->setCharset(null); if ($this->isFlowed()) $this->setFlowed(false); $this->setEncoding("7bit"); } } } ./kohana/system/vendor/swift/Swift/Log.php0000644000175000017500000000627010660421612020310 0ustar tokkeetokkee * @package Swift_Log * @license GNU Lesser General Public License */ /** * The Logger class/interface. * @package Swift_Log * @author Chris Corbyn */ abstract class Swift_Log { /** * A command type entry */ const COMMAND = ">>"; /** * A response type entry */ const RESPONSE = "<<"; /** * An error type entry */ const ERROR = "!!"; /** * A standard entry */ const NORMAL = "++"; /** * Logging is off. */ const LOG_NOTHING = 0; /** * Only errors are logged. */ const LOG_ERRORS = 1; /** * Errors + sending failures. */ const LOG_FAILURES = 2; /** * All SMTP instructions + failures + errors. */ const LOG_NETWORK = 3; /** * Runtime info + SMTP instructions + failures + errors. */ const LOG_EVERYTHING = 4; /** * Failed recipients * @var array */ protected $failedRecipients = array(); /** * The maximum number of log entries * @var int */ protected $maxSize = 50; /** * The level of logging currently set. * @var int */ protected $logLevel = self::LOG_NOTHING; /** * Add a new entry to the log * @param string The information to log * @param string The type of entry (see the constants: COMMAND, RESPONSE, ERROR, NORMAL) */ abstract public function add($text, $type = self::NORMAL); /** * Dump the contents of the log to the browser. * @param boolean True if the string should be returned rather than output. */ abstract public function dump($return_only=false); /** * Empty the log contents */ abstract public function clear(); /** * Check if logging is enabled. */ public function isEnabled() { return ($this->logLevel > self::LOG_NOTHING); } /** * Add a failed recipient to the list * @param string The address of the recipient */ public function addFailedRecipient($address) { $this->failedRecipients[$address] = null; $this->add("Recipient '" . $address . "' rejected by connection.", self::ERROR); } /** * Get the list of failed recipients * @return array */ public function getFailedRecipients() { return array_keys($this->failedRecipients); } /** * Set the maximum size of this log (zero is no limit) * @param int The maximum entries */ public function setMaxSize($size) { $this->maxSize = (int) $size; } /** * Get the current maximum allowed log size * @return int */ public function getMaxSize() { return $this->maxSize; } /** * Set the log level to one of the constants provided. * @param int Level */ public function setLogLevel($level) { $level = (int)$level; $this->add("Log level changed to " . $level, self::NORMAL); $this->logLevel = $level; } /** * Get the current log level. * @return int */ public function getLogLevel() { return $this->logLevel; } /** * Check if the log level includes the one given. * @param int Level * @return boolean */ public function hasLevel($level) { return ($this->logLevel >= ((int)$level)); } } ./kohana/system/vendor/swift/Swift/Address.php0000644000175000017500000000416610631577345021173 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_AddressContainer"); /** * Swift_Address is just a lone e-mail address reprsented as an object * @package Swift * @author Chris Corbyn */ class Swift_Address extends Swift_AddressContainer { /** * The e-mail address portion * @var string */ protected $address = null; /** * The personal name part * @var string */ protected $name = null; /** * Constructor * @param string The address portion * @param string The personal name, optional */ public function __construct($address, $name=null) { $this->setAddress($address); if ($name !== null) $this->setName($name); } /** * Set the email address * @param string */ public function setAddress($address) { $this->address = trim((string)$address); } /** * Get the address portion * @return string */ public function getAddress() { return $this->address; } /** * Set the personal name * @param string */ public function setName($name) { if ($name !== null) $this->name = (string) $name; else $this->name = null; } /** * Get personal name portion * @return string */ public function getName() { return $this->name; } /** * Build the address the way it should be structured * @param boolean If the string will be sent to a SMTP server as an envelope * @return string */ public function build($smtp=false) { if ($smtp) { return "<" . $this->address . ">"; } else { if (($this->name !== null)) { return $this->name . " <" . $this->address . ">"; } else return $this->address; } } /** * PHP's casting conversion * @return string */ public function __toString() { return $this->build(true); } } ./kohana/system/vendor/swift/Swift/Plugin/0000755000175000017500000000000011263472453020320 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Plugin/BandwidthMonitor.php0000644000175000017500000000477210607101013024275 0ustar tokkeetokkee * @package Swift_Plugin * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_CommandListener"); Swift_ClassLoader::load("Swift_Events_ResponseListener"); /** * Swift Bandwidth Monitor. * Tracks bytes in and out of the connection. * @package Swift_Plugin * @author Chris Corbyn */ class Swift_Plugin_BandwidthMonitor implements Swift_Events_CommandListener, Swift_Events_ResponseListener { /** * The number of bytes received * @var int */ protected $in = 0; /** * The number of bytes sent * @var int */ protected $out = 0; /** * Part of the interface which is notified after a command is sent. * @param Swift_Events_CommandEvent */ public function commandSent(Swift_Events_CommandEvent $e) { $code = $e->getCode(); $add = 0; if ($code != -1) $add = 2; $bytes = strlen($e->getString()) + $add; $this->addBytesOut($bytes); } /** * Part of the interface which is notified when a response is received * @param Swift_Events_ResponseEvent */ public function responseReceived(Swift_Events_ResponseEvent $e) { $bytes = strlen($e->getString()) + 2; $this->addBytesIn($bytes); } /** * Add some bytes to the running totals for incoming bandwidth * @param int Bytes in */ public function addBytesIn($num) { $num = abs((int)$num); $this->setBytesIn($this->getBytesIn() + $num); } /** * Add some bytes to the running totals for outgoing bandwidth * @param int Bytes out */ public function addBytesOut($num) { $num = abs((int)$num); $this->setBytesOut($this->getBytesOut() + $num); } /** * Get the total number of bytes received * @return int */ public function getBytesIn() { return $this->in; } /** * Get the total number of bytes sent * @return int */ public function getBytesOut() { return $this->out; } /** * Set the total number of bytes received. * Can be used to reset the counters at runtime. * @param int The bytes in */ public function setBytesIn($num) { $this->in = abs((int)$num); } /** * Set the total number of bytes sent. * Can be used to reset the counters at runtime. * @param int The bytes out */ public function setBytesOut($num) { $this->out = abs((int)$num); } } ./kohana/system/vendor/swift/Swift/Plugin/Decorator.php0000644000175000017500000001702410772423225022754 0ustar tokkeetokkee * @package Swift_Plugin * @subpackage Decorator * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_BeforeSendListener"); Swift_ClassLoader::load("Swift_Plugin_Decorator_Replacements"); /** * Swift Decorator Plugin. * Allows messages to be slightly different for each recipient. * @package Swift_Plugin * @subpackage Decorator * @author Chris Corbyn */ class Swift_Plugin_Decorator implements Swift_Events_BeforeSendListener { /** * The replacements object. * @var Swift_Plugin_Decorator_Replacements */ protected $replacements; /** * Temporary storage so we can restore changes we make. * @var array */ protected $store; /** * A list of allowed mime types to replace bodies for. * @var array */ protected $permittedTypes = array("text/plain" => 1, "text/html" => 1); /** * True if values in the headers can be replaced * @var boolean */ protected $permittedInHeaders = true; /** * Ctor. * @param mixed Replacements as a 2-d array or Swift_Plugin_Decorator_Replacements instance. */ public function __construct($replacements=null) { $this->setReplacements($replacements); } /** * Enable of disable the ability to replace values in the headers * @param boolean */ public function setPermittedInHeaders($bool) { $this->permittedInHeaders = (bool) $bool; } /** * Check if replacements in headers are allowed. * @return boolean */ public function getPermittedInHeaders() { return $this->permittedInHeaders; } /** * Add a mime type to the list of permitted type to replace values in the body. * @param string The mime type (e.g. text/plain) */ public function addPermittedType($type) { $type = strtolower($type); $this->permittedTypes[$type] = 1; } /** * Remove the ability to replace values in the body of the given mime type * @param string The mime type */ public function removePermittedType($type) { unset($this->permittedTypes[$type]); } /** * Get the list of mime types for which the body can be changed. * @return array */ public function getPermittedTypes() { return array_keys($this->permittedTypes); } /** * Check if the body can be replaced in the given mime type. * @param string The mime type * @return boolean */ public function isPermittedType($type) { return array_key_exists(strtolower($type), $this->permittedTypes); } /** * Called just before Swift sends a message. * We perform operations on the message here. * @param Swift_Events_SendEvent The event object for sending a message */ public function beforeSendPerformed(Swift_Events_SendEvent $e) { $message = $e->getMessage(); $this->recursiveRestore($message, $this->store); //3.3.3 bugfix $recipients = $e->getRecipients(); $to = array_keys($recipients->getTo()); if (count($to) > 0) $to = $to[0]; else return; $replacements = (array)$this->replacements->getReplacementsFor($to); $this->store = array( "headers" => array(), "body" => false, "children" => array() ); $this->recursiveReplace($message, $replacements, $this->store); } /** * Replace strings in the message searching through all the allowed sub-parts. * @param Swift_Message_Mime The message (or part) * @param array The list of replacements * @param array The array to cache original values into where needed */ protected function recursiveReplace(Swift_Message_Mime $mime, $replacements, &$store) { //Check headers if ($this->getPermittedInHeaders()) { foreach ($mime->headers->getList() as $name => $value) { if (is_string($value) && ($replaced = $this->replace($replacements, $value)) != $value) { $mime->headers->set($name, $replaced); $store["headers"][$name] = array(); $store["headers"][$name]["value"] = $value; $store["headers"][$name]["attributes"] = array(); } foreach ($mime->headers->listAttributes($name) as $att_name => $att_value) { if (is_string($att_value) && ($att_replaced = $this->replace($replacements, $att_value)) != $att_value) { if (!isset($store["headers"][$name])) { $store["headers"][$name] = array("value" => false, "attributes" => array()); } $mime->headers->setAttribute($name, $att_name, $att_replaced); $store["headers"][$name]["attributes"][$att_name] = $att_value; } } } } //Check body $body = $mime->getData(); if ($this->isPermittedType($mime->getContentType()) && is_string($body) && ($replaced = $this->replace($replacements, $body)) != $body) { $mime->setData($replaced); $store["body"] = $body; } //Check sub-parts foreach ($mime->listChildren() as $id) { $store["children"][$id] = array( "headers" => array(), "body" => false, "children" => array() ); $child = $mime->getChild($id); $this->recursiveReplace($child, $replacements, $store["children"][$id]); } } /** * Perform a str_replace() over the given value. * @param array The list of replacements as (search => replacement) * @param string The string to replace * @return string */ protected function replace($replacements, $value) { return str_replace(array_keys($replacements), array_values($replacements), $value); } /** * Put the original values back in the message after it was modified before sending. * @param Swift_Message_Mime The message (or part) * @param array The location of the stored values */ protected function recursiveRestore(Swift_Message_Mime $mime, &$store) { if (empty($store)) //3.3.3 bugfix { return; } //Restore headers foreach ($store["headers"] as $name => $array) { if ($array["value"] !== false) $mime->headers->set($name, $array["value"]); foreach ($array["attributes"] as $att_name => $att_value) { $mime->headers->setAttribute($name, $att_name, $att_value); } } //Restore body if ($store["body"] !== false) { $mime->setData($store["body"]); } //Restore children foreach ($store["children"] as $id => $child_store) { $child = $mime->getChild($id); $this->recursiveRestore($child, $child_store); } } /** * Set the replacements as a 2-d array or an instance of Swift_Plugin_Decorator_Replacements. * @param mixed Array or Swift_Plugin_Decorator_Replacements */ public function setReplacements($replacements) { if ($replacements === null) { $r = array(); $this->replacements = new Swift_Plugin_Decorator_Replacements($r); } elseif (is_array($replacements)) { $this->replacements = new Swift_Plugin_Decorator_Replacements($replacements); } elseif ($replacements instanceof Swift_Plugin_Decorator_Replacements) { $this->replacements = $replacements; } else { throw new Exception( "Decorator replacements must be array or instance of Swift_Plugin_Decorator_Replacements."); } } /** * Get the replacements object. * @return Swift_Plugin_Decorator_Replacements */ public function getReplacements() { return $this->replacements; } } ./kohana/system/vendor/swift/Swift/Plugin/FileEmbedder.php0000644000175000017500000003333710623121155023336 0ustar tokkeetokkee * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_BeforeSendListener"); /** * Swift FileEmbedder Plugin to embed remote files. * Scans a Swift_Message instance for remote files and then embeds them before sending. * This also embeds local files from disk. * @package Swift_Plugin * @author Chris Corbyn */ class Swift_Plugin_FileEmbedder implements Swift_Events_BeforeSendListener { /** * True if remote files will be embedded. * @var boolean */ protected $embedRemoteFiles = true; /** * True if local files will be embedded. * @var boolean */ protected $embedLocalFiles = true; /** * (X)HTML tag defintions listing allowed attributes and extensions. * @var array */ protected $definitions = array( "img" => array( "attributes" => array("src"), "extensions" => array("gif", "png", "jpg", "jpeg", "pjpeg") ), "link" => array( "attributes" => array("href"), "extensions" => array("css") ), "script" => array( "attributes" => array("src"), "extensions" => array("js") )); /** * Protocols which may be used to download a remote file. * @var array */ protected $protocols = array( "http" => "http", "https" => "https", "ftp" => "ftp" ); /** * A PCRE regexp which will be passed via sprintf() to produce a complete pattern. * @var string */ protected $remoteFilePatternFormat = "~ (<(?:%s)\\s+[^>]*? #Opening tag followed by (possible) attributes (?:%s)=((?:\"|')?)) #Permitted attributes followed by (possible) quotation marks ((?:%s)://[\\x01-\\x7F]*?(?:%s)?) #Remote URL (matching a permitted protocol) (\\2[^>]*>) #Remaining attributes followed by end of tag ~isx"; /** * A PCRE regexp which will be passed via sprintf() to produce a complete pattern. * @var string */ protected $localFilePatternFormat = "~ (<(?:%s)\\s+[^>]*? #Opening tag followed by (possible) attributes (?:%s)=((?:\"|')?)) #Permitted attributes followed by (possible) quotation marks ((?:/|[a-z]:\\\\|[a-z]:/)[\\x01-\\x7F]*?(?:%s)?) #Local, absolute path (\\2[^>]*>) #Remaining attributes followed by end of tag ~isx"; /** * A list of extensions mapping to their usual MIME types. * @var array */ protected $mimeTypes = array( "gif" => "image/gif", "png" => "image/png", "jpeg" => "image/jpeg", "jpg" => "image/jpeg", "pjpeg" => "image/pjpeg", "js" => "text/javascript", "css" => "text/css"); /** * Child IDs of files already embedded. * @var array */ protected $registeredFiles = array(); /** * Get the MIME type based upon the extension. * @param string The extension (sans the dot). * @return string */ public function getType($ext) { $ext = strtolower($ext); if (isset($this->mimeTypes[$ext])) { return $this->mimeTypes[$ext]; } else return null; } /** * Add a new MIME type defintion (or overwrite an existing one). * @param string The extension (sans the dot) * @param string The MIME type (e.g. image/jpeg) */ public function addType($ext, $type) { $this->mimeTypes[strtolower($ext)] = strtolower($type); } /** * Set the PCRE pattern which finds -full- HTML tags and copies the path for a local file into a backreference. * The pattern contains three %s replacements for sprintf(). * First replacement is the tag name (e.g. img) * Second replacement is the attribute name (e.g. src) * Third replacement is the file extension (e.g. jpg) * This pattern should contain the full URL in backreference index 3. * @param string sprintf() format string containing a PCRE regexp. */ public function setLocalFilePatternFormat($format) { $this->localFilePatternFormat = $format; } /** * Gets the sprintf() format string for the PCRE pattern to scan for remote files. * @return string */ public function getLocalFilePatternFormat() { return $this->localFilePatternFormat; } /** * Set the PCRE pattern which finds -full- HTML tags and copies the URL for the remote file into a backreference. * The pattern contains four %s replacements for sprintf(). * First replacement is the tag name (e.g. img) * Second replacement is the attribute name (e.g. src) * Third replacement is the protocol (e.g. http) * Fourth replacement is the file extension (e.g. jpg) * This pattern should contain the full URL in backreference index 3. * @param string sprintf() format string containing a PCRE regexp. */ public function setRemoteFilePatternFormat($format) { $this->remoteFilePatternFormat = $format; } /** * Gets the sprintf() format string for the PCRE pattern to scan for remote files. * @return string */ public function getRemoteFilePatternFormat() { return $this->remoteFilePatternFormat; } /** * Add a new protocol which can be used to download files. * Protocols should not include the "://" portion. This method expects alphanumeric characters only. * @param string The protocol name (e.g. http or ftp) */ public function addProtocol($prot) { $prot = strtolower($prot); $this->protocols[$prot] = $prot; } /** * Remove a protocol from the list of allowed protocols once added. * @param string The name of the protocol (e.g. http) */ public function removeProtocol($prot) { unset($this->protocols[strtolower($prot)]); } /** * Get a list of all registered protocols. * @return array */ public function getProtocols() { return array_values($this->protocols); } /** * Add, or modify a tag definition. * This affects how the plugins scans for files to download. * @param string The name of a tag to search for (e.g. img) * @param string The name of attributes to look for (e.g. src). You can pass an array if there are multiple possibilities. * @param array A list of extensions to allow (sans dot). If there's only one you can just pass a string. */ public function setTagDefinition($tag, $attributes, $extensions) { $tag = strtolower($tag); $attributes = (array)$attributes; $extensions = (array)$extensions; if (empty($tag) || empty($attributes) || empty($extensions)) { return null; } $this->definitions[$tag] = array("attributes" => $attributes, "extensions" => $extensions); return true; } /** * Remove a tag definition for remote files. * @param string The name of the tag */ public function removeTagDefinition($tag) { unset($this->definitions[strtolower($tag)]); } /** * Get a tag definition. * Returns an array with indexes "attributes" and "extensions". * Each element is an array listing the values within it. * @param string The name of the tag * @return array */ public function getTagDefinition($tag) { $tag = strtolower($tag); if (isset($this->definitions[$tag])) return $this->definitions[$tag]; else return null; } /** * Get the PCRE pattern for a remote file based on the tag name. * @param string The name of the tag * @return string */ public function getRemoteFilePattern($tag_name) { $tag_name = strtolower($tag_name); $pattern_format = $this->getRemoteFilePatternFormat(); if ($def = $this->getTagDefinition($tag_name)) { $pattern = sprintf($pattern_format, $tag_name, implode("|", $def["attributes"]), implode("|", $this->getProtocols()), implode("|", $def["extensions"])); return $pattern; } else return null; } /** * Get the PCRE pattern for a local file based on the tag name. * @param string The name of the tag * @return string */ public function getLocalFilePattern($tag_name) { $tag_name = strtolower($tag_name); $pattern_format = $this->getLocalFilePatternFormat(); if ($def = $this->getTagDefinition($tag_name)) { $pattern = sprintf($pattern_format, $tag_name, implode("|", $def["attributes"]), implode("|", $def["extensions"])); return $pattern; } else return null; } /** * Register a file which has been downloaded so it doesn't need to be downloaded twice. * @param string The remote URL * @param string The ID as attached in the message * @param Swift_Message_EmbeddedFile The file object itself */ public function registerFile($url, $cid, $file) { $url = strtolower($url); if (!isset($this->registeredFiles[$url])) $this->registeredFiles[$url] = array("cids" => array(), "obj" => null); $this->registeredFiles[$url]["cids"][] = $cid; if (empty($this->registeredFiles[$url]["obj"])) $this->registeredFiles[$url]["obj"] = $file; } /** * Turn on or off remote file embedding. * @param boolean */ public function setEmbedRemoteFiles($set) { $this->embedRemoteFiles = (bool)$set; } /** * Returns true if remote files can be embedded, or false if not. * @return boolean */ public function getEmbedRemoteFiles() { return $this->embedRemoteFiles; } /** * Turn on or off local file embedding. * @param boolean */ public function setEmbedLocalFiles($set) { $this->embedLocalFiles = (bool)$set; } /** * Returns true if local files can be embedded, or false if not. * @return boolean */ public function getEmbedLocalFiles() { return $this->embedLocalFiles; } /** * Callback method for preg_replace(). * Embeds files which have been found during scanning. * @param array Backreferences from preg_replace() * @return string The tag with it's URL replaced with a CID */ protected function embedRemoteFile($matches) { $url = preg_replace("~^([^#]+)#.*\$~s", "\$1", $matches[3]); $bits = parse_url($url); $ext = preg_replace("~^.*?\\.([^\\.]+)\$~s", "\$1", $bits["path"]); $lower_url = strtolower($url); if (array_key_exists($lower_url, $this->registeredFiles)) { $registered = $this->registeredFiles[$lower_url]; foreach ($registered["cids"] as $cid) { if ($this->message->hasChild($cid)) { return $matches[1] . $cid . $matches[4]; } } //If we get here the file is downloaded, but not embedded $cid = $this->message->attach($registered["obj"]); $this->registerFile($url, $cid, $registered["obj"]); return $matches[1] . $cid . $matches[4]; } $magic_quotes = get_magic_quotes_runtime(); set_magic_quotes_runtime(0); $filedata = @file_get_contents($url); set_magic_quotes_runtime($magic_quotes); if (!$filedata) { return $matches[1] . $matches[3] . $matches[4]; } $filename = preg_replace("~^.*/([^/]+)\$~s", "\$1", $url); $att = new Swift_Message_EmbeddedFile($filedata, $filename, $this->getType($ext)); $id = $this->message->attach($att); $this->registerFile($url, $id, $att); return $matches[1] . $id . $matches[4]; } /** * Callback method for preg_replace(). * Embeds files which have been found during scanning. * @param array Backreferences from preg_replace() * @return string The tag with it's path replaced with a CID */ protected function embedLocalFile($matches) { $path = realpath($matches[3]); if (!$path) { return $matches[1] . $matches[3] . $matches[4]; } $ext = preg_replace("~^.*?\\.([^\\.]+)\$~s", "\$1", $path); $lower_path = strtolower($path); if (array_key_exists($lower_path, $this->registeredFiles)) { $registered = $this->registeredFiles[$lower_path]; foreach ($registered["cids"] as $cid) { if ($this->message->hasChild($cid)) { return $matches[1] . $cid . $matches[4]; } } //If we get here the file is downloaded, but not embedded $cid = $this->message->attach($registered["obj"]); $this->registerFile($path, $cid, $registered["obj"]); return $matches[1] . $cid . $matches[4]; } $filename = basename($path); $att = new Swift_Message_EmbeddedFile(new Swift_File($path), $filename, $this->getType($ext)); $id = $this->message->attach($att); $this->registerFile($path, $id, $att); return $matches[1] . $id . $matches[4]; } /** * Empty out the cache of registered files. */ public function clearCache() { $this->registeredFiles = null; $this->registeredFiles = array(); } /** * Swift's BeforeSendListener required method. * Runs just before Swift sends a message. Here is where we do all the replacements. * @param Swift_Events_SendEvent */ public function beforeSendPerformed(Swift_Events_SendEvent $e) { $this->message = $e->getMessage(); foreach ($this->message->listChildren() as $id) { $part = $this->message->getChild($id); $body = $part->getData(); if (!is_string($body) || substr(strtolower($part->getContentType()), 0, 5) != "text/") continue; foreach ($this->definitions as $tag_name => $def) { if ($this->getEmbedRemoteFiles()) { $re = $this->getRemoteFilePattern($tag_name); $body = preg_replace_callback($re, array($this, "embedRemoteFile"), $body); } if ($this->getEmbedLocalFiles()) { $re = $this->getLocalFilePattern($tag_name); $body = preg_replace_callback($re, array($this, "embedLocalFile"), $body); } } $part->setData($body); } } } ./kohana/system/vendor/swift/Swift/Plugin/ConnectionRotator.php0000644000175000017500000000623310635210315024474 0ustar tokkeetokkee * @package Swift_Plugin * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_SendListener"); Swift_ClassLoader::load("Swift_Events_DisconnectListener"); /** * Swift Rotating Connection Controller * Invokes the nextConnection() method of Swift_Connection_Rotator upon sending a given number of messages * @package Swift_Plugin * @author Chris Corbyn */ class Swift_Plugin_ConnectionRotator implements Swift_Events_SendListener, Swift_Events_DisconnectListener { /** * The number of emails which must be sent before the connection is rotated * @var int Threshold number of emails */ protected $threshold = 1; /** * The total number of emails sent on this connection * @var int */ protected $count = 0; /** * The connections we have used thus far * @var array */ protected $used = array(); /** * Internal check to see if this plugin has yet been invoked * @var boolean */ protected $called = false; /** * Constructor * @param int The number of emails to send before rotating */ public function __construct($threshold=1) { $this->setThreshold($threshold); } /** * Set the number of emails to send before a connection rotation is tried * @param int Number of emails */ public function setThreshold($threshold) { $this->threshold = (int) $threshold; } /** * Get the number of emails which must be sent before a rotation occurs * @return int */ public function getThreshold() { return $this->threshold; } /** * Swift's SendEvent listener. * Invoked when Swift sends a message * @param Swift_Events_SendEvent The event information * @throws Swift_ConnectionException If the connection cannot be rotated */ public function sendPerformed(Swift_Events_SendEvent $e) { if (!method_exists($e->getSwift()->connection, "nextConnection")) { throw new Swift_ConnectionException("The ConnectionRotator plugin cannot be used with connections other than Swift_Connection_Rotator."); } if (!$this->called) { $this->used[] = $e->getSwift()->connection->getActive(); } $this->count++; if ($this->count >= $this->getThreshold()) { $e->getSwift()->connection->nextConnection(); if (!in_array(($id = $e->getSwift()->connection->getActive()), $this->used)) { $e->getSwift()->connect(); $this->used[] = $id; } $this->count = 0; } $this->called = true; } /** * Disconnect all the other connections * @param Swift_Events_DisconnectEvent The event info */ public function disconnectPerformed(Swift_Events_DisconnectEvent $e) { $active = $e->getConnection()->getActive(); $e->getConnection()->nextConnection(); while ($e->getConnection()->getActive() != $active) { $e->getSwift()->command("QUIT", 221); $e->getConnection()->stop(); $e->getConnection()->nextConnection(); } $this->used = array(); } } ./kohana/system/vendor/swift/Swift/Plugin/AntiFlood.php0000644000175000017500000000505010635210315022675 0ustar tokkeetokkee * @package Swift_Plugin * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_SendListener"); /** * Swift AntiFlood controller. * Closes a connection and pauses for X seconds after a number of emails have been sent. * @package Swift_Plugin * @author Chris Corbyn */ class Swift_Plugin_AntiFlood implements Swift_Events_SendListener { /** * The number of emails to send between connections * @var int */ protected $threshold = null; /** * The number of seconds to pause for between connections * @var int */ protected $waitFor = null; /** * Number of emails sent so far * @var int */ protected $count = 0; /** * Constructor * @param int Number of emails to send before re-connecting * @param int The timeout in seconds between connections */ public function __construct($threshold, $wait=0) { $this->setThreshold($threshold); $this->setWait($wait); } /** * Set the number of emails which must be sent for a reconnection to occur * @param int Number of emails */ public function setThreshold($threshold) { $this->threshold = (int) $threshold; } /** * Get the number of emails which need to be sent for reconnection to occur * @return int */ public function getThreshold() { return $this->threshold; } /** * Set the number of seconds the plugin should wait for before reconnecting * @param int Time in seconds */ public function setWait($time) { $this->waitFor = (int) $time; } /** * Get the number of seconds the plugin should wait for before re-connecting * @return int */ public function getWait() { return $this->waitFor; } /** * Sleep for a given number of seconds * @param int Number of seconds to wait for */ public function wait($seconds) { if ($seconds) sleep($seconds); } /** * Swift's SendEvent listener. * Invoked when Swift sends a message * @param Swift_Events_SendEvent The event information * @throws Swift_ConnectionException If the connection cannot be closed/re-opened */ public function sendPerformed(Swift_Events_SendEvent $e) { $this->count++; if ($this->count >= $this->getThreshold()) { $e->getSwift()->disconnect(); $this->wait($this->getWait()); $e->getSwift()->connect(); $this->count = 0; } } } ./kohana/system/vendor/swift/Swift/Plugin/MailSend.php0000644000175000017500000001211210635210315022507 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_SendListener"); Swift_ClassLoader::load("Swift_Events_BeforeSendListener"); /** * Swift mail() send plugin * Sends the message using mail() when a SendEvent is fired. Using the NativeMail connection provides stub responses to allow this to happen cleanly. * @package Swift_Connection * @author Chris Corbyn */ class Swift_Plugin_MailSend implements Swift_Events_SendListener, Swift_Events_BeforeSendListener { /** * The operating system of the server * @var string */ protected $OS = null; /** * The return path in use here * @var string */ protected $returnPath = null; /** * The line ending before we intrusively change it * @var string */ protected $oldLE = "\r\n"; /** * 5th parameter in mail(). * @var string */ protected $additionalParams; /** * Constructor. * @param string 5th mail() function parameter as a sprintf() formatted string where %s is the sender. */ public function __construct($params="-oi -f %s") { $this->setAdditionalParams($params); $this->setOS(PHP_OS); } /** * Set the 5th mail() function parameter as a sprintf() formatted string where %s is the sender. * @param string */ public function setAdditionalParams($params) { $this->additionalParams = $params; } /** * Get the 5th mail() function parameter as a sprintf() string. * @return string */ public function getAdditionalParams() { return $this->additionalParams; } /** * Set the operating system string (changes behaviour with LE) * @param string The operating system */ public function setOS($os) { $this->OS = $os; } /** * Get the operating system string * @return string */ public function getOS() { return $this->OS; } /** * Check if this is windows or not * @return boolean */ public function isWindows() { return (substr($this->getOS(), 0, 3) == "WIN"); } /** * Swift's BeforeSendEvent listener. * Invoked just before Swift sends a message * @param Swift_Events_SendEvent The event information */ public function beforeSendPerformed(Swift_Events_SendEvent $e) { $message = $e->getMessage(); $message->uncacheAll(); $this->oldLE = $message->getLE(); if (!$this->isWindows() && $this->oldLE != "\n") $message->setLE("\n"); } /** * Swift's SendEvent listener. * Invoked when Swift sends a message * @param Swift_Events_SendEvent The event information * @throws Swift_ConnectionException If mail() returns false */ public function sendPerformed(Swift_Events_SendEvent $e) { $message = $e->getMessage(); $recipients = $e->getRecipients(); $to = array(); foreach ($recipients->getTo() as $addr) { if ($this->isWindows()) $to[] = substr($addr->build(true), 1, -1); else $to[] = $addr->build(); } $to = implode(", ", $to); $bcc_orig = $message->headers->has("Bcc") ? $message->headers->get("Bcc") : null; $subject_orig = $message->headers->has("Subject") ? $message->headers->get("Subject") : null; $to_orig = $message->headers->has("To") ? $message->headers->get("To") : null; $bcc = array(); foreach ($recipients->getBcc() as $addr) $bcc[] = $addr->build(); if (!empty($bcc)) $message->headers->set("Bcc", $bcc); $bcc = null; $body_data = $message->buildData(); $message_body = $body_data->readFull(); $subject_enc = $message->headers->has("Subject") ? $message->headers->getEncoded("Subject") : ""; $message->headers->set("To", null); $message->headers->set("Subject", null); $sender = $e->getSender(); $this->returnPath = $sender->build(); if ($message->headers->has("Return-Path")) $this->returnPath = $message->headers->get("Return-Path"); if (preg_match("~<([^>]+)>[^>]*\$~", $this->returnPath, $matches)) $this->returnPath = $matches[1]; $this->doMail($to, $subject_enc, $message_body, $message->headers, sprintf($this->getAdditionalParams(), $this->returnPath)); $message->setLE($this->oldLE); $message->headers->set("To", $to_orig); $message->headers->set("Subject", $subject_orig); $message->headers->set("Bcc", $bcc_orig); } public function doMail($to, $subject, $message, $headers, $params) { $original_from = @ini_get("sendmail_from"); @ini_set("sendmail_from", $this->returnPath); $headers = $headers->build(); if (!ini_get("safe_mode")) $success = mail($to, $subject, $message, $headers, $params); else $success = mail($to, $subject, $message, $headers); if (!$success) { @ini_set("sendmail_from", $original_from); throw new Swift_ConnectionException("Sending failed using mail() as PHP's default mail() function returned boolean FALSE."); } @ini_set("sendmail_from", $original_from); } } ./kohana/system/vendor/swift/Swift/Plugin/Decorator/0000755000175000017500000000000011263472452022241 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Plugin/Decorator/Replacements.php0000644000175000017500000000401610633021667025373 0ustar tokkeetokkee * @package Swift_Plugin * @subpackage Decorator * @license GNU Lesser General Public License */ /** * Swift Decorator Plugin Replacements. * Provides and manages the list of replacements for the decorator plugin. * @package Swift_Plugin * @subpackage Decorator * @author Chris Corbyn */ class Swift_Plugin_Decorator_Replacements { /** * The list of replacements as a 2-d array * @var array,array */ protected $replacements; /** * Ctor. * @param array The replacements as a 2-d array, optional */ public function __construct($replacements = array()) { $this->setReplacements($replacements); } /** * Add a list of replacements for a given address. * @param string The e-mail address * @param array The replacements as (search => replacement) form. */ public function addReplacements($address, $replacements) { $this->replacements[strtolower($address)] = (array)$replacements; } /** * Set the complete list of replacements as a 2-d array. * The array is formed thus (address => (search => replace), address => (search => replace)) * @param array,array The replacements. */ public function setReplacements($replacements) { $this->replacements = array_change_key_case((array) $replacements, CASE_LOWER); } /** * Get the entire list of replacements as a 2-d array * @return array,array */ public function getReplacements() { return $this->replacements; } /** * Get the list of replacements for the address given. * Returns an array where (search => replacement). * @param string The address to get replacements for * @return array */ public function getReplacementsFor($address) { $address = strtolower($address); if (array_key_exists($address, $this->replacements)) { return (array)$this->replacements[$address]; } else return array(); } } ./kohana/system/vendor/swift/Swift/Plugin/VerboseSending.php0000644000175000017500000000475510617176724023765 0ustar tokkeetokkee * @package Swift_Plugin * @subpackage VerboseSending * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_SendListener"); Swift_ClassLoader::load("Swift_Plugin_VerboseSending_DefaultView"); /** * Verbose Sending plugin for Swift Mailer. * Displays "pass" or "fail" messages in realtime as the messages are sent. * @package Swift_Plugin * @subpackage VerboseSending * @author Chris Corbyn */ class Swift_Plugin_VerboseSending implements Swift_Events_SendListener { /** * The view layer which displays the results. * @var Swift_Plugin_VerboseSending_AbstractView */ protected $view; /** * Ctor. * @param Swift_Plugin_VerboseSending_AbstractView The view object to display the result */ public function __construct(Swift_Plugin_VerboseSending_AbstractView $view) { $this->setView($view); } /** * Part of the interface which is notified when a message has been sent. * @param Swift_Events_SendEvent */ public function sendPerformed(Swift_Events_SendEvent $e) { $recipients = $e->getRecipients(); $failed = $e->getFailedRecipients(); $it = $recipients->getIterator("to"); while ($it->hasNext()) { $it->next(); $address = $it->getValue(); $pass = !in_array($address->getAddress(), $failed); $this->getView()->paintResult($address->getAddress(), $pass); } $it = $recipients->getIterator("cc"); while ($it->hasNext()) { $it->next(); $address = $it->getValue(); $pass = !in_array($address->getAddress(), $failed); $this->getView()->paintResult($address->getAddress(), $pass); } $it = $recipients->getIterator("bcc"); while ($it->hasNext()) { $it->next(); $address = $it->getValue(); $pass = !in_array($address->getAddress(), $failed); $this->getView()->paintResult($address->getAddress(), $pass); } } /** * Set the View component to display results. * @param Swift_Plugin_VerboseSending_AbstractView The view object to display the result */ public function setView(Swift_Plugin_VerboseSending_AbstractView $view) { $this->view = $view; } /** * Get the View component. * @return Swift_Plugin_VerboseSending_AbstractView */ public function getView() { return $this->view; } } ./kohana/system/vendor/swift/Swift/Plugin/VerboseSending/0000755000175000017500000000000011263472453023235 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Plugin/VerboseSending/DefaultView.php0000644000175000017500000000260510607101013026146 0ustar tokkeetokkee * @package Swift_Plugin * @subpackage VerboseSending * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../../ClassLoader.php"; Swift_ClassLoader::load("Swift_Plugin_VerboseSending_AbstractView"); /** * The Default View for the Verbose Sending Plugin * @package Swift_Plugin * @subpackage VerboseSending * @author Chris Corbyn */ class Swift_Plugin_VerboseSending_DefaultView extends Swift_Plugin_VerboseSending_AbstractView { /** * Number of recipients painted * @var int */ protected $count = 0; /** * Paint the result of a send operation * @param string The email address that was tried * @param boolean True if the message was successfully sent */ public function paintResult($address, $result) { $this->count++; $color = $result ? "#51c45f" : "#d67d71"; $result_text = $result ? "PASS" : "FAIL"; ?>
    Recipient (count; ?>):
    * @package Swift_Plugin * @subpackage VerboseSending * @license GNU Lesser General Public License */ /** * The View layer for the Verbose Sending Plugin * @package Swift_Plugin * @subpackage VerboseSending * @author Chris Corbyn */ abstract class Swift_Plugin_VerboseSending_AbstractView { /** * Paint the result of a send operation * @param string The email address that was tried * @param boolean True if the message was successfully sent */ abstract public function paintResult($address, $result); } ./kohana/system/vendor/swift/Swift/Plugin/Throttler.php0000644000175000017500000000750610607101013023006 0ustar tokkeetokkee * @package Swift_Plugin * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Plugin_BandwidthMonitor"); Swift_ClassLoader::load("Swift_Events_SendListener"); /** * Throttler plugin for Swift Mailer. * Restricts the speed at which Swift will operate. * @package Swift_Plugin * @author Chris Corbyn */ class Swift_Plugin_Throttler extends Swift_Plugin_BandwidthMonitor implements Swift_Events_SendListener { /** * The rate in byte-per-minute * @var int */ protected $bpm = null; /** * The rate as emails-per-minute * @var int */ protected $epm = null; /** * The number of emails sent so far * @var int */ protected $sent = 0; /** * The time at the start of overall execution * @var int */ protected $time = null; /** * Part of the interface which is notified after a command is sent. * @param Swift_Events_CommandEvent */ public function commandSent(Swift_Events_CommandEvent $e) { parent::commandSent($e); if (null === $rate = $this->getBytesPerMinute()) return; $duration = $this->getTimeLapse(); $bytes_sent = $this->getBytesOut(); $bytes_per_sec = $rate / 60; $seconds_allowed_so_far = ceil($bytes_sent / $bytes_per_sec); $overrun = $seconds_allowed_so_far - $duration; if ($overrun > 0) { $this->wait($overrun); } } /** * Part of the interface which is notified when a message has been sent. * @param Swift_Events_SendEvent */ public function sendPerformed(Swift_Events_SendEvent $e) { $this->setSent($this->getSent() + 1); if (null === $rate = $this->getEmailsPerMinute()) return; $duration = $this->getTimeLapse(); $emails_sent = $this->getSent(); $emails_per_sec = $rate / 60; $seconds_allowed_so_far = ceil($emails_sent / $emails_per_sec); $overrun = $seconds_allowed_so_far - $duration; if ($overrun > 0) { $this->wait($overrun); } } /** * Wait for $seconds before continuing * @param int The number of seconds to wait */ public function wait($secs) { sleep($secs); } /** * Set the time if it's not already set */ protected function setTime() { if ($this->time === null) $this->time = time(); } /** * Get the time taken thus far (full seconds). * @return int */ public function getTimeLapse() { $this->setTime(); return time() - $this->time; } /** * Set the number of emails sent * @param int Emails sent so far */ public function setSent($num) { $this->sent = (int)$num; } /** * Get the number of emails sent * @return int */ public function getSent() { return $this->sent; } /** * Set the throttling rate as bytes per minute * @param int The maximum number of outgoing bytes in 60 seconds. */ public function setBytesPerMinute($bpm) { if ($bpm === null) { $this->bpm = null; return; } $this->setEmailsPerMinute(null); $this->bpm = abs((int)$bpm); } /** * Get the number of bytes allowed per minute. * Reurns NULL if not used. * @return int */ public function getBytesPerMinute() { return $this->bpm; } /** * Set the rate as emails-per-minute. * @param int The max number of emails to send in a minute. */ public function setEmailsPerMinute($epm) { if ($epm === null) { $this->epm = null; return; } $this->setBytesPerMinute(null); $this->epm = abs((int)$epm); } /** * Get the rate as number of emails per minute. * Returns null if not used. * @return int */ public function getEmailsPerMinute() { return $this->epm; } } ./kohana/system/vendor/swift/Swift/Plugin/EasySwiftResponseTracker.php0000644000175000017500000000222410607101013025760 0ustar tokkeetokkee * @author Chris Corbyn * @package EasySwift * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Events_ResponseListener"); /** * EasySwift, Swift Response Tracker. * Updates properties in EasySwift when a response is received by Swift. * @package EasySwift * @author Chris Corbyn */ class Swift_Plugin_EasySwiftResponseTracker implements Swift_Events_ResponseListener { /** * The target object to update * @var EasySwift */ protected $target = null; /** * Constructor * @param EasySwift The instance of EasySwift to run against */ public function __construct($obj) { $this->target = $obj; } /** * Response listener method * @param Swift_Events_ResponseEvent The event occured in Swift */ public function responseReceived(Swift_Events_ResponseEvent $e) { $this->target->lastResponse = $e->getString(); $this->target->responseCode = $e->getCode(); } } ./kohana/system/vendor/swift/Swift/Log/0000755000175000017500000000000011263472452017602 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Log/DefaultLog.php0000644000175000017500000000256610660421612022342 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Log * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Log"); /** * The Default Logger class * @package Swift_Log * @author Chris Corbyn */ class Swift_Log_DefaultLog extends Swift_Log { /** * Lines in the log * @var array */ protected $entries = array(); /** * Add a log entry * @param string The text for this entry * @param string The label for the type of entry */ public function add($text, $type = self::NORMAL) { $this->entries[] = $type . " " . $text; if ($this->getMaxSize() > 0) $this->entries = array_slice($this->entries, (-1 * $this->getMaxSize())); } /** * Dump the contents of the log to the browser. * @param boolean True if the string should be returned rather than output. */ public function dump($return_only=false) { $ret = implode("\n", $this->entries); if (!$return_only) echo $ret; else return $ret; } /** * Empty the log */ public function clear() { $this->failedRecipients = null; $this->failedRecipients = array(); $this->entries = null; $this->entries = array(); } } ./kohana/system/vendor/swift/Swift/ClassLoader.php0000644000175000017500000000161610607101013021751 0ustar tokkeetokkee * @package Swift * @license GNU Lesser General Public License */ if (!defined("SWIFT_ABS_PATH")) define("SWIFT_ABS_PATH", dirname(__FILE__) . "/.."); /** * Locates and includes class files * @package Swift * @author Chris Corbyn */ class Swift_ClassLoader { /** * A list of files already located * @var array */ protected static $located = array(); /** * Load a new class into memory * @param string The name of the class, case SenSItivE */ public static function load($name) { if (in_array($name, self::$located) || class_exists($name, false) || interface_exists($name, false)) return; require_once SWIFT_ABS_PATH . "/" . str_replace("_", "/", $name) . ".php"; self::$located[] = $name; } } ./kohana/system/vendor/swift/Swift/BatchMailer.php0000644000175000017500000001364510633031341021742 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift * @license GNU Lesser General Public License */ class Swift_BatchMailer { /** * The current instance of Swift. * @var Swift */ protected $swift; /** * The maximum number of times a single recipient can be attempted before giving up. * @var int */ protected $maxTries = 2; /** * The number of seconds to sleep for if an error occurs. * @var int */ protected $sleepTime = 0; /** * Failed recipients (undeliverable) * @var array */ protected $failed = array(); /** * The maximum number of successive failures before giving up. * @var int */ protected $maxFails = 0; /** * A temporary copy of some message headers. * @var array */ protected $headers = array(); /** * Constructor. * @param Swift The current instance of Swift */ public function __construct(Swift $swift) { $this->setSwift($swift); } /** * Set the current Swift instance. * @param Swift The instance */ public function setSwift(Swift $swift) { $this->swift = $swift; } /** * Get the Swift instance which is running. * @return Swift */ public function getSwift() { return $this->swift; } /** * Set the maximum number of times a single address is allowed to be retried. * @param int The maximum number of tries. */ public function setMaxTries($max) { $this->maxTries = abs($max); } /** * Get the number of times a single address will be attempted in a batch. * @return int */ public function getMaxTries() { return $this->maxTries; } /** * Set the amount of time to sleep for if an error occurs. * @param int Number of seconds */ public function setSleepTime($secs) { $this->sleepTime = abs($secs); } /** * Get the amount of time to sleep for on errors. * @return int */ public function getSleepTime() { return $this->sleepTime; } /** * Log a failed recipient. * @param string The email address. */ public function addFailedRecipient($address) { $this->failed[] = $address; $this->failed = array_unique($this->failed); } /** * Get all recipients which failed in this batch. * @return array */ public function getFailedRecipients() { return $this->failed; } /** * Clear out the list of failed recipients. */ public function flushFailedRecipients() { $this->failed = null; $this->failed = array(); } /** * Set the maximum number of times an error can be thrown in succession and still be hidden. * @param int */ public function setMaxSuccessiveFailures($fails) { $this->maxFails = abs($fails); } /** * Get the maximum number of times an error can be thrown and still be hidden. * @return int */ public function getMaxSuccessiveFailures() { return $this->maxFails; } /** * Restarts Swift forcibly. */ protected function forceRestartSwift() { //Pre-empting problems trying to issue "QUIT" to a dead connection $this->swift->connection->stop(); $this->swift->connection->start(); $this->swift->disconnect(); //Restart swift $this->swift->connect(); } /** * Takes a temporary copy of original message headers in case an error occurs and they need restoring. * @param Swift_Message The message object */ protected function copyMessageHeaders(&$message) { $this->headers["To"] = $message->headers->has("To") ? $message->headers->get("To") : null; $this->headers["Reply-To"] = $message->headers->has("Reply-To") ? $message->headers->get("Reply-To") : null; $this->headers["Return-Path"] = $message->headers->has("Return-Path") ? $message->headers->get("Return-Path") : null; $this->headers["From"] = $message->headers->has("From") ? $message->headers->get("From") : null; } /** * Restore message headers to original values in the event of a failure. * @param Swift_Message The message */ protected function restoreMessageHeaders(&$message) { foreach ($this->headers as $name => $value) { $message->headers->set($name, $value); } } /** * Run a batch send in a fail-safe manner. * This operates as Swift::batchSend() except it deals with errors itself. * @param Swift_Message To send * @param Swift_RecipientList Recipients (To: only) * @param Swift_Address The sender's address * @return int The number sent to */ public function send(Swift_Message $message, Swift_RecipientList $recipients, $sender) { $sent = 0; $successive_fails = 0; $it = $recipients->getIterator("to"); while ($it->hasNext()) { $it->next(); $recipient = $it->getValue(); $tried = 0; $loop = true; while ($loop && $tried < $this->getMaxTries()) { try { $tried++; $loop = false; $this->copyMessageHeaders($message); $sent += ($n = $this->swift->send($message, $recipient, $sender)); if (!$n) $this->addFailedRecipient($recipient->getAddress()); $successive_fails = 0; } catch (Exception $e) { $successive_fails++; $this->restoreMessageHeaders($message); if (($max = $this->getMaxSuccessiveFailures()) && $successive_fails > $max) { throw new Exception( "Too many successive failures. BatchMailer is configured to allow no more than " . $max . " successive failures."); } //If an exception was thrown, give it one more go if ($t = $this->getSleepTime()) sleep($t); $this->forceRestartSwift(); $loop = true; } } } return $sent; } } ./kohana/system/vendor/swift/Swift/LogContainer.php0000644000175000017500000000170610660421612022152 0ustar tokkeetokkee * @package Swift_Log * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_Log_DefaultLog"); /** * A registry holding the current instance of the log. * @package Swift_Log * @author Chris Corbyn */ class Swift_LogContainer { /** * The log instance. * @var Swift_Log */ protected static $log = null; /** * Registers the logger. * @param Swift_Log The log */ public static function setLog(Swift_Log $log) { self::$log = $log; } /** * Returns the current instance of the log, or lazy-loads the default one. * @return Swift_Log */ public static function getLog() { if (self::$log === null) { self::setLog(new Swift_Log_DefaultLog()); } return self::$log; } } ./kohana/system/vendor/swift/Swift/Authenticator/0000755000175000017500000000000011263472453021674 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Authenticator/PLAIN.php0000644000175000017500000000260410635210315023237 0ustar tokkeetokkee * @package Swift_Authenticator * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Authenticator"); /** * Swift PLAIN Authenticator * This form of authentication is unbelievably insecure since everything is done plain-text * @package Swift_Authenticator * @author Chris Corbyn */ class Swift_Authenticator_PLAIN implements Swift_Authenticator { /** * Try to authenticate using the username and password * Returns false on failure * @param string The username * @param string The password * @param Swift The instance of Swift this authenticator is used in * @return boolean */ public function isAuthenticated($user, $pass, Swift $swift) { try { //The authorization string uses ascii null as a separator (See RFC 2554) $credentials = base64_encode($user . chr(0) . $user . chr(0) . $pass); $swift->command("AUTH PLAIN " . $credentials, 235); } catch (Swift_ConnectionException $e) { $swift->reset(); return false; } return true; } /** * Return the name of the AUTH extension this is for * @return string */ public function getAuthExtensionName() { return "PLAIN"; } } ./kohana/system/vendor/swift/Swift/Authenticator/CRAMMD5.php0000644000175000017500000000412310635210315023422 0ustar tokkeetokkee * @package Swift_Authenticator * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Authenticator"); /** * Swift CRAM-MD5 Authenticator * This form of authentication is a secure challenge-response method * @package Swift_Authenticator * @author Chris Corbyn */ class Swift_Authenticator_CRAMMD5 implements Swift_Authenticator { /** * Try to authenticate using the username and password * Returns false on failure * @param string The username * @param string The password * @param Swift The instance of Swift this authenticator is used in * @return boolean */ public function isAuthenticated($user, $pass, Swift $swift) { try { $encoded_challenge = substr($swift->command("AUTH CRAM-MD5", 334)->getString(), 4); $challenge = base64_decode($encoded_challenge); $response = base64_encode($user . " " . self::generateCRAMMD5Hash($pass, $challenge)); $swift->command($response, 235); } catch (Swift_ConnectionException $e) { $swift->reset(); return false; } return true; } /** * Return the name of the AUTH extension this is for * @return string */ public function getAuthExtensionName() { return "CRAM-MD5"; } /** * Generate a CRAM-MD5 hash from a challenge * @param string The string to get a hash from * @param string The challenge to use to make the hash * @return string */ public static function generateCRAMMD5Hash($password, $challenge) { if (strlen($password) > 64) $password = pack('H32', md5($password)); if (strlen($password) < 64) $password = str_pad($password, 64, chr(0)); $k_ipad = substr($password, 0, 64) ^ str_repeat(chr(0x36), 64); $k_opad = substr($password, 0, 64) ^ str_repeat(chr(0x5C), 64); $inner = pack('H32', md5($k_ipad.$challenge)); $digest = md5($k_opad.$inner); return $digest; } } ./kohana/system/vendor/swift/Swift/Authenticator/@PopB4Smtp.php0000644000175000017500000000534110664327612024300 0ustar tokkeetokkee * @package Swift_Authenticator * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Authenticator"); Swift_ClassLoader::load("Swift_LogContainer"); /** * Swift PopB4Smtp Authenticator * This form of authentication requires a quick connection to be made with a POP3 server before finally connecting to SMTP * @package Swift_Authenticator * @author Chris Corbyn */ class Swift_Authenticator_PopB4Smtp implements Swift_Authenticator { protected $connection = null; /** * Constructor * @param mixed Swift_Authenticator_PopB4Smtp_Pop3Connection or string FQDN of POP3 server * @param int The remote port number * @param int The level of encryption to use */ public function __construct($conn=null, $port=110, $encryption=0) { if (is_object($conn)) $this->connection = $conn; else { Swift_ClassLoader::load("Swift_Authenticator_PopB4Smtp_Pop3Connection"); $this->connection = new Swift_Authenticator_PopB4Smtp_Pop3Connection($conn, $port, $encryption); } } /** * Try to authenticate using the username and password * Returns false on failure * @param string The username * @param string The password * @param Swift The instance of Swift this authenticator is used in * @return boolean */ public function isAuthenticated($user, $pass, Swift $swift) { $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Trying POP3 Before SMTP authentication. Disconnecting from SMTP first."); } $swift->disconnect(); try { $this->connection->start(); $this->connection->assertOk($this->connection->read()); $this->connection->write("USER " . $user); $this->connection->assertOk($this->connection->read()); $this->connection->write("PASS " . $pass); $this->connection->assertOk($this->connection->read()); $this->connection->write("QUIT"); $this->connection->assertOk($this->connection->read()); $this->connection->stop(); } catch (Swift_ConnectionException $e) { if ($log->hasLevel(Swift_Log::LOG_ERRORS)) { $log->add("POP3 authentication failed."); } return false; } $options = $swift->getOptions(); $swift->setOptions($options | Swift::NO_POST_CONNECT); $swift->connect(); $swift->setOptions($options); return true; } /** * Return the name of the AUTH extension this is for * @return string */ public function getAuthExtensionName() { return "*PopB4Smtp"; } } ./kohana/system/vendor/swift/Swift/Authenticator/PopB4Smtp/0000755000175000017500000000000011263472453023464 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Authenticator/PopB4Smtp/Pop3Connection.php0000644000175000017500000001075210635210315027030 0ustar tokkeetokkee * @package Swift_Authenticator * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../../ClassLoader.php"; /** * Swift PopB4Smtp Authenticator Connection Component for the POP3 server * Provides a I/O wrapper for the POP3 connection * @package Swift_Authenticator * @author Chris Corbyn */ class Swift_Authenticator_PopB4Smtp_Pop3Connection { /** * Constant for no encyption */ const ENC_OFF = 0; /** * Constant for SSL encryption */ const ENC_SSL = 1; /** * The server to connect to (IP or FQDN) * @var string */ protected $server = null; /** * The port to connect to * @var int */ protected $port = null; /** * The open connection resource from fsockopen() * @var resource */ protected $handle = null; /** * Constructor * @param string The name of the POP3 server * @param int The port for the POP3 service * @param int The level of encryption to use */ public function __construct($server="localhost", $port=110, $encryption=0) { $this->setServer($server); $this->setPort($port); $this->setEncryption($encryption); } /** * Set the server name * @param string The IP or FQDN of the POP3 server */ public function setServer($server) { $this->server = (string) $server; } /** * Set the port number for the POP3 server * @param int */ public function setPort($port) { $this->port = (int) $port; } /** * Get the server name * @return string */ public function getServer() { return $this->server; } /** * Get the remote port number * @return int */ public function getPort() { return $this->port; } /** * Set the level of enryption to use (see ENC_OFF or ENC_SSL) * @param int The constant for the encryption level */ public function setEncryption($enc) { $this->encryption = (int) $enc; } /** * Get the current encryption level set (corresponds to ENC_SSL or ENC_OFF) * @return int */ public function getEncryption() { return $this->encryption; } /** * Check if the response is a +OK response * @throws Swift_ConnectionException Upon bad response */ public function assertOk($line) { if (substr($line, 0, 3) != "+OK") { Swift_ClassLoader::load("Swift_ConnectionException"); throw new Swift_ConnectionException("The POP3 server did not suitably respond with a +OK response. " . "[" . $line . "]"); } } /** * Try to open the connection * @throws Swift_ConnectionException If the connection will not start */ public function start() { $url = $this->getServer(); if ($this->getEncryption() == self::ENC_SSL) $url = "ssl://" . $url; if ((false === $this->handle = fsockopen($url, $this->getPort(), $errno, $errstr, $timeout))) { Swift_ClassLoader::load("Swift_ConnectionException"); throw new Swift_ConnectionException("The POP3 connection failed to start. The error string returned from fsockopen() is [" . $errstr . "] #" . $errno); } } /** * Try to close the connection * @throws Swift_ConnectionException If the connection won't close */ public function stop() { if ($this->handle !== null) { if (false === fclose($this->handle)) { Swift_ClassLoader::load("Swift_ConnectionException"); throw new Swift_ConnectionException("The POP3 connection did not close successfully."); } } $this->handle = null; } /** * Return the unread buffer contents * @return string * @throws Swift_ConnectionException If the connection will not allow data to be read */ public function read() { if (false === $response = fgets($this->handle)) { Swift_ClassLoader::load("Swift_ConnectionException"); throw new Swift_ConnectionException("Data could not be read from the POP3 connection."); } return trim($response); } /** * Write a command to the remote socket * @param string the command to send (without CRLF) * @throws Swift_ConnectionException If the command cannot be written */ public function write($command) { if (false !== fwrite($this->handle, $command . "\r\n")) { Swift_ClassLoader::load("Swift_ConnectionException"); throw new Swift_ConnectionException("Data could not be written to the POP3 connection."); } } } ./kohana/system/vendor/swift/Swift/Authenticator/LOGIN.php0000644000175000017500000000234010635210315023241 0ustar tokkeetokkee * @package Swift_Authenticator * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Authenticator"); /** * Swift LOGIN Authenticator * @package Swift_Authenticator * @author Chris Corbyn */ class Swift_Authenticator_LOGIN implements Swift_Authenticator { /** * Try to authenticate using the username and password * Returns false on failure * @param string The username * @param string The password * @param Swift The instance of Swift this authenticator is used in * @return boolean */ public function isAuthenticated($user, $pass, Swift $swift) { try { $swift->command("AUTH LOGIN", 334); $swift->command(base64_encode($user), 334); $swift->command(base64_encode($pass), 235); } catch (Swift_ConnectionException $e) { $swift->reset(); return false; } return true; } /** * Return the name of the AUTH extension this is for * @return string */ public function getAuthExtensionName() { return "LOGIN"; } } ./kohana/system/vendor/swift/Swift/Cache/0000755000175000017500000000000011263472453020065 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Cache/OutputStream.php0000644000175000017500000000244010607101013023230 0ustar tokkeetokkee * @package Swift_Cache * @license GNU Lesser General Public License */ /** * The wraps the streaming functionality of the cache * @package Swift_Cache * @author Chris Corbyn */ class Swift_Cache_OutputStream { /** * The key to read in the actual cache * @var string */ protected $key; /** * The cache object to read * @var Swift_Cache */ protected $cache; /** * Ctor. * @param Swift_Cache The cache to read from * @param string The key for the cached data */ public function __construct(Swift_Cache $cache, $key) { $this->cache = $cache; $this->key = $key; } /** * Read bytes from the cache and seek through the buffer * Returns false if EOF is reached * @param int The number of bytes to read (could be ignored) * @return string The read bytes */ public function read($size=null) { return $this->cache->read($this->key, $size); } /** * Read the entire cached data as one string * @return string */ public function readFull() { $ret = ""; while (false !== $bytes = $this->read()) $ret .= $bytes; return $ret; } } ./kohana/system/vendor/swift/Swift/Cache/JointOutputStream.php0000644000175000017500000000312010607101013024230 0ustar tokkeetokkee * @package Swift_Cache * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Cache_OutputStream"); /** * Makes multiple output streams act as one super sream * @package Swift_Cache * @author Chris Corbyn */ class Swift_Cache_JointOutputStream extends Swift_Cache_OutputStream { /** * The streams to join * @var array */ protected $streams = array(); /** * The current stream in use * @var int */ protected $pointer = 0; /** * Ctor * @param array An array of Swift_Cache_OutputStream instances */ public function __construct($streams=array()) { $this->streams = $streams; } /** * Add a new output stream * @param Swift_Cache_OutputStream */ public function addStream(Swift_Cache_OutputStream $stream) { $this->streams[] = $stream; } /** * Read data from all streams as if they are one stream * @param int The number of bytes to read from each stream * @return string */ public function read($size=null) { $ret = $this->streams[$this->pointer]->read($size); if ($ret !== false) { return $ret; } else { if (isset($this->streams[($this->pointer+1)])) { $this->pointer++; return $this->read($size); } else { $this->pointer = 0; return false; } } } }./kohana/system/vendor/swift/Swift/Cache/Disk.php0000644000175000017500000000603210607101013021447 0ustar tokkeetokkee * @package Swift_Cache * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Cache"); /** * Caches data in files on disk - this is the best approach if possible * @package Swift_Cache * @author Chris Corbyn */ class Swift_Cache_Disk extends Swift_Cache { /** * Open file handles * @var array */ protected $open = array(); /** * The prefix to prepend to files * @var string */ protected $prefix; /** * The save path on disk * @var string */ protected static $save_path = "/tmp"; /** * Ctor */ public function __construct() { $this->prefix = md5(uniqid(microtime(), true)); } /** * Set the save path of the disk - this is a global setting and called statically! * @param string The path to a writable directory */ public static function setSavePath($path="/tmp") { self::$save_path = realpath($path); } /** * Write data to the cache * @param string The cache key * @param string The data to write */ public function write($key, $data) { $handle = fopen(self::$save_path . "/" . $this->prefix . $key, "ab"); if (false === fwrite($handle, $data)) { Swift_ClassLoader::load("Swift_FileException"); throw new Swift_FileException("Disk Caching failed. Tried to write to file at [" . self::$save_path . "/" . $this->prefix . $key . "] but failed. Check the permissions, or don't use disk caching."); } fclose($handle); } /** * Clear the cached data (unlink) * @param string The cache key */ public function clear($key) { @unlink(self::$save_path . "/" . $this->prefix . $key); } /** * Check if data is cached for $key * @param string The cache key * @return boolean */ public function has($key) { return file_exists(self::$save_path . "/" . $this->prefix . $key); } /** * Read data from the cache for $key * @param string The cache key * @param int The number of bytes to read * @return string */ public function read($key, $size=null) { if ($size === null) $size = 8190; if (!$this->has($key)) return false; if (!isset($this->open[$key])) { $this->open[$key] = fopen(self::$save_path . "/" . $this->prefix . $key, "rb"); } if (feof($this->open[$key])) { fclose($this->open[$key]); unset($this->open[$key]); return false; } $ret = fread($this->open[$key], $size); if ($ret !== false) { return $ret; } else { fclose($this->open[$key]); unset($this->open[$key]); return false; } } /** * Dtor. * Clear out cached data at end of script execution or cache destruction */ public function __destruct() { $list = glob(self::$save_path . "/" . $this->prefix . "*"); foreach ((array)$list as $f) { @unlink($f); } } } ./kohana/system/vendor/swift/Swift/Cache/Memory.php0000644000175000017500000000332310607101013022025 0ustar tokkeetokkee * @package Swift_Cache * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Cache"); /** * Caches data in variables - uses memory! * @package Swift_Cache * @author Chris Corbyn */ class Swift_Cache_Memory extends Swift_Cache { /** * The storage container for this cache * @var array */ protected $store = array(); /** * The key which was last requested * @var string */ protected $requested; /** * Write data to the cache * @param string The cache key * @param string The data to write */ public function write($key, $data) { if (!isset($this->store[$key])) $this->store[$key] = $data; else $this->store[$key] .= $data; } /** * Clear the cached data (unset) * @param string The cache key */ public function clear($key) { $this->store[$key] = null; unset($this->store[$key]); } /** * Check if data is cached for $key * @param string The cache key * @return boolean */ public function has($key) { return array_key_exists($key, $this->store); } /** * Read data from the cache for $key * It makes no difference to memory/speed if data is read in chunks so arguments are ignored * @param string The cache key * @return string */ public function read($key, $size=null) { if (!$this->has($key)) return false; if ($this->requested == $key) { $this->requested = null; return false; } $this->requested = $key; return $this->store[$key]; } } ./kohana/system/vendor/swift/Swift/Events/0000755000175000017500000000000011263472453020326 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Events/ConnectEvent.php0000644000175000017500000000155210607101013023413 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Generated every time Swift connects with a MTA * @package Swift_Events * @author Chris Corbyn */ class Swift_Events_ConnectEvent extends Swift_Events { /** * A reference to the connection object * @var Swift_Connection */ protected $connection = null; /** * Constructor * @param Swift_Connection The new connection */ public function __construct(Swift_Connection $connection) { $this->connection = $connection; } /** * Get the connection object * @return Swift_Connection */ public function getConnection() { return $this->connection; } } ./kohana/system/vendor/swift/Swift/Events/CommandListener.php0000644000175000017500000000126710607101013024107 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Contains the list of methods a plugin requiring the use of a CommandEvent must implement * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_CommandListener extends Swift_Events_Listener { /** * Executes when Swift sends a command * @param Swift_Events_CommandEvent Information about the command sent */ public function commandSent(Swift_Events_CommandEvent $e); } ./kohana/system/vendor/swift/Swift/Events/DisconnectListener.php0000644000175000017500000000132010607101013024610 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Contains the list of methods a plugin requiring the use of a DisconnectEvent must implement * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_DisconnectListener extends Swift_Events_Listener { /** * Executes when Swift closes a connection * @param Swift_Events_DisconnectEvent Information about the connection */ public function disconnectPerformed(Swift_Events_DisconnectEvent $e); } ./kohana/system/vendor/swift/Swift/Events/Listener.php0000644000175000017500000000060310540342471022614 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Used for identity only * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_Listener {} ./kohana/system/vendor/swift/Swift/Events/SendListener.php0000644000175000017500000000125710607101013023421 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Contains the list of methods a plugin requiring the use of a SendEvent must implement * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_SendListener extends Swift_Events_Listener { /** * Executes when Swift sends a message * @param Swift_Events_SendEvent Information about the message being sent */ public function sendPerformed(Swift_Events_SendEvent $e); } ./kohana/system/vendor/swift/Swift/Events/ResponseEvent.php0000644000175000017500000000250210607101013023614 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Generated when Swift receives a server response * @package Swift_Events * @author Chris Corbyn */ class Swift_Events_ResponseEvent extends Swift_Events { /** * Contains the response received * @var string */ protected $string = null; /** * Contains the response code * @var int */ protected $code = null; /** * Constructor * @param string The received response */ public function __construct($string) { $this->setString($string); $this->setCode(substr($string, 0, 3)); } /** * Set the response received * @param string The response */ public function setString($string) { $this->string = (string) $string; } /** * Get the received response * @return string */ public function getString() { return $this->string; } /** * Set response code * @param int The response code */ public function setCode($code) { $this->code = (int) $code; } /** * Get the response code * @return int */ public function getCode() { return $this->code; } } ./kohana/system/vendor/swift/Swift/Events/ListenerMapper.php0000644000175000017500000000227610607101013023756 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Maps event listener names to the methods they implement * @package Swift_Events * @author Chris Corbyn */ class Swift_Events_ListenerMapper { /** * Get the mapped names (Class => Method(s)) * @return array */ public static function getMap() { $map = array( "SendListener" => "sendPerformed", "BeforeSendListener" => "beforeSendPerformed", "CommandListener" => "commandSent", "BeforeCommandListener" => "beforeCommandSent", "ResponseListener" => "responseReceived", "ConnectListener" => "connectPerformed", "DisconnectListener" => "disconnectPerformed" ); return $map; } /** * Get the name of the method which needs running based upon the listener name * @return string */ public static function getNotifyMethod($listener) { $map = self::getMap(); if (isset($map[$listener])) return $map[$listener]; else return false; } } ./kohana/system/vendor/swift/Swift/Events/BeforeSendListener.php0000644000175000017500000000134510607101013024542 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Contains the list of methods a plugin requiring the use of a SendEvent before the message is sent must implement * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_BeforeSendListener extends Swift_Events_Listener { /** * Executes just before Swift sends a message * @param Swift_Events_SendEvent Information about the message being sent */ public function beforeSendPerformed(Swift_Events_SendEvent $e); } ./kohana/system/vendor/swift/Swift/Events/ConnectListener.php0000644000175000017500000000130110607101013024107 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Contains the list of methods a plugin requiring the use of a ConnectEvent must implement * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_ConnectListener extends Swift_Events_Listener { /** * Executes when Swift initiates a connection * @param Swift_Events_ConnectEvent Information about the connection */ public function connectPerformed(Swift_Events_ConnectEvent $e); } ./kohana/system/vendor/swift/Swift/Events/ResponseListener.php0000644000175000017500000000130110607101013024314 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Contains the list of methods a plugin requiring the use of a ResponseEvent must implement * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_ResponseListener extends Swift_Events_Listener { /** * Executes when Swift receives a response * @param Swift_Events_ResponseEvent Information about the response */ public function responseReceived(Swift_Events_ResponseEvent $e); } ./kohana/system/vendor/swift/Swift/Events/BeforeCommandListener.php0000644000175000017500000000135210607101013025225 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Contains the list of methods a plugin requiring the use of a CommandEvent, before it is sent must implement * @package Swift_Events * @author Chris Corbyn */ interface Swift_Events_BeforeCommandListener extends Swift_Events_Listener { /** * Executes just before Swift sends a command * @param Swift_Events_CommandEvent Information about the being command sent */ public function beforeCommandSent(Swift_Events_CommandEvent $e); } ./kohana/system/vendor/swift/Swift/Events/CommandEvent.php0000644000175000017500000000272510607101013023403 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Generated when Swift is sending a command * @package Swift_Events * @author Chris Corbyn */ class Swift_Events_CommandEvent extends Swift_Events { /** * Contains the command being sent * @var string */ protected $string = null; /** * Contains the expected response code (or null) * @var int */ protected $code = null; /** * Constructor * @param string The command being sent * @param int The expected code */ public function __construct($string, $code=null) { $this->setString($string); $this->setCode($code); } /** * Set the command being sent (without CRLF) * @param string The command being sent */ public function setString($string) { $this->string = (string) $string; } /** * Get the command being sent * @return string */ public function getString() { return $this->string; } /** * Set response code which is expected * @param int The response code */ public function setCode($code) { if ($code === null) $this->code = null; else $this->code = (int) $code; } /** * Get the expected response code * @return int */ public function getCode() { return $this->code; } } ./kohana/system/vendor/swift/Swift/Events/SendEvent.php0000644000175000017500000000472610607101013022721 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Generated every time a message is sent with Swift * @package Swift_Events * @author Chris Corbyn */ class Swift_Events_SendEvent extends Swift_Events { /** * A reference to the message being sent * @var Swift_Message */ protected $message = null; /** * A reference to the sender address object * @var Swift_Address */ protected $sender = null; /** * A reference to the recipients being sent to * @var Swift_RecipientList */ protected $recipients = null; /** * The number of recipients sent to so * @var int */ protected $sent = null; /** * Recipients we couldn't send to * @var array */ protected $failed = array(); /** * Constructor * @param Swift_Message The message being sent * @param Swift_RecipientList The recipients * @param Swift_Address The sender address * @param int The number of addresses sent to */ public function __construct(Swift_Message $message, Swift_RecipientList $list, Swift_Address $from, $sent=0) { $this->message = $message; $this->recipients = $list; $this->sender = $from; $this->sent = $sent; } /** * Get the message being sent * @return Swift_Message */ public function getMessage() { return $this->message; } /** * Get the list of recipients * @return Swift_RecipientList */ public function getRecipients() { return $this->recipients; } /** * Get the sender's address * @return Swift_Address */ public function getSender() { return $this->sender; } /** * Set the number of recipients to how many were sent * @param int */ public function setNumSent($sent) { $this->sent = (int) $sent; } /** * Get the total number of addresses to which the email sent successfully * @return int */ public function getNumSent() { return $this->sent; } /** * Add an email address to the failed recipient list for this send * @var string The email address */ public function addFailedRecipient($address) { $this->failed[] = $address; } /** * Get an array of failed recipients for this send * @return array */ public function getFailedRecipients() { return $this->failed; } } ./kohana/system/vendor/swift/Swift/Events/DisconnectEvent.php0000644000175000017500000000156410607101013024116 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Events * @license GNU Lesser General Public License */ /** * Generated every time Swift disconnects from a MTA * @package Swift_Events * @author Chris Corbyn */ class Swift_Events_DisconnectEvent extends Swift_Events { /** * A reference to the connection object * @var Swift_Connection */ protected $connection = null; /** * Constructor * @param Swift_Connection The dead connection */ public function __construct(Swift_Connection $connection) { $this->connection = $connection; } /** * Get the connection object * @return Swift_Connection */ public function getConnection() { return $this->connection; } } ./kohana/system/vendor/swift/Swift/AddressContainer.php0000644000175000017500000000026710535037203023017 0ustar tokkeetokkee */ abstract class Swift_AddressContainer {} ./kohana/system/vendor/swift/Swift/Iterator.php0000644000175000017500000000174110620320206021347 0ustar tokkeetokkee * @package Swift * @license GNU Lesser General Public License */ /** * Swift Iterator Interface * Provides the interface for iterators used for retrieving addresses in batch sends. * @package Swift * @author Chris Corbyn */ interface Swift_Iterator { /** * Check if there is a value in the list after the current one. * @return boolean */ public function hasNext(); /** * Move to the next position in the list if possible. * @return boolean */ public function next(); /** * Seek to the given numeric index in the list of possible. * @return boolean */ public function seekTo($pos); /** * Get the value of the list at the current position. * @return mixed */ public function getValue(); /** * Get the current list position. * @return int */ public function getPosition(); } ./kohana/system/vendor/swift/Swift/File.php0000644000175000017500000001131710611160730020441 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_FileException"); /** * Swift File stream abstraction layer * Reads bytes from a file * @package Swift * @author Chris Corbyn */ class Swift_File { /** * The accessible path to the file * @var string */ protected $path = null; /** * The name of the file * @var string */ protected $name = null; /** * The resource returned by fopen() against the path * @var resource */ protected $handle = null; /** * The status of magic_quotes in php.ini * @var boolean */ protected $magic_quotes = false; /** * Constructor * @param string The path the the file * @throws Swift_FileException If the file cannot be found */ public function __construct($path) { $this->setPath($path); $this->magic_quotes = get_magic_quotes_runtime(); } /** * Set the path to the file * @param string The path to the file * @throws Swift_FileException If the file cannot be found */ public function setPath($path) { if (!file_exists($path)) { throw new Swift_FileException("No such file '" . $path ."'"); } $this->handle = null; $this->path = $path; $this->name = null; $this->name = $this->getFileName(); } /** * Get the path to the file * @return string */ public function getPath() { return $this->path; } /** * Get the name of the file without it's full path * @return string */ public function getFileName() { if ($this->name !== null) { return $this->name; } else { return basename($this->getPath()); } } /** * Establish an open file handle on the file if the file is not yet opened * @throws Swift_FileException If the file cannot be opened for reading */ protected function createHandle() { if ($this->handle === null) { if (!$this->handle = fopen($this->path, "rb")) { throw new Swift_FileException("Unable to open file '" . $this->path . " for reading. Check the file permissions."); } } } /** * Check if the pointer as at the end of the file * @return boolean * @throws Swift_FileException If the file cannot be read */ public function EOF() { $this->createHandle(); return feof($this->handle); } /** * Get a single byte from the file * Returns false past EOF * @return string * @throws Swift_FileException If the file cannot be read */ public function getByte() { $this->createHandle(); return $this->read(1); } /** * Read one full line from the file including the line ending * Returns false past EOF * @return string * @throws Swift_FileException If the file cannot be read */ public function readln() { set_magic_quotes_runtime(0); $this->createHandle(); if (!$this->EOF()) { $ret = fgets($this->handle); } else $ret = false; set_magic_quotes_runtime($this->magic_quotes); return $ret; } /** * Get the entire file contents as a string * @return string * @throws Swift_FileException If the file cannot be read */ public function readFull() { $ret = ""; set_magic_quotes_runtime(0); while (false !== $chunk = $this->read(8192, false)) $ret .= $chunk; set_magic_quotes_runtime($this->magic_quotes); return $ret; } /** * Read a given number of bytes from the file * Returns false past EOF * @return string * @throws Swift_FileException If the file cannot be read */ public function read($bytes, $unquote=true) { if ($unquote) set_magic_quotes_runtime(0); $this->createHandle(); if (!$this->EOF()) { $ret = fread($this->handle, $bytes); } else $ret = false; if ($unquote) set_magic_quotes_runtime($this->magic_quotes); return $ret; } /** * Get the size of the file in bytes * @return int */ public function length() { return filesize($this->path); } /** * Close the open handle on the file * @throws Swift_FileException If the file cannot be read */ public function close() { $this->createHandle(); fclose($this->handle); $this->handle = null; } /** * Reset the file pointer back to zero */ public function reset() { $this->createHandle(); fseek($this->handle, 0); } /** * Destructor * Closes the file */ public function __destruct() { if ($this->handle !== null) $this->close(); } } ./kohana/system/vendor/swift/Swift/CacheFactory.php0000644000175000017500000000207410607101013022107 0ustar tokkeetokkee * @package Swift_Cache * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; /** * Makes instances of the cache the user has defined * @package Swift_Cache * @author Chris Corbyn */ class Swift_CacheFactory { /** * The name of the class which defines the cache * @var string Case SenSITivE */ protected static $className = "Swift_Cache_Memory"; /** * Set the name of the class which is supposed to be used * This also includes the file * @param string The class name */ public static function setClassName($name) { Swift_ClassLoader::load($name); self::$className = $name; } /** * Return a new instance of the cache object * @return Swift_Cache */ public static function getCache() { $className = self::$className; Swift_ClassLoader::load($className); $instance = new $className(); return $instance; } } ./kohana/system/vendor/swift/Swift/ConnectionException.php0000644000175000017500000000100710660421612023536 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_Exception"); /** * Swift Connection Exception * @package Swift_Connection * @author Chris Corbyn */ class Swift_ConnectionException extends Swift_Exception { } ./kohana/system/vendor/swift/Swift/Iterator/0000755000175000017500000000000011263472452020652 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Iterator/MySQLResult.php0000644000175000017500000000502210620320206023507 0ustar tokkeetokkee * @package Swift * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Iterator"); /** * Swift Mailer MySQL Resultset Iterator. * Iterates over MySQL Resultset from mysql_query(). * @package Swift * @author Chris Corbyn */ class Swift_Iterator_MySQLResult implements Swift_Iterator { /** * The MySQL resource. * @var resource */ protected $resultSet; /** * The current row (array) in the resultset. * @var array */ protected $currentRow = array(null, null); /** * The current array position. * @var int */ protected $pos = -1; /** * The total number of rows in the resultset. * @var int */ protected $numRows = 0; /** * Ctor. * @param resource The resultset iterate over. */ public function __construct($rs) { $this->resultSet = $rs; $this->numRows = mysql_num_rows($rs); } /** * Get the resultset. * @return resource */ public function getResultSet() { return $this->resultSet; } /** * Returns true if there is a value after the current one. * @return boolean */ public function hasNext() { return (($this->pos + 1) < $this->numRows); } /** * Moves to the next array element if possible. * @return boolean */ public function next() { if ($this->hasNext()) { $this->currentRow = mysql_fetch_array($this->resultSet); $this->pos++; return true; } return false; } /** * Goes directly to the given element in the array if possible. * @param int Numeric position * @return boolean */ public function seekTo($pos) { if ($pos >= 0 && $pos < $this->numRows) { mysql_data_seek($this->resultSet, $pos); $this->currentRow = mysql_fetch_array($this->resultSet); mysql_data_seek($this->resultSet, $pos); $this->pos = $pos; return true; } return false; } /** * Returns the value at the current position, or NULL otherwise. * @return mixed. */ public function getValue() { $row = $this->currentRow; if ($row[0] !== null) return new Swift_Address($row[0], isset($row[1]) ? $row[1] : null); else return null; } /** * Gets the current numeric position within the array. * @return int */ public function getPosition() { return $this->pos; } } ./kohana/system/vendor/swift/Swift/Iterator/Array.php0000644000175000017500000000425210621565412022440 0ustar tokkeetokkee * @package Swift * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Iterator"); /** * Swift Array Iterator Interface * Iterates over a standard PHP array. * @package Swift * @author Chris Corbyn */ class Swift_Iterator_Array implements Swift_Iterator { /** * All keys in this array. * @var array */ protected $keys; /** * All values in this array. * @var array */ protected $values; /** * The current array position. * @var int */ protected $pos = -1; /** * Ctor. * @param array The array to iterate over. */ public function __construct($input) { $input = (array) $input; $this->keys = array_keys($input); $this->values = array_values($input); } /** * Returns the original array. * @return array */ public function getArray() { return array_combine($this->keys, $this->values); } /** * Returns true if there is a value after the current one. * @return boolean */ public function hasNext() { return array_key_exists($this->pos + 1, $this->keys); } /** * Moves to the next array element if possible. * @return boolean */ public function next() { if ($this->hasNext()) { ++$this->pos; return true; } return false; } /** * Goes directly to the given element in the array if possible. * @param int Numeric position * @return boolean */ public function seekTo($pos) { if (array_key_exists($pos, $this->keys)) { $this->pos = $pos; return true; } return false; } /** * Returns the value at the current position, or NULL otherwise. * @return mixed. */ public function getValue() { if (array_key_exists($this->pos, $this->values)) return $this->values[$this->pos]; else return null; } /** * Gets the current numeric position within the array. * @return int */ public function getPosition() { return $this->pos; } } ./kohana/system/vendor/swift/Swift/Authenticator.php0000644000175000017500000000155510607101013022371 0ustar tokkeetokkee * @package Swift_Authenticator * @license GNU Lesser General Public License */ /** * Swift Authenticator Interface * Lists the methods all authenticators must implement * @package Swift_Authenticator * @author Chris Corbyn */ interface Swift_Authenticator { /** * Try to authenticate using the username and password * Returns false on failure * @param string The username * @param string The password * @param Swift The instance of Swift this authenticator is used in * @return boolean */ public function isAuthenticated($username, $password, Swift $instance); /** * Return the name of the AUTH extension this is for * @return string */ public function getAuthExtensionName(); } ./kohana/system/vendor/swift/Swift/Message/0000755000175000017500000000000011263472452020445 5ustar tokkeetokkee./kohana/system/vendor/swift/Swift/Message/Attachment.php0000644000175000017500000001050510625276373023254 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ /** * Attachment component for Swift Mailer * @package Swift_Message * @author Chris Corbyn */ class Swift_Message_Attachment extends Swift_Message_Mime { /** * A numeric counter, incremented by 1 when a filename is made. * @var int */ protected static $fileId = 0; /** * Constructor * @param mixed The data to use in the body * @param string Mime type * @param string The encoding format used * @param string The charset used */ public function __construct($data=null, $name=null, $type="application/octet-stream", $encoding="base64", $disposition="attachment") { parent::__construct(); $this->setContentType($type); $this->setEncoding($encoding); $this->setDescription($name); $this->setDisposition($disposition); $this->setFileName($name); if ($data !== null) $this->setData($data, ($name === null)); } /** * Get a unique filename (just a sequence) * @param string the prefix for the filename * @return string */ public static function generateFileName($prefix="file") { return $prefix . (self::$fileId++); } /** * Get the level in the MIME hierarchy at which this section should appear. * @return string */ public function getLevel() { return Swift_Message_Mime::LEVEL_MIXED; } /** * Overrides setData() in MIME so that a filename can be set * @param mixed The data to set for the body * @param boolean If the stream is a file, should it's filename be used? * @throws Swift_FileException If the stream cannot be read */ public function setData($data, $read_filename=true) { parent::setData($data); if ($read_filename && ($data instanceof Swift_file)) { $this->setFileName($data->getFileName()); } } /** * Set the name (and description) used to identify the file * This method overrides any value previously set with setDescription() * @param string The filename including it's extension if any * @throws Swift_Message_MimeException If some required headers have been deliberately removed */ public function setFileName($name) { $this->headers->setAttribute("Content-Type", "name", $name); $this->setDescription($name); if ($this->headers->has("Content-Disposition")) { $this->headers->setAttribute("Content-Disposition", "filename", $name); } } /** * Get the filename of this attachment * @return string * @throws Swift_Message_MimeException If some vital headers have been removed */ public function getFileName() { if ($this->headers->hasAttribute("Content-Type", "name")) { return $this->headers->getAttribute("Content-Type", "name"); } else return null; } /** * Set the Content-Description header * @param string The description in the header (filename usually!) */ public function setDescription($desc) { $this->headers->set("Content-Description", $desc); } /** * Return the description in the headers * @return string */ public function getDescription() { if ($this->headers->has("Content-Description")) { return $this->headers->get("Content-Description"); } else return null; } /** * Set the disposition of the attachment (usually inline or attachment) * @param string The value to use in the Content-Disposition field */ public function setDisposition($disposition) { $this->headers->set("Content-Disposition", $disposition); } /** * Get the disposition used in the attachment (usually inline or attachment) * @return string */ public function getDisposition() { if ($this->headers->has("Content-Disposition")) { return $this->headers->get("Content-Disposition"); } else return null; } /** * Execute needed logic prior to building */ public function preBuild() { if ($this->getFileName() === null) { if ($this->getData() instanceof Swift_File) { $this->setFileName($this->getData()->getFileName()); } else { $this->setFileName(self::generateFileName("file.att.")); } } } } ./kohana/system/vendor/swift/Swift/Message/Part.php0000644000175000017500000000660210617143555022071 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Message_Mime"); /** * MIME Part body component for Swift Mailer * @package Swift_Message * @author Chris Corbyn */ class Swift_Message_Part extends Swift_Message_Mime { /** * Constructor * @param mixed The data to use in the body * @param string Mime type * @param string The encoding format used * @param string The charset used */ public function __construct($data=null, $type="text/plain", $encoding=null, $charset=null) { parent::__construct(); $this->setContentType($type); $this->setEncoding($encoding); $this->setCharset($charset); $this->setFlowed(false); if ($data !== null) { $this->setData($data); if ($charset === null) { Swift_ClassLoader::load("Swift_Message_Encoder"); if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data)) $this->setCharset("utf-8"); else $this->setCharset("iso-8859-1"); //The likely encoding } } } /** * Get the level in the MIME hierarchy at which this section should appear. * @return string */ public function getLevel() { return Swift_Message_Mime::LEVEL_ALTERNATIVE; } /** * Alias for setData() * @param mixed Body */ public function setBody($body) { $this->setData($body); } /** * Alias for getData() * @return mixed The document body */ public function getBody() { return $this->getData(); } /** * Set the charset of the document * @param string The charset used */ public function setCharset($charset) { $this->headers->setAttribute("Content-Type", "charset", $charset); if (($this->getEncoding() == "7bit") && (strtolower($charset) == "utf-8" || strtolower($charset) == "utf8")) $this->setEncoding("8bit"); } /** * Get the charset used in the document * Returns null if none is set * @return string */ public function getCharset() { if ($this->headers->hasAttribute("Content-Type", "charset")) { return $this->headers->getAttribute("Content-Type", "charset"); } else { return null; } } /** * Set the "format" attribute to flowed * @param boolean On or Off */ public function setFlowed($flowed=true) { $value = null; if ($flowed) $value = "flowed"; $this->headers->setAttribute("Content-Type", "format", $value); } /** * Pre-compilation logic */ public function preBuild() { if (!($enc = $this->getEncoding())) $this->setEncoding("8bit"); $data = $this->getData(); if ($this->getCharset() === null && !$this->numChildren()) { if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data)) { $this->setCharset("utf-8"); } elseif (is_string($data) && Swift_Message_Encoder::instance()->is7BitAscii($data)) { $this->setCharset("us-ascii"); if (!$enc) $this->setEncoding("7bit"); } else $this->setCharset("iso-8859-1"); } elseif ($this->numChildren()) { $this->setCharset(null); $this->setEncoding("7bit"); } } } ./kohana/system/vendor/swift/Swift/Message/MimeException.php0000644000175000017500000000077210660421612023722 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Exception"); /** * Swift MIME Exception * @package Swift_Message * @author Chris Corbyn */ class Swift_Message_MimeException extends Swift_Exception { } ./kohana/system/vendor/swift/Swift/Message/Encoder.php0000644000175000017500000003614510704334477022551 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_File"); /** * Encodes strings in a variety of formats and detects some encoding formats * @package Swift_Message * @author Chris Corbyn */ class Swift_Message_Encoder { /** * A regular expression which matches valid e-mail addresses (including some unlikely ones) */ const CHEAP_ADDRESS_RE = '(?#Start of dot-atom )[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+(?:\.[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+)*(?# End of dot-atom)(?:@(?#Start of domain)[-0-9A-Za-z]+(?:\.[-0-9A-Za-z]+)*(?#End of domain))?'; /** * A singleton of this class * @var Swift_Message_Encoder */ protected static $instance = null; /** * Retreive an instance of the encoder as a singleton. * New instances are never ever needed since it's monostatic. * @return Message_Encoder */ public static function instance() { if (self::$instance === null) { self::$instance = new Swift_Message_Encoder(); } return self::$instance; } /** * Break a string apart at every occurence of and return an array * This method does NOT remove any characters like a preg_split() would do. * Elements matching an address start with "a" followed by the numeric index * @param string The input string to separate * @return array */ public function addressChunk($input) { $elements = 0; while (preg_match('/^(.*?)(<' . self::CHEAP_ADDRESS_RE . '>)/s', $input, $matches)) { if (!empty($matches[1])) $ret[($elements++)] = $matches[1]; $ret[('a' . ($elements++))] = $matches[2]; $input = substr($input, strlen($matches[0])); } if ($input != "") $ret[($elements++)] = $input; //Whatever is left over return $ret; } /** * Break a string apart at every occurence of and return an array * This method does NOT remove any characters like a preg_split() would do. * Elements matching a quoted string start with "a" followed by the numeric index * @param string The input string to separate * @return array */ public function quoteChunk($input) { $elements = 0; while (preg_match('/^(.*?)(<[\x20-\x3A\x3C-\x7E]*>)/s', $input, $matches)) { if (!empty($matches[1])) $ret[($elements++)] = $matches[1]; $ret[('a' . ($elements++))] = $matches[2]; $input = substr($input, strlen($matches[0])); } if ($input != "") $ret[($elements++)] = $input; //Whatever is left over return $ret; } /** * Return the base64 encoded version of the string * @param string The input string to encode * @param int The maximum length of each line of output (inc CRLF) * @param int The maximum length of the first line in the output (for headers) * @param boolean Whether email addresses between < and > chars should be preserved or not * @param string The line ending * @return string */ public function base64Encode($data, $chunk=76, $init_chunk=0, $headers=false, $le="\r\n") { $ret = ""; $chunk -= 2; $chunk = $this->getHcf($chunk, 4); if ($init_chunk >= 2) { $init_chunk -= 2; $init_chunk = $this->getHcf($init_chunk, 4); } if ($headers) $data = $this->quoteChunk($data); else $data = array($data); foreach ($data as $key => $string) { $key = (string) $key; if ($key{0} == 'a') //This is an address { if ($init_chunk && $init_chunk < (strlen($string)+2)) $ret .= $le; $ret .= $le . $string; } else { $string = $this->rawBase64Encode($string); if ($init_chunk > 2) { $ret .= substr($string, 0, $init_chunk) . $le; $string = substr($string, $init_chunk); } elseif ($init_chunk) $ret .= $le; $ret .= trim(chunk_split($string, $chunk, $le)) . $le; } $init_chunk = 0; } return trim($ret); } /** * Return the base64 encoded version of a string with no breaks * @param The input string to encode * @return string */ public function rawBase64Encode($string) { return $string = base64_encode($string); } /** * Return the base64 encoded version of a file * @param Swift_File The file input stream * @param int Max line length * @param string The line ending * @return Swift_Cache_OutputStream * @throws Swift_FileException If the file cannot be read */ public function base64EncodeFile(Swift_File $file, $chunk=76, $le="\r\n") { Swift_ClassLoader::load("Swift_CacheFactory"); $cache = Swift_CacheFactory::getCache(); $chunk -= 2; $chunk = $this->getHcf($chunk, 4); $loop = false; //We have to read in multiples of 3 bytes but avoid doing such small chunks that it takes too long while (false !== $bytes = $file->read(8190)) { if ($loop) $cache->write("b64", $le); $loop = true; $next = chunk_split($this->rawBase64Encode($bytes), $chunk, $le); $next = trim($next); $cache->write("b64", $next); } $file->reset(); return $cache->getOutputStream("b64"); } /** * Return the quoted printable version of the input string * @param string The input string to encode * @param int The maximum length of each line of output (inc CRLF) * @param int The maximum length of the first line in the output (for headers) * @param boolean Whether email addresses between < and > chars should be preserved or not * @param string The line ending * @return string */ public function QPEncode($data, $chunk=76, $init_chunk=0, $headers=false, $le="\r\n") { $ret = ""; if ($headers) $data = $this->quoteChunk($data); else $data = array($data); $trailing_spaces = chr(9) . chr(32); foreach ($data as $key => $string) { $key = (string) $key; if ($key{0} == 'a') //An address { if ($init_chunk && $init_chunk < (strlen($string)+3)) $ret .= "="; $ret .= $le . $string; } else { $lines = explode($le, $string); foreach ($lines as $n => $line) $lines[$n] = $this->rawQPEncode(rtrim($line, $trailing_spaces)); $string = implode($le, $lines); if ($init_chunk > 3) { if (preg_match('/^.{1,'.($init_chunk-5).'}[^=]{2}(?!=[A-F0-9]{2})/', $string, $matches) || preg_match('/^.{1,'.($init_chunk-6).'}([^=]{0,3})?/', $string, $matches)) { $ret .= $this->fixLE($matches[0] . "=", $le); //fixLE added 24/08/07 $string = substr($string, strlen($matches[0])); } } elseif ($init_chunk) $ret .= "="; while (preg_match('/^.{1,'.($init_chunk-5).'}[^=]{2}(?!=[A-F0-9]{2})/', $string, $matches) || preg_match('/^.{1,'.($chunk-6).'}([^=]{0,3})?/', $string, $matches) || (strlen($string) > 0 && $matches = array($string))) { $ret .= $this->fixLE($le . $matches[0] . "=", $le); //fixLE added 24/08/07 $string = substr($string, strlen($matches[0])); } } $init_chunk = 0; } if (substr($ret, -1) == "=") return trim(substr($ret, 0, -1)); else return trim($ret); } /** * Return the QP encoded version of a string with no breaks * @param string The input to encode * @param boolean True if the data we're encoding is binary * @return string */ public function rawQPEncode($string, $bin=false) { $ret = ""; if (!$bin) { $string = str_replace(array("\r\n", "\r"), "\n", $string); $string = str_replace("\n", "\r\n", $string); } $len = strlen($string); for ($i = 0; $i < $len; $i++) { $val = ord($string{$i}); //9, 32 = HT, SP; 10, 13 = CR, LF; 33-60 & 62-126 are ok // 63 = '?'; 95 = '_' and need encoding to go in the headers if ((!$bin && ($val == 32 || $val == 9 || $val == 10 || $val == 13)) || ($val >= 33 && $val <= 60) || ($val >= 62 && $val <= 126) && $val != 63) { $ret .= $string{$i}; } else { $ret .= sprintf("=%02X", $val); } } return $ret; } /** * Return a file as a quoted printable encoded string * @param Swift_File The file to encode * @param int Max line length * @param string The line ending * @return Swift_Cache_OutputStream * @throws Swift_FileException If the file cannot be read */ public function QPEncodeFile(Swift_File $file, $chunk=76, $le="\r\n") { Swift_ClassLoader::load("Swift_CacheFactory"); $cache = Swift_CacheFactory::getCache(); while (false !== $bytes = $file->readln()) { $next = $this->rawQPEncode($bytes, true); preg_match_all('/.{1,'.($chunk-6).'}([^=]{0,3})?/', $next, $next); if (count($next[0])) $cache->write("qp", $this->fixLE(implode("=" . $le, $next[0]), $le)); } return $cache->getOutputStream("qp"); } /** * Encode a string as 7bit ascii * @param string Input data to encode * @param int Max line length * @param string The line ending * @return string */ public function encode7Bit($data, $chunk=76, $le="\r\n") { return $this->fixLE(wordwrap($data, $chunk-2, $le, 1), $le); } /** * Return a 7bit string from a file * @param Swift_File The file stream to read from * @param int The max line length * @param string The line ending * @return Swift_Cache_OutputStream * @throws Swift_FileException If the file cannot be read */ public function encode7BitFile(Swift_File $file, $chunk=76, $le="\r\n") { Swift_ClassLoader::load("Swift_CacheFactory"); $cache = Swift_CacheFactory::getCache(); $ret = ""; while (false !== $bytes = $file->read(8192)) $ret .= $bytes; $cache->write("7b", $this->fixLE(wordwrap($ret, $chunk-2, $le, 1), $le)); return $cache->getOutputStream("7b"); } /** * Return the 8bit encoded form of a string (unchanged there-abouts) * @param string Input data to encode * @param int Maximum line length * @param string The line ending * @return string */ public function encode8Bit($data, $chunk=76, $le="\r\n") { return $this->fixLE(wordwrap($data, $chunk-2, $le, 1), $le); } /** * Return a 8bit string from a file * @param Swift_File The file stream to read from * @param int Max line length (including CRLF) * @param string The line ending * @return Swift_Cache_OutputStream * @throws Swift_FileException If the file cannot be read */ public function encode8BitFile(Swift_File $file, $chunk=76, $le="\r\n") { Swift_ClassLoader::load("Swift_CacheFactory"); $cache = Swift_CacheFactory::getCache(); $ret = ""; while (false !== $bytes = $file->read(8192)) $ret .= $bytes; $cache->write("8b", $this->fixLE(wordwrap($ret, $chunk-2, $le, 1), $le)); return $cache->getOutputStream("8b"); } /** * Keeps lines longer than 76 characters trimmed down to size * This currently does not convert other string encodings into 7bit * @param string The data to make safe for headers (defaults to RFC 2822 standards) * @param int maximum length of lines returned * @param int The maximum length of the first line * @param string The Line ending * @return string */ public function header7BitEncode($data, $chunk=76, $init_chunk=0, $le="\r\n") { $data = $this->encode7BitPrintable($data); $ret = ""; if ($init_chunk > 2) { $data_wrapped = wordwrap($data, $init_chunk, $le); $lines = explode($le, $data_wrapped); $first_line = array_shift($lines); $ret .= $first_line . $le; $data = preg_replace("~^[ \t]~D", "", substr($data, strlen($first_line))); } elseif ($init_chunk) $ret .= $le; $ret .= wordwrap($data, $chunk-2, $le); return trim($ret); } /** * Strip out any characters which are not in the ASCII 7bit printable range * @param string The string to clean * @return string */ public function encode7BitPrintable($data) { return preg_replace('/[^\x20-\x7E]/', '', $data); } /** * Detect if a string contains multi-byte non-ascii chars that fall in the UTF-8 ranges * @param string Data to detect UTF-8 sequences in * @return boolean */ public function isUTF8($data) { return preg_match('%(?: [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte |\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte |\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates |\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 |[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 |\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 )+%xs', $data); } /** * This function checks for 7bit *printable* characters * which excludes \r \n \t etc and so, is safe for use in mail headers * Actual permitted chars [\ !"#\$%&'\(\)\*\+,-\.\/0123456789:;<=>\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz{\|}~] * Ranges \x00-\x1F are printer control sequences * \x7F is the ascii delete character * @param string Data to check against * @return boolean */ public function is7BitPrintable($data) { return (!preg_match('/[^\x20-\x7E]/', $data)); } /** * Check that a string does not contain any evil characters for headers. * @param string The string to check * @return boolean */ public function isHeaderSafe($data) { return ($this->is7BitPrintable($data) && strpos($data, ";") === false); } /** * If the characters fall exclusively in the 7bit ascii range, return true * @param string Input to check * @return boolean */ public function is7BitAscii($data) { return (!preg_match('/[^\x01-\x7F]/', $data)); } /** * Encode a string for RFC 2047 compatability (url-encode) * @param string The input for encoding * @param string The charset used * @param string The language used * @param int The maximum line length * @param int The maximum length of the first line * @param string The line ending * @return string */ public function rfc2047Encode($str, $charset="iso-8859-1", $language="en-us", $chunk=76, $le="\r\n") { $lang_spec = ""; if (!$this->is7BitPrintable($str)) { $lang_spec = $charset . "'" . $language . "'"; $str = $lang_spec . str_replace("+", "%20", urlencode($str)); } preg_match_all('~.{1,'.($chunk-6).'}([^%]{0,3})~', $str, $matches); if (count($matches[0])) return implode($le, $matches[0]); } /** * Fixes line endings to be whatever is specified by the user * SMTP requires the CRLF be used, but using sendmail in -t mode uses LF * This method also escapes dots on a start of line to avoid injection * @param string The data to fix * @return string */ protected function fixLE($data, $le) { $data = str_replace(array("\r\n", "\r"), "\n", $data); if ($le != "\n") $data = str_replace("\n", $le, $data); return $data = str_replace($le . ".", $le . "..", $data); } protected function getHcf($value, $factor) { return ($value - ($value % $factor)); } } ./kohana/system/vendor/swift/Swift/Message/Image.php0000644000175000017500000000365110607204072022175 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Message_EmbeddedFile"); /** * Embedded Image component for Swift Mailer * @package Swift_Message * @author Chris Corbyn */ class Swift_Message_Image extends Swift_Message_EmbeddedFile { /** * Constructor * @param Swift_File The input source file * @param string The filename to use, optional * @param string The MIME type to use, optional * @param string The Content-ID to use, optional * @param string The encoding format to use, optional */ public function __construct(Swift_File $data=null, $name=null, $type="application/octet-stream", $cid=null, $encoding="base64") { parent::__construct($data, $name, $type, $cid, $encoding); } /** * Set data for the image * This overrides setData() in Swift_Message_Attachment * @param Swift_File The data to set, as a file * @throws Swift_Message_MimeException If the image cannot be used, or the file is not */ public function setData($data, $read_filename=true) { if (!($data instanceof Swift_File)) throw new Exception("Parameter 1 of " . __METHOD__ . " must be instance of Swift_File"); parent::setData($data, $read_filename); $img_data = @getimagesize($data->getPath()); if (!$img_data) { throw new Swift_Message_MimeException( "Cannot use file '" . $data->getPath() . "' as image since getimagesize() was unable to detect a file format. " . "Try using Swift_Message_EmbeddedFile instead"); } $type = image_type_to_mime_type($img_data[2]); $this->setContentType($type); if (!$this->getFileName()) $this->setFileName($data->getFileName()); } } ./kohana/system/vendor/swift/Swift/Message/EmbeddedFile.php0000644000175000017500000000413510625276373023457 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_Message_Attachment"); /** * Embedded File component for Swift Mailer * @package Swift_Message * @author Chris Corbyn */ class Swift_Message_EmbeddedFile extends Swift_Message_Attachment { /** * The content-id in the headers (used in values) * @var string */ protected $cid = null; /** * Constructor * @param mixed The input source. Can be a file or a string * @param string The filename to use, optional * @param string The MIME type to use, optional * @param string The Content-ID to use, optional * @param string The encoding format to use, optional */ public function __construct($data=null, $name=null, $type="application/octet-stream", $cid=null, $encoding="base64") { parent::__construct($data, $name, $type, $encoding, "inline"); if ($cid === null) { $cid = self::generateFileName("swift-" . uniqid(time()) . "."); $cid = urlencode($cid) . "@" . (!empty($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : "swift"); } $this->setContentId($cid); if ($name === null && !($data instanceof Swift_File)) $this->setFileName($cid); $this->headers->set("Content-Description", null); } /** * Get the level in the MIME hierarchy at which this section should appear. * @return string */ public function getLevel() { return Swift_Message_Mime::LEVEL_RELATED; } /** * Set the Content-Id to use * @param string The content-id */ public function setContentId($id) { $id = (string) $id; $this->cid = $id; $this->headers->set("Content-ID", "<" . $id . ">"); } /** * Get the content-id of this file * @return string */ public function getContentId() { return $this->cid; } } ./kohana/system/vendor/swift/Swift/Message/Mime.php0000644000175000017500000003472710623121155022050 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; Swift_ClassLoader::load("Swift_File"); Swift_ClassLoader::load("Swift_Message_MimeException"); /** * Mime is the underbelly for Messages, Attachments, Parts, Embedded Images, Forwarded Mail, etc * In fact, every single component of the composed email is simply a new Mime document nested inside another * When you piece an email together in this way you see just how straight-forward it really is * @package Swift_Message * @author Chris Corbyn */ abstract class Swift_Message_Mime { /** * Constant for plain-text emails */ const PLAIN = "text/plain"; /** * Constant for HTML emails */ const HTML = "text/html"; /** * Constant for miscellaneous mime type */ const MISC = "application/octet-stream"; /** * Constant for MIME sections which must appear in the multipart/alternative section. */ const LEVEL_ALTERNATIVE = "alternative"; /** * Constant for MIME sections which must appear in the multipart/related section. */ const LEVEL_RELATED = "related"; /** * Constant for MIME sections which must appear in the multipart/mixed section. */ const LEVEL_MIXED = "mixed"; /** * Constant for MIME sections which must appear in the multipart/mixed section. */ const LEVEL_TOP = "top"; /** * Constant for safe line length in almost all places */ const SAFE_LENGTH = 1000; //RFC 2822 /** * Constant for really safe line length */ const VERY_SAFE_LENGTH = 76; //For command line mail clients such as pine /** * The header part of this MIME document * @var Swift_Message_Headers */ public $headers = null; /** * The body of the documented (unencoded) * @var string data */ protected $data = ""; /** * Maximum line length * @var int */ protected $wrap = 1000; //RFC 2822 /** * Nested mime parts * @var array */ protected $children = array(); /** * The boundary used to separate mime parts * @var string */ protected $boundary = null; /** * The line ending characters needed * @var string */ protected $LE = "\r\n"; /** * An instance of Swift_Cache * @var Swift_Cache */ protected $cache; /** * A list of used MIME boundaries after they're generated. * @var array */ protected static $usedBoundaries = array(); /** * Constructor */ public function __construct() { Swift_ClassLoader::load("Swift_Message_Headers"); $this->setHeaders(new Swift_Message_Headers()); Swift_ClassLoader::load("Swift_CacheFactory"); $this->cache = Swift_CacheFactory::getCache(); } /** * Compute a unique boundary * @return string */ public static function generateBoundary() { do { $boundary = uniqid(rand(), true); } while (in_array($boundary, self::$usedBoundaries)); self::$usedBoundaries[] = $boundary; return "_=_swift-" . $boundary . "_=_"; } /** * Replace the current headers with new ones * DO NOT DO THIS UNLESS YOU KNOW WHAT YOU'RE DOING! * @param Swift_Message_Headers The headers to use */ public function setHeaders($headers) { $this->headers = $headers; } /** * Set the line ending character to use * @param string The line ending sequence * @return boolean */ public function setLE($le) { if (in_array($le, array("\r", "\n", "\r\n"))) { $this->cache->clear("body"); $this->LE = $le; //This change should be recursive $this->headers->setLE($le); foreach ($this->children as $id => $child) { $this->children[$id]->setLE($le); } return true; } else return false; } /** * Get the line ending sequence * @return string */ public function getLE() { return $this->LE; } /** * Reset the entire cache state from this branch of the tree and traversing down through the children */ public function uncacheAll() { $this->cache->clear("body"); $this->cache->clear("append"); $this->cache->clear("headers"); $this->cache->clear("dbl_le"); $this->headers->uncacheAll(); foreach ($this->children as $id => $child) { $this->children[$id]->uncacheAll(); } } /** * Set the content type of this MIME document * @param string The content type to use in the same format as MIME 1.0 expects */ public function setContentType($type) { $this->headers->set("Content-Type", $type); } /** * Get the content type which has been set * The MIME 1.0 Content-Type is provided as a string * @return string */ public function getContentType() { try { return $this->headers->get("Content-Type"); } catch (Swift_Message_MimeException $e) { return false; } } /** * Set the encoding format to be used on the body of the document * @param string The encoding type used * @param boolean If this encoding format should be used recursively. Note, this only takes effect if no encoding is set in the children. * @param boolean If the encoding should only be applied when the string is not ascii. */ public function setEncoding($encoding, $recursive=false, $non_ascii=false) { $this->cache->clear("body"); switch (strtolower($encoding)) { case "q": case "qp": case "quoted-printable": $encoding = "quoted-printable"; break; case "b": case "base64": $encoding = "base64"; break; case "7bit": case "8bit": case "binary": $encoding = strtolower($encoding); break; } $data = $this->getData(); Swift_ClassLoader::load("Swift_Message_Encoder"); if ($non_ascii && is_string($data) && strlen($data) > 0 && !Swift_Message_Encoder::instance()->is7BitAscii($data)) { $this->headers->set("Content-Transfer-Encoding", $encoding); } elseif (!$non_ascii || !is_string($data)) { $this->headers->set("Content-Transfer-Encoding", $encoding); } if ($recursive) { foreach ($this->children as $id => $child) { if (!$child->getEncoding()) $this->children[$id]->setEncoding($encoding, $recursive, $non_ascii); } } } /** * Get the encoding format used in this document * @return string */ public function getEncoding() { try { return $this->headers->get("Content-Transfer-Encoding"); } catch (Swift_Message_MimeException $e) { return false; } } /** * Specify the string which makes up the body of this message * HINT: You can always nest another MIME document here if you call it's build() method. * $data can be an object of Swift_File or a string * @param mixed The body of the document */ public function setData($data) { $this->cache->clear("body"); if ($data instanceof Swift_File) $this->data = $data; else $this->data = (string) $data; } /** * Return the string which makes up the body of this MIME document * @return string,Swift_File */ public function getData() { return $this->data; } /** * Get the data in the format suitable for sending * @return Swift_Cache_OutputStream * @throws Swift_FileException If the file stream given cannot be read * @throws Swift_Message_MimeException If some required headers have been forcefully removed */ public function buildData() { Swift_ClassLoader::load("Swift_Message_Encoder"); Swift_ClassLoader::load("Swift_Cache_JointOutputStream"); if (!empty($this->children)) //If we've got some mime parts we need to stick them onto the end of the message { if ($this->boundary === null) $this->boundary = self::generateBoundary(); $this->headers->setAttribute("Content-Type", "boundary", $this->boundary); $this->cache->clear("append"); foreach ($this->children as $part) { $this->cache->write("append", $this->LE . "--" . $this->boundary . $this->LE); $part_stream = $part->build(); while (false !== $bytes = $part_stream->read()) $this->cache->write("append", $bytes); } $this->cache->write("append", $this->LE . "--" . $this->boundary . "--" . $this->LE); } $joint_os = new Swift_Cache_JointOutputStream(); //Try using a cached version to save some cycles (at the expense of memory) //if ($this->cache !== null) return $this->cache . $append; if ($this->cache->has("body")) { $joint_os->addStream($this->cache->getOutputStream("body")); $joint_os->addStream($this->cache->getOutputStream("append")); return $joint_os; } $is_file = ($this->getData() instanceof Swift_File); switch ($this->getEncoding()) { case "quoted-printable": if ($is_file) { $qp_os = Swift_Message_Encoder::instance()->QPEncodeFile($this->getData(), 76, $this->LE); while (false !== $bytes = $qp_os->read()) $this->cache->write("body", $bytes); } else { $this->cache->write("body", Swift_Message_Encoder::instance()->QPEncode($this->getData(), 76, 0, false, $this->LE)); } break; case "base64": if ($is_file) { $b64_os = Swift_Message_Encoder::instance()->base64EncodeFile($this->getData(), 76, $this->LE); while (false !== $bytes = $b64_os->read()) $this->cache->write("body", $bytes); } else { $this->cache->write("body", Swift_Message_Encoder::instance()->base64Encode($this->getData(), 76, 0, false, $this->LE)); } break; case "binary": if ($is_file) { $data = $this->getData(); while (false !== $bytes = $data->read(8192)) $this->cache->write("body", $bytes); } else { $this->cache->write("body", $this->getData()); } break; case "7bit": if ($is_file) { $os = Swift_Message_Encoder::instance()->encode7BitFile($this->getData(), $this->wrap, $this->LE); while (false !== $bytes = $os->read()) $this->cache->write("body", $bytes); } else { $this->cache->write("body", Swift_Message_Encoder::instance()->encode7Bit($this->getData(), $this->wrap, $this->LE)); } break; case "8bit": default: if ($is_file) { $os = Swift_Message_Encoder::instance()->encode8BitFile($this->getData(), $this->wrap, $this->LE); while (false !== $bytes = $os->read()) $this->cache->write("body", $bytes); } else { $this->cache->write("body", Swift_Message_Encoder::instance()->encode8Bit($this->getData(), $this->wrap, $this->LE)); } break; } $joint_os->addStream($this->cache->getOutputStream("body")); $joint_os->addStream($this->cache->getOutputStream("append")); return $joint_os; } /** * Set the size at which lines wrap around (includes the CRLF) * @param int The length of a line */ public function setLineWrap($len) { $this->cache->clear("body"); $this->wrap = (int) $len; } /** * Nest a child mime part in this document * @param Swift_Message_Mime * @param string The identifier to use, optional * @param int Add the part before (-1) or after (+1) the other parts * @return string The identifier for this part */ public function addChild(Swift_Message_Mime $mime, $id=null, $after=1) { if (empty($id)) { do { $id = uniqid(); } while (array_key_exists($id, $this->children)); } $id = (string) $id; if ($after == -1) $this->children = array_merge(array($id => $mime), $this->children); else $this->children[$id] = $mime; return $id; } /** * Check if a child exists identified by $id * @param string Identifier to look for * @return boolean */ public function hasChild($id) { return array_key_exists($id, $this->children); } /** * Get a child document, identified by $id * @param string The identifier for this child * @return Swift_Message_Mime The child document * @throws Swift_Message_MimeException If no such child exists */ public function getChild($id) { if ($this->hasChild($id)) { return $this->children[$id]; } else { throw new Swift_Message_MimeException( "Cannot retrieve child part identified by '" . $id . "' as it does not exist. Consider using hasChild() to check."); } } /** * Remove a part from the document * @param string The identifier of the child * @throws Swift_Message_MimeException If no such part exists */ public function removeChild($id) { $id = (string) $id; if (!$this->hasChild($id)) { throw new Swift_Message_MimeException( "Cannot remove child part identified by '" . $id . "' as it does not exist. Consider using hasChild() to check."); } else { $this->children[$id] = null; unset($this->children[$id]); } } /** * List the IDs of all children in this document * @return array */ public function listChildren() { return array_keys($this->children); } /** * Get the total number of children present in this document * @return int */ public function numChildren() { return count($this->children); } /** * Get the level at which this mime part would appear in a document * One of "mixed", "alternative" or "related" * @return string */ abstract public function getLevel(); /** * Compile the entire MIME document into a string * The returned string may be used in other documents if needed. * @return Swift_Cache_OutputStream */ public function build() { $this->preBuild(); $data = $this->buildData(); $joint_os = new Swift_Cache_JointOutputStream(); $this->cache->clear("headers"); $this->cache->write("headers", $this->headers->build()); $joint_os->addStream($this->cache->getOutputStream("headers")); $this->cache->clear("dbl_le"); $this->cache->write("dbl_le", str_repeat($this->LE, 2)); $joint_os->addStream($this->cache->getOutputStream("dbl_le")); $joint_os->addStream($data); return $joint_os; //return $this->headers->build() . str_repeat($this->LE, 2) . $data; } /** * Execute any logic needed prior to building */ abstract public function preBuild(); } ./kohana/system/vendor/swift/Swift/Message/Headers.php0000644000175000017500000004333410651646033022536 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift_Message * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/../ClassLoader.php"; /** * Contains and constructs the headers for a MIME document * @package Swift_Message * @author Chris Corbyn */ class Swift_Message_Headers { /** * Headers which may contain email addresses, and therefore should take notice when encoding * @var array headers */ protected $emailContainingHeaders = array( "To", "From", "Reply-To", "Cc", "Bcc", "Return-Path", "Sender"); /** * The encoding format used for the body of the document * @var string format */ protected $encoding = "B"; /** * The charset used in the headers * @var string */ protected $charset = false; /** * A collection of headers * @var array headers */ protected $headers = array(); /** * A container of references to the headers * @var array */ protected $lowerHeaders = array(); /** * Attributes appended to headers * @var array */ protected $attributes = array(); /** * If QP or Base64 encoding should be forced * @var boolean */ protected $forceEncoding = false; /** * The language used in the headers (doesn't really matter much) * @var string */ protected $language = "en-us"; /** * Cached, pre-built headers * @var string */ protected $cached = array(); /** * The line ending used in the headers * @var string */ protected $LE = "\r\n"; /** * Set the line ending character to use * @param string The line ending sequence * @return boolean */ public function setLE($le) { if (in_array($le, array("\r", "\n", "\r\n"))) { foreach (array_keys($this->cached) as $k) $this->cached[$k] = null; $this->LE = $le; return true; } else return false; } /** * Get the line ending sequence * @return string */ public function getLE() { return $this->LE; } /** * Reset the cache state in these headers */ public function uncacheAll() { foreach (array_keys($this->cached) as $k) { $this->cached[$k] = null; } } /** * Add a header or change an existing header value * @param string The header name, for example "From" or "Subject" * @param string The value to be inserted into the header. This is safe from header injection. */ public function set($name, $value) { $lname = strtolower($name); if (!isset($this->lowerHeaders[$lname])) { $this->headers[$name] = null; $this->lowerHeaders[$lname] =& $this->headers[$name]; } $this->cached[$lname] = null; Swift_ClassLoader::load("Swift_Message_Encoder"); if (is_array($value)) { foreach ($value as $v) { if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($v)) { $this->setCharset("utf-8"); break; } } } elseif ($value !== null) { if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($value)) { $this->setCharset("utf-8"); } } if (!is_array($value) && $value !== null) $this->lowerHeaders[$lname] = (string) $value; else $this->lowerHeaders[$lname] = $value; } /** * Get the value at a given header * @param string The name of the header, for example "From" or "Subject" * @return string * @throws Swift_Message_MimeException If no such header exists * @see hasHeader */ public function get($name) { $lname = strtolower($name); if ($this->has($name)) { return $this->lowerHeaders[$lname]; } } /** * Remove a header from the list * @param string The name of the header */ public function remove($name) { $lname = strtolower($name); if ($this->has($name)) { unset($this->headers[$name]); unset($this->lowerHeaders[$lname]); unset($this->cached[$lname]); if (isset($this->attributes[$lname])) unset($this->attributes[$lname]); } } /** * Just fetch the array containing the headers * @return array */ public function getList() { return $this->headers; } /** * Check if a header has been set or not * @param string The name of the header, for example "From" or "Subject" * @return boolean */ public function has($name) { $lname = strtolower($name); return (array_key_exists($lname, $this->lowerHeaders) && $this->lowerHeaders[$lname] !== null); } /** * Set the language used in the headers to $lang (e.g. en-us, en-gb, sv etc) * @param string The language to use */ public function setLanguage($lang) { $this->language = (string) $lang; } /** * Get the language used in the headers to $lang (e.g. en-us, en-gb, sv etc) * @return string */ public function getLanguage() { return $this->language; } /** * Set the charset used in the headers * @param string The charset name */ public function setCharset($charset) { $this->charset = (string) $charset; } /** * Get the current charset used * @return string */ public function getCharset() { return $this->charset; } /** * Specify the encoding to use for the headers if characters outside the 7-bit-printable ascii range are found * This encoding will never be used if only 7-bit-printable characters are found in the headers. * Possible values are: * - QP * - Q * - Quoted-Printable * - B * - Base64 * NOTE: Q, QP, Quoted-Printable are all the same; as are B and Base64 * @param string The encoding format to use * @return boolean */ public function setEncoding($encoding) { switch (strtolower($encoding)) { case "qp": case "q": case "quoted-printable": $this->encoding = "Q"; return true; case "base64": case "b": $this->encoding = "B"; return true; default: return false; } } /** * Get the encoding format used in this document * @return string */ public function getEncoding() { return $this->encoding; } /** * Turn on or off forced header encoding * @param boolean On/Off */ public function forceEncoding($force=true) { $this->forceEncoding = (boolean) $force; } /** * Set an attribute in a major header * For example $headers->setAttribute("Content-Type", "format", "flowed") * @param string The main header these values exist in * @param string The name for this value * @param string The value to set * @throws Swift_Message_MimeException If no such header exists */ public function setAttribute($header, $name, $value) { $name = strtolower($name); $lheader = strtolower($header); $this->cached[$lheader] = null; if (!$this->has($header)) { throw new Swift_Message_MimeException( "Cannot set attribute '" . $name . "' for header '" . $header . "' as the header does not exist. " . "Consider using Swift_Message_Headers->has() to check."); } else { Swift_ClassLoader::load("Swift_Message_Encoder"); if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($value)) $this->setCharset("utf-8"); if (!isset($this->attributes[$lheader])) $this->attributes[$lheader] = array(); if ($value !== null) $this->attributes[$lheader][$name] = (string) $value; else $this->attributes[$lheader][$name] = $value; } } /** * Check if a header has a given attribute applied to it * @param string The name of the main header * @param string The name of the attribute * @return boolean */ public function hasAttribute($header, $name) { $name = strtolower($name); $lheader = strtolower($header); if (!$this->has($header)) { return false; } else { return (isset($this->attributes[$lheader]) && isset($this->attributes[$lheader][$name]) && ($this->attributes[$lheader][$name] !== null)); } } /** * Get the value for a given attribute on a given header * @param string The name of the main header * @param string The name of the attribute * @return string * @throws Swift_Message_MimeException If no header is set */ public function getAttribute($header, $name) { if (!$this->has($header)) { throw new Swift_Message_MimeException( "Cannot locate attribute '" . $name . "' for header '" . $header . "' as the header does not exist. " . "Consider using Swift_Message_Headers->has() to check."); } $name = strtolower($name); $lheader = strtolower($header); if ($this->hasAttribute($header, $name)) { return $this->attributes[$lheader][$name]; } } /** * Remove an attribute from a header * @param string The name of the header to remove the attribute from * @param string The name of the attribute to remove */ public function removeAttribute($header, $name) { $name = strtolower($name); $lheader = strtolower($header); if ($this->has($header)) { unset($this->attributes[$lheader][$name]); } } /** * Get a list of all the attributes in the given header. * @param string The name of the header * @return array */ public function listAttributes($header) { $header = strtolower($header); if (array_key_exists($header, $this->attributes)) { return $this->attributes[$header]; } else return array(); } /** * Get the header in it's compliant, encoded form * @param string The name of the header * @return string * @throws Swift_Message_MimeException If the header doesn't exist */ public function getEncoded($name) { if (!$this->getCharset()) $this->setCharset("iso-8859-1"); Swift_ClassLoader::load("Swift_Message_Encoder"); //I'll try as best I can to walk through this... $lname = strtolower($name); if ($this->cached[$lname] !== null) return $this->cached[$lname]; $value = $this->get($name); $is_email = in_array($name, $this->emailContainingHeaders); $encoded_value = (array) $value; //Turn strings into arrays (just to make the following logic simpler) //Look at each value in this header // There will only be 1 value if it was a string to begin with, and usually only address lists will be multiple foreach ($encoded_value as $key => $row) { $spec = ""; //The bit which specifies the encoding of the header (if any) $end = ""; //The end delimiter for an encoded header //If the header is 7-bit printable it's at no risk of injection if (Swift_Message_Encoder::instance()->isHeaderSafe($row) && !$this->forceEncoding) { //Keeps the total line length at less than 76 chars, taking into account the Header name length $encoded_value[$key] = Swift_Message_Encoder::instance()->header7BitEncode( $row, 72, ($key > 0 ? 0 : (75-(strlen($name)+5))), $this->LE); } elseif ($this->encoding == "Q") //QP encode required { $spec = "=?" . $this->getCharset() . "?Q?"; //e.g. =?iso-8859-1?Q? $end = "?="; //Calculate the length of, for example: "From: =?iso-8859-1?Q??=" $used_length = strlen($name) + 2 + strlen($spec) + 2; //Encode to QP, excluding the specification for now but keeping the lines short enough to be compliant $encoded_value[$key] = str_replace(" ", "_", Swift_Message_Encoder::instance()->QPEncode( $row, (75-(strlen($spec)+6)), ($key > 0 ? 0 : (75-$used_length)), true, $this->LE)); } elseif ($this->encoding == "B") //Need to Base64 encode { //See the comments in the elseif() above since the logic is the same (refactor?) $spec = "=?" . $this->getCharset() . "?B?"; $end = "?="; $used_length = strlen($name) + 2 + strlen($spec) + 2; $encoded_value[$key] = Swift_Message_Encoder::instance()->base64Encode( $row, (75-(strlen($spec)+5)), ($key > 0 ? 0 : (76-($used_length+3))), true, $this->LE); } if (false !== $p = strpos($encoded_value[$key], $this->LE)) { $cb = 'str_replace("' . $this->LE . '", "", "<$1>");'; $encoded_value[$key] = preg_replace("/<([^>]+)>/e", $cb, $encoded_value[$key]); } //Turn our header into an array of lines ready for wrapping around the encoding specification $lines = explode($this->LE, $encoded_value[$key]); for ($i = 0, $len = count($lines); $i < $len; $i++) { //Don't allow commas in address fields without quotes unless they're encoded if (empty($spec) && $is_email && (false !== $p = strpos($lines[$i], ","))) { $s = strpos($lines[$i], " <"); $e = strpos($lines[$i], ">"); if ($s < $e) { $addr = substr($lines[$i], $s); $lines[$i] = "\"" . substr($lines[$i], 0, $s) . "\"" . $addr; } else { $lines[$i] = "\"" . $lines[$i] . "\""; } } if ($this->encoding == "Q") $lines[$i] = rtrim($lines[$i], "="); if ($lines[$i] == "" && $i > 0) { unset($lines[$i]); //Empty line, we'd rather not have these in the headers thank you! continue; } if ($i > 0) { //Don't stick the specification part around the line if it's an address if (substr($lines[$i], 0, 1) == '<' && substr($lines[$i], -1) == '>') $lines[$i] = " " . $lines[$i]; else $lines[$i] = " " . $spec . $lines[$i] . $end; } else { if (substr($lines[$i], 0, 1) != '<' || substr($lines[$i], -1) != '>') $lines[$i] = $spec . $lines[$i] . $end; } } //Build back into a string, now includes the specification $encoded_value[$key] = implode($this->LE, $lines); $lines = null; } //If there are multiple values in this header, put them on separate lines, cleared by commas $this->cached[$lname] = implode("," . $this->LE . " ", $encoded_value); //Append attributes if there are any if (!empty($this->attributes[$lname])) $this->cached[$lname] .= $this->buildAttributes($this->cached[$lname], $lname); return $this->cached[$lname]; } /** * Build the list of attributes for appending to the given header * This is RFC 2231 & 2047 compliant. * A HUGE thanks to Joaquim Homrighausen for heaps of help, advice * and testing to get this working rock solid. * @param string The header built without attributes * @param string The lowercase name of the header * @return string * @throws Swift_Message_MimeException If no such header exists or there are no attributes */ protected function buildAttributes($header_line, $header_name) { Swift_ClassLoader::load("Swift_Message_Encoder"); $lines = explode($this->LE, $header_line); $used_len = strlen($lines[count($lines)-1]); $lines= null; $ret = ""; foreach ($this->attributes[$header_name] as $attribute => $att_value) { if ($att_value === null) continue; // 70 to account for LWSP, CRLF, quotes and a semi-colon // + length of attribute // + 4 for a 2 digit number and 2 asterisks $avail_len = 70 - (strlen($attribute) + 4); $encoded = Swift_Message_Encoder::instance()->rfc2047Encode($att_value, $this->charset, $this->language, $avail_len, $this->LE); $lines = explode($this->LE, $encoded); foreach ($lines as $i => $line) { //Add quotes if needed (RFC 2045) if (preg_match("~[\\s\";,<>\\(\\)@:\\\\/\\[\\]\\?=]~", $line)) $lines[$i] = '"' . $line . '"'; } $encoded = implode($this->LE, $lines); //If we can fit this entire attribute onto the same line as the header then do it! if ((strlen($encoded) + $used_len + strlen($attribute) + 4) < 74) { if (strpos($encoded, "'") !== false) $attribute .= "*"; $append = "; " . $attribute . "=" . $encoded; $ret .= $append; $used_len += strlen($append); } else //... otherwise list of underneath { $ret .= ";"; if (count($lines) > 1) { $loop = false; $add_asterisk = false; foreach ($lines as $i => $line) { $att_copy = $attribute; //Because it's multi-line it needs asterisks with decimal indices $att_copy .= "*" . $i; if ($add_asterisk || strpos($encoded, "'") !== false) { $att_copy .= "*"; //And if it's got a ' then it needs another asterisk $add_asterisk = true; } $append = ""; if ($loop) $append .= ";"; $append .= $this->LE . " " . $att_copy . "=" . $line; $ret .= $append; $used_len = strlen($append)+1; $loop = true; } } else { if (strpos($encoded, "'") !== false) $attribute .= "*"; $append = $this->LE . " " . $attribute . "=" . $encoded; $used_len = strlen($append)+1; $ret .= $append; } } $lines= null; } return $ret; } /** * Compile the list of headers which have been set and return an ascii string * The return value should always be 7-bit ascii and will have been cleaned for header injection * If this looks complicated it's probably because it is!! Keeping everything compliant is not easy. * This is RFC 2822 compliant * @return string */ public function build() { $ret = ""; foreach ($this->headers as $name => $value) //Look at each header { if ($value === null) continue; $ret .= ltrim($name, ".") . ": " . $this->getEncoded($name) . $this->LE; } return trim($ret); } } ./kohana/system/vendor/swift/Swift/Exception.php0000644000175000017500000000157410660520700021525 0ustar tokkeetokkee * @package Swift_Log * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_LogContainer"); /** * The Logger Interface * @package Swift_Log * @author Chris Corbyn */ class Swift_Exception extends Exception { /** * Constructor. * Creates the exception and appends log information if available. * @param string Message * @param int Code */ public function __construct($message, $code = 0) { if (($log = Swift_LogContainer::getLog()) && $log->isEnabled()) { $message .= "

    Log Information

    "; $message .= "
    " . htmlentities($log->dump(true)) . "
    "; } parent::__construct($message, $code); } } ./kohana/system/vendor/swift/Swift/ConnectionBase.php0000644000175000017500000000535610660421612022465 0ustar tokkeetokkee * @package Swift_Connection * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_LogContainer"); Swift_ClassLoader::load("Swift_Connection"); Swift_ClassLoader::load("Swift_ConnectionException"); /** * Swift Connection Base Class * @package Swift_Connection * @author Chris Corbyn */ abstract class Swift_ConnectionBase implements Swift_Connection { /** * Any extensions the server might support * @var array */ protected $extensions = array(); /** * True if the connection is ESMTP. * @var boolean */ protected $isESMTP = false; /** * Set an extension which the connection reports to support * @param string Extension name * @param array Attributes of the extension */ public function setExtension($name, $options=array()) { $this->extensions[$name] = $options; $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("SMTP extension '" . $name . "' reported with attributes [" . implode(", ", $options) . "]."); } } /** * Check if a given extension has been set as available * @param string The name of the extension * @return boolean */ public function hasExtension($name) { return array_key_exists($name, $this->extensions); } /** * Execute any needed logic after connecting and handshaking */ public function postConnect(Swift $instance) {} /** * Get the list of attributes supported by the given extension * @param string The name of the connection * @return array The list of attributes * @throws Swift_ConnectionException If the extension cannot be found */ public function getAttributes($extension) { if ($this->hasExtension($extension)) { return $this->extensions[$extension]; } else { throw new Swift_ConnectionException( "Unable to locate any attributes for the extension '" . $extension . "' since the extension cannot be found. " . "Consider using hasExtension() to check."); } } /** * Returns TRUE if the connection needs a EHLO greeting. * @return boolean */ public function getRequiresEHLO() { return $this->isESMTP; } /** * Set TRUE if the connection needs a EHLO greeting. * @param boolean */ public function setRequiresEHLO($set) { $this->isESMTP = (bool) $set; $log = Swift_LogContainer::getLog(); if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) { $log->add("Forcing ESMTP mode. HELO is EHLO."); } } } ./kohana/system/vendor/swift/Swift/FileException.php0000644000175000017500000000073710660421612022327 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/ClassLoader.php"; Swift_ClassLoader::load("Swift_Exception"); /** * Swift File Exception * @package Swift * @author Chris Corbyn */ class Swift_FileException extends Swift_Exception { } ./kohana/system/vendor/swift/Swift.php0000644000175000017500000004153710704334477017607 0ustar tokkeetokkee * @author Chris Corbyn * @package Swift * @version 3.3.2 * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/Swift/ClassLoader.php"; Swift_ClassLoader::load("Swift_LogContainer"); Swift_ClassLoader::load("Swift_ConnectionBase"); Swift_ClassLoader::load("Swift_BadResponseException"); Swift_ClassLoader::load("Swift_Cache"); Swift_ClassLoader::load("Swift_CacheFactory"); Swift_ClassLoader::load("Swift_Message"); Swift_ClassLoader::load("Swift_RecipientList"); Swift_ClassLoader::load("Swift_BatchMailer"); Swift_ClassLoader::load("Swift_Events"); Swift_ClassLoader::load("Swift_Events_Listener"); /** * Swift is the central component in the Swift library. * @package Swift * @author Chris Corbyn * @version 3.3.2 */ class Swift { /** * The version number. */ const VERSION = "3.3.2"; /** * Constant to flag Swift not to try and connect upon instantiation */ const NO_START = 2; /** * Constant to tell Swift not to perform the standard SMTP handshake upon connect */ const NO_HANDSHAKE = 4; /** * Constant to ask Swift to start logging */ const ENABLE_LOGGING = 8; /** * Constant to prevent postConnect() being run in the connection */ const NO_POST_CONNECT = 16; /** * The connection object currently active * @var Swift_Connection */ public $connection = null; /** * The domain name of this server (should technically be a FQDN) * @var string */ protected $domain = null; /** * Flags to change the behaviour of Swift * @var int */ protected $options; /** * Loaded plugins, separated into containers according to roles * @var array */ protected $listeners = array(); /** * Constructor * @param Swift_Connection The connection object to deal with I/O * @param string The domain name of this server (the client) as a FQDN * @param int Optional flags * @throws Swift_ConnectionException If a connection cannot be established or the connection is behaving incorrectly */ public function __construct(Swift_Connection $conn, $domain=false, $options=null) { $this->initializeEventListenerContainer(); $this->setOptions($options); $log = Swift_LogContainer::getLog(); if ($this->hasOption(self::ENABLE_LOGGING) && !$log->isEnabled()) { $log->setLogLevel(Swift_Log::LOG_NETWORK); } if (!$domain) $domain = !empty($_SERVER["SERVER_ADDR"]) ? "[" . $_SERVER["SERVER_ADDR"] . "]" : "localhost.localdomain"; $this->setDomain($domain); $this->connection = $conn; if ($conn && !$this->hasOption(self::NO_START)) { if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) $log->add("Trying to connect...", Swift_Log::NORMAL); $this->connect(); } } /** * Populate the listeners array with the defined listeners ready for plugins */ protected function initializeEventListenerContainer() { Swift_ClassLoader::load("Swift_Events_ListenerMapper"); foreach (Swift_Events_ListenerMapper::getMap() as $interface => $method) { if (!isset($this->listeners[$interface])) $this->listeners[$interface] = array(); } } /** * Add a new plugin to Swift * Plugins must implement one or more event listeners * @param Swift_Events_Listener The plugin to load */ public function attachPlugin(Swift_Events_Listener $plugin, $id) { foreach (array_keys($this->listeners) as $key) { $listener = "Swift_Events_" . $key; Swift_ClassLoader::load($listener); if ($plugin instanceof $listener) $this->listeners[$key][$id] = $plugin; } } /** * Get an attached plugin if it exists * @param string The id of the plugin * @return Swift_Event_Listener */ public function getPlugin($id) { foreach ($this->listeners as $type => $arr) { if (isset($arr[$id])) return $this->listeners[$type][$id]; } return null; //If none found } /** * Remove a plugin attached under the ID of $id * @param string The ID of the plugin */ public function removePlugin($id) { foreach ($this->listeners as $type => $arr) { if (isset($arr[$id])) { $this->listeners[$type][$id] = null; unset($this->listeners[$type][$id]); } } } /** * Send a new type of event to all objects which are listening for it * @param Swift_Events The event to send * @param string The type of event */ public function notifyListeners($e, $type) { Swift_ClassLoader::load("Swift_Events_ListenerMapper"); if (!empty($this->listeners[$type]) && $notifyMethod = Swift_Events_ListenerMapper::getNotifyMethod($type)) { $e->setSwift($this); foreach ($this->listeners[$type] as $k => $listener) { $listener->$notifyMethod($e); } } else $e = null; } /** * Check if an option flag has been set * @param string Option name * @return boolean */ public function hasOption($option) { return ($this->options & $option); } /** * Adjust the options flags * E.g. $obj->setOptions(Swift::NO_START | Swift::NO_HANDSHAKE) * @param int The bits to set */ public function setOptions($options) { $this->options = (int) $options; } /** * Get the current options set (as bits) * @return int */ public function getOptions() { return (int) $this->options; } /** * Set the FQDN of this server as it will identify itself * @param string The FQDN of the server */ public function setDomain($name) { $this->domain = (string) $name; } /** * Attempt to establish a connection with the service * @throws Swift_ConnectionException If the connection cannot be established or behaves oddly */ public function connect() { $this->connection->start(); $greeting = $this->command("", 220); if (!$this->hasOption(self::NO_HANDSHAKE)) { $this->handshake($greeting); } Swift_ClassLoader::load("Swift_Events_ConnectEvent"); $this->notifyListeners(new Swift_Events_ConnectEvent($this->connection), "ConnectListener"); } /** * Disconnect from the MTA * @throws Swift_ConnectionException If the connection will not stop */ public function disconnect() { $this->command("QUIT"); $this->connection->stop(); Swift_ClassLoader::load("Swift_Events_DisconnectEvent"); $this->notifyListeners(new Swift_Events_DisconnectEvent($this->connection), "DisconnectListener"); } /** * Throws an exception if the response code wanted does not match the one returned * @param Swift_Event_ResponseEvent The full response from the service * @param int The 3 digit response code wanted * @throws Swift_BadResponseException If the code does not match */ protected function assertCorrectResponse(Swift_Events_ResponseEvent $response, $codes) { $codes = (array)$codes; if (!in_array($response->getCode(), $codes)) { $log = Swift_LogContainer::getLog(); $error = "Expected response code(s) [" . implode(", ", $codes) . "] but got response [" . $response->getString() . "]"; if ($log->hasLevel(Swift_Log::LOG_ERRORS)) $log->add($error, Swift_Log::ERROR); throw new Swift_BadResponseException($error); } } /** * Have a polite greeting with the server and work out what it's capable of * @param Swift_Events_ResponseEvent The initial service line respoonse * @throws Swift_ConnectionException If conversation is not going very well */ protected function handshake(Swift_Events_ResponseEvent $greeting) { if ($this->connection->getRequiresEHLO() || strpos($greeting->getString(), "ESMTP")) $this->setConnectionExtensions($this->command("EHLO " . $this->domain, 250)); else $this->command("HELO " . $this->domain, 250); //Connection might want to do something like authenticate now if (!$this->hasOption(self::NO_POST_CONNECT)) $this->connection->postConnect($this); } /** * Set the extensions which the service reports in the connection object * @param Swift_Events_ResponseEvent The list of extensions as reported by the service */ protected function setConnectionExtensions(Swift_Events_ResponseEvent $list) { $le = (strpos($list->getString(), "\r\n") !== false) ? "\r\n" : "\n"; $list = explode($le, $list->getString()); for ($i = 1, $len = count($list); $i < $len; $i++) { $extension = substr($list[$i], 4); $attributes = split("[ =]", $extension); $this->connection->setExtension($attributes[0], (isset($attributes[1]) ? array_slice($attributes, 1) : array())); } } /** * Execute a command against the service and get the response * @param string The command to execute (leave off any CRLF!!!) * @param int The code to check for in the response, if any. -1 indicates that no response is wanted. * @return Swift_Events_ResponseEvent The server's response (could be multiple lines) * @throws Swift_ConnectionException If a code was expected but does not match the one returned */ public function command($command, $code=null) { $log = Swift_LogContainer::getLog(); Swift_ClassLoader::load("Swift_Events_CommandEvent"); if ($command !== "") { $command_event = new Swift_Events_CommandEvent($command, $code); $command = null; //For memory reasons $this->notifyListeners($command_event, "BeforeCommandListener"); if ($log->hasLevel(Swift_Log::LOG_NETWORK) && $code != -1) $log->add($command_event->getString(), Swift_Log::COMMAND); $end = ($code != -1) ? "\r\n" : null; $this->connection->write($command_event->getString(), $end); $this->notifyListeners($command_event, "CommandListener"); } if ($code == -1) return null; Swift_ClassLoader::load("Swift_Events_ResponseEvent"); $response_event = new Swift_Events_ResponseEvent($this->connection->read()); $this->notifyListeners($response_event, "ResponseListener"); if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add($response_event->getString(), Swift_Log::RESPONSE); if ($command !== "" && $command_event->getCode() !== null) $this->assertCorrectResponse($response_event, $command_event->getCode()); return $response_event; } /** * Reset a conversation which has gone badly * @throws Swift_ConnectionException If the service refuses to reset */ public function reset() { $this->command("RSET", 250); } /** * Send a message to any number of recipients * @param Swift_Message The message to send. This does not need to (and shouldn't really) have any of the recipient headers set. * @param mixed The recipients to send to. Can be a string, Swift_Address or Swift_RecipientList. Note that all addresses apart from Bcc recipients will appear in the message headers * @param mixed The address to send the message from. Can either be a string or an instance of Swift_Address. * @return int The number of successful recipients * @throws Swift_ConnectionException If sending fails for any reason. */ public function send(Swift_Message $message, $recipients, $from) { Swift_ClassLoader::load("Swift_Message_Encoder"); if (is_string($recipients) && preg_match("/^" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . "\$/", $recipients)) { $recipients = new Swift_Address($recipients); } elseif (!($recipients instanceof Swift_AddressContainer)) throw new Exception("The recipients parameter must either be a valid string email address, ". "an instance of Swift_RecipientList or an instance of Swift_Address."); if (is_string($from) && preg_match("/^" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . "\$/", $from)) { $from = new Swift_Address($from); } elseif (!($from instanceof Swift_Address)) throw new Exception("The sender parameter must either be a valid string email address or ". "an instance of Swift_Address."); $log = Swift_LogContainer::getLog(); if (!$message->getEncoding() && !$this->connection->hasExtension("8BITMIME")) { $message->setEncoding("QP", true, true); } $list = $recipients; if ($recipients instanceof Swift_Address) { $list = new Swift_RecipientList(); $list->addTo($recipients); } Swift_ClassLoader::load("Swift_Events_SendEvent"); $send_event = new Swift_Events_SendEvent($message, $list, $from, 0); $this->notifyListeners($send_event, "BeforeSendListener"); $to = $cc = array(); if (!($has_from = $message->getFrom())) $message->setFrom($from); if (!($has_return_path = $message->getReturnPath())) $message->setReturnPath($from->build(true)); if (!($has_reply_to = $message->getReplyTo())) $message->setReplyTo($from); if (!($has_message_id = $message->getId())) $message->generateId(); $this->command("MAIL FROM: " . $message->getReturnPath(true), 250); $failed = 0; $sent = 0; $tmp_sent = 0; $it = $list->getIterator("to"); while ($it->hasNext()) { $it->next(); $address = $it->getValue(); $to[] = $address->build(); try { $this->command("RCPT TO: " . $address->build(true), 250); $tmp_sent++; } catch (Swift_BadResponseException $e) { $failed++; $send_event->addFailedRecipient($address->getAddress()); if ($log->hasLevel(Swift_Log::LOG_FAILURES)) $log->addfailedRecipient($address->getAddress()); } } $it = $list->getIterator("cc"); while ($it->hasNext()) { $it->next(); $address = $it->getValue(); $cc[] = $address->build(); try { $this->command("RCPT TO: " . $address->build(true), 250); $tmp_sent++; } catch (Swift_BadResponseException $e) { $failed++; $send_event->addFailedRecipient($address->getAddress()); if ($log->hasLevel(Swift_Log::LOG_FAILURES)) $log->addfailedRecipient($address->getAddress()); } } if ($failed == (count($to) + count($cc))) { $this->reset(); $this->notifyListeners($send_event, "SendListener"); return 0; } if (!($has_to = $message->getTo()) && !empty($to)) $message->setTo($to); if (!($has_cc = $message->getCc()) && !empty($cc)) $message->setCc($cc); $this->command("DATA", 354); $data = $message->build(); while (false !== $bytes = $data->read()) $this->command($bytes, -1); if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add("", Swift_Log::COMMAND); try { $this->command("\r\n.", 250); $sent += $tmp_sent; } catch (Swift_BadResponseException $e) { $failed += $tmp_sent; } $tmp_sent = 0; $has_bcc = $message->getBcc(); $it = $list->getIterator("bcc"); while ($it->hasNext()) { $it->next(); $address = $it->getValue(); if (!$has_bcc) $message->setBcc($address->build()); try { $this->command("MAIL FROM: " . $message->getReturnPath(true), 250); $this->command("RCPT TO: " . $address->build(true), 250); $this->command("DATA", 354); $data = $message->build(); while (false !== $bytes = $data->read()) $this->command($bytes, -1); if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add("", Swift_Log::COMMAND); $this->command("\r\n.", 250); $sent++; } catch (Swift_BadResponseException $e) { $failed++; $send_event->addFailedRecipient($address->getAddress()); if ($log->hasLevel(Swift_Log::LOG_FAILURES)) $log->addfailedRecipient($address->getAddress()); $this->reset(); } } $total = count($to) + count($cc) + count($list->getBcc()); $send_event->setNumSent($sent); $this->notifyListeners($send_event, "SendListener"); if (!$has_return_path) $message->setReturnPath(""); if (!$has_from) $message->setFrom(""); if (!$has_to) $message->setTo(""); if (!$has_reply_to) $message->setReplyTo(null); if (!$has_cc) $message->setCc(null); if (!$has_bcc) $message->setBcc(null); if (!$has_message_id) $message->setId(null); if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add("Message sent to " . $sent . "/" . $total . " recipients", Swift_Log::NORMAL); return $sent; } /** * Send a message to a batch of recipients. * Unlike send() this method ignores Cc and Bcc recipients and does not reveal every recipients' address in the headers * @param Swift_Message The message to send (leave out the recipient headers unless you are deliberately overriding them) * @param Swift_RecipientList The addresses to send to * @param Swift_Address The address the mail is from (sender) * @return int The number of successful recipients */ public function batchSend(Swift_Message $message, Swift_RecipientList $to, $from) { $batch = new Swift_BatchMailer($this); return $batch->send($message, $to, $from); } } ./kohana/system/vendor/swift/EasySwift.php0000644000175000017500000006566610660517650020437 0ustar tokkeetokkee * @package EasySwift * @version 1.0.3 * @license GNU Lesser General Public License */ require_once dirname(__FILE__) . "/Swift/ClassLoader.php"; Swift_ClassLoader::load("Swift"); Swift_ClassLoader::load("Swift_Connection_SMTP"); Swift_ClassLoader::load("Swift_Connection_Sendmail"); //Some constants for backwards compatibility with v2 code if (!defined("SWIFT_TLS")) define("SWIFT_TLS", Swift_Connection_SMTP::ENC_TLS); if (!defined("SWIFT_SSL")) define("SWIFT_SSL", Swift_Connection_SMTP::ENC_SSL); if (!defined("SWIFT_OPEN")) define("SWIFT_OPEN", Swift_Connection_SMTP::ENC_OFF); if (!defined("SWIFT_SECURE_PORT")) define("SWIFT_SECURE_PORT", Swift_Connection_SMTP::PORT_SECURE); if (!defined("SWIFT_DEFAULT_PORT")) define("SWIFT_DEFAULT_PORT", Swift_Connection_SMTP::PORT_DEFAULT); /** * EasySwift: Facade for Swift Mailer Version 3. * Provides (most of) the API from older versions of Swift, wrapped around the new version 3 API. * Due to the popularity of the new API, EasySwift will not be around indefinitely. * @package EasySwift * @author Chris Corbyn * @deprecated */ class EasySwift { /** * The instance of Swift this class wrappers * @var Swift */ public $swift = null; /** * This value becomes set to true when Swift fails * @var boolean */ public $failed = false; /** * The number of loaded plugins * @var int */ protected $pluginCount = 0; /** * An instance of Swift_Message * @var Swift_Message */ public $message = null; /** * An address list to send to (Cc, Bcc, To..) * @var Swift_RecipientList */ public $recipients = null; /** * If all recipients should get the same copy of the message, including headers * This is already implied if any Cc or Bcc recipients are set * @var boolean */ protected $exactCopy = false; /** * If EasySwift should get rid of the message and recipients once it's done sending * @var boolean */ protected $autoFlush = true; /** * A list of the IDs of all parts added to the message * @var array */ protected $partIds = array(); /** * A list of all the IDs of the attachments add to the message * @var array */ protected $attachmentIds = array(); /** * The last response received from the server * @var string */ public $lastResponse = ""; /** * The 3 digit code in the last response received from the server * @var int */ public $responseCode = 0; /** * The list of errors handled at runtime * @var array */ public $errors = array(); /** * The last error received * @var string */ public $lastError = null; /** * Constructor * @param Swift_Connection The connection to use * @param string The domain name of this server (not the SMTP server) */ public function __construct(Swift_Connection $connection, $domain=null) { try { $this->swift = new Swift($connection, $domain, Swift::ENABLE_LOGGING); Swift_ClassLoader::load("Swift_Plugin_EasySwiftResponseTracker"); $this->swift->attachPlugin(new Swift_Plugin_EasySwiftResponseTracker($this), "_ResponseTracker"); } catch (Swift_ConnectionException $e) { $this->failed = true; $this->setError("The connection failed to start. An exception was thrown:
    " . $e->getMessage()); } $this->newMessage(); $this->newRecipientList(); } /** * Set an error message * @param string Error message */ public function setError($msg) { $this->errors[] = ($this->lastError = $msg); } /** * Get the full list of errors * @return array */ public function getErrors() { return $this->errors; } /** * Get the last error that occured * @return string */ public function getLastError() { return $this->lastError; } /** * Clear the current list of errors */ public function flushErrors() { $this->errors = null; $this->errors = array(); } /** * Turn automatic flsuhing on or off. * This in ON by deault. It removes the message and all parts after sending. * @param boolean */ public function autoFlush($flush=true) { $this->autoFlush = $flush; } /** * Set the maximum size of the log * @param int */ public function setMaxLogSize($size) { $log = Swift_LogContainer::getLog(); $log->setMaxSize($size); } /** * Turn logging on or off (saves memory) * @param boolean */ public function useLogging($use=true) { $log = Swift_LogContainer::getLog(); if ($use) $log->setLogLevel(Swift_Log::LOG_NETWORK); else $log->setLogLevel(Swift_Log::LOG_NOTHING); } /** * Enable line resizing (on 1000 by default) * @param int The number of characters allowed on a line */ public function useAutoLineResizing($size=1000) { $this->message->setLineWrap($size); } /** * Dump the log contents * @deprecated */ public function getTransactions() { return $this->dumpLog(); } /** * Dump the contents of the log to the browser * The log contains some < and > characters so you may need to view source * Note that this method dumps data to the browser, it does NOT return anything. */ public function dumpLog() { $log = Swift_LogContainer::getLog(); $log->dump(); } /** * This method should be called if you do not wish to send messages in batch mode (i.e. if all recipients should see each others' addresses) * @param boolean If this mode should be used */ public function useExactCopy($bool=true) { $this->exactCopy = $bool; } /** * Reset the current message and start a fresh one */ public function newMessage($msg=false) { if (!$msg) $msg = new Swift_Message(); $this->message = $msg; $this->partIds = array(); $this->attachmentIds = array(); } /** * Clear out all message parts * @return boolean */ public function flushParts() { $success = true; foreach ($this->partIds as $id) { try { $this->message->detach($id); } catch (Swift_Message_MimeException $e) { $success = false; $this->setError("A MIME part failed to detach due to the error:
    " . $e->getMessage()); } } $this->partIds = array(); return $success; } /** * Clear out all attachments * @return boolean */ public function flushAttachments() { $success = true; foreach ($this->attachmentIds as $id) { try { $this->message->detach($id); } catch (Swift_Message_MimeException $e) { $success = false; $this->setError("An attachment failed to detach due to the error:
    " . $e->getMessage()); } } $this->attachmentIds = array(); return $success; } /** * Clear out all message headers * @deprecated */ public function flushHeaders() { $this->newMessage(); } /** * Reset the current list of recipients and start a new one */ public function newRecipientList($list=false) { if (!$list) $list = new Swift_RecipientList(); $this->recipients = $list; } /** * Check if Swift has failed or not * This facade stops processing if so * @return boolean */ public function hasFailed() { return $this->failed; } /** * Check if the current connection is open or not * @return boolean */ public function isConnected() { return (($this->swift !== null) && $this->swift->connection->isAlive()); } /** * Connect to the MTA if not already connected */ public function connect() { if (!$this->isConnected()) { try { $this->swift->connect(); return true; } catch (Swift_ConnectionException $e) { $this->failed = true; $this->setError("Swift failed to run the connection process:
    " . $e->getMessage()); } } return false; } /** * Perform the SMTP greeting process (don't do this unless you understand why you're doing it) */ public function handshake() { $this->swift->handshake(); } /** * Close the connection to the MTA * @return boolean */ public function close() { if ($this->isConnected()) { try { $this->swift->disconnect(); return true; } catch (Swift_ConnectionException $e) { $this->setError("Disconnect failed:
    " . $e->getMessage()); } } return false; } /** * Send a command to Swift and get a response * @param string The command to send (leave of CRLF) * @return string */ public function command($command) { if (substr($command, -2) == "\r\n") $command = substr($command, 0, -2); try { $rs = $this->swift->command($command); return $rs->getString(); } catch (Swift_ConnectionException $e) { $this->setError("Command failed:
    " . $e->getMessage()); return false; } } /** * Add a new plugin to respond to events * @param Swift_Events_Listener The plugin to load * @param string The ID to identify the plugin by if needed * @return string The ID of the plugin */ public function loadPlugin(Swift_Events_Listener $plugin, $name=null) { $this->pluginCount++; if (!$name) $name = "p" . $this->pluginCount; $this->swift->attachPlugin($plugin, $name); return $name; } /** * Get a reference to the plugin identified by $name * @param string the ID of the plugin * @return Swift_Events_Listener */ public function getPlugin($name) { try { $plugin = $this->swift->getPlugin($name); return $plugin; } catch (Exception $e) { return null; } } /** * Remove the plugin identified by $name * @param string The ID of the plugin * @return boolean */ public function removePlugin($name) { try { $this->swift->removePlugin($name); return true; } catch (Exception $e) { return false; } } /** * Load in a new authentication mechanism for SMTP * This needn't be called since Swift will locate any available in Swift/Authenticator/*.php * @param Swift_Authenticator The authentication mechanism to load * @throws Exception If the wrong connection is used */ public function loadAuthenticator(Swift_Authenticator $auth) { if (method_exists($this->swift->connection, "attachAuthenticator")) { $this->swift->connection->attachAuthenticator($auth); } else throw new Exception("SMTP authentication cannot be used with connection class '" . get_class($this->connection) . "'. Swift_Connection_SMTP is needed"); } /** * Authenticate with SMTP authentication * @param string The SMTP username * @param string The SMTP password * @return boolean * @throws Exception If the wrong connection is used */ public function authenticate($username, $password) { if (method_exists($this->swift->connection, "runAuthenticators")) { try { $this->swift->connection->runAuthenticators($username, $password, $this->swift); return true; } catch (Swift_ConnectionException $e) { $this->setError("Authentication failed:
    " . $e->getMessage()); return false; } } else throw new Exception("SMTP authentication cannot be used with connection class '" . get_class($this->connection) . "'. Swift_Connection_SMTP is needed"); } /** * Turn a string representation of an email address into a Swift_Address object * @paramm string The email address * @return Swift_Address */ public function stringToAddress($string) { $name = null; $address = null; // Foo Bar // or: "Foo Bar" // or: Swift_ClassLoader::load("Swift_Message_Encoder"); if (preg_match("/^\\s*(\"?)(.*?)\\1 *<(" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . ")>\\s*\$/", $string, $matches)) { if (!empty($matches[2])) $name = $matches[2]; $address = $matches[3]; } elseif (preg_match("/^\\s*" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . "\\s*\$/", $string)) { $address = trim($string); } else return false; $swift_address = new Swift_Address($address, $name); return $swift_address; } /** * Set the encoding used in the message header * The encoding can be one of Q (quoted-printable) or B (base64) * @param string The encoding to use */ public function setHeaderEncoding($mode="B") { switch (strtoupper($mode)) { case "Q": case "QP": case "QUOTED-PRINTABLE": $this->message->headers->setEncoding("Q"); break; default: $this->message->headers->setEncoding("B"); } } /** * Set the return path address (where bounces go to) * @param mixed The address as a string or Swift_Address */ public function setReturnPath($address) { return $this->message->setReturnPath($address); } /** * Request for a read recipient to be sent to the reply-to address * @param boolean */ public function requestReadReceipt($request=true) { //$this->message->requestReadReceipt(true); } /** * Set the message priority * This is an integer between 1 (high) and 5 (low) * @param int The level of priority to use */ public function setPriority($priority) { $this->message->setPriority($priority); } /** * Get the return-path address as a string * @return string */ public function getReturnPath() { try { return $this->message->getReturnPath(); } catch (Swift_Message_MimeException $e) { return false; } } /** * Set the reply-to header * @param mixed The address replies come to. String, or Swift_Address, or an array of either. */ public function setReplyTo($address) { return $this->message->setReplyTo($address); } /** * Get the reply-to address(es) as an array of strings * @return array */ public function getReplyTo() { try { return $this->message->getReplyTo(); } catch (Swift_Message_MimeException $e) { return false; } } /** * Add To: recipients to the email * @param mixed To address(es) * @return boolean */ public function addTo($address) { return $this->addRecipients($address, "To"); } /** * Get an array of To addresses * This currently returns an array of Swift_Address objects and may be simplified to an array of strings in later versions * @return array */ public function getToAddresses() { return $this->recipients->getTo(); } /** * Clear out all To: recipients */ public function flushTo() { $this->recipients->flushTo(); } /** * Add Cc: recipients to the email * @param mixed Cc address(es) * @return boolean */ public function addCc($address) { return $this->addRecipients($address, "Cc"); } /** * Get an array of Cc addresses * This currently returns an array of Swift_Address objects and may be simplified to an array of strings in later versions * @return array */ public function getCcAddresses() { return $this->recipients->getCc(); } /** * Clear out all Cc: recipients */ public function flushCc() { $this->recipients->flushCc(); } /** * Add Bcc: recipients to the email * @param mixed Bcc address(es) * @return boolean */ public function addBcc($address) { return $this->addRecipients($address, "Bcc"); } /** * Get an array of Bcc addresses * This currently returns an array of Swift_Address objects and may be simplified to an array of strings in later versions * @return array */ public function getBccAddresses() { return $this->recipients->getBcc(); } /** * Clear out all Bcc: recipients */ public function flushBcc() { $this->recipients->flushBcc(); } /** * Add recipients to the email * @param mixed Address(es) * @param string Recipient type (To, Cc, Bcc) * @return boolean */ protected function addRecipients($address, $type) { if (!in_array($type, array("To", "Cc", "Bcc"))) return false; $method = "add" . $type; if ($address instanceof Swift_Address) { $this->recipients->$method($address); return true; } else { $added = 0; foreach ((array)$address as $addr) { if (is_array($addr)) { $addr = array_values($addr); if (count($addr) >= 2) { $this->recipients->$method($addr[0], $addr[1]); $added++; continue; } elseif (count($addr) == 1) $addr = $addr[0]; else continue; } if (is_string($addr)) { $addr = $this->stringToAddress($addr); $this->recipients->$method($addr); $added++; } } return ($added > 0); } } /** * Flush message, recipients and headers */ public function flush() { $this->newMessage(); $this->newRecipientList(); } /** * Get a list of any addresses which have failed since instantiation * @return array */ public function getFailedRecipients() { $log = Swift_LogContainer::getLog(); return $log->getFailedRecipients(); } /** * Set the multipart MIME warning message (only seen by old clients) * @param string The message to show */ public function setMimeWarning($text) { $this->message->setMimeWarning($text); } /** * Get the currently set MIME warning (seen by old clients) * @return string */ public function getMimeWarning() { return $this->message->getMimeWarning(); } /** * Set the charset of the charset to use in the message * @param string The charset (e.g. utf-8, iso-8859-1 etc) * @return boolean */ public function setCharset($charset) { try { $this->message->setCharset($charset); return true; } catch (Swift_Message_MimeException $e) { $this->setError("Unable to set the message charset:
    " . $e->getMessage()); return false; } } /** * Get the charset of the charset to use in the message * @return string */ public function getCharset() { return $this->message->getCharset(); } /** * Add a new MIME part to the message * @param mixed The part to add. If this is a string it's used as the body. If it's an instance of Swift_Message_Part it's used as the entire part * @param string Content-type, default text/plain * @param string The encoding used (default is to let Swift decide) * @param string The charset to use (default is to let swift decide) */ public function addPart($body, $type="text/plain", $encoding=null, $charset=null) { if ($body instanceof Swift_Message_Mime) { try { $this->partIds[] = $this->message->attach($body); } catch (Swift_Message_MimeException $e) { $this->setError("A MIME part failed to attach:
    " . $e->getMessage()); return false; } } else { try { $this->partIds[] = $this->message->attach(new Swift_Message_Part($body, $type, $encoding, $charset)); } catch (Swift_Message_MimeException $e) { $this->setError("A MIME part failed to attach:
    " . $e->getMessage()); return false; } } } /** * Add a new attachment to the message * @param mixed The attachment to add. If this is a string it's used as the file contents. If it's an instance of Swift_Message_Attachment it's used as the entire part. If it's an instance of Swift_File it's used as the contents. * @param string Filename, optional * @param string Content-type. Default application/octet-stream * @param string The encoding used (default is base64) * @return boolean */ public function addAttachment($data, $filename=null, $type="application/octet-stream", $encoding=null) { if ($data instanceof Swift_Message_Mime) { try { $this->attachmentIds[] = $this->message->attach($data); } catch (Swift_Message_MimeException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } } else { try { $this->attachmentIds[] = $this->message->attach(new Swift_Message_Attachment($data, $filename, $type, $encoding)); } catch (Swift_Message_MimeException $e) { $this->setError("An attachment failed to attach
    " . $e->getMessage()); return false; } catch (Swift_FileException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } } return true; } /** * Embed an image into the message and get the src attribute for HTML * Returns FALSE on failure * @param mixed The path to the image, a Swift_Message_Image object or a Swift_File object * @return string */ public function addImage($input) { $ret = false; if ($input instanceof Swift_Message_Image) { $ret = $this->message->attach($input); $this->attachmentIds[] = $ret; return $ret; } elseif ($input instanceof Swift_File) { try { $ret = $this->message->attach(new Swift_Message_Image($input)); $this->attachmentIds[] = $ret; return $ret; } catch (Swift_Message_MimeException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } catch (Swift_FileException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } } else { try { $ret = $this->message->attach(new Swift_Message_Image(new Swift_File($input))); $this->attachmentIds[] = $ret; return $ret; } catch (Swift_Message_MimeException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } catch (Swift_FileException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } } } /** * Embed an inline file into the message, such as a Image or MIDI file * @param mixed The file contents, Swift_File object or Swift_Message_EmbeddedFile object * @param string The content-type of the file, optional * @param string The filename to use, optional * @param string the Content-ID to use, optional * @return string */ public function embedFile($data, $type="application/octet-stream", $filename=null, $cid=null) { $ret = false; if ($data instanceof Swift_Message_EmbeddedFile) { $ret = $this->message->attach($data); $this->attachmentIds[] = $ret; return $ret; } elseif ($data instanceof Swift_File) { try { $ret = $this->message->attach(new Swift_Message_EmbeddedFile($data, $filename, $type, $cid)); $this->attachmentIds[] = $ret; return $ret; } catch (Swift_Message_MimeException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } catch (Swift_FileException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } } else { try { $ret = $this->message->attach(new Swift_Message_EmbeddedFile($data, $filename, $type, $cid)); $this->attachmentIds[] = $ret; return $ret; } catch (Swift_Message_MimeException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } catch (Swift_FileException $e) { $this->setError("An attachment failed to attach:
    " . $e->getMessage()); return false; } } } /** * Add headers to the message * @param string The message headers to append, separated by CRLF * @deprecated */ public function addHeaders($string) { //Split at the line ending only if it's not followed by LWSP (as in, a full header) $headers = preg_split("~\r?\n(?![ \t])~", $string); foreach ($headers as $header) { if (empty($header)) continue; //Get the bit before the colon $header_name = substr($header, 0, ($c_pos = strpos($header, ": "))); // ... and trim it away $header = substr($header, $c_pos+2); //Try splitting at "; " for attributes $attribute_pairs = preg_split("~\\s*;\\s+~", $header); //The value would always be right after the colon $header_value = $attribute_pairs[0]; $this->message->headers->set($header_name, $header_value); unset($attribute_pairs[0]); foreach ($attribute_pairs as $pair) { //Now try finding the attribute name, and it's value (removing quotes) if (preg_match("~^(.*?)=(\"?)(.*?)\\2\\s*\$~", $pair, $matches)) { try { $this->message->headers->setAttribute($header_name, $matches[1], $matches[3]); } catch (Swift_Message_MimeException $e) { $this->setError("There was a problem parsing or setting a header attribute:
    " . $e->getMessage()); //Ignored... it's EasySwift... C'mon ;) } } } } } /** * Set a header in the message * @param string The name of the header * @param string The value of the header (without attributes) * @see {addHeaderAttribute} */ public function setHeader($name, $value) { $this->message->headers->set($name, $value); } /** * Set an attribute in the message headers * For example charset in Content-Type: text/html; charset=utf-8 set by $swift->setHeaderAttribute("Content-Type", "charset", "utf-8") * @param string The name of the header * @param string The name of the attribute * @param string The value of the attribute */ public function setHeaderAttribute($name, $attribute, $value) { if ($this->message->headers->has($name)) $this->message->headers->setAttribute($name, $attribute, $value); } /** * Send an email to a number of recipients * Returns the number of successful recipients, or FALSE on failure * @param mixed The recipients to send to. One of string, array, 2-dimensional array or Swift_Address * @param mixed The address to send from. string or Swift_Address * @param string The message subject * @param string The message body, optional * @return int */ public function send($recipients, $from, $subject, $body=null) { $this->addTo($recipients); $sender = false; if (is_string($from)) $sender = $this->stringToAddress($from); elseif ($from instanceof Swift_Address) $sender = $from; if (!$sender) return false; $this->message->setSubject($subject); if ($body) $this->message->setBody($body); try { if (!$this->exactCopy && !$this->recipients->getCc() && !$this->recipients->getBcc()) { $sent = $this->swift->batchSend($this->message, $this->recipients, $sender); } else { $sent = $this->swift->send($this->message, $this->recipients, $sender); } if ($this->autoFlush) $this->flush(); return $sent; } catch (Swift_ConnectionException $e) { $this->setError("Sending failed:
    " . $e->getMessage()); return false; } } } ./kohana/system/vendor/Markdown.php0000644000175000017500000024171511160460317017127 0ustar tokkeetokkee # # Original Markdown # Copyright (c) 2004-2006 John Gruber # # define( 'MARKDOWN_VERSION', "1.0.1m" ); # Sat 21 Jun 2008 define( 'MARKDOWNEXTRA_VERSION', "1.2.3" ); # Wed 31 Dec 2008 # # Global default settings: # # Change to ">" for HTML output @define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />"); # Define the width of a tab for code blocks. @define( 'MARKDOWN_TAB_WIDTH', 4 ); # Optional title attribute for footnote links and backlinks. @define( 'MARKDOWN_FN_LINK_TITLE', "" ); @define( 'MARKDOWN_FN_BACKLINK_TITLE', "" ); # Optional class attribute for footnote links and backlinks. @define( 'MARKDOWN_FN_LINK_CLASS', "" ); @define( 'MARKDOWN_FN_BACKLINK_CLASS', "" ); # # WordPress settings: # # Change to false to remove Markdown from posts and/or comments. @define( 'MARKDOWN_WP_POSTS', true ); @define( 'MARKDOWN_WP_COMMENTS', true ); ### Standard Function Interface ### @define( 'MARKDOWN_PARSER_CLASS', 'MarkdownExtra_Parser' ); function Markdown($text) { # # Initialize the parser and return the result of its transform method. # # Setup static parser variable. static $parser; if (!isset($parser)) { $parser_class = MARKDOWN_PARSER_CLASS; $parser = new $parser_class; } # Transform text using parser. return $parser->transform($text); } ### WordPress Plugin Interface ### /* Plugin Name: Markdown Extra Plugin URI: http://www.michelf.com/projects/php-markdown/ Description: Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More... Version: 1.2.2 Author: Michel Fortin Author URI: http://www.michelf.com/ */ if (isset($wp_version)) { # More details about how it works here: # # Post content and excerpts # - Remove WordPress paragraph generator. # - Run Markdown on excerpt, then remove all tags. # - Add paragraph tag around the excerpt, but remove it for the excerpt rss. if (MARKDOWN_WP_POSTS) { remove_filter('the_content', 'wpautop'); remove_filter('the_content_rss', 'wpautop'); remove_filter('the_excerpt', 'wpautop'); add_filter('the_content', 'mdwp_MarkdownPost', 6); add_filter('the_content_rss', 'mdwp_MarkdownPost', 6); add_filter('get_the_excerpt', 'mdwp_MarkdownPost', 6); add_filter('get_the_excerpt', 'trim', 7); add_filter('the_excerpt', 'mdwp_add_p'); add_filter('the_excerpt_rss', 'mdwp_strip_p'); remove_filter('content_save_pre', 'balanceTags', 50); remove_filter('excerpt_save_pre', 'balanceTags', 50); add_filter('the_content', 'balanceTags', 50); add_filter('get_the_excerpt', 'balanceTags', 9); } # Add a footnote id prefix to posts when inside a loop. function mdwp_MarkdownPost($text) { static $parser; if (!$parser) { $parser_class = MARKDOWN_PARSER_CLASS; $parser = new $parser_class; } if (is_single() || is_page() || is_feed()) { $parser->fn_id_prefix = ""; } else { $parser->fn_id_prefix = get_the_ID() . "."; } return $parser->transform($text); } # Comments # - Remove WordPress paragraph generator. # - Remove WordPress auto-link generator. # - Scramble important tags before passing them to the kses filter. # - Run Markdown on excerpt then remove paragraph tags. if (MARKDOWN_WP_COMMENTS) { remove_filter('comment_text', 'wpautop', 30); remove_filter('comment_text', 'make_clickable'); add_filter('pre_comment_content', 'Markdown', 6); add_filter('pre_comment_content', 'mdwp_hide_tags', 8); add_filter('pre_comment_content', 'mdwp_show_tags', 12); add_filter('get_comment_text', 'Markdown', 6); add_filter('get_comment_excerpt', 'Markdown', 6); add_filter('get_comment_excerpt', 'mdwp_strip_p', 7); global $mdwp_hidden_tags, $mdwp_placeholders; $mdwp_hidden_tags = explode(' ', '

     
  • '); $mdwp_placeholders = explode(' ', str_rot13( 'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '. 'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli')); } function mdwp_add_p($text) { if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) { $text = '

    '.$text.'

    '; $text = preg_replace('{\n{2,}}', "

    \n\n

    ", $text); } return $text; } function mdwp_strip_p($t) { return preg_replace('{}i', '', $t); } function mdwp_hide_tags($text) { global $mdwp_hidden_tags, $mdwp_placeholders; return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text); } function mdwp_show_tags($text) { global $mdwp_hidden_tags, $mdwp_placeholders; return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text); } } ### bBlog Plugin Info ### function identify_modifier_markdown() { return array( 'name' => 'markdown', 'type' => 'modifier', 'nicename' => 'PHP Markdown Extra', 'description' => 'A text-to-HTML conversion tool for web writers', 'authors' => 'Michel Fortin and John Gruber', 'licence' => 'GPL', 'version' => MARKDOWNEXTRA_VERSION, 'help' => 'Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More...', ); } ### Smarty Modifier Interface ### function smarty_modifier_markdown($text) { return Markdown($text); } ### Textile Compatibility Mode ### # Rename this file to "classTextile.php" and it can replace Textile everywhere. if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) { # Try to include PHP SmartyPants. Should be in the same directory. @include_once 'smartypants.php'; # Fake Textile class. It calls Markdown instead. class Textile { function TextileThis($text, $lite='', $encode='') { if ($lite == '' && $encode == '') $text = Markdown($text); if (function_exists('SmartyPants')) $text = SmartyPants($text); return $text; } # Fake restricted version: restrictions are not supported for now. function TextileRestricted($text, $lite='', $noimage='') { return $this->TextileThis($text, $lite); } # Workaround to ensure compatibility with TextPattern 4.0.3. function blockLite($text) { return $text; } } } # # Markdown Parser Class # class Markdown_Parser { # Regex to match balanced [brackets]. # Needed to insert a maximum bracked depth while converting to PHP. var $nested_brackets_depth = 6; var $nested_brackets_re; var $nested_url_parenthesis_depth = 4; var $nested_url_parenthesis_re; # Table of hash values for escaped characters: var $escape_chars = '\`*_{}[]()>#+-.!'; var $escape_chars_re; # Change to ">" for HTML output. var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX; var $tab_width = MARKDOWN_TAB_WIDTH; # Change to `true` to disallow markup or entities. var $no_markup = false; var $no_entities = false; # Predefined urls and titles for reference links and images. var $predef_urls = array(); var $predef_titles = array(); function Markdown_Parser() { # # Constructor function. Initialize appropriate member variables. # $this->_initDetab(); $this->prepareItalicsAndBold(); $this->nested_brackets_re = str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). str_repeat('\])*', $this->nested_brackets_depth); $this->nested_url_parenthesis_re = str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; # Sort document, block, and span gamut in ascendent priority order. asort($this->document_gamut); asort($this->block_gamut); asort($this->span_gamut); } # Internal hashes used during transformation. var $urls = array(); var $titles = array(); var $html_hashes = array(); # Status flag to avoid invalid nesting. var $in_anchor = false; function setup() { # # Called before the transformation process starts to setup parser # states. # # Clear global hashes. $this->urls = $this->predef_urls; $this->titles = $this->predef_titles; $this->html_hashes = array(); $in_anchor = false; } function teardown() { # # Called after the transformation process to clear any variable # which may be taking up memory unnecessarly. # $this->urls = array(); $this->titles = array(); $this->html_hashes = array(); } function transform($text) { # # Main function. Performs some preprocessing on the input text # and pass it through the document gamut. # $this->setup(); # Remove UTF-8 BOM and marker character in input, if present. $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); # Standardize line endings: # DOS to Unix and Mac to Unix $text = preg_replace('{\r\n?}', "\n", $text); # Make sure $text ends with a couple of newlines: $text .= "\n\n"; # Convert all tabs to spaces. $text = $this->detab($text); # Turn block-level HTML blocks into hash entries $text = $this->hashHTMLBlocks($text); # Strip any lines consisting only of spaces and tabs. # This makes subsequent regexen easier to write, because we can # match consecutive blank lines with /\n+/ instead of something # contorted like /[ ]*\n+/ . $text = preg_replace('/^[ ]+$/m', '', $text); # Run document gamut methods. foreach ($this->document_gamut as $method => $priority) { $text = $this->$method($text); } $this->teardown(); return $text . "\n"; } var $document_gamut = array( # Strip link definitions, store in hashes. "stripLinkDefinitions" => 20, "runBasicBlockGamut" => 30, ); function stripLinkDefinitions($text) { # # Strips link definitions from text, stores the URLs and titles in # hash references. # $less_than_tab = $this->tab_width - 1; # Link defs are in the form: ^[id]: url "optional title" $text = preg_replace_callback('{ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 [ ]* \n? # maybe *one* newline [ ]* ? # url = $2 [ ]* \n? # maybe one newline [ ]* (?: (?<=\s) # lookbehind for whitespace ["(] (.*?) # title = $3 [")] [ ]* )? # title is optional (?:\n+|\Z) }xm', array(&$this, '_stripLinkDefinitions_callback'), $text); return $text; } function _stripLinkDefinitions_callback($matches) { $link_id = strtolower($matches[1]); $this->urls[$link_id] = $matches[2]; $this->titles[$link_id] =& $matches[3]; return ''; # String that will replace the block } function hashHTMLBlocks($text) { if ($this->no_markup) return $text; $less_than_tab = $this->tab_width - 1; # Hashify HTML blocks: # We only want to do this for block-level HTML tags, such as headers, # lists, and tables. That's because we still want to wrap

    s around # "paragraphs" that are wrapped in non-block-level tags, such as anchors, # phrase emphasis, and spans. The list of tags we're looking for is # hard-coded: # # * List "a" is made of tags which can be both inline or block-level. # These will be treated block-level when the start tag is alone on # its line, otherwise they're not matched here and will be taken as # inline later. # * List "b" is made of tags which are always block-level; # $block_tags_a_re = 'ins|del'; $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. 'script|noscript|form|fieldset|iframe|math'; # Regular expression for the content of a block tag. $nested_tags_level = 4; $attr = ' (?> # optional tag attributes \s # starts with whitespace (?> [^>"/]+ # text outside quotes | /+(?!>) # slash not followed by ">" | "[^"]*" # text inside double quotes (tolerate ">") | \'[^\']*\' # text inside single quotes (tolerate ">") )* )? '; $content = str_repeat(' (?> [^<]+ # content without tag | <\2 # nested opening tag '.$attr.' # attributes (?> /> | >', $nested_tags_level). # end of opening tag '.*?'. # last level nested tag content str_repeat(' # closing nested tag ) | <(?!/\2\s*> # other tags with a different name ) )*', $nested_tags_level); $content2 = str_replace('\2', '\3', $content); # First, look for nested blocks, e.g.: #

    #
    # tags for inner block must be indented. #
    #
    # # The outermost tags must start at the left margin for this to match, and # the inner nested divs must be indented. # We need to do this before the next, more liberal match, because the next # match will start at the first `
    ` and stop at the first `
    `. $text = preg_replace_callback('{(?> (?> (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in $1 # Match from `\n` to `\n`, handling nested tags # in between. [ ]{0,'.$less_than_tab.'} <('.$block_tags_b_re.')# start tag = $2 '.$attr.'> # attributes followed by > and \n '.$content.' # content, support nesting # the matching end tag [ ]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document | # Special version for tags of group a. [ ]{0,'.$less_than_tab.'} <('.$block_tags_a_re.')# start tag = $3 '.$attr.'>[ ]*\n # attributes followed by > '.$content2.' # content, support nesting # the matching end tag [ ]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document | # Special case just for
    . It was easier to make a special # case than to make the other regex more complicated. [ ]{0,'.$less_than_tab.'} <(hr) # start tag = $2 '.$attr.' # attributes /?> # the matching end tag [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document | # Special case for standalone HTML comments: [ ]{0,'.$less_than_tab.'} (?s: ) [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document | # PHP and ASP-style processor instructions ( ) [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) )}Sxmi', array(&$this, '_hashHTMLBlocks_callback'), $text); return $text; } function _hashHTMLBlocks_callback($matches) { $text = $matches[1]; $key = $this->hashBlock($text); return "\n\n$key\n\n"; } function hashPart($text, $boundary = 'X') { # # Called whenever a tag must be hashed when a function insert an atomic # element in the text stream. Passing $text to through this function gives # a unique text-token which will be reverted back when calling unhash. # # The $boundary argument specify what character should be used to surround # the token. By convension, "B" is used for block elements that needs not # to be wrapped into paragraph tags at the end, ":" is used for elements # that are word separators and "X" is used in the general case. # # Swap back any tag hash found in $text so we do not have to `unhash` # multiple times at the end. $text = $this->unhash($text); # Then hash the block. static $i = 0; $key = "$boundary\x1A" . ++$i . $boundary; $this->html_hashes[$key] = $text; return $key; # String that will replace the tag. } function hashBlock($text) { # # Shortcut function for hashPart with block-level boundaries. # return $this->hashPart($text, 'B'); } var $block_gamut = array( # # These are all the transformations that form block-level # tags like paragraphs, headers, and list items. # "doHeaders" => 10, "doHorizontalRules" => 20, "doLists" => 40, "doCodeBlocks" => 50, "doBlockQuotes" => 60, ); function runBlockGamut($text) { # # Run block gamut tranformations. # # We need to escape raw HTML in Markdown source before doing anything # else. This need to be done for each block, and not only at the # begining in the Markdown function since hashed blocks can be part of # list items and could have been indented. Indented blocks would have # been seen as a code block in a previous pass of hashHTMLBlocks. $text = $this->hashHTMLBlocks($text); return $this->runBasicBlockGamut($text); } function runBasicBlockGamut($text) { # # Run block gamut tranformations, without hashing HTML blocks. This is # useful when HTML blocks are known to be already hashed, like in the first # whole-document pass. # foreach ($this->block_gamut as $method => $priority) { $text = $this->$method($text); } # Finally form paragraph and restore hashed blocks. $text = $this->formParagraphs($text); return $text; } function doHorizontalRules($text) { # Do Horizontal Rules: return preg_replace( '{ ^[ ]{0,3} # Leading space ([-*_]) # $1: First marker (?> # Repeated marker group [ ]{0,2} # Zero, one, or two spaces. \1 # Marker character ){2,} # Group repeated at least twice [ ]* # Tailing spaces $ # End of line. }mx', "\n".$this->hashBlock("empty_element_suffix")."\n", $text); } var $span_gamut = array( # # These are all the transformations that occur *within* block-level # tags like paragraphs, headers, and list items. # # Process character escapes, code spans, and inline HTML # in one shot. "parseSpan" => -30, # Process anchor and image tags. Images must come first, # because ![foo][f] looks like an anchor. "doImages" => 10, "doAnchors" => 20, # Make links out of things like `` # Must come after doAnchors, because you can use < and > # delimiters in inline links like [this](). "doAutoLinks" => 30, "encodeAmpsAndAngles" => 40, "doItalicsAndBold" => 50, "doHardBreaks" => 60, ); function runSpanGamut($text) { # # Run span gamut tranformations. # foreach ($this->span_gamut as $method => $priority) { $text = $this->$method($text); } return $text; } function doHardBreaks($text) { # Do hard breaks: return preg_replace_callback('/ {2,}\n/', array(&$this, '_doHardBreaks_callback'), $text); } function _doHardBreaks_callback($matches) { return $this->hashPart("empty_element_suffix\n"); } function doAnchors($text) { # # Turn Markdown link shortcuts into XHTML tags. # if ($this->in_anchor) return $text; $this->in_anchor = true; # # First, handle reference-style links: [link text] [id] # $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ ('.$this->nested_brackets_re.') # link text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }xs', array(&$this, '_doAnchors_reference_callback'), $text); # # Next, inline-style links: [link text](url "optional title") # $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ ('.$this->nested_brackets_re.') # link text = $2 \] \( # literal paren [ ]* (?: <(\S*)> # href = $3 | ('.$this->nested_url_parenthesis_re.') # href = $4 ) [ ]* ( # $5 ([\'"]) # quote char = $6 (.*?) # Title = $7 \6 # matching quote [ ]* # ignore any spaces/tabs between closing quote and ) )? # title is optional \) ) }xs', array(&$this, '_DoAnchors_inline_callback'), $text); # # Last, handle reference-style shortcuts: [link text] # These must come last in case you've also got [link test][1] # or [link test](/foo) # // $text = preg_replace_callback('{ // ( # wrap whole match in $1 // \[ // ([^\[\]]+) # link text = $2; can\'t contain [ or ] // \] // ) // }xs', // array(&$this, '_doAnchors_reference_callback'), $text); $this->in_anchor = false; return $text; } function _doAnchors_reference_callback($matches) { $whole_match = $matches[1]; $link_text = $matches[2]; $link_id =& $matches[3]; if ($link_id == "") { # for shortcut links like [this][] or [this]. $link_id = $link_text; } # lower-case and turn embedded newlines into spaces $link_id = strtolower($link_id); $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); if (isset($this->urls[$link_id])) { $url = $this->urls[$link_id]; $url = $this->encodeAttribute($url); $result = "titles[$link_id] ) ) { $title = $this->titles[$link_id]; $title = $this->encodeAttribute($title); $result .= " title=\"$title\""; } $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; $result = $this->hashPart($result); } else { $result = $whole_match; } return $result; } function _doAnchors_inline_callback($matches) { $whole_match = $matches[1]; $link_text = $this->runSpanGamut($matches[2]); $url = $matches[3] == '' ? $matches[4] : $matches[3]; $title =& $matches[7]; $url = $this->encodeAttribute($url); $result = "encodeAttribute($title); $result .= " title=\"$title\""; } $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; return $this->hashPart($result); } function doImages($text) { # # Turn Markdown image shortcuts into tags. # # # First, handle reference-style labeled images: ![alt text][id] # $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ ('.$this->nested_brackets_re.') # alt text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }xs', array(&$this, '_doImages_reference_callback'), $text); # # Next, handle inline images: ![alt text](url "optional title") # Don't forget: encode * and _ # $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ ('.$this->nested_brackets_re.') # alt text = $2 \] \s? # One optional whitespace character \( # literal paren [ ]* (?: <(\S*)> # src url = $3 | ('.$this->nested_url_parenthesis_re.') # src url = $4 ) [ ]* ( # $5 ([\'"]) # quote char = $6 (.*?) # title = $7 \6 # matching quote [ ]* )? # title is optional \) ) }xs', array(&$this, '_doImages_inline_callback'), $text); return $text; } function _doImages_reference_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; $link_id = strtolower($matches[3]); if ($link_id == "") { $link_id = strtolower($alt_text); # for shortcut links like ![this][]. } $alt_text = $this->encodeAttribute($alt_text); if (isset($this->urls[$link_id])) { $url = $this->encodeAttribute($this->urls[$link_id]); $result = "\"$alt_text\"";titles[$link_id])) { $title = $this->titles[$link_id]; $title = $this->encodeAttribute($title); $result .= " title=\"$title\""; } $result .= $this->empty_element_suffix; $result = $this->hashPart($result); } else { # If there's no such link ID, leave intact: $result = $whole_match; } return $result; } function _doImages_inline_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; $url = $matches[3] == '' ? $matches[4] : $matches[3]; $title =& $matches[7]; $alt_text = $this->encodeAttribute($alt_text); $url = $this->encodeAttribute($url); $result = "\"$alt_text\"";encodeAttribute($title); $result .= " title=\"$title\""; # $title already quoted } $result .= $this->empty_element_suffix; return $this->hashPart($result); } function doHeaders($text) { # Setext-style headers: # Header 1 # ======== # # Header 2 # -------- # $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', array(&$this, '_doHeaders_callback_setext'), $text); # atx-style headers: # # Header 1 # ## Header 2 # ## Header 2 with closing hashes ## # ... # ###### Header 6 # $text = preg_replace_callback('{ ^(\#{1,6}) # $1 = string of #\'s [ ]* (.+?) # $2 = Header text [ ]* \#* # optional closing #\'s (not counted) \n+ }xm', array(&$this, '_doHeaders_callback_atx'), $text); return $text; } function _doHeaders_callback_setext($matches) { # Terrible hack to check we haven't found an empty list item. if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) return $matches[0]; $level = $matches[2]{0} == '=' ? 1 : 2; $block = "".$this->runSpanGamut($matches[1]).""; return "\n" . $this->hashBlock($block) . "\n\n"; } function _doHeaders_callback_atx($matches) { $level = strlen($matches[1]); $block = "".$this->runSpanGamut($matches[2]).""; return "\n" . $this->hashBlock($block) . "\n\n"; } function doLists($text) { # # Form HTML ordered (numbered) and unordered (bulleted) lists. # $less_than_tab = $this->tab_width - 1; # Re-usable patterns to match list item bullets and number markers: $marker_ul_re = '[*+-]'; $marker_ol_re = '\d+[.]'; $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; $markers_relist = array($marker_ul_re, $marker_ol_re); foreach ($markers_relist as $marker_re) { # Re-usable pattern to match any entirel ul or ol list: $whole_list_re = ' ( # $1 = whole list ( # $2 [ ]{0,'.$less_than_tab.'} ('.$marker_re.') # $3 = first list item marker [ ]+ ) (?s:.+?) ( # $4 \z | \n{2,} (?=\S) (?! # Negative lookahead for another list item marker [ ]* '.$marker_re.'[ ]+ ) ) ) '; // mx # We use a different prefix before nested lists than top-level lists. # See extended comment in _ProcessListItems(). if ($this->list_level) { $text = preg_replace_callback('{ ^ '.$whole_list_re.' }mx', array(&$this, '_doLists_callback'), $text); } else { $text = preg_replace_callback('{ (?:(?<=\n)\n|\A\n?) # Must eat the newline '.$whole_list_re.' }mx', array(&$this, '_doLists_callback'), $text); } } return $text; } function _doLists_callback($matches) { # Re-usable patterns to match list item bullets and number markers: $marker_ul_re = '[*+-]'; $marker_ol_re = '\d+[.]'; $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; $list = $matches[1]; $list_type = preg_match("/$marker_ul_re/", $matches[3]) ? "ul" : "ol"; $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); $list .= "\n"; $result = $this->processListItems($list, $marker_any_re); $result = $this->hashBlock("<$list_type>\n" . $result . ""); return "\n". $result ."\n\n"; } var $list_level = 0; function processListItems($list_str, $marker_any_re) { # # Process the contents of a single ordered or unordered list, splitting it # into individual list items. # # The $this->list_level global keeps track of when we're inside a list. # Each time we enter a list, we increment it; when we leave a list, # we decrement. If it's zero, we're not in a list anymore. # # We do this because when we're not inside a list, we want to treat # something like this: # # I recommend upgrading to version # 8. Oops, now this line is treated # as a sub-list. # # As a single paragraph, despite the fact that the second line starts # with a digit-period-space sequence. # # Whereas when we're inside a list (or sub-list), that line will be # treated as the start of a sub-list. What a kludge, huh? This is # an aspect of Markdown's syntax that's hard to parse perfectly # without resorting to mind-reading. Perhaps the solution is to # change the syntax rules such that sub-lists must start with a # starting cardinal number; e.g. "1." or "a.". $this->list_level++; # trim trailing blank lines: $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); $list_str = preg_replace_callback('{ (\n)? # leading line = $1 (^[ ]*) # leading whitespace = $2 ('.$marker_any_re.' # list marker and space = $3 (?:[ ]+|(?=\n)) # space only required if item is not empty ) ((?s:.*?)) # list item text = $4 (?:(\n+(?=\n))|\n) # tailing blank line = $5 (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) }xm', array(&$this, '_processListItems_callback'), $list_str); $this->list_level--; return $list_str; } function _processListItems_callback($matches) { $item = $matches[4]; $leading_line =& $matches[1]; $leading_space =& $matches[2]; $marker_space = $matches[3]; $tailing_blank_line =& $matches[5]; if ($leading_line || $tailing_blank_line || preg_match('/\n{2,}/', $item)) { # Replace marker with the appropriate whitespace indentation $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; $item = $this->runBlockGamut($this->outdent($item)."\n"); } else { # Recursion for sub-lists: $item = $this->doLists($this->outdent($item)); $item = preg_replace('/\n+$/', '', $item); $item = $this->runSpanGamut($item); } return "
  • " . $item . "
  • \n"; } function doCodeBlocks($text) { # # Process Markdown `
    ` blocks.
    	#
    		$text = preg_replace_callback('{
    				(?:\n\n|\A\n?)
    				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    				  (?>
    					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
    					.*\n+
    				  )+
    				)
    				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
    			}xm',
    			array(&$this, '_doCodeBlocks_callback'), $text);
    
    		return $text;
    	}
    	function _doCodeBlocks_callback($matches) {
    		$codeblock = $matches[1];
    
    		$codeblock = $this->outdent($codeblock);
    		$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    
    		# trim leading newlines and trailing newlines
    		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
    
    		$codeblock = "
    $codeblock\n
    "; return "\n\n".$this->hashBlock($codeblock)."\n\n"; } function makeCodeSpan($code) { # # Create a code span markup for $code. Called from handleSpanToken. # $code = htmlspecialchars(trim($code), ENT_NOQUOTES); return $this->hashPart("$code"); } var $em_relist = array( '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(?em_relist as $em => $em_re) { foreach ($this->strong_relist as $strong => $strong_re) { # Construct list of allowed token expressions. $token_relist = array(); if (isset($this->em_strong_relist["$em$strong"])) { $token_relist[] = $this->em_strong_relist["$em$strong"]; } $token_relist[] = $em_re; $token_relist[] = $strong_re; # Construct master expression from list. $token_re = '{('. implode('|', $token_relist) .')}'; $this->em_strong_prepared_relist["$em$strong"] = $token_re; } } } function doItalicsAndBold($text) { $token_stack = array(''); $text_stack = array(''); $em = ''; $strong = ''; $tree_char_em = false; while (1) { # # Get prepared regular expression for seraching emphasis tokens # in current context. # $token_re = $this->em_strong_prepared_relist["$em$strong"]; # # Each loop iteration seach for the next emphasis token. # Each token is then passed to handleSpanToken. # $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); $text_stack[0] .= $parts[0]; $token =& $parts[1]; $text =& $parts[2]; if (empty($token)) { # Reached end of text span: empty stack without emitting. # any more emphasis. while ($token_stack[0]) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); } break; } $token_len = strlen($token); if ($tree_char_em) { # Reached closing marker while inside a three-char emphasis. if ($token_len == 3) { # Three-char closing marker, close em and strong. array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); $span = "$span"; $text_stack[0] .= $this->hashPart($span); $em = ''; $strong = ''; } else { # Other closing marker: close one em or strong and # change current token state to match the other $token_stack[0] = str_repeat($token{0}, 3-$token_len); $tag = $token_len == 2 ? "strong" : "em"; $span = $text_stack[0]; $span = $this->runSpanGamut($span); $span = "<$tag>$span"; $text_stack[0] = $this->hashPart($span); $$tag = ''; # $$tag stands for $em or $strong } $tree_char_em = false; } else if ($token_len == 3) { if ($em) { # Reached closing marker for both em and strong. # Closing strong marker: for ($i = 0; $i < 2; ++$i) { $shifted_token = array_shift($token_stack); $tag = strlen($shifted_token) == 2 ? "strong" : "em"; $span = array_shift($text_stack); $span = $this->runSpanGamut($span); $span = "<$tag>$span"; $text_stack[0] .= $this->hashPart($span); $$tag = ''; # $$tag stands for $em or $strong } } else { # Reached opening three-char emphasis marker. Push on token # stack; will be handled by the special condition above. $em = $token{0}; $strong = "$em$em"; array_unshift($token_stack, $token); array_unshift($text_stack, ''); $tree_char_em = true; } } else if ($token_len == 2) { if ($strong) { # Unwind any dangling emphasis marker: if (strlen($token_stack[0]) == 1) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); } # Closing strong marker: array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); $span = "$span"; $text_stack[0] .= $this->hashPart($span); $strong = ''; } else { array_unshift($token_stack, $token); array_unshift($text_stack, ''); $strong = $token; } } else { # Here $token_len == 1 if ($em) { if (strlen($token_stack[0]) == 1) { # Closing emphasis marker: array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); $span = "$span"; $text_stack[0] .= $this->hashPart($span); $em = ''; } else { $text_stack[0] .= $token; } } else { array_unshift($token_stack, $token); array_unshift($text_stack, ''); $em = $token; } } } return $text_stack[0]; } function doBlockQuotes($text) { $text = preg_replace_callback('/ ( # Wrap whole match in $1 (?> ^[ ]*>[ ]? # ">" at the start of a line .+\n # rest of the first line (.+\n)* # subsequent consecutive lines \n* # blanks )+ ) /xm', array(&$this, '_doBlockQuotes_callback'), $text); return $text; } function _doBlockQuotes_callback($matches) { $bq = $matches[1]; # trim one level of quoting - trim whitespace-only lines $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); $bq = $this->runBlockGamut($bq); # recurse $bq = preg_replace('/^/m', " ", $bq); # These leading spaces cause problem with
     content, 
    		# so we need to fix that:
    		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', array(&$this, '_DoBlockQuotes_callback2'), $bq); return "\n". $this->hashBlock("
    \n$bq\n
    ")."\n\n"; } function _doBlockQuotes_callback2($matches) { $pre = $matches[1]; $pre = preg_replace('/^ /m', '', $pre); return $pre; } function formParagraphs($text) { # # Params: # $text - string to process with html

    tags # # Strip leading and trailing lines: $text = preg_replace('/\A\n+|\n+\z/', '', $text); $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); # # Wrap

    tags and unhashify HTML blocks # foreach ($grafs as $key => $value) { if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { # Is a paragraph. $value = $this->runSpanGamut($value); $value = preg_replace('/^([ ]*)/', "

    ", $value); $value .= "

    "; $grafs[$key] = $this->unhash($value); } else { # Is a block. # Modify elements of @grafs in-place... $graf = $value; $block = $this->html_hashes[$graf]; $graf = $block; // if (preg_match('{ // \A // ( # $1 =
    tag //
    ]* // \b // markdown\s*=\s* ([\'"]) # $2 = attr quote char // 1 // \2 // [^>]* // > // ) // ( # $3 = contents // .* // ) // (
    ) # $4 = closing tag // \z // }xs', $block, $matches)) // { // list(, $div_open, , $div_content, $div_close) = $matches; // // # We can't call Markdown(), because that resets the hash; // # that initialization code should be pulled into its own sub, though. // $div_content = $this->hashHTMLBlocks($div_content); // // # Run document gamut methods on the content. // foreach ($this->document_gamut as $method => $priority) { // $div_content = $this->$method($div_content); // } // // $div_open = preg_replace( // '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); // // $graf = $div_open . "\n" . $div_content . "\n" . $div_close; // } $grafs[$key] = $graf; } } return implode("\n\n", $grafs); } function encodeAttribute($text) { # # Encode text for a double-quoted HTML attribute. This function # is *not* suitable for attributes enclosed in single quotes. # $text = $this->encodeAmpsAndAngles($text); $text = str_replace('"', '"', $text); return $text; } function encodeAmpsAndAngles($text) { # # Smart processing for ampersands and angle brackets that need to # be encoded. Valid character entities are left alone unless the # no-entities mode is set. # if ($this->no_entities) { $text = str_replace('&', '&', $text); } else { # Ampersand-encoding based entirely on Nat Irons's Amputator # MT plugin: $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', '&', $text);; } # Encode remaining <'s $text = str_replace('<', '<', $text); return $text; } function doAutoLinks($text) { $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', array(&$this, '_doAutoLinks_url_callback'), $text); # Email addresses: $text = preg_replace_callback('{ < (?:mailto:)? ( [-.\w\x80-\xFF]+ \@ [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ ) > }xi', array(&$this, '_doAutoLinks_email_callback'), $text); return $text; } function _doAutoLinks_url_callback($matches) { $url = $this->encodeAttribute($matches[1]); $link = "$url"; return $this->hashPart($link); } function _doAutoLinks_email_callback($matches) { $address = $matches[1]; $link = $this->encodeEmailAddress($address); return $this->hashPart($link); } function encodeEmailAddress($addr) { # # Input: an email address, e.g. "foo@example.com" # # Output: the email address as a mailto link, with each character # of the address encoded as either a decimal or hex entity, in # the hopes of foiling most address harvesting spam bots. E.g.: # #

    foo@exampl # e.com

    # # Based by a filter by Matthew Wickline, posted to BBEdit-Talk. # With some optimizations by Milian Wolff. # $addr = "mailto:" . $addr; $chars = preg_split('/(? $char) { $ord = ord($char); # Ignore non-ascii chars. if ($ord < 128) { $r = ($seed * (1 + $key)) % 100; # Pseudo-random function. # roughly 10% raw, 45% hex, 45% dec # '@' *must* be encoded. I insist. if ($r > 90 && $char != '@') /* do nothing */; else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';'; else $chars[$key] = '&#'.$ord.';'; } } $addr = implode('', $chars); $text = implode('', array_slice($chars, 7)); # text without `mailto:` $addr = "$text"; return $addr; } function parseSpan($str) { # # Take the string $str and parse it into tokens, hashing embeded HTML, # escaped characters and handling code spans. # $output = ''; $span_re = '{ ( \\\\'.$this->escape_chars_re.' | (?no_markup ? '' : ' | # comment | <\?.*?\?> | <%.*?%> # processing instruction | <[/!$]?[-a-zA-Z0-9:]+ # regular tags (?> \s (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* )? > ').' ) }xs'; while (1) { # # Each loop iteration seach for either the next tag, the next # openning code span marker, or the next escaped character. # Each token is then passed to handleSpanToken. # $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); # Create token from text preceding tag. if ($parts[0] != "") { $output .= $parts[0]; } # Check if we reach the end. if (isset($parts[1])) { $output .= $this->handleSpanToken($parts[1], $parts[2]); $str = $parts[2]; } else { break; } } return $output; } function handleSpanToken($token, &$str) { # # Handle $token provided by parseSpan by determining its nature and # returning the corresponding value that should replace it. # switch ($token{0}) { case "\\": return $this->hashPart("&#". ord($token{1}). ";"); case "`": # Search for end marker in remaining text. if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', $str, $matches)) { $str = $matches[2]; $codespan = $this->makeCodeSpan($matches[1]); return $this->hashPart($codespan); } return $token; // return as text since no ending marker found. default: return $this->hashPart($token); } } function outdent($text) { # # Remove one level of line-leading tabs or spaces # return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text); } # String length function for detab. `_initDetab` will create a function to # hanlde UTF-8 if the default function does not exist. var $utf8_strlen = 'mb_strlen'; function detab($text) { # # Replace tabs with the appropriate amount of space. # # For each line we separate the line in blocks delemited by # tab characters. Then we reconstruct every line by adding the # appropriate number of space between each blocks. $text = preg_replace_callback('/^.*\t.*$/m', array(&$this, '_detab_callback'), $text); return $text; } function _detab_callback($matches) { $line = $matches[0]; $strlen = $this->utf8_strlen; # strlen function for UTF-8. # Split in blocks. $blocks = explode("\t", $line); # Add each blocks to the line. $line = $blocks[0]; unset($blocks[0]); # Do not add first block twice. foreach ($blocks as $block) { # Calculate amount of space, insert spaces, insert block. $amount = $this->tab_width - $strlen($line, 'UTF-8') % $this->tab_width; $line .= str_repeat(" ", $amount) . $block; } return $line; } function _initDetab() { # # Check for the availability of the function in the `utf8_strlen` property # (initially `mb_strlen`). If the function is not available, create a # function that will loosely count the number of UTF-8 characters with a # regular expression. # if (function_exists($this->utf8_strlen)) return; $this->utf8_strlen = create_function('$text', 'return preg_match_all( "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", $text, $m);'); } function unhash($text) { # # Swap back in all the tags hashed by _HashHTMLBlocks. # return preg_replace_callback('/(.)\x1A[0-9]+\1/', array(&$this, '_unhash_callback'), $text); } function _unhash_callback($matches) { return $this->html_hashes[$matches[0]]; } } # # Markdown Extra Parser Class # class MarkdownExtra_Parser extends Markdown_Parser { # Prefix for footnote ids. var $fn_id_prefix = ""; # Optional title attribute for footnote links and backlinks. var $fn_link_title = MARKDOWN_FN_LINK_TITLE; var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE; # Optional class attribute for footnote links and backlinks. var $fn_link_class = MARKDOWN_FN_LINK_CLASS; var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS; # Predefined abbreviations. var $predef_abbr = array(); function MarkdownExtra_Parser() { # # Constructor function. Initialize the parser object. # # Add extra escapable characters before parent constructor # initialize the table. $this->escape_chars .= ':|'; # Insert extra document, block, and span transformations. # Parent constructor will do the sorting. $this->document_gamut += array( "doFencedCodeBlocks" => 5, "stripFootnotes" => 15, "stripAbbreviations" => 25, "appendFootnotes" => 50, ); $this->block_gamut += array( "doFencedCodeBlocks" => 5, "doTables" => 15, "doDefLists" => 45, ); $this->span_gamut += array( "doFootnotes" => 5, "doAbbreviations" => 70, ); parent::Markdown_Parser(); } # Extra variables used during extra transformations. var $footnotes = array(); var $footnotes_ordered = array(); var $abbr_desciptions = array(); var $abbr_word_re = ''; # Give the current footnote number. var $footnote_counter = 1; function setup() { # # Setting up Extra-specific variables. # parent::setup(); $this->footnotes = array(); $this->footnotes_ordered = array(); $this->abbr_desciptions = array(); $this->abbr_word_re = ''; $this->footnote_counter = 1; foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { if ($this->abbr_word_re) $this->abbr_word_re .= '|'; $this->abbr_word_re .= preg_quote($abbr_word); $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); } } function teardown() { # # Clearing Extra-specific variables. # $this->footnotes = array(); $this->footnotes_ordered = array(); $this->abbr_desciptions = array(); $this->abbr_word_re = ''; parent::teardown(); } ### HTML Block Parser ### # Tags that are always treated as block tags: var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend'; # Tags treated as block tags only if the opening tag is alone on it's line: var $context_block_tags_re = 'script|noscript|math|ins|del'; # Tags where markdown="1" default to span mode: var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; # Tags which must not have their contents modified, no matter where # they appear: var $clean_tags_re = 'script|math'; # Tags that do not need to be closed. var $auto_close_tags_re = 'hr|img'; function hashHTMLBlocks($text) { # # Hashify HTML Blocks and "clean tags". # # We only want to do this for block-level HTML tags, such as headers, # lists, and tables. That's because we still want to wrap

    s around # "paragraphs" that are wrapped in non-block-level tags, such as anchors, # phrase emphasis, and spans. The list of tags we're looking for is # hard-coded. # # This works by calling _HashHTMLBlocks_InMarkdown, which then calls # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. # These two functions are calling each other. It's recursive! # # # Call the HTML-in-Markdown hasher. # list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); return $text; } function _hashHTMLBlocks_inMarkdown($text, $indent = 0, $enclosing_tag_re = '', $span = false) { # # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. # # * $indent is the number of space to be ignored when checking for code # blocks. This is important because if we don't take the indent into # account, something like this (which looks right) won't work as expected: # #

    #
    # Hello World. <-- Is this a Markdown code block or text? #
    <-- Is this a Markdown code block or a real tag? #
    # # If you don't like this, just don't indent the tag on which # you apply the markdown="1" attribute. # # * If $enclosing_tag_re is not empty, stops at the first unmatched closing # tag with that name. Nested tags supported. # # * If $span is true, text inside must treated as span. So any double # newline will be replaced by a single newline so that it does not create # paragraphs. # # Returns an array of that form: ( processed text , remaining text ) # if ($text === '') return array('', ''); # Regex to check for the presense of newlines around a block tag. $newline_before_re = '/(?:^\n?|\n\n)*$/'; $newline_after_re = '{ ^ # Start of text following the tag. (?>[ ]*)? # Optional comment. [ ]*\n # Must be followed by newline. }xs'; # Regex to match any tag. $block_tag_re = '{ ( # $2: Capture hole tag. # Tag name. '.$this->block_tags_re.' | '.$this->context_block_tags_re.' | '.$this->clean_tags_re.' | (?!\s)'.$enclosing_tag_re.' ) (?: (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. (?> ".*?" | # Double quotes (can contain `>`) \'.*?\' | # Single quotes (can contain `>`) .+? # Anything but quotes and `>`. )*? )? > # End of tag. | # HTML Comment | <\?.*?\?> | <%.*?%> # Processing instruction | # CData Block | # Code span marker `+ '. ( !$span ? ' # If not in span. | # Indented code block (?> ^[ ]*\n? | \n[ ]*\n ) [ ]{'.($indent+4).'}[^\n]* \n (?> (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n )* | # Fenced code block marker (?> ^ | \n ) [ ]{'.($indent).'}~~~+[ ]*\n ' : '' ). ' # End (if not is span). ) }xs'; $depth = 0; # Current depth inside the tag tree. $parsed = ""; # Parsed text that will be returned. # # Loop through every tag until we find the closing tag of the parent # or loop until reaching the end of text if no parent tag specified. # do { # # Split the text using the first $tag_match pattern found. # Text before pattern will be first in the array, text after # pattern will be at the end, and between will be any catches made # by the pattern. # $parts = preg_split($block_tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); # If in Markdown span mode, add a empty-string span-level hash # after each newline to prevent triggering any block element. if ($span) { $void = $this->hashPart("", ':'); $newline = "$void\n"; $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; } $parsed .= $parts[0]; # Text before current tag. # If end of $text has been reached. Stop loop. if (count($parts) < 3) { $text = ""; break; } $tag = $parts[1]; # Tag to handle. $text = $parts[2]; # Remaining text after current tag. $tag_re = preg_quote($tag); # For use in a regular expression. # # Check for: Code span marker # if ($tag{0} == "`") { # Find corresponding end marker. $tag_re = preg_quote($tag); if (preg_match('{^(?>.+?|\n(?!\n))*?(?.*\n)+?'.$tag_re.' *\n}', $text, $matches)) { # End marker found: pass text unchanged until marker. $parsed .= $tag . $matches[0]; $text = substr($text, strlen($matches[0])); } else { # No end marker: just skip it. $parsed .= $tag; } } } # # Check for: Opening Block level tag or # Opening Context Block tag (like ins and del) # used as a block tag (tag is alone on it's line). # else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) || ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) && preg_match($newline_before_re, $parsed) && preg_match($newline_after_re, $text) ) ) { # Need to parse tag and following text using the HTML parser. list($block_text, $text) = $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); # Make sure it stays outside of any paragraph by adding newlines. $parsed .= "\n\n$block_text\n\n"; } # # Check for: Clean tag (like script, math) # HTML Comments, processing instructions. # else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) || $tag{1} == '!' || $tag{1} == '?') { # Need to parse tag and following text using the HTML parser. # (don't check for markdown attribute) list($block_text, $text) = $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); $parsed .= $block_text; } # # Check for: Tag with same name as enclosing tag. # else if ($enclosing_tag_re !== '' && # Same name as enclosing tag. preg_match('{^= 0); return array($parsed, $text); } function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { # # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. # # * Calls $hash_method to convert any blocks. # * Stops when the first opening tag closes. # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. # (it is not inside clean tags) # # Returns an array of that form: ( processed text , remaining text ) # if ($text === '') return array('', ''); # Regex to match `markdown` attribute inside of a tag. $markdown_attr_re = ' { \s* # Eat whitespace before the `markdown` attribute markdown \s*=\s* (?> (["\']) # $1: quote delimiter (.*?) # $2: attribute value \1 # matching delimiter | ([^\s>]*) # $3: unquoted attribute value ) () # $4: make $3 always defined (avoid warnings) }xs'; # Regex to match any tag. $tag_re = '{ ( # $2: Capture hole tag. ".*?" | # Double quotes (can contain `>`) \'.*?\' | # Single quotes (can contain `>`) .+? # Anything but quotes and `>`. )*? )? > # End of tag. | # HTML Comment | <\?.*?\?> | <%.*?%> # Processing instruction | # CData Block ) }xs'; $original_text = $text; # Save original text in case of faliure. $depth = 0; # Current depth inside the tag tree. $block_text = ""; # Temporary text holder for current text. $parsed = ""; # Parsed text that will be returned. # # Get the name of the starting tag. # (This pattern makes $base_tag_name_re safe without quoting.) # if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) $base_tag_name_re = $matches[1]; # # Loop through every tag until we find the corresponding closing tag. # do { # # Split the text using the first $tag_match pattern found. # Text before pattern will be first in the array, text after # pattern will be at the end, and between will be any catches made # by the pattern. # $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); if (count($parts) < 3) { # # End of $text reached with unbalenced tag(s). # In that case, we return original text unchanged and pass the # first character as filtered to prevent an infinite loop in the # parent function. # return array($original_text{0}, substr($original_text, 1)); } $block_text .= $parts[0]; # Text before current tag. $tag = $parts[1]; # Tag to handle. $text = $parts[2]; # Remaining text after current tag. # # Check for: Auto-close tag (like
    ) # Comments and Processing Instructions. # if (preg_match('{^auto_close_tags_re.')\b}', $tag) || $tag{1} == '!' || $tag{1} == '?') { # Just add the tag to the block as if it was text. $block_text .= $tag; } else { # # Increase/decrease nested tag count. Only do so if # the tag's name match base tag's. # if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; $span_mode = $this->mode == 'span' || $this->mode != 'block' && preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag); # Calculate indent before tag. if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { $strlen = $this->utf8_strlen; $indent = $strlen($matches[1], 'UTF-8'); } else { $indent = 0; } # End preceding block with this tag. $block_text .= $tag; $parsed .= $this->$hash_method($block_text); # Get enclosing tag name for the ParseMarkdown function. # (This pattern makes $tag_name_re safe without quoting.) preg_match('/^<([\w:$]*)\b/', $tag, $matches); $tag_name_re = $matches[1]; # Parse the content using the HTML-in-Markdown parser. list ($block_text, $text) = $this->_hashHTMLBlocks_inMarkdown($text, $indent, $tag_name_re, $span_mode); # Outdent markdown text. if ($indent > 0) { $block_text = preg_replace("/^[ ]{1,$indent}/m", "", $block_text); } # Append tag content to parsed text. if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; else $parsed .= "$block_text"; # Start over a new block. $block_text = ""; } else $block_text .= $tag; } } while ($depth > 0); # # Hash last block text that wasn't processed inside the loop. # $parsed .= $this->$hash_method($block_text); return array($parsed, $text); } function hashClean($text) { # # Called whenever a tag must be hashed when a function insert a "clean" tag # in $text, it pass through this function and is automaticaly escaped, # blocking invalid nested overlap. # return $this->hashPart($text, 'C'); } function doHeaders($text) { # # Redefined to add id attribute support. # # Setext-style headers: # Header 1 {#header1} # ======== # # Header 2 {#header2} # -------- # $text = preg_replace_callback( '{ (^.+?) # $1: Header text (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # $2: Id attribute [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer }mx', array(&$this, '_doHeaders_callback_setext'), $text); # atx-style headers: # # Header 1 {#header1} # ## Header 2 {#header2} # ## Header 2 with closing hashes ## {#header3} # ... # ###### Header 6 {#header2} # $text = preg_replace_callback('{ ^(\#{1,6}) # $1 = string of #\'s [ ]* (.+?) # $2 = Header text [ ]* \#* # optional closing #\'s (not counted) (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute [ ]* \n+ }xm', array(&$this, '_doHeaders_callback_atx'), $text); return $text; } function _doHeaders_attr($attr) { if (empty($attr)) return ""; return " id=\"$attr\""; } function _doHeaders_callback_setext($matches) { if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) return $matches[0]; $level = $matches[3]{0} == '=' ? 1 : 2; $attr = $this->_doHeaders_attr($id =& $matches[2]); $block = "".$this->runSpanGamut($matches[1]).""; return "\n" . $this->hashBlock($block) . "\n\n"; } function _doHeaders_callback_atx($matches) { $level = strlen($matches[1]); $attr = $this->_doHeaders_attr($id =& $matches[3]); $block = "".$this->runSpanGamut($matches[2]).""; return "\n" . $this->hashBlock($block) . "\n\n"; } function doTables($text) { # # Form HTML tables. # $less_than_tab = $this->tab_width - 1; # # Find tables with leading pipe. # # | Header 1 | Header 2 # | -------- | -------- # | Cell 1 | Cell 2 # | Cell 3 | Cell 4 # $text = preg_replace_callback(' { ^ # Start of a line [ ]{0,'.$less_than_tab.'} # Allowed whitespace. [|] # Optional leading pipe (present) (.+) \n # $1: Header row (at least one pipe) [ ]{0,'.$less_than_tab.'} # Allowed whitespace. [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline ( # $3: Cells (?> [ ]* # Allowed whitespace. [|] .* \n # Row content. )* ) (?=\n|\Z) # Stop at final double newline. }xm', array(&$this, '_doTable_leadingPipe_callback'), $text); # # Find tables without leading pipe. # # Header 1 | Header 2 # -------- | -------- # Cell 1 | Cell 2 # Cell 3 | Cell 4 # $text = preg_replace_callback(' { ^ # Start of a line [ ]{0,'.$less_than_tab.'} # Allowed whitespace. (\S.*[|].*) \n # $1: Header row (at least one pipe) [ ]{0,'.$less_than_tab.'} # Allowed whitespace. ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline ( # $3: Cells (?> .* [|] .* \n # Row content )* ) (?=\n|\Z) # Stop at final double newline. }xm', array(&$this, '_DoTable_callback'), $text); return $text; } function _doTable_leadingPipe_callback($matches) { $head = $matches[1]; $underline = $matches[2]; $content = $matches[3]; # Remove leading pipe for each row. $content = preg_replace('/^ *[|]/m', '', $content); return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); } function _doTable_callback($matches) { $head = $matches[1]; $underline = $matches[2]; $content = $matches[3]; # Remove any tailing pipes for each line. $head = preg_replace('/[|] *$/m', '', $head); $underline = preg_replace('/[|] *$/m', '', $underline); $content = preg_replace('/[|] *$/m', '', $content); # Reading alignement from header underline. $separators = preg_split('/ *[|] */', $underline); foreach ($separators as $n => $s) { if (preg_match('/^ *-+: *$/', $s)) $attr[$n] = ' align="right"'; else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"'; else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"'; else $attr[$n] = ''; } # Parsing span elements, including code spans, character escapes, # and inline HTML tags, so that pipes inside those gets ignored. $head = $this->parseSpan($head); $headers = preg_split('/ *[|] */', $head); $col_count = count($headers); # Write column headers. $text = "\n"; $text .= "\n"; $text .= "\n"; foreach ($headers as $n => $header) $text .= " ".$this->runSpanGamut(trim($header))."\n"; $text .= "\n"; $text .= "\n"; # Split content by row. $rows = explode("\n", trim($content, "\n")); $text .= "\n"; foreach ($rows as $row) { # Parsing span elements, including code spans, character escapes, # and inline HTML tags, so that pipes inside those gets ignored. $row = $this->parseSpan($row); # Split row by cell. $row_cells = preg_split('/ *[|] */', $row, $col_count); $row_cells = array_pad($row_cells, $col_count, ''); $text .= "\n"; foreach ($row_cells as $n => $cell) $text .= " ".$this->runSpanGamut(trim($cell))."\n"; $text .= "\n"; } $text .= "\n"; $text .= "
    "; return $this->hashBlock($text) . "\n"; } function doDefLists($text) { # # Form HTML definition lists. # $less_than_tab = $this->tab_width - 1; # Re-usable pattern to match any entire dl list: $whole_list_re = '(?> ( # $1 = whole list ( # $2 [ ]{0,'.$less_than_tab.'} ((?>.*\S.*\n)+) # $3 = defined term \n? [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition ) (?s:.+?) ( # $4 \z | \n{2,} (?=\S) (?! # Negative lookahead for another term [ ]{0,'.$less_than_tab.'} (?: \S.*\n )+? # defined term \n? [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition ) (?! # Negative lookahead for another definition [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition ) ) ) )'; // mx $text = preg_replace_callback('{ (?>\A\n?|(?<=\n\n)) '.$whole_list_re.' }mx', array(&$this, '_doDefLists_callback'), $text); return $text; } function _doDefLists_callback($matches) { # Re-usable patterns to match list item bullets and number markers: $list = $matches[1]; # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary: $result = trim($this->processDefListItems($list)); $result = "
    \n" . $result . "\n
    "; return $this->hashBlock($result) . "\n\n"; } function processDefListItems($list_str) { # # Process the contents of a single definition list, splitting it # into individual term and definition list items. # $less_than_tab = $this->tab_width - 1; # trim trailing blank lines: $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); # Process definition terms. $list_str = preg_replace_callback('{ (?>\A\n?|\n\n+) # leading line ( # definition terms = $1 [ ]{0,'.$less_than_tab.'} # leading whitespace (?![:][ ]|[ ]) # negative lookahead for a definition # mark (colon) or more whitespace. (?> \S.* \n)+? # actual term (not whitespace). ) (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed # with a definition mark. }xm', array(&$this, '_processDefListItems_callback_dt'), $list_str); # Process actual definitions. $list_str = preg_replace_callback('{ \n(\n+)? # leading line = $1 ( # marker space = $2 [ ]{0,'.$less_than_tab.'} # whitespace before colon [:][ ]+ # definition mark (colon) ) ((?s:.+?)) # definition text = $3 (?= \n+ # stop at next definition mark, (?: # next term or end of text [ ]{0,'.$less_than_tab.'} [:][ ] |
    | \z ) ) }xm', array(&$this, '_processDefListItems_callback_dd'), $list_str); return $list_str; } function _processDefListItems_callback_dt($matches) { $terms = explode("\n", trim($matches[1])); $text = ''; foreach ($terms as $term) { $term = $this->runSpanGamut(trim($term)); $text .= "\n
    " . $term . "
    "; } return $text . "\n"; } function _processDefListItems_callback_dd($matches) { $leading_line = $matches[1]; $marker_space = $matches[2]; $def = $matches[3]; if ($leading_line || preg_match('/\n{2,}/', $def)) { # Replace marker with the appropriate whitespace indentation $def = str_repeat(' ', strlen($marker_space)) . $def; $def = $this->runBlockGamut($this->outdent($def . "\n\n")); $def = "\n". $def ."\n"; } else { $def = rtrim($def); $def = $this->runSpanGamut($this->outdent($def)); } return "\n
    " . $def . "
    \n"; } function doFencedCodeBlocks($text) { # # Adding the fenced code block syntax to regular Markdown: # # ~~~ # Code block # ~~~ # $less_than_tab = $this->tab_width; $text = preg_replace_callback('{ (?:\n|\A) # 1: Opening marker ( ~{3,} # Marker: three tilde or more. ) [ ]* \n # Whitespace and newline following marker. # 2: Content ( (?> (?!\1 [ ]* \n) # Not a closing marker. .*\n+ )+ ) # Closing marker. \1 [ ]* \n }xm', array(&$this, '_doFencedCodeBlocks_callback'), $text); return $text; } function _doFencedCodeBlocks_callback($matches) { $codeblock = $matches[2]; $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); $codeblock = preg_replace_callback('/^\n+/', array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock); $codeblock = "
    $codeblock
    "; return "\n\n".$this->hashBlock($codeblock)."\n\n"; } function _doFencedCodeBlocks_newlines($matches) { return str_repeat("empty_element_suffix", strlen($matches[0])); } # # Redefining emphasis markers so that emphasis by underscore does not # work in the middle of a word. # var $em_relist = array( '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? tags # # Strip leading and trailing lines: $text = preg_replace('/\A\n+|\n+\z/', '', $text); $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); # # Wrap

    tags and unhashify HTML blocks # foreach ($grafs as $key => $value) { $value = trim($this->runSpanGamut($value)); # Check if this should be enclosed in a paragraph. # Clean tag hashes & block tag hashes are left alone. $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); if ($is_p) { $value = "

    $value

    "; } $grafs[$key] = $value; } # Join grafs in one text, then unhash HTML tags. $text = implode("\n\n", $grafs); # Finish by removing any tag hashes still present in $text. $text = $this->unhash($text); return $text; } ### Footnotes function stripFootnotes($text) { # # Strips link definitions from text, stores the URLs and titles in # hash references. # $less_than_tab = $this->tab_width - 1; # Link defs are in the form: [^id]: url "optional title" $text = preg_replace_callback('{ ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1 [ ]* \n? # maybe *one* newline ( # text = $2 (no blank lines allowed) (?: .+ # actual text | \n # newlines but (?!\[\^.+?\]:\s)# negative lookahead for footnote marker. (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed # by non-indented content )* ) }xm', array(&$this, '_stripFootnotes_callback'), $text); return $text; } function _stripFootnotes_callback($matches) { $note_id = $this->fn_id_prefix . $matches[1]; $this->footnotes[$note_id] = $this->outdent($matches[2]); return ''; # String that will replace the block } function doFootnotes($text) { # # Replace footnote references in $text [^id] with a special text-token # which will be replaced by the actual footnote marker in appendFootnotes. # if (!$this->in_anchor) { $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); } return $text; } function appendFootnotes($text) { # # Append footnote list to text. # $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', array(&$this, '_appendFootnotes_callback'), $text); if (!empty($this->footnotes_ordered)) { $text .= "\n\n"; $text .= "
    \n"; $text .= "fn_backlink_class != "") { $class = $this->fn_backlink_class; $class = $this->encodeAttribute($class); $attr .= " class=\"$class\""; } if ($this->fn_backlink_title != "") { $title = $this->fn_backlink_title; $title = $this->encodeAttribute($title); $attr .= " title=\"$title\""; } $num = 0; while (!empty($this->footnotes_ordered)) { $footnote = reset($this->footnotes_ordered); $note_id = key($this->footnotes_ordered); unset($this->footnotes_ordered[$note_id]); $footnote .= "\n"; # Need to append newline before parsing. $footnote = $this->runBlockGamut("$footnote\n"); $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', array(&$this, '_appendFootnotes_callback'), $footnote); $attr = str_replace("%%", ++$num, $attr); $note_id = $this->encodeAttribute($note_id); # Add backlink to last paragraph; create new paragraph if needed. $backlink = ""; if (preg_match('{

    $}', $footnote)) { $footnote = substr($footnote, 0, -4) . " $backlink

    "; } else { $footnote .= "\n\n

    $backlink

    "; } $text .= "
  • \n"; $text .= $footnote . "\n"; $text .= "
  • \n\n"; } $text .= "\n"; $text .= "
    "; } return $text; } function _appendFootnotes_callback($matches) { $node_id = $this->fn_id_prefix . $matches[1]; # Create footnote marker only if it has a corresponding footnote *and* # the footnote hasn't been used by another marker. if (isset($this->footnotes[$node_id])) { # Transfert footnote content to the ordered list. $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; unset($this->footnotes[$node_id]); $num = $this->footnote_counter++; $attr = " rel=\"footnote\""; if ($this->fn_link_class != "") { $class = $this->fn_link_class; $class = $this->encodeAttribute($class); $attr .= " class=\"$class\""; } if ($this->fn_link_title != "") { $title = $this->fn_link_title; $title = $this->encodeAttribute($title); $attr .= " title=\"$title\""; } $attr = str_replace("%%", $num, $attr); $node_id = $this->encodeAttribute($node_id); return "". "$num". ""; } return "[^".$matches[1]."]"; } ### Abbreviations ### function stripAbbreviations($text) { # # Strips abbreviations from text, stores titles in hash references. # $less_than_tab = $this->tab_width - 1; # Link defs are in the form: [id]*: url "optional title" $text = preg_replace_callback('{ ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1 (.*) # text = $2 (no blank lines allowed) }xm', array(&$this, '_stripAbbreviations_callback'), $text); return $text; } function _stripAbbreviations_callback($matches) { $abbr_word = $matches[1]; $abbr_desc = $matches[2]; if ($this->abbr_word_re) $this->abbr_word_re .= '|'; $this->abbr_word_re .= preg_quote($abbr_word); $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); return ''; # String that will replace the block } function doAbbreviations($text) { # # Find defined abbreviations in text and wrap them in elements. # if ($this->abbr_word_re) { // cannot use the /x modifier because abbr_word_re may // contain significant spaces: $text = preg_replace_callback('{'. '(?abbr_word_re.')'. '(?![\w\x1A])'. '}', array(&$this, '_doAbbreviations_callback'), $text); } return $text; } function _doAbbreviations_callback($matches) { $abbr = $matches[0]; if (isset($this->abbr_desciptions[$abbr])) { $desc = $this->abbr_desciptions[$abbr]; if (empty($desc)) { return $this->hashPart("$abbr"); } else { $desc = $this->encodeAttribute($desc); return $this->hashPart("$abbr"); } } else { return $matches[0]; } } } /* PHP Markdown Extra ================== Description ----------- This is a PHP port of the original Markdown formatter written in Perl by John Gruber. This special "Extra" version of PHP Markdown features further enhancements to the syntax for making additional constructs such as tables and definition list. Markdown is a text-to-HTML filter; it translates an easy-to-read / easy-to-write structured text format into HTML. Markdown's text format is most similar to that of plain text email, and supports features such as headers, *emphasis*, code blocks, blockquotes, and links. Markdown's syntax is designed not as a generic markup language, but specifically to serve as a front-end to (X)HTML. You can use span-level HTML tags anywhere in a Markdown document, and you can use block level HTML tags (like
    and as well). For more information about Markdown's syntax, see: Bugs ---- To file bug reports please send email to: Please include with your report: (1) the example input; (2) the output you expected; (3) the output Markdown actually produced. Version History --------------- See the readme file for detailed release notes for this version. Copyright and License --------------------- PHP Markdown & Extra Copyright (c) 2004-2008 Michel Fortin All rights reserved. Based on Markdown Copyright (c) 2003-2006 John Gruber All rights reserved. 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. * Neither the name "Markdown" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. This software is provided by the copyright holders and contributors "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 the copyright owner or 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. */ ?>./kohana/system/controllers/0000755000175000017500000000000011263472437015705 5ustar tokkeetokkee./kohana/system/controllers/template.php0000644000175000017500000000246311121324570020221 0ustar tokkeetokkeetemplate = new View($this->template); if ($this->auto_render == TRUE) { // Render the template immediately after the controller method Event::add('system.post_controller', array($this, '_render')); } } /** * Render the loaded template. */ public function _render() { if ($this->auto_render == TRUE) { // Render the template when the class is destroyed $this->template->render(TRUE); } } } // End Template_Controller./kohana/system/controllers/captcha.php0000644000175000017500000000130111121324570017777 0ustar tokkeetokkee" /> * * $Id: captcha.php 3769 2008-12-15 00:48:56Z zombor $ * * @package Captcha * @author Kohana Team * @copyright (c) 2007-2008 Kohana Team * @license http://kohanaphp.com/license.html */ class Captcha_Controller extends Controller { public function __call($method, $args) { // Output the Captcha challenge resource (no html) // Pull the config group name from the URL Captcha::factory($this->uri->segment(2))->render(FALSE); } } // End Captcha_Controller./kohana/system/tests/0000755000175000017500000000000011263472436014500 5ustar tokkeetokkee./kohana/system/config/0000755000175000017500000000000011263472437014604 5ustar tokkeetokkee./kohana/system/config/inflector.php0000644000175000017500000000145611133566364017307 0ustar tokkeetokkee 'children', 'clothes' => 'clothing', 'man' => 'men', 'movie' => 'movies', 'person' => 'people', 'woman' => 'women', 'mouse' => 'mice', 'goose' => 'geese', 'ox' => 'oxen', 'leaf' => 'leaves', 'course' => 'courses', 'size' => 'sizes', ); ./kohana/system/config/database.php0000644000175000017500000000277011121324570017052 0ustar tokkeetokkee 'mysql://dbuser:secret@localhost/kohana' * character_set - Database character set * table_prefix - Database table prefix * object - Enable or disable object results * cache - Enable or disable query caching * escape - Enable automatic query builder escaping */ $config['default'] = array ( 'benchmark' => TRUE, 'persistent' => FALSE, 'connection' => array ( 'type' => 'mysql', 'user' => 'dbuser', 'pass' => 'p@ssw0rd', 'host' => 'localhost', 'port' => FALSE, 'socket' => FALSE, 'database' => 'kohana' ), 'character_set' => 'utf8', 'table_prefix' => '', 'object' => TRUE, 'cache' => FALSE, 'escape' => TRUE );./kohana/system/config/encryption.php0000644000175000017500000000242011121324570017470 0ustar tokkeetokkee 'K0H@NA+PHP_7hE-SW!FtFraM3w0R|<', 'mode' => MCRYPT_MODE_NOFB, 'cipher' => MCRYPT_RIJNDAEL_128 ); ./kohana/system/config/profiler.php0000644000175000017500000000046511121324570017127 0ustar tokkeetokkee File cache is fast and reliable, but requires many filesystem lookups. * > Database cache can be used to cache items remotely, but is slower. * > Memcache is very high performance, but prevents cache tags from being used. * * params - Driver parameters, specific to each driver. * * lifetime - Default lifetime of caches in seconds. By default caches are stored for * thirty minutes. Specific lifetime can also be set when creating a new cache. * Setting this to 0 will never automatically delete caches. * * requests - Average number of cache requests that will processed before all expired * caches are deleted. This is commonly referred to as "garbage collection". * Setting this to 0 or a negative number will disable automatic garbage collection. */ $config['default'] = array ( 'driver' => 'file', 'params' => APPPATH.'cache', 'lifetime' => 1800, 'requests' => 1000 ); ./kohana/system/config/user_agents.php0000644000175000017500000000674111164163732017637 0ustar tokkeetokkee 'Windows Vista', 'windows nt 5.2' => 'Windows 2003', 'windows nt 5.0' => 'Windows 2000', 'windows nt 5.1' => 'Windows XP', 'windows nt 4.0' => 'Windows NT', 'winnt4.0' => 'Windows NT', 'winnt 4.0' => 'Windows NT', 'winnt' => 'Windows NT', 'windows 98' => 'Windows 98', 'win98' => 'Windows 98', 'windows 95' => 'Windows 95', 'win95' => 'Windows 95', 'windows' => 'Unknown Windows OS', 'os x' => 'Mac OS X', 'intel mac' => 'Intel Mac', 'ppc mac' => 'PowerPC Mac', 'powerpc' => 'PowerPC', 'ppc' => 'PowerPC', 'cygwin' => 'Cygwin', 'linux' => 'Linux', 'debian' => 'Debian', 'openvms' => 'OpenVMS', 'sunos' => 'Sun Solaris', 'amiga' => 'Amiga', 'beos' => 'BeOS', 'apachebench' => 'ApacheBench', 'freebsd' => 'FreeBSD', 'netbsd' => 'NetBSD', 'bsdi' => 'BSDi', 'openbsd' => 'OpenBSD', 'os/2' => 'OS/2', 'warp' => 'OS/2', 'aix' => 'AIX', 'irix' => 'Irix', 'osf' => 'DEC OSF', 'hp-ux' => 'HP-UX', 'hurd' => 'GNU/Hurd', 'unix' => 'Unknown Unix OS', ); // The order of this array should NOT be changed. Many browsers return // multiple browser types so we want to identify the sub-type first. $config['browser'] = array ( 'Opera' => 'Opera', 'MSIE' => 'Internet Explorer', 'Internet Explorer' => 'Internet Explorer', 'Shiira' => 'Shiira', 'Firefox' => 'Firefox', 'Chimera' => 'Chimera', 'Phoenix' => 'Phoenix', 'Firebird' => 'Firebird', 'Camino' => 'Camino', 'Netscape' => 'Netscape', 'OmniWeb' => 'OmniWeb', 'Chrome' => 'Chrome', 'Safari' => 'Safari', 'Konqueror' => 'Konqueror', 'Epiphany' => 'Epiphany', 'Galeon' => 'Galeon', 'Mozilla' => 'Mozilla', 'icab' => 'iCab', 'lynx' => 'Lynx', 'links' => 'Links', 'hotjava' => 'HotJava', 'amaya' => 'Amaya', 'IBrowse' => 'IBrowse', ); $config['mobile'] = array ( 'mobileexplorer' => 'Mobile Explorer', 'openwave' => 'Open Wave', 'opera mini' => 'Opera Mini', 'operamini' => 'Opera Mini', 'elaine' => 'Palm', 'palmsource' => 'Palm', 'digital paths' => 'Palm', 'avantgo' => 'Avantgo', 'xiino' => 'Xiino', 'palmscape' => 'Palmscape', 'nokia' => 'Nokia', 'ericsson' => 'Ericsson', 'blackBerry' => 'BlackBerry', 'motorola' => 'Motorola', 'iphone' => 'iPhone', 'android' => 'Android', ); // There are hundreds of bots but these are the most common. $config['robot'] = array ( 'googlebot' => 'Googlebot', 'msnbot' => 'MSNBot', 'slurp' => 'Inktomi Slurp', 'yahoo' => 'Yahoo', 'askjeeves' => 'AskJeeves', 'fastcrawler' => 'FastCrawler', 'infoseek' => 'InfoSeek Robot 1.0', 'lycos' => 'Lycos', );./kohana/system/config/captcha.php0000644000175000017500000000174411121324570016711 0ustar tokkeetokkee 'basic', 'width' => 150, 'height' => 50, 'complexity' => 4, 'background' => '', 'fontpath' => SYSPATH.'fonts/', 'fonts' => array('DejaVuSerif.ttf'), 'promote' => FALSE, );./kohana/system/config/email.php0000644000175000017500000000142311121324570016367 0ustar tokkeetokkee 'pagination', 'style' => 'classic', 'uri_segment' => 3, 'query_string' => '', 'items_per_page' => 20, 'auto_hide' => FALSE, ); ./kohana/system/config/cookie.php0000644000175000017500000000157711121324570016563 0ustar tokkeetokkee array ( 'length' => '13,14,15,16,17,18,19', 'prefix' => '', 'luhn' => TRUE ), 'american express' => array ( 'length' => '15', 'prefix' => '3[47]', 'luhn' => TRUE ), 'diners club' => array ( 'length' => '14,16', 'prefix' => '36|55|30[0-5]', 'luhn' => TRUE ), 'discover' => array ( 'length' => '16', 'prefix' => '6(?:5|011)', 'luhn' => TRUE, ), 'jcb' => array ( 'length' => '15,16', 'prefix' => '3|1800|2131', 'luhn' => TRUE ), 'maestro' => array ( 'length' => '16,18', 'prefix' => '50(?:20|38)|6(?:304|759)', 'luhn' => TRUE ), 'mastercard' => array ( 'length' => '16', 'prefix' => '5[1-5]', 'luhn' => TRUE ), 'visa' => array ( 'length' => '13,16', 'prefix' => '4', 'luhn' => TRUE ), );./kohana/system/config/http.php0000644000175000017500000000056711121324570016267 0ustar tokkeetokkee array('text/h323'), '7z' => array('application/x-7z-compressed'), 'abw' => array('application/x-abiword'), 'acx' => array('application/internet-property-stream'), 'ai' => array('application/postscript'), 'aif' => array('audio/x-aiff'), 'aifc' => array('audio/x-aiff'), 'aiff' => array('audio/x-aiff'), 'asf' => array('video/x-ms-asf'), 'asr' => array('video/x-ms-asf'), 'asx' => array('video/x-ms-asf'), 'atom' => array('application/atom+xml'), 'avi' => array('video/avi', 'video/msvideo', 'video/x-msvideo'), 'bin' => array('application/octet-stream','application/macbinary'), 'bmp' => array('image/bmp'), 'c' => array('text/x-csrc'), 'c++' => array('text/x-c++src'), 'cab' => array('application/x-cab'), 'cc' => array('text/x-c++src'), 'cda' => array('application/x-cdf'), 'class' => array('application/octet-stream'), 'cpp' => array('text/x-c++src'), 'cpt' => array('application/mac-compactpro'), 'csh' => array('text/x-csh'), 'css' => array('text/css'), 'csv' => array('text/x-comma-separated-values', 'application/vnd.ms-excel', 'text/comma-separated-values', 'text/csv'), 'dbk' => array('application/docbook+xml'), 'dcr' => array('application/x-director'), 'deb' => array('application/x-debian-package'), 'diff' => array('text/x-diff'), 'dir' => array('application/x-director'), 'divx' => array('video/divx'), 'dll' => array('application/octet-stream', 'application/x-msdos-program'), 'dmg' => array('application/x-apple-diskimage'), 'dms' => array('application/octet-stream'), 'doc' => array('application/msword'), 'dvi' => array('application/x-dvi'), 'dxr' => array('application/x-director'), 'eml' => array('message/rfc822'), 'eps' => array('application/postscript'), 'evy' => array('application/envoy'), 'exe' => array('application/x-msdos-program', 'application/octet-stream'), 'fla' => array('application/octet-stream'), 'flac' => array('application/x-flac'), 'flc' => array('video/flc'), 'fli' => array('video/fli'), 'flv' => array('video/x-flv'), 'gif' => array('image/gif'), 'gtar' => array('application/x-gtar'), 'gz' => array('application/x-gzip'), 'h' => array('text/x-chdr'), 'h++' => array('text/x-c++hdr'), 'hh' => array('text/x-c++hdr'), 'hpp' => array('text/x-c++hdr'), 'hqx' => array('application/mac-binhex40'), 'hs' => array('text/x-haskell'), 'htm' => array('text/html'), 'html' => array('text/html'), 'ico' => array('image/x-icon'), 'ics' => array('text/calendar'), 'iii' => array('application/x-iphone'), 'ins' => array('application/x-internet-signup'), 'iso' => array('application/x-iso9660-image'), 'isp' => array('application/x-internet-signup'), 'jar' => array('application/java-archive'), 'java' => array('application/x-java-applet'), 'jpe' => array('image/jpeg', 'image/pjpeg'), 'jpeg' => array('image/jpeg', 'image/pjpeg'), 'jpg' => array('image/jpeg', 'image/pjpeg'), 'js' => array('application/x-javascript'), 'json' => array('application/json'), 'latex' => array('application/x-latex'), 'lha' => array('application/octet-stream'), 'log' => array('text/plain', 'text/x-log'), 'lzh' => array('application/octet-stream'), 'm4a' => array('audio/mpeg'), 'm4p' => array('video/mp4v-es'), 'm4v' => array('video/mp4'), 'man' => array('application/x-troff-man'), 'mdb' => array('application/x-msaccess'), 'midi' => array('audio/midi'), 'mid' => array('audio/midi'), 'mif' => array('application/vnd.mif'), 'mka' => array('audio/x-matroska'), 'mkv' => array('video/x-matroska'), 'mov' => array('video/quicktime'), 'movie' => array('video/x-sgi-movie'), 'mp2' => array('audio/mpeg'), 'mp3' => array('audio/mpeg'), 'mp4' => array('application/mp4','audio/mp4','video/mp4'), 'mpa' => array('video/mpeg'), 'mpe' => array('video/mpeg'), 'mpeg' => array('video/mpeg'), 'mpg' => array('video/mpeg'), 'mpg4' => array('video/mp4'), 'mpga' => array('audio/mpeg'), 'mpp' => array('application/vnd.ms-project'), 'mpv' => array('video/x-matroska'), 'mpv2' => array('video/mpeg'), 'ms' => array('application/x-troff-ms'), 'msg' => array('application/msoutlook','application/x-msg'), 'msi' => array('application/x-msi'), 'nws' => array('message/rfc822'), 'oda' => array('application/oda'), 'odb' => array('application/vnd.oasis.opendocument.database'), 'odc' => array('application/vnd.oasis.opendocument.chart'), 'odf' => array('application/vnd.oasis.opendocument.forumla'), 'odg' => array('application/vnd.oasis.opendocument.graphics'), 'odi' => array('application/vnd.oasis.opendocument.image'), 'odm' => array('application/vnd.oasis.opendocument.text-master'), 'odp' => array('application/vnd.oasis.opendocument.presentation'), 'ods' => array('application/vnd.oasis.opendocument.spreadsheet'), 'odt' => array('application/vnd.oasis.opendocument.text'), 'oga' => array('audio/ogg'), 'ogg' => array('application/ogg'), 'ogv' => array('video/ogg'), 'otg' => array('application/vnd.oasis.opendocument.graphics-template'), 'oth' => array('application/vnd.oasis.opendocument.web'), 'otp' => array('application/vnd.oasis.opendocument.presentation-template'), 'ots' => array('application/vnd.oasis.opendocument.spreadsheet-template'), 'ott' => array('application/vnd.oasis.opendocument.template'), 'p' => array('text/x-pascal'), 'pas' => array('text/x-pascal'), 'patch' => array('text/x-diff'), 'pbm' => array('image/x-portable-bitmap'), 'pdf' => array('application/pdf', 'application/x-download'), 'php' => array('application/x-httpd-php'), 'php3' => array('application/x-httpd-php'), 'php4' => array('application/x-httpd-php'), 'php5' => array('application/x-httpd-php'), 'phps' => array('application/x-httpd-php-source'), 'phtml' => array('application/x-httpd-php'), 'pl' => array('text/x-perl'), 'pm' => array('text/x-perl'), 'png' => array('image/png', 'image/x-png'), 'po' => array('text/x-gettext-translation'), 'pot' => array('application/vnd.ms-powerpoint'), 'pps' => array('application/vnd.ms-powerpoint'), 'ppt' => array('application/powerpoint'), 'ps' => array('application/postscript'), 'psd' => array('application/x-photoshop', 'image/x-photoshop'), 'pub' => array('application/x-mspublisher'), 'py' => array('text/x-python'), 'qt' => array('video/quicktime'), 'ra' => array('audio/x-realaudio'), 'ram' => array('audio/x-realaudio', 'audio/x-pn-realaudio'), 'rar' => array('application/rar'), 'rgb' => array('image/x-rgb'), 'rm' => array('audio/x-pn-realaudio'), 'rpm' => array('audio/x-pn-realaudio-plugin', 'application/x-redhat-package-manager'), 'rss' => array('application/rss+xml'), 'rtf' => array('text/rtf'), 'rtx' => array('text/richtext'), 'rv' => array('video/vnd.rn-realvideo'), 'sea' => array('application/octet-stream'), 'sh' => array('text/x-sh'), 'shtml' => array('text/html'), 'sit' => array('application/x-stuffit'), 'smi' => array('application/smil'), 'smil' => array('application/smil'), 'so' => array('application/octet-stream'), 'src' => array('application/x-wais-source'), 'svg' => array('image/svg+xml'), 'swf' => array('application/x-shockwave-flash'), 't' => array('application/x-troff'), 'tar' => array('application/x-tar'), 'tcl' => array('text/x-tcl'), 'tex' => array('application/x-tex'), 'text' => array('text/plain'), 'texti' => array('application/x-texinfo'), 'textinfo' => array('application/x-texinfo'), 'tgz' => array('application/x-tar'), 'tif' => array('image/tiff'), 'tiff' => array('image/tiff'), 'torrent' => array('application/x-bittorrent'), 'tr' => array('application/x-troff'), 'tsv' => array('text/tab-separated-values'), 'txt' => array('text/plain'), 'wav' => array('audio/x-wav'), 'wax' => array('audio/x-ms-wax'), 'wbxml' => array('application/wbxml'), 'wm' => array('video/x-ms-wm'), 'wma' => array('audio/x-ms-wma'), 'wmd' => array('application/x-ms-wmd'), 'wmlc' => array('application/wmlc'), 'wmv' => array('video/x-ms-wmv', 'application/octet-stream'), 'wmx' => array('video/x-ms-wmx'), 'wmz' => array('application/x-ms-wmz'), 'word' => array('application/msword', 'application/octet-stream'), 'wp5' => array('application/wordperfect5.1'), 'wpd' => array('application/vnd.wordperfect'), 'wvx' => array('video/x-ms-wvx'), 'xbm' => array('image/x-xbitmap'), 'xcf' => array('image/xcf'), 'xhtml' => array('application/xhtml+xml'), 'xht' => array('application/xhtml+xml'), 'xl' => array('application/excel', 'application/vnd.ms-excel'), 'xla' => array('application/excel', 'application/vnd.ms-excel'), 'xlc' => array('application/excel', 'application/vnd.ms-excel'), 'xlm' => array('application/excel', 'application/vnd.ms-excel'), 'xls' => array('application/excel', 'application/vnd.ms-excel'), 'xlt' => array('application/excel', 'application/vnd.ms-excel'), 'xml' => array('text/xml'), 'xof' => array('x-world/x-vrml'), 'xpm' => array('image/x-xpixmap'), 'xsl' => array('text/xml'), 'xvid' => array('video/x-xvid'), 'xwd' => array('image/x-xwindowdump'), 'z' => array('application/x-compress'), 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed') ); ./kohana/system/config/sql_types.php0000644000175000017500000000434411207465364017344 0ustar tokkeetokkee array('type' => 'int', 'max' => 127), 'smallint' => array('type' => 'int', 'max' => 32767), 'mediumint' => array('type' => 'int', 'max' => 8388607), 'int' => array('type' => 'int', 'max' => 2147483647), 'integer' => array('type' => 'int', 'max' => 2147483647), 'bigint' => array('type' => 'int', 'max' => 9223372036854775807), 'float' => array('type' => 'float'), 'float unsigned' => array('type' => 'float', 'min' => 0), 'boolean' => array('type' => 'boolean'), 'time' => array('type' => 'string', 'format' => '00:00:00'), 'time with time zone' => array('type' => 'string'), 'date' => array('type' => 'string', 'format' => '0000-00-00'), 'year' => array('type' => 'string', 'format' => '0000'), 'datetime' => array('type' => 'string', 'format' => '0000-00-00 00:00:00'), 'timestamp with time zone' => array('type' => 'string'), 'char' => array('type' => 'string', 'exact' => TRUE), 'binary' => array('type' => 'string', 'binary' => TRUE, 'exact' => TRUE), 'varchar' => array('type' => 'string'), 'varbinary' => array('type' => 'string', 'binary' => TRUE), 'blob' => array('type' => 'string', 'binary' => TRUE), 'text' => array('type' => 'string') ); // DOUBLE $config['double'] = $config['double precision'] = $config['decimal'] = $config['real'] = $config['numeric'] = $config['float']; $config['double unsigned'] = $config['float unsigned']; // BIT $config['bit'] = $config['boolean']; // TIMESTAMP $config['timestamp'] = $config['timestamp without time zone'] = $config['datetime']; // ENUM $config['enum'] = $config['set'] = $config['varchar']; // TEXT $config['tinytext'] = $config['mediumtext'] = $config['longtext'] = $config['text']; // BLOB $config['tsvector'] = $config['tinyblob'] = $config['mediumblob'] = $config['longblob'] = $config['clob'] = $config['bytea'] = $config['blob']; // CHARACTER $config['character'] = $config['char']; $config['character varying'] = $config['varchar']; // TIME $config['time without time zone'] = $config['time']; ./kohana/system/config/image.php0000644000175000017500000000044711121324570016367 0ustar tokkeetokkee '127.0.0.1', 'port' => 11211, 'persistent' => FALSE, ) ); /** * Enable cache data compression. */ $config['compression'] = FALSE; ./kohana/application/0000755000175000017500000000000011263472433014312 5ustar tokkeetokkee./kohana/application/hooks/0000755000175000017500000000000011263472433015435 5ustar tokkeetokkee./kohana/application/cache/0000755000175000017500000000000011263472433015355 5ustar tokkeetokkee./kohana/application/helpers/0000755000175000017500000000000011263472433015754 5ustar tokkeetokkee./kohana/application/views/0000755000175000017500000000000011263472433015447 5ustar tokkeetokkee./kohana/application/views/welcome_content.php0000644000175000017500000000123711121324570021337 0ustar tokkeetokkee

    This is the default Kohana index page. You may also access this page as .

    To change what gets displayed for this page, edit application/controllers/welcome.php.
    To change this text, edit application/views/welcome_content.php.

      $url): ?>
    ./kohana/application/models/0000755000175000017500000000000011263472433015575 5ustar tokkeetokkee./kohana/application/libraries/0000755000175000017500000000000011263472433016266 5ustar tokkeetokkee./kohana/application/logs/0000755000175000017500000000000011263472433015256 5ustar tokkeetokkee./kohana/application/controllers/0000755000175000017500000000000011263472433016660 5ustar tokkeetokkee./kohana/application/controllers/examples.php0000644000175000017500000003310311176355175021215 0ustar tokkeetokkeeExamples:\n"; echo "
      \n"; foreach ($examples as $method) { if ($method == __FUNCTION__) continue; echo '
    • '.html::anchor('examples/'.$method, $method)."
    • \n"; } echo "
    \n"; echo '

    '.Kohana::lang('core.stats_footer')."

    \n"; } /** * Demonstrates how to archive a directory. First enable the archive module */ //public function archive($build = FALSE) //{ // if ($build === 'build') // { // // Load archive // $archive = new Archive('zip'); // // Download the application/views directory // $archive->add(APPPATH.'views/', 'app_views/', TRUE); // // Download the built archive // $archive->download('test.zip'); // } // else // { // echo html::anchor(Router::$current_uri.'/build', 'Download views'); // } //} /** * Demonstrates how to parse RSS feeds by using DOMDocument. */ function rss() { // Parse an external atom feed $feed = feed::parse('http://dev.kohanaphp.com/projects/kohana2/activity.atom'); // Show debug info echo Kohana::debug($feed); echo Kohana::lang('core.stats_footer'); } /** * Demonstrates the Session library and using session data. */ function session() { // Gets the singleton instance of the Session library $s = Session::instance(); echo 'SESSID:
    '.session_id()."
    \n"; echo '
    '.print_r($_SESSION, TRUE)."
    \n"; echo '
    {execution_time} seconds'; } /** * Demonstrates how to use the form helper with the Validation libraryfor file uploads . */ function form() { // Anything submitted? if ($_POST) { // Merge the globals into our validation object. $post = Validation::factory(array_merge($_POST, $_FILES)); // Ensure upload helper is correctly configured, config/upload.php contains default entries. // Uploads can be required or optional, but should be valid $post->add_rules('imageup1', 'upload::required', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[1M]'); $post->add_rules('imageup2', 'upload::required', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[1M]'); // Alternative syntax for multiple file upload validation rules //$post->add_rules('imageup.*', 'upload::required', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[1M]'); if ($post->validate() ) { // It worked! // Move (and rename) the files from php upload folder to configured application folder upload::save('imageup1'); upload::save('imageup2'); echo 'Validation successfull, check your upload folder!'; } else { // You got validation errors echo '

    validation errors: '.var_export($post->errors(), TRUE).'

    '; echo Kohana::debug($post); } } // Display the form echo form::open('examples/form', array('enctype' => 'multipart/form-data')); echo form::label('imageup', 'Image Uploads').':
    '; // Use discrete upload fields // Alternative syntax for multiple file uploads // echo form::upload('imageup[]').'
    '; echo form::upload('imageup1').'
    '; echo form::upload('imageup2').'
    '; echo form::submit('upload', 'Upload!'); echo form::close(); } /** * Demontrates how to use the Validation library to validate an arbitrary array. */ function validation() { // To demonstrate Validation being able to validate any array, I will // be using a pre-built array. When you load validation with no arguments // it will default to validating the POST array. $data = array ( 'user' => 'hello', 'pass' => 'bigsecret', 'reme' => '1' ); $validation = new Validation($data); $validation->add_rules('user', 'required', 'length[1,12]')->pre_filter('trim', 'user'); $validation->add_rules('pass', 'required')->post_filter('sha1', 'pass'); $validation->add_rules('reme', 'required'); $result = $validation->validate(); var_dump($validation->errors()); var_dump($validation->as_array()); // Yay! echo '{execution_time} ALL DONE!'; } /** * Demontrates how to use the Captcha library. */ public function captcha() { // Look at the counters for valid and invalid // responses in the Session Profiler. new Profiler; // Load Captcha library, you can supply the name // of the config group you would like to use. $captcha = new Captcha; // Ban bots (that accept session cookies) after 50 invalid responses. // Be careful not to ban real people though! Set the threshold high enough. if ($captcha->invalid_count() > 49) exit('Bye! Stupid bot.'); // Form submitted if ($_POST) { // Captcha::valid() is a static method that can be used as a Validation rule also. if (Captcha::valid($this->input->post('captcha_response'))) { echo '

    Good answer!

    '; } else { echo '

    Wrong answer!

    '; } // Validate other fields here } // Show form echo form::open(); echo '

    Other form fields here...

    '; // Don't show Captcha anymore after the user has given enough valid // responses. The "enough" count is set in the captcha config. if ( ! $captcha->promoted()) { echo '

    '; echo $captcha->render(); // Shows the Captcha challenge (image/riddle/etc) echo '

    '; echo form::input('captcha_response'); } else { echo '

    You have been promoted to human.

    '; } // Close form echo form::submit(array('value' => 'Check')); echo form::close(); } /** * Demonstrates the features of the Database library. * * Table Structure: * CREATE TABLE `pages` ( * `id` mediumint( 9 ) NOT NULL AUTO_INCREMENT , * `page_name` varchar( 100 ) NOT NULL , * `title` varchar( 255 ) NOT NULL , * `content` longtext NOT NULL , * `menu` tinyint( 1 ) NOT NULL default '0', * `filename` varchar( 255 ) NOT NULL , * `order` mediumint( 9 ) NOT NULL , * `date` int( 11 ) NOT NULL , * `child_of` mediumint( 9 ) NOT NULL default '0', * PRIMARY KEY ( `id` ) , * UNIQUE KEY `filename` ( `filename` ) * ) ENGINE = MYISAM DEFAULT CHARSET = utf8 PACK_KEYS =0; * */ function database() { $db = new Database; $table = 'pages'; echo 'Does the '.$table.' table exist? '; if ($db->table_exists($table)) { echo '

    YES! Lets do some work =)

    '; $query = $db->select('DISTINCT pages.*')->from($table)->get(); echo $db->last_query(); echo '

    Iterate through the result:

    '; foreach ($query as $item) { echo '

    '.$item->title.'

    '; } echo '

    Numrows using count(): '.count($query).'

    '; echo 'Table Listing:
    '.print_r($db->list_tables(), TRUE).'
    '; echo '

    Try Query Binding with objects:

    '; $sql = 'SELECT * FROM '.$table.' WHERE id = ?'; $query = $db->query($sql, array(1)); echo '

    '.$db->last_query().'

    '; $query->result(TRUE); foreach ($query as $item) { echo '
    '.print_r($item, true).'
    '; } echo '

    Try Query Binding with arrays (returns both associative and numeric because I pass MYSQL_BOTH to result():

    '; $sql = 'SELECT * FROM '.$table.' WHERE id = ?'; $query = $db->query($sql, array(1)); echo '

    '.$db->last_query().'

    '; $query->result(FALSE, MYSQL_BOTH); foreach ($query as $item) { echo '
    '.print_r($item, true).'
    '; } echo '

    Look, we can also manually advance the result pointer!

    '; $query = $db->select('title')->from($table)->get(); echo 'First:
    '.print_r($query->current(), true).'

    '; $query->next(); echo 'Second:
    '.print_r($query->current(), true).'

    '; $query->next(); echo 'Third:
    '.print_r($query->current(), true).'
    '; echo '

    And we can reset it to the beginning:

    '; $query->rewind(); echo 'Rewound:
    '.print_r($query->current(), true).'
    '; echo '

    Number of rows using count_records(): '.$db->count_records('pages').'

    '; } else { echo 'NO! The '.$table.' table doesn\'t exist, so we can\'t continue =( '; } echo "

    \n"; echo 'done in {execution_time} seconds'; } /** * Demonstrates how to use the Pagination library and Pagination styles. */ function pagination() { $pagination = new Pagination(array( // Base_url will default to the current URI // 'base_url' => 'welcome/pagination_example/page/x', // The URI segment (integer) in which the pagination number can be found // The URI segment (string) that precedes the pagination number (aka "label") 'uri_segment' => 'page', // You could also use the query string for pagination instead of the URI segments // Just set this to the $_GET key that contains the page number // 'query_string' => 'page', // The total items to paginate through (probably need to use a database COUNT query here) 'total_items' => 254, // The amount of items you want to display per page 'items_per_page' => 10, // The pagination style: classic (default), digg, extended or punbb // Easily add your own styles to views/pagination and point to the view name here 'style' => 'classic', // If there is only one page, completely hide all pagination elements // Pagination->render() will return an empty string 'auto_hide' => TRUE, )); // Just echo to display the links (__toString() rocks!) echo 'Classic style: '.$pagination; // You can also use the render() method and pick a style on the fly if you want echo '
    Digg style: ', $pagination->render('digg'); echo '
    Extended style: ', $pagination->render('extended'); echo '
    PunBB style: ', $pagination->render('punbb'); echo 'done in {execution_time} seconds'; } /** * Demonstrates the User_Agent library. */ function user_agent() { foreach (array('agent', 'browser', 'version') as $key) { echo $key.': '.Kohana::user_agent($key).'
    '."\n"; } echo "

    \n"; echo 'done in {execution_time} seconds'; } /** * Demonstrates the Payment library. */ /*function payment() { $credit_card = new Payment; // You can also pass the driver name to the library to use multiple ones: $credit_card = new Payment('Paypal'); $credit_card = new Payment('Authorize'); // You can specify one parameter at a time: $credit_card->login = 'this'; $credit_card->first_name = 'Jeremy'; $credit_card->last_name = 'Bush'; $credit_card->card_num = '1234567890'; $credit_card->exp_date = '0910'; $credit_card->amount = '478.41'; // Or you can also set fields with an array and the method: $credit_card->set_fields(array('login' => 'test', 'first_name' => 'Jeremy', 'last_name' => 'Bush', 'card_num' => '1234567890', 'exp_date' => '0910', 'amount' => '487.41')); echo '
    '.print_r($credit_card, true).'
    '; echo 'Success? '; echo ($response = $credit_card->process() == TRUE) ? 'YES!' : $response; }*/ function calendar() { $profiler = new Profiler; $calendar = new Calendar($this->input->get('month', date('m')), $this->input->get('year', date('Y'))); $calendar->attach($calendar->event() ->condition('year', 2008) ->condition('month', 8) ->condition('day', 8) ->output(html::anchor('http://forum.kohanaphp.com/comments.php?DiscussionID=275', 'Learning about Kohana Calendar'))); echo $calendar->render(); } /** * Demonstrates how to use the Image libarary.. */ function image() { // For testing only, save the new image in DOCROOT $dir = realpath(DOCROOT); // Original Image filename $image = DOCROOT.'kohana.png'; // Create an instance of Image, with file // The orginal image is not affected $image = new Image($image); // Most methods are chainable // Resize the image, crop the center left $image->resize(200, 100)->crop(150, 50, 'center', 'left'); // Display image in browser. // Keep the actions, to be applied when saving the image. $image->render($keep_actions = TRUE); // Save the image, as a jpeg // Here the actions will be discarded, by default. $image->save($dir.'/mypic_thumb.jpg'); //echo Kohana::debug($image); } /** * Demonstrates how to use vendor software with Kohana. */ function vendor() { // Let's do a little Markdown shall we. $br = "\n\n"; $output = '#Marked Down!#'.$br; $output .= 'This **_markup_** is created *on-the-fly*, by '; $output .= '[php-markdown-extra](http://michelf.com/projects/php-markdown/extra)'.$br; $output .= 'It\'s *great* for user & writing about ``'.$br; $output .= 'It\'s also good at footnotes :-) [^1]'.$br; $output .= '[^1]: A footnote.'; // looks in system/vendor for Markdown.php require Kohana::find_file('vendor', 'Markdown'); echo Markdown($output); echo 'done in {execution_time} seconds'; } } // End Examples ./kohana/application/controllers/welcome.php0000644000175000017500000000366611163566360021041 0ustar tokkeetokkeetemplate->content = new View('welcome_content'); // You can assign anything variable to a view by using standard OOP // methods. In my welcome view, the $title variable will be assigned // the value I give it here. $this->template->title = 'Welcome to Kohana!'; // An array of links to display. Assiging variables to views is completely // asyncronous. Variables can be set in any order, and can be any type // of data, including objects. $this->template->content->links = array ( 'Home Page' => 'http://kohanaphp.com/', 'Documentation' => 'http://docs.kohanaphp.com/', 'Forum' => 'http://forum.kohanaphp.com/', 'License' => 'Kohana License.html', 'Donate' => 'http://kohanaphp.com/donate', ); } public function __call($method, $arguments) { // Disable auto-rendering $this->auto_render = FALSE; // By defining a __call method, all pages routed to this controller // that result in 404 errors will be handled by this method, instead of // being displayed as "Page Not Found" errors. echo 'This text is generated by __call. If you expected the index page, you need to use: welcome/index/'.substr(Router::$current_uri, 8); } } // End Welcome Controller./kohana/application/config/0000755000175000017500000000000011263472433015557 5ustar tokkeetokkee./kohana/application/config/config.php0000644000175000017500000000722611211620440017526 0ustar tokkeetokkee Kohana Installation

    Environment Tests

    The following tests have been run to determine if Kohana will work in your environment. If any of the tests have failed, consult the documentation for more information on how to correct the problem.

    =')): ?>
    PHP Version Kohana requires PHP 5.2 or newer, this version is .
    System Directory The configured system directory does not exist or does not contain required files.
    Application Directory The configured application directory does not exist or does not contain required files.
    Modules Directory The configured modules directory does not exist or does not contain required files.
    PCRE UTF-8 PCRE support is missing. PCRE has not been compiled with UTF-8 support. PCRE has not been compiled with Unicode property support. Pass
    Reflection Enabled Pass PHP reflection is either not loaded or not compiled in.
    Filters Enabled Pass The filter extension is either not loaded or not compiled in.
    Iconv Extension Loaded Pass The iconv extension is not loaded.
    SPL Enabled Pass SPL is not enabled.
    Mbstring Not Overloaded The mbstring extension is overloading PHP's native string functions. Pass
    XML support PHP is compiled without XML support, thus lacking support for utf8_encode()/utf8_decode(). Pass
    URI Determination Pass Neither $_SERVER['REQUEST_URI'] or $_SERVER['PHP_SELF'] is available.

    Kohana may not work correctly with your environment.

    Your environment passed all requirements. Remove or rename the install file now.

    ./kohana/example.htaccess0000644000175000017500000000063711053614635015166 0ustar tokkeetokkee# Turn on URL rewriting RewriteEngine On # Installation directory RewriteBase /kohana/ # Protect application and system files from being viewed RewriteRule ^(application|modules|system) - [F,L] # Allow any files or directories that exist to be displayed directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # Rewrite all other URLs to index.php/URL RewriteRule .* index.php/$0 [PT,L]./kohana/Kohana License.html0000644000175000017500000000422510753177703015451 0ustar tokkeetokkee Kohana License

    Kohana License Agreement

    This license is a legal agreement between you and the Kohana Software Foundation for the use of Kohana Framework (the "Software"). By obtaining the Software you agree to comply with the terms and conditions of this license.

    Copyright (c) 2007-2008 Kohana Team
    All rights reserved.

    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.
    • Neither the name of the Kohana nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR 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.

    NOTE: This license is modeled after the BSD software license.

    ./kohana/kohana.png0000644000175000017500000005567310754770712014003 0ustar tokkeetokkeePNG  IHDRIw pHYsHHFk> vpAg[*IDATxwu;ުzsB#A`&0A%Yʒ-e[^i-ٲVVږdQ,K$JH'8I$`B{Q~Я9lWuVկ9sW^X$$$$K"X DV `%$$JHHX5$jH+!!aՐVBBª!UC"X DV `%$$JHHX5$jH+!!aՐVBBª!UC"X DV `%$$JHHX5$jH+!!aՐVBBª!UC"X DV `%$$n@-ձF&VJv9O+aq$u[\1&!j$dʏ D{,3[!m) @`=zIk rxChR%U d"#c&C)V"%s-Q O"X@2ׇotzjAV'tUƙz-mdc@WFeEnF Y;5z)aHȦ`K¨B&<8Es;D B+:EW Hi"$nI%2H C "bDdkW=عSM0'ւLz"6 D9 ?GT4jy,*XB'C?,#7r.4L=P`]iC b.DcEDD (MDB+*6S&dQ ۀ0(F "ي͂bL7g$$u9cI3Vâ%:mvĚ, K9ׁfW&ðuUbCkdpupZ!uRey2'B13`!Ю?'C ˎ01ښ[Ȯ*UE["& ' u&Q^%Bv*'brE&~|&E b2TLٰe\UU8M羜\ԜȬ$5'F ^Z&#kvrHDI1a鈝&D (E(A94OY{%}o+.U"ȂLDVoB߄+GAU(%UWК"֪l)}ӿ!^߆U)Q5a%ڕ0/`͆j~##kل(Q`EDD$pQ0-&`.G1*|Uum"B~1tK)JHX<`Ǵ$ NZ0>hU5N"2v{VĘſUPϳx!L|~j5:Ճ)NZW,6$ëIk5^yI+EaYaƱxf0; LY NARyjd#֊5r }D4kGcaLLPbU‚$5ű5H)&@bC?mUFDJ )Zj2VDE9si_{Ԅ8!XD)Qk ِiLh˶JDՊ|!j[$- ЮrRJHffչ &$\D=WG*1E}Ѩ+\T%,IZÚO\n7jj5@Jvּ$nVHr {B-"ЮV *IHX<`]"!Z!9t5b~zNb^*g vE="pӎL;k\A d4B90K=Ba"5IBŠ"k(yFĂ&1 +ͭog,fLEn!@jQs abI*zr[lhܧF8]sL QݪϠXjɇ}'^&)VWx)xMH鼫gw/0Q%35 :"[lPgSzG^@o8a|XUnIٸ bpa›c@.H&&bc3~CĨ4@_s찐%$\/n}bł!L2ߙ_|/ Mi2ZlUYQ~LW ׍[}%qϔN-6:@%Wktn ʁf/X!w`Bbڈa Nv#:" q@,JW דFh=.@DOnI-{?Ր[@Nٹ |X0dC+մt~b&[*NXM~#Yㄿ)舅,DلѪ:G6n`a C5K `C;e: xufsŒ דHdN,  @ B?-׌Y%U+Vt$*qҳLsO3Q+[ nFXQs{Ю+L"^ ׉~ B~S8K4n /3`zƍ "`M0,Jʬy >hϑDn(`˒Rf{nيӎZzUrX\%`nK ixTOa͋hmjQ׀_ΙW/;>nڋ{Ӛ*0܄M `-+R%y3SB9* J/0DkJ*#R45kaBS ̄E(I-^s42MSt,3.u5\ՠ%: 00A٪JPE:R}OX&hN397ѸOdz:b!V&ڷ(nEHuKjip}d);GXTچt!=Yk~!žαM.}*2 tC\іMQ:*78չ{šYr@k5~lr@TঀѶBAFB }Ollo;w=92<{bq禦.3:BrKx63Iܜb:12tI?>svmw? N2,"029nS -"kBhw$N!w]/|@l3pR(pJyb\lx[>ptç&kz;~;wi (yhckCX`qIN 59oL]w4ysKWGAXXOxcd&`^9n氆Nb6n}KP){>)O3]P.~mܓھWr1uq>7O;vxV ֈY+s"XNj۳_"+q^ 31&\,u7[/X R6ݗ|),@'li.{'Cs.ty{o<]iDSŲW.Fd*qXd"6ppf/c]GXD3mvnZ/qm51#w=|SGC%hVbm< B궭"]E0lab |9}𞃗ʜ>yP޴"%R3? Dby 6^QWXX䜍=%Xю;-Z+*TN| m~÷f#]|3H)hZW)R ? %L^ܔi:|I"|tglCɌ]p"5lڽ3ϻ^y ^u7r>gEiҚ SHH;ʆ6Y\hiti9+ Ϊ `^9Jی}k5R@cwRvx/JvH9.*w&EX߆]NSJi^%񆳧`k퇙1TB߶7հCo4?C<#ٖ/eq1aׅMw)`-ҙUV+Ns_t&JoǾ'6Q"TJ&rڪNSی`r)+46眿`)];4t]X7F̟kN1Lm;sHq+-SD 1r<5KW#Sɢg/nyJum_ ߽!g鷸P{.R{V[oݥMwTu3k?8FϷQ V$:aޑUh:_>wŒ։ǕvYO){妚er"+T8}{L.]le^`zRGD,圍UҮ=?! Ɵ K_B(#Zb3};P`v>q<.&EwUu1cI5#-nq,% ^jȌ8 㸬J M\R [6C+at|x].B@Q;7M04pxKn?.W^[\4iDx񍍭o7$S ڻ[Λ?vCΔ-^sRz|M+ P9#p< GQ jC-PJa•Xy#\0U`2)ڱ|8^n,2kl6*i  P(RE2 `!k'ZfX 72;m6kji9bNղw'hoyJ3AES8R \'?-J,mLJZ%r‡zѩQ9 Lx /,UT0E FfyG _Xb)<[J  X&e)ꢪkmDW+I S9o`gS_ 8uoRi؅ՃVh5 b_s뙉J6u-YZlLo(64"N^pnd@, )O("Z%Q%^,!pg'*&jj@M*E -p>Jbmbv,`޽= WTSފYM@g6Ugsr8;{tMˌbaβIBct!^mBj*\YP,2/9@ CX-UR\{ B0j1[>n *;r:vDzϮ GNovF\I$NE"aR^5ud\/x rs U;i`6f|߽V~g_4 ƿWhxE΄@ԌNN3#"/& `+uJ;7$vvxY yLݳio%]*~xރd_yy ?5@UXӓf]uA,_N8)v6^ Rԗf+fg+ kgD &o ]~ JO,oiM_ He)pEH1,w@KfLI#I\G&N11r-w:>P uB_@5SF&>@?Өc a샰& ]!p{/n]Mj~8Z[I!mq{Ӫxf̖ŭhWacrGkOm: 3~G7,ܞK%B."h4X.5B Pi<nN鸈 JΓ nhx' R)NW AϑM-AgwO,0C"Ƃ;DwG=3SӗEJ92[\B%8~]'0B^M ʬ(=/"ۘkio.p5W ,5}ںwN2lAYKw$J\3RJ ToWo=~m'UJēRDd.O8xLK5 &)uu }BB] f.S3bjقMo. v-w]*Wݳ%gIgi3|݈` .Zϰ\Gڠ65uk0떯:m\D!B3vvmBx U b)i j +`@"SLiG7 MKd OxQBj^MTk"]@&KmPuFP\@ܙH,~z/9_#""ކލϼPؕO_qJ&v}k5jV~~Kw{źX9O_`bT-WzU7q&Ub{xc kOߔVkED@&]/I yNf;V`]홮eݷLX0@Dܵ`U=a!c_lP j%#SCC=6o&XBSpUDLlǔ -ldގG=lo杽5z)АRP:A(R D\gˆɐY@l*0c48@W~.8;6,"omý.w(ͻ7ؒYBʼv,JPug?M#k-1j,4w=wP '\QTg8JL7z? CoLdV_0[8.]uʆDpGW3W,d,)L ]'8 ^N;-[6y-;Hc&ZIkHJdW{3?  d":l^q'u<5a[[7~."L;1LpἁҠK{N3Dq9Rv)HPa5xbO^Y"}cY_~U/u6K-\FCT.QN֜JxL*r+Zl&V oªR f'L2%!;]xq>љ5{sm6Z}e%DwΝ GG}QJ13]|ޟim۾i;To_7_2mXظ~| ".W솔8= pr஝xAI1;sr,ؕrB(İ]i0{zP>jv1aeoY&cz`skllڵ;pK|)];" TbAN (̦\1̡//.«JEӥ (nc{8*WF4"*`C8D؇8zᎦl{/C^}6'cBPCfu7nDRD J{!e\Ҹ7fѤ& G̹o7Ⱥ;_|:}Ah tϾTR7tlZsaD)XRzJ+Tz}XU2^!;zK>tpW"j.0σˡɰL8T[s]z/P(ȰH@/B# s:=Yєf)8:\1P,(e1B3 2Ǐ+h/9zƊW(FpYyV`U$s85b!"RAdk {~H߽8цauPKJ9LLd(6rPI!JpaC+a9x>PjUF5ci_Q`XHykly";i e,֊5I)N:tQ5y.24UBk*R](y<1P&3 X5bMa5:xN"J+a )hid$\|KђYIGsˑS>V`R^k#,6Pe8vZ]Qk > e;'_[aX=I)tJT@<n*GlSY֬H{jA)tDA h!#+H)߆X /[E` Zf_jN_z6}}O ~R v~&@h_ !E6W<1EyL`>F NZմ@b-jD9' c`Z02/4SVAo[+h-+Y8r&O_Y"1ec22k'ͥ9 C)YH;dy!>4X+`:4+V6QȔIi){ܥ&bjAvajPn,͈S'4V3qN;.<K k۪,mw/\{02^xtnQ#7ݷo0 E JzؚH zdk,&Zg"bB]rTP`2LG>ܵ|jZēA앞=-as(@.d-Ò΁U,s](.'|졭_z 6=z߸|C"PY8>qKV|ge*ggNkMY9"$|eF*F( d]\S\SW]{lTSt%, ؓsFba\[]r ִ@H/D"OiXa4v4=-Fj:OELb1Vh*=ʲF++̿"f)Rka1JÚ̇ĚRyzJ"?DU^<[r\(0RqÛ)b'_\9ɺ 66EZg)r5"8xMxjVwU+/[lj~#dX=X#z-K+E3 Ch\0bā^# ll9˹ jhPM tZՁY bBfo;>,[ʹPPgƧ$ *r"?rM9DfP^_ VNJ.=RnZO[GQYrY#?Fx$z@[a9Q7a/D(nFOD`IYnbگ!VNJKeb@,MISkZcAne2FD ’:`&|#qSR֜:U0IDaAL찛rfu#Nᤝi*j5"KzZ9'{2fi4ckyIDJ'Rp4 Ml: sf0N p݋r&>a>g*LdMh1SR9'gDacM<) `is\?Qnye:{YՁkXD:"Bor^L:CT~ۈMd V,İM(D -(ZQIkR^p3O z V8ň5b#1㴐b!._RX8V9!/|6 [&Ee׍ZT%\ Ўr2JH:2k6XG մ=tlmȦ'/κ>}HƟ(^.?avv~Kǫ_,-&jwM~+U?wt|ZSm0kIcןY'Y:e'-,XÎ8 G?+|ɍXkXxZ=HNIG?1¢idmݞj<7,GnSml;~d2<_]W?wonC}~οV?ljz$6xrsvlS_Ğ|Vxu~E1GO =].N6am-??poJc0oGgli-vw~v8rx5GOD=u^p}*UDP6Yj@sR9]M al*キTVPPx]$C~r ~/ sEB!rg?5^b>>99|w*( ?jރ\Z5lt?Qh.ظ߽߼x?󫬧 滷ߎ?ßc=}OTi|W?MSb|7~{oZ#MaD&(W#_}t;7FXrJ~^&oKǟW"^'vſ~)((~=sFCSd׺kٵoY)vOlxwV5Ū>ߵ6 CSݾ{snG'{47tZcsSs^^ATg6FG_}g?U?7O>>ܴh~nK~a!"бwSvY[g_V'mb?"O ǏWO|Ⴜ6ǿ_x_x?%-}#=q4Ūo2,|~r_ş4D{>8[N5s:G,VERcPPZǙD` 58Q*E  طΎ8Ͻp׾/5RyR)L,(cX###}lNF DT*q/)r$ŖӠ!_O?:=*ؐv~??^nnt6}~[9r$L"]y`\|t|)/R"m]S1ڕ_}q$c~?5TPxPN+^d1o 0(2oR<'GA86y9Ҙv8 #[Zڜ%"/ip<܅s{o "h@i_3NNgySAXLpW;;sފ~T:TùY!vMG1ȿ2IR^+4rah{?Ku4QtԞro+j.[_{?[*囐ץ3_=s<.ff+׾(t!Ҩ}G?}j7A!gC>#7~`9%$M:=~M Ku@$"ȔS꭛(ʪ?^/7o*R.޴:^B R֊S&BbٿlėW_3Z]jzu=36仿s3]!ة {珿[`?z*5Qw=69whb{z+15nj7ִv"6~ߛ(\ϲB`ԜHնq_Mϼ'7̙ٽ(zrc;g8;#nf O|c_;y,UZI58nV6BV`v[kR^4d*hW;ЮJ5NF: #HAPv$fݨ-nk❆%S g+QCեƴn8oTF{c ?ܡ6W?S/rZ-jc_>ڽ~ m޹W=N82U2@ShCC1/)k|"s39=#sGG,muE&desVy)5Pió7LE /kNu:͹?{,TjNŜ1QR)S9[NLSݻD>=_<{ػ;O̴aʮK;// mSqob¢L\m{J+"sў_g{x-ZaGXF&B7 ^q-O((D&ie?=O$禦r6!/ؑ09gY,^Ɲ|l(њ}FzO^{?>ׯ83]ȑsy8:2/Gž_&Wn=G;C֦:EIqBnjwgkhu0hImmu3TQ6s<]ICb[nKG^G{ٵ?_zO3Y-LN mrv|/ ^g.PLx_{g7d=2{-f~D=.}svIѷOɏ=ovnԙr)l,n~8޴u3oږ}v`m(o?Ċ`s}a`~ٟr:foؼfsŮ`AXSؔvJ9#כ*[t=\M+@`%RxWq/P`&JOT*k뻀IMlhN_z~/kqu="4-#?77ܿw'g?~OLnvצq?x3ViT~[{f9:jg^zZ79 @6Ċ{Bi2. 80rNi8LJ_HhD,"\qn0߳V)/džE.< G׵z_<6Jg>{ayt~N}s[Ymv拇sJ{Mh}]ޟ*!,/|èl2X4ɷ3n c!I);:>塜~njQ<(|H)C%?gcwnԻn8;s~o _YA29 2Bb{|J䤴rHH*iY(j^+Eup\JeM {Q'>2c;k?ot w9ScƤSYzȿxOh}täyG Vl*zi71ywx8/o{gw23GRE{/ R9 JeU{?Rɪonhx(heә8E.jpܔN\rP]#?W?V䦝Tr;('Tβjuq2Ϳj9ԧcw0H]C)y]c9n*OOĦ{>X 'pjȈZM= (6DmJL⩬0VP5RjfoNLe=P-Ȯ|?Yx{z 4|??=] t_qޅXѾg'{_U`<>&͋O!0QཕvfϐiruvNYMu.̢s/jZk?;~?_F\"ZEWTYmwF2ZZ{ `z -(49ArCrzrĮEBJHH)cfUTbAȏLq@A]y JH5&-ALS+TGW8T% ,t*ۈ=VBBª!UC"X DV `%$$JHHX5$jH+!!aՐVBBª!UC"X DV `%$$JHHX5$jH+!!aՐVBBª!UC"X DV `%$$JHHX5$jH+!!aՐVBBª!UC"X DV `%$$hk4ea"zTXtSoftwarexsLOJUMLO JML/Ԯ MIENDB`./kohana/index.php0000644000175000017500000000713611135434604013632 0ustar tokkeetokkeepre_filter('trim') ->add_rules('name', 'required', 'length[4,32]') ->add_rules('description', 'length[0,255]'); return parent::validate($array, $save); } /** * Allows finding roles by name. */ public function unique_key($id) { if ( ! empty($id) AND is_string($id) AND ! ctype_digit($id)) { return 'name'; } return parent::unique_key($id); } } // End Auth Role Model./kohana/modules/auth/models/auth_user.php0000644000175000017500000001023311207325052020402 0ustar tokkeetokkeehash_password($value); } parent::__set($key, $value); } /** * Validates and optionally saves a new user record from an array. * * @param array values to check * @param boolean save the record when validation succeeds * @return boolean */ public function validate(array & $array, $save = FALSE) { $array = Validation::factory($array) ->pre_filter('trim') ->add_rules('email', 'required', 'length[4,127]', 'valid::email', array($this, 'email_available')) ->add_rules('username', 'required', 'length[4,32]', 'chars[a-zA-Z0-9_.]', array($this, 'username_available')) ->add_rules('password', 'required', 'length[5,42]') ->add_rules('password_confirm', 'matches[password]'); return parent::validate($array, $save); } /** * Validates login information from an array, and optionally redirects * after a successful login. * * @param array values to check * @param string URI or URL to redirect to * @return boolean */ public function login(array & $array, $redirect = FALSE) { $array = Validation::factory($array) ->pre_filter('trim') ->add_rules('username', 'required', 'length[4,127]') ->add_rules('password', 'required', 'length[5,42]'); // Login starts out invalid $status = FALSE; if ($array->validate()) { // Attempt to load the user $this->find($array['username']); if ($this->loaded AND Auth::instance()->login($this, $array['password'])) { if (is_string($redirect)) { // Redirect after a successful login url::redirect($redirect); } // Login is successful $status = TRUE; } else { $array->add_error('username', 'invalid'); } } return $status; } /** * Validates an array for a matching password and password_confirm field. * * @param array values to check * @param string save the user if * @return boolean */ public function change_password(array & $array, $save = FALSE) { $array = Validation::factory($array) ->pre_filter('trim') ->add_rules('password', 'required', 'length[5,127]') ->add_rules('password_confirm', 'matches[password]'); if ($status = $array->validate()) { // Change the password $this->password = $array['password']; if ($save !== FALSE AND $status = $this->save()) { if (is_string($save)) { // Redirect to the success page url::redirect($save); } } } return $status; } /** * Tests if a username exists in the database. This can be used as a * Valdidation rule. * * @param mixed id to check * @return boolean * */ public function username_exists($id) { return $this->unique_key_exists($id); } /** * Does the reverse of unique_key_exists() by returning TRUE if user id is available * Validation rule. * * @param mixed id to check * @return boolean */ public function username_available($username) { return ! $this->unique_key_exists($username); } /** * Does the reverse of unique_key_exists() by returning TRUE if email is available * Validation Rule * * @param string $email * @return void */ public function email_available($email) { return ! $this->unique_key_exists($email); } /** * Tests if a unique key value exists in the database * * @param mixed value the value to test * @return boolean */ public function unique_key_exists($value) { return (bool) $this->db ->where($this->unique_key($value), $value) ->count_records($this->table_name); } /** * Allows a model to be loaded by username or email address. */ public function unique_key($id) { if ( ! empty($id) AND is_string($id) AND ! ctype_digit($id)) { return valid::email($id) ? 'email' : 'username'; } return parent::unique_key($id); } } // End Auth User Model./kohana/modules/auth/models/user_token.php0000644000175000017500000000027411121324570020564 0ustar tokkeetokkeenow = time(); if (mt_rand(1, 100) === 1) { // Do garbage collection $this->delete_expired(); } if ($this->expires < $this->now) { // This object has expired $this->delete(); } } /** * Overload saving to set the created time and to create a new token * when the object is saved. */ public function save() { if ($this->loaded === FALSE) { // Set the created time, token, and hash of the user agent $this->created = $this->now; $this->user_agent = sha1(Kohana::$user_agent); } // Create a new token each time the token is saved $this->token = $this->create_token(); return parent::save(); } /** * Deletes all expired tokens. * * @return void */ public function delete_expired() { // Delete all expired tokens $this->db->where('expires <', $this->now)->delete($this->table_name); return $this; } /** * Finds a new unique token, using a loop to make sure that the token does * not already exist in the database. This could potentially become an * infinite loop, but the chances of that happening are very unlikely. * * @return string */ protected function create_token() { while (TRUE) { // Create a random token $token = text::random('alnum', 32); // Make sure the token does not already exist if ($this->db->select('id')->where('token', $token)->get($this->table_name)->count() === 0) { // A unique token has been found return $token; } } } /** * Allows loading by token string. */ public function unique_key($id) { if ( ! empty($id) AND is_string($id) AND ! ctype_digit($id)) { return 'token'; } return parent::unique_key($id); } } // End Auth User Token Model./kohana/modules/auth/models/role.php0000644000175000017500000000025211121324570017343 0ustar tokkeetokkeeusers = empty($config['users']) ? array() : $config['users']; } /** * Logs a user in. * * @param string username * @param string password * @param boolean enable auto-login (not supported) * @return boolean */ public function login($username, $password, $remember) { if (isset($this->users[$username]) AND $this->users[$username] === $password) { // Complete the login return $this->complete_login($username); } // Login failed return FALSE; } /** * Forces a user to be logged in, without specifying a password. * * @param mixed username * @return boolean */ public function force_login($username) { // Complete the login return $this->complete_login($username); } /** * Get the stored password for a username. * * @param mixed username * @return string */ public function password($username) { return isset($this->users[$username]) ? $this->users[$username] : FALSE; } } // End Auth_File_Driver./kohana/modules/auth/libraries/drivers/Auth/ORM.php0000644000175000017500000001147511200416640022116 0ustar tokkeetokkeesession->get($this->config['session_key']); if (is_object($user) AND $user instanceof User_Model AND $user->loaded) { // Everything is okay so far $status = TRUE; if ( ! empty($role)) { // If role is an array if (is_array($role)) { // Check each role foreach ($role as $role_iteration) { if ( ! is_object($role_iteration)) { $role_iteration = ORM::factory('role', $role_iteration); } // If the user doesn't have the role if( ! $user->has($role_iteration)) { // Set the status false and get outta here $status = FALSE; break; } } } else { // Else just check the one supplied roles if ( ! is_object($role)) { // Load the role $role = ORM::factory('role', $role); } // Check that the user has the given role $status = $user->has($role); } } } return $status; } /** * Logs a user in. * * @param string username * @param string password * @param boolean enable auto-login * @return boolean */ public function login($user, $password, $remember) { if ( ! is_object($user)) { // Load the user $user = ORM::factory('user', $user); } // If the passwords match, perform a login if ($user->has(ORM::factory('role', 'login')) AND $user->password === $password) { if ($remember === TRUE) { // Create a new autologin token $token = ORM::factory('user_token'); // Set token data $token->user_id = $user->id; $token->expires = time() + $this->config['lifetime']; $token->save(); // Set the autologin cookie cookie::set('authautologin', $token->token, $this->config['lifetime']); } // Finish the login $this->complete_login($user); return TRUE; } // Login failed return FALSE; } /** * Forces a user to be logged in, without specifying a password. * * @param mixed username * @return boolean */ public function force_login($user) { if ( ! is_object($user)) { // Load the user $user = ORM::factory('user', $user); } // Mark the session as forced, to prevent users from changing account information $_SESSION['auth_forced'] = TRUE; // Run the standard completion $this->complete_login($user); } /** * Logs a user in, based on the authautologin cookie. * * @return boolean */ public function auto_login() { if ($token = cookie::get('authautologin')) { // Load the token and user $token = ORM::factory('user_token', $token); if ($token->loaded AND $token->user->loaded) { if ($token->user_agent === sha1(Kohana::$user_agent)) { // Save the token to create a new unique token $token->save(); // Set the new token cookie::set('authautologin', $token->token, $token->expires - time()); // Complete the login with the found data $this->complete_login($token->user); // Automatic login was successful return TRUE; } // Token is invalid $token->delete(); } } return FALSE; } /** * Log a user out and remove any auto-login cookies. * * @param boolean completely destroy the session * @return boolean */ public function logout($destroy) { if ($token = cookie::get('authautologin')) { // Delete the autologin cookie to prevent re-login cookie::delete('authautologin'); // Clear the autologin token from the database $token = ORM::factory('user_token', $token); if ($token->loaded) { $token->delete(); } } return parent::logout($destroy); } /** * Get the stored password for a username. * * @param mixed username * @return string */ public function password($user) { if ( ! is_object($user)) { // Load the user $user = ORM::factory('user', $user); } return $user->password; } /** * Complete the login for a user by incrementing the logins and setting * session data: user_id, username, roles * * @param object user model object * @return void */ protected function complete_login($user) { // Update the number of logins $user->logins += 1; // Set the last login date $user->last_login = time(); // Save the user $user->save(); return parent::complete_login($user); } } // End Auth_ORM_Driver./kohana/modules/auth/libraries/drivers/Auth.php0000644000175000017500000000537611202055577021476 0ustar tokkeetokkeesession = Session::instance(); // Store config $this->config = $config; } /** * Checks if a session is active. * * @param string role name (not supported) * @return boolean */ public function logged_in($role) { return isset($_SESSION[$this->config['session_key']]); } /** * Gets the currently logged in user from the session. * Returns FALSE if no user is currently logged in. * * @return mixed */ public function get_user() { if ($this->logged_in(NULL)) { return $_SESSION[$this->config['session_key']]; } return FALSE; } /** * Logs a user in. * * @param string username * @param string password * @param boolean enable auto-login * @return boolean */ abstract public function login($username, $password, $remember); /** * Forces a user to be logged in, without specifying a password. * * @param mixed username * @return boolean */ abstract public function force_login($username); /** * Logs a user in, based on stored credentials, typically cookies. * Not supported by default. * * @return boolean */ public function auto_login() { return FALSE; } /** * Log a user out. * * @param boolean completely destroy the session * @return boolean */ public function logout($destroy) { if ($destroy === TRUE) { // Destroy the session completely Session::instance()->destroy(); } else { // Remove the user from the session $this->session->delete($this->config['session_key']); // Regenerate session_id $this->session->regenerate(); } // Double check return ! $this->logged_in(NULL); } /** * Get the stored password for a username. * * @param mixed username * @return string */ abstract public function password($username); /** * Completes a login by assigning the user to the session key. * * @param string username * @return TRUE */ protected function complete_login($user) { // Regenerate session_id $this->session->regenerate(); // Store username in session $_SESSION[$this->config['session_key']] = $user; return TRUE; } } // End Auth_Driver./kohana/modules/auth/libraries/Auth.php0000644000175000017500000001230111207327555020005 0ustar tokkeetokkeeconfig = $config; // Set the driver class name $driver = 'Auth_'.$config['driver'].'_Driver'; if ( ! Kohana::auto_load($driver)) throw new Kohana_Exception('core.driver_not_found', $config['driver'], get_class($this)); // Load the driver $driver = new $driver($config); if ( ! ($driver instanceof Auth_Driver)) throw new Kohana_Exception('core.driver_implements', $config['driver'], get_class($this), 'Auth_Driver'); // Load the driver for access $this->driver = $driver; Kohana::log('debug', 'Auth Library loaded'); } /** * Check if there is an active session. Optionally allows checking for a * specific role. * * @param string role name * @return boolean */ public function logged_in($role = NULL) { return $this->driver->logged_in($role); } /** * Returns the currently logged in user, or FALSE. * * @return mixed */ public function get_user() { return $this->driver->get_user(); } /** * Attempt to log in a user by using an ORM object and plain-text password. * * @param string username to log in * @param string password to check against * @param boolean enable auto-login * @return boolean */ public function login($username, $password, $remember = FALSE) { if (empty($password)) return FALSE; if (is_string($password)) { // Get the salt from the stored password $salt = $this->find_salt($this->driver->password($username)); // Create a hashed password using the salt from the stored password $password = $this->hash_password($password, $salt); } return $this->driver->login($username, $password, $remember); } /** * Attempt to automatically log a user in. * * @return boolean */ public function auto_login() { return $this->driver->auto_login(); } /** * Force a login for a specific username. * * @param mixed username * @return boolean */ public function force_login($username) { return $this->driver->force_login($username); } /** * Log out a user by removing the related session variables. * * @param boolean completely destroy the session * @return boolean */ public function logout($destroy = FALSE) { return $this->driver->logout($destroy); } /** * Creates a hashed password from a plaintext password, inserting salt * based on the configured salt pattern. * * @param string plaintext password * @return string hashed password string */ public function hash_password($password, $salt = FALSE) { if ($salt === FALSE) { // Create a salt seed, same length as the number of offsets in the pattern $salt = substr($this->hash(uniqid(NULL, TRUE)), 0, count($this->config['salt_pattern'])); } // Password hash that the salt will be inserted into $hash = $this->hash($salt.$password); // Change salt to an array $salt = str_split($salt, 1); // Returned password $password = ''; // Used to calculate the length of splits $last_offset = 0; foreach ($this->config['salt_pattern'] as $offset) { // Split a new part of the hash off $part = substr($hash, 0, $offset - $last_offset); // Cut the current part out of the hash $hash = substr($hash, $offset - $last_offset); // Add the part to the password, appending the salt character $password .= $part.array_shift($salt); // Set the last offset to the current offset $last_offset = $offset; } // Return the password, with the remaining hash appended return $password.$hash; } /** * Perform a hash, using the configured method. * * @param string string to hash * @return string */ public function hash($str) { return hash($this->config['hash_method'], $str); } /** * Finds the salt from a password, based on the configured salt pattern. * * @param string hashed password * @return string */ public function find_salt($password) { $salt = ''; foreach ($this->config['salt_pattern'] as $i => $offset) { // Find salt characters, take a good long look... $salt .= $password[$offset + $i]; } return $salt; } } // End Auth./kohana/modules/auth/controllers/0000755000175000017500000000000011263472445016771 5ustar tokkeetokkee./kohana/modules/auth/config/0000755000175000017500000000000011263472445015670 5ustar tokkeetokkee./kohana/modules/auth/config/auth.php0000644000175000017500000000274411121324570017335 0ustar tokkeetokkee 'b3154acf3a344170077d11bdb5fff31532f679a1919e716a02', );./kohana/modules/smarty/0000755000175000017500000000000011263472444015000 5ustar tokkeetokkee./kohana/modules/smarty/views/0000755000175000017500000000000011263472444016135 5ustar tokkeetokkee./kohana/modules/smarty/views/demo.tpl0000644000175000017500000000007111002053537017565 0ustar tokkeetokkee

    An example of smarty template

    {$message}

    ./kohana/modules/smarty/views/demo.php0000644000175000017500000000017511121324570017562 0ustar tokkeetokkee

    Smarty is disabled!

    ./kohana/modules/smarty/libraries/0000755000175000017500000000000011263472444016754 5ustar tokkeetokkee./kohana/modules/smarty/libraries/MY_View.php0000644000175000017500000000071311145364057021004 0ustar tokkeetokkeeMY_Smarty = new MY_Smarty; } } public function _kohana_load_view($template, $vars) { if ($template == '') return; if (substr(strrchr($template, '.'), 1) === Kohana::config('smarty.templates_ext')) { // Assign variables to the template if (is_array($vars) AND count($vars) > 0) { foreach ($vars AS $key => $val) { $this->MY_Smarty->assign($key, $val); } } // Send Kohana::instance to all templates $this->MY_Smarty->assign('this', $this); // Fetch the output $output = $this->MY_Smarty->fetch($template); } else { $output = parent::_kohana_load_view($template, $vars); } return $output; } } ./kohana/modules/smarty/libraries/MY_Smarty.php0000644000175000017500000000502611121324570021341 0ustar tokkeetokkeecache_dir = Kohana::config('smarty.cache_path'); $this->compile_dir = Kohana::config('smarty.compile_path'); $this->config_dir = Kohana::config('smarty.configs_path'); $this->plugins_dir[] = Kohana::config('smarty.plugins_path'); $this->debug_tpl = Kohana::config('smarty.debug_tpl'); $this->debugging_ctrl = Kohana::config('smarty.debugging_ctrl'); $this->debugging = Kohana::config('smarty.debugging'); $this->caching = Kohana::config('smarty.caching'); $this->force_compile = Kohana::config('smarty.force_compile'); $this->security = Kohana::config('smarty.security'); // check if cache directory is exists $this->checkDirectory($this->cache_dir); // check if smarty_compile directory is exists $this->checkDirectory($this->compile_dir); // check if smarty_cache directory is exists $this->checkDirectory($this->cache_dir); if ($this->security) { $configSecureDirectories = Kohana::config('smarty.secure_dirs'); $safeTemplates = array(Kohana::config('smarty.global_templates_path')); $this->secure_dir = array_merge($configSecureDirectories, $safeTemplates); $this->security_settings['IF_FUNCS'] = Kohana::config('smarty.if_funcs'); $this->security_settings['MODIFIER_FUNCS'] = Kohana::config('smarty.modifier_funcs'); } // Autoload filters $this->autoload_filters = array('pre' => Kohana::config('smarty.pre_filters'), 'post' => Kohana::config('smarty.post_filters'), 'output' => Kohana::config('smarty.output_filters')); // Add all helpers to plugins_dir $helpers = glob(APPPATH . 'helpers/*', GLOB_ONLYDIR | GLOB_MARK); foreach ($helpers as $helper) { $this->plugins_dir[] = $helper; } } public function checkDirectory($directory) { if ((! file_exists($directory) AND ! @mkdir($directory, 0755)) OR ! is_writable($directory) OR !is_executable($directory)) { $error = 'Compile/Cache directory "%s" is not writeable/executable'; $error = sprintf($error, $directory); throw new Kohana_User_Exception('Compile/Cache directory is not writeable/executable', $error); } return TRUE; } } ./kohana/modules/smarty/controllers/0000755000175000017500000000000011263472444017346 5ustar tokkeetokkee./kohana/modules/smarty/controllers/smarty_demo.php0000644000175000017500000000050411121324570022366 0ustar tokkeetokkeemessage = "Welcome to the Kohana!"; $welcome->render(TRUE); } } ./kohana/modules/smarty/config/0000755000175000017500000000000011263472444016245 5ustar tokkeetokkee./kohana/modules/smarty/config/smarty.php0000644000175000017500000000253211121324570020264 0ustar tokkeetokkee TRUE, // Enable/Disable Smarty integration 'templates_ext' => 'tpl', 'global_templates_path' => APPPATH.'views/', 'cache_path' => APPPATH.'cache/smarty_cache/', 'compile_path' => APPPATH.'cache/smarty_compile/', 'configs_path' => APPPATH.'views/smarty_configs/', 'plugins_path' => APPPATH.'views/smarty_plugins/', 'debug_tpl' => APPPATH.'views/debug.tpl', 'debugging_ctrl' => FALSE, 'debugging' => TRUE, 'caching' => FALSE, 'force_compile' => FALSE, 'security' => TRUE, 'secure_dirs' => array // Smarty secure directories ( MODPATH.'smarty/views' ), 'if_funcs' => array // We'll allow these functions in if statement ( 'array', 'list', 'trim', 'isset', 'empty', 'sizeof', 'in_array', 'is_array', 'true', 'false', 'null', 'reset', 'array_keys', 'end', 'count' ), 'modifier_funcs' => array // We'll allow these modifiers ( 'sprintf', 'count' ), 'post_filters' => array ( ), 'output_filters' => array ( 'trimwhitespace' ), 'pre_filters' => array ( ), 'escape_exclude_list' => array ( ), ); ./kohana/modules/smarty/config/view.php0000644000175000017500000000030711121324570017715 0ustar tokkeetokkee <>> ./kohana/modules/flot/libraries/0000755000175000017500000000000011263472445016402 5ustar tokkeetokkee./kohana/modules/flot/libraries/Flot_Dataset.php0000644000175000017500000000120211121324570021443 0ustar tokkeetokkeedata[] = array($x, $y); return $this; } } // End Flot Dataset./kohana/modules/flot/libraries/Flot.php0000644000175000017500000000463111121324570020007 0ustar tokkeetokkeeattr += $attr; // Set the type, if not NULL empty($type) or $this->type = $type; // Create the data set array $this->dataset = array(); // Create the options object $this->options = new StdClass; } public function __get($key) { if ( ! isset($this->options->$key)) { // Create the object if it does not exist $this->options->$key = new StdClass; } // Return the option return $this->options->$key; } public function __set($key, $value) { // Set the option value $this->options->$key = $value; } /** * Return the rendered graph as an HTML string. * * @return string */ public function __toString() { return $this->render(); } /** * Add data to the data set. * * @chainable * @param object a constructed Flot_Dataset * @return object */ public function add(Flot_Dataset $set, $label = NULL) { // Add the label, if requested empty($label) or $set->label = $label; // Add the set to the current data set $this->dataset[] = $set; return $this; } /** * Set options. * * @chainable * @param string option name * @param mixed options value * @return object */ public function set($key, $value) { // Set the requested value $this->__set($key, $value); return $this; } /** * Return the rendered graph as an HTML string. * * @return string */ public function render($template = 'kohana_flot') { // Load the template return View::factory($template) // Set container properties ->set('type', $this->type) ->set('attr', $this->attr) // JSON encode the dataset and options ->set('dataset', array_map('json_encode', $this->dataset)) ->set('options', json_encode($this->options)) // And return the rendered view ->render(); } } // End Flot./kohana/modules/gmaps/0000755000175000017500000000000011263472445014571 5ustar tokkeetokkee./kohana/modules/gmaps/views/0000755000175000017500000000000011263472445015726 5ustar tokkeetokkee./kohana/modules/gmaps/views/gmaps/0000755000175000017500000000000011263472445017035 5ustar tokkeetokkee./kohana/modules/gmaps/views/gmaps/jquery_javascript.php0000644000175000017500000000246311121324570023304 0ustar tokkeetokkee google.load("maps", "2.x", {"language" : ""}); $(function() { if (GBrowserIsCompatible()) { // Initialize the Gmap render(1), "\n" ?> // Load map markers $.ajax ({ type: 'GET', url: '', dataType: 'xml', success: function(data, status) { $(data).find('marker').each(function() { // Current marker var node = $(this); // Extract HTML var html = node.find('html').text(); // Create a new map marker var marker = new google.maps.Marker(new google.maps.LatLng(node.attr("lat"), node.attr("lon"))); google.maps.Event.addListener(marker, "click", function() { marker.openInfoWindowHtml(html); }); // Add the marker to the map map.addOverlay(marker); }); }, error: function(request, status, error) { alert('There was an error retrieving the marker information, please refresh the page to try again.'); } }); } }); // Unload the map when the window is closed $(document.body).unload(function(){ GBrowserIsCompatible() && GUnload(); }); ./kohana/modules/gmaps/views/gmaps/xml.php0000644000175000017500000000020211121324570020324 0ustar tokkeetokkee

    title;?>,
    description;?>

    ./kohana/modules/gmaps/views/gmaps/jquery.php0000644000175000017500000000133311121324570021051 0ustar tokkeetokkee Gmaps jQuery + XML Example

    You can use your scroll wheel to zoom in and out of the map.

    ./kohana/modules/gmaps/views/gmaps/javascript.php0000644000175000017500000000133711121324570021704 0ustar tokkeetokkee google.load("maps", "2.x", {"language" : ""}); function initialize() { if (GBrowserIsCompatible()) { // Initialize the GMap render(1), "\n" ?> // Build custom marker icons render(1), "\n" ?> // Show map points render(1), "\n" ?> } } google.setOnLoadCallback(initialize);./kohana/modules/gmaps/views/gmaps/info_window.php0000644000175000017500000000073111121324570022055 0ustar tokkeetokkee
    $location->link, 'alt' => $location->title, 'width' => 100, 'height' => 100)) ?>
    title ?>
    ', implode("

    \n

    ", explode("\n\n", $location->description)), "

    \n"; ?>
    ./kohana/modules/gmaps/views/gmaps/static_demo.php0000644000175000017500000000067311121324570022033 0ustar tokkeetokkee Google Maps Static Map Example ./kohana/modules/gmaps/views/gmaps/api_demo.php0000644000175000017500000000116711121324570021314 0ustar tokkeetokkee Google Maps JavaScript API Example

    You can use your scroll wheel to zoom in and out of the map.

    ./kohana/modules/gmaps/models/0000755000175000017500000000000011263472445016054 5ustar tokkeetokkee./kohana/modules/gmaps/models/location.php0000644000175000017500000000102011121324570020352 0ustar tokkeetokkee $value) { if (in_array($key, $this->valid_options)) { // Set all valid options $this->options[$key] = (bool) $value; } } } public function render($tabs = 0) { // Create the tabs $tabs = empty($tabs) ? '' : str_repeat("\t", $tabs); // Render each option $output = array(); foreach ($this->options as $option => $value) { if ($value === TRUE) { // Add an enable $output[] = 'map.enable'.$option.'();'; } else { // Add a disable $output[] = 'map.disable'.$option.'();'; } } return implode("\n".$tabs, $output); } } // End Gmap Options./kohana/modules/gmaps/libraries/Gmap_Marker.php0000644000175000017500000000362211121324570021432 0ustar tokkeetokkeelatitude = $lat; $this->longitude = $lon; // Set the info window HTML $this->html = $html; if (count($options) > 0) { foreach ($options as $option => $value) { // Set marker options if (in_array($option, $this->valid_options, true)) $this->options[] = "$option:$value"; } } } public function render($tabs = 0) { // Create the tabs $tabs = empty($tabs) ? '' : str_repeat("\t", $tabs); // Marker ID $marker = 'm'.++self::$id; $output[] = 'var '.$marker.' = new google.maps.Marker(new google.maps.LatLng('.$this->latitude.', '.$this->longitude.'), {'.implode(",", $this->options).'});'; if ($html = $this->html) { $output[] = 'google.maps.Event.addListener('.$marker.', "click", function()'; $output[] = '{'; $output[] = "\t".$marker.'.openInfoWindowHtml('; $output[] = "\t\t'".implode("'+\n\t\t$tabs'", explode("\n", $html))."'"; $output[] = "\t);"; $output[] = '});'; } $output[] = 'map.addOverlay('.$marker.');'; return implode("\n".$tabs, $output); } } // End Gmap Marker./kohana/modules/gmaps/libraries/Gmap.php0000644000175000017500000002213211176461505020140 0ustar tokkeetokkeeid = $id; $this->options = new Gmap_Options((array) $options); } /** * Return GMap javascript url * * @param string API component * @param array API parameters * @return string */ public static function api_url($component = 'jsapi', $parameters = NULL, $separator = '&') { if (empty($parameters['ie'])) { // Set input encoding to UTF-8 $parameters['ie'] = 'utf-8'; } if (empty($parameters['oe'])) { // Set ouput encoding to input encoding $parameters['oe'] = $parameters['ie']; } if (empty($parameters['key'])) { // Set the API key last $parameters['key'] = Kohana::config('gmaps.api_key'); } return 'http://'.Kohana::config('gmaps.api_domain').'/'.$component.'?'.http_build_query($parameters, '', $separator); } /** * Retrieves the latitude and longitude of an address. * * @param string $address address * @return array longitude, latitude */ public static function address_to_ll($address) { $lat = NULL; $lon = NULL; if ($xml = Gmap::address_to_xml($address)) { // Get the latitude and longitude from the Google Maps XML // NOTE: the order (lon, lat) is the correct order list ($lon, $lat) = explode(',', $xml->Response->Placemark->Point->coordinates); } return array($lat, $lon); } /** * Retrieves the XML geocode address lookup. * ! Results of this method are cached for 1 day. * * @param string $address adress * @return object SimpleXML */ public static function address_to_xml($address) { static $cache; // Load Cache if ($cache === NULL) { $cache = Cache::instance(); } // Address cache key $key = 'gmap-address-'.sha1($address); if ($xml = $cache->get($key)) { // Return the cached XML return simplexml_load_string($xml); } else { // Setup the retry counter and retry delay $remaining_retries = Kohana::config('gmaps.retries'); $retry_delay = Kohana::config('gmaps.retry_delay'); // Set the XML URL $xml_url = Gmap::api_url('maps/geo', array('output' => 'xml', 'q' => $address), '&'); // Disable error reporting while fetching the feed $ER = error_reporting(~E_NOTICE); // Enter the request/retry loop. while ($remaining_retries) { // Load the XML $xml = simplexml_load_file($xml_url); if (is_object($xml) AND ($xml instanceof SimpleXMLElement) AND (int) $xml->Response->Status->code === 200) { // Cache the XML $cache->set($key, $xml->asXML(), array('gmaps'), 86400); // Since the geocode was successful, theres no need to try again $remaining_retries = 0; } elseif ((int) $xml->Response->Status->code === 620) { /* Goole is rate limiting us - either we're making too many requests too fast, or * we've exceeded the 15k per 24hour limit. */ // Reduce the number of remaining retries $remaining_retries--; if ( ! $remaining_retries) return FALSE; // Sleep for $retry_delay microseconds before trying again. usleep($retry_delay); } else { // Invalid XML response $xml = FALSE; // Dont retry. $remaining_retries = 0; } } // Turn error reporting back on error_reporting($ER); } return $xml; } /** * Returns an image map * * @param mixed $lat latitude or an array of marker points * @param float $lon longitude * @param integer $zoom zoom level (1-19) * @param string $type map type (roadmap or mobile) * @param integer $width map width * @param integer $height map height * @return string */ public static function static_map($lat = 0, $lon = 0, $zoom = 6, $type = NULL, $width = 300, $height = 300) { // Valid map types $types = array('roadmap', 'mobile'); // Maximum width and height are 640px $width = min(640, abs($width)); $height = min(640, abs($height)); $parameters['size'] = $width.'x'.$height; // Minimum zoom = 0, maximum zoom = 19 $parameters['zoom'] = max(0, min(19, abs($zoom))); if (in_array($type, $types)) { // Set map type $parameters['maptype'] = $type; } if (is_array($lat)) { foreach ($lat as $_lat => $_lon) { $parameters['markers'][] = $_lat.','.$_lon; } $parameters['markers'] = implode('|', $parameters['markers']); } else { $parameters['center'] = $lat.','.$lon; } return Gmap::api_url('staticmap', $parameters); } /** * Set the GMap center point. * * @chainable * @param float $lat latitude * @param float $lon longitude * @param integer $zoom zoom level (1-19) * @param string $type default map type * @return object */ public function center($lat, $lon, $zoom = 6, $type = 'G_NORMAL_MAP') { $zoom = max(0, min(19, abs($zoom))); $type = ($type != 'G_NORMAL_MAP' AND in_array($type, $this->default_types, true)) ? $type : 'G_NORMAL_MAP'; // Set center location, zoom and default map type $this->center = array($lat, $lon, $zoom, $type); return $this; } /** * Set the GMap controls size. * * @chainable * @param string $size small or large * @return object */ public function controls($size = NULL) { // Set the control type $this->control = (strtolower($size) == 'small') ? 'Small' : 'Large'; return $this; } /** * Set the GMap overview map. * * @chainable * @param integer $width width * @param integer $height height * @return object */ public function overview($width = '', $height = '') { $size = (is_int($width) AND is_int($height)) ? 'new GSize('.$width.','.$height.')' : ''; $this->overview_control = 'map.addControl(new google.maps.OverviewMapControl('.$size.'));'; return $this; } /** * Set the GMap type controls. * by default renders G_NORMAL_MAP, G_SATELLITE_MAP, and G_HYBRID_MAP * * @chainable * @param string $type map type * @param string $action add or remove map type * @return object */ public function types($type = NULL, $action = 'remove') { $this->type_control = TRUE; if ($type !== NULL AND in_array($type, $this->default_types, true)) { // Set the map type and action $this->types[$type] = (strtolower($action) == 'remove') ? 'remove' : 'add'; } return $this; } /** * Create a custom marker icon * * @chainable * @param string $name icon name * @param array $options icon options * @return object */ public function add_icon($name, array $options) { // Add a new cusotm icon $this->icons[] = new Gmap_Icon($name, $options); return $this; } /** * Set the GMap marker point. * * @chainable * @param float $lat latitude * @param float $lon longitude * @param string $html HTML for info window * @param array $options marker options * @return object */ public function add_marker($lat, $lon, $html = '', $options = array()) { // Add a new marker $this->markers[] = new Gmap_Marker($lat, $lon, $html, $options); return $this; } /** * Render the map into GMap Javascript. * * @param string $template template name * @param array $extra extra fields passed to the template * @return string */ public function render($template = 'gmaps/javascript', $extra = array()) { // Latitude, longitude, zoom and default map type list ($lat, $lon, $zoom, $default_type) = $this->center; // Map $map = 'var map = new google.maps.Map2(document.getElementById("'.$this->id.'"));'; // Map controls $controls[] = empty($this->control) ? '' : 'map.addControl(new google.maps.'.$this->control.'MapControl());'; // Map Types if ($this->type_control === TRUE) { if (count($this->types) > 0) { foreach($this->types as $type => $action) $controls[] = 'map.'.$action.'MapType('.$type.');'; } $controls[] = 'map.addControl(new google.maps.MapTypeControl());'; } if ( ! empty($this->overview_control)) $controls[] = $this->overview_control; // Map centering $center = 'map.setCenter(new google.maps.LatLng('.$lat.', '.$lon.'), '.$zoom.', '.$default_type.');'; $data = array_merge($extra, array ( 'map' => $map, 'options' => $this->options, 'controls' => implode("\n", $controls), 'center' => $center, 'icons' => $this->icons, 'markers' => $this->markers, )); // Render the Javascript return View::factory($template, $data)->render(); } } // End Gmap./kohana/modules/gmaps/libraries/Gmap_Icon.php0000644000175000017500000000466511121324570021111 0ustar tokkeetokkeename = $name; foreach ($options as $key => $value) { if (in_array($key, $this->valid_options, true)) { // Set all valid methods switch($key) { case 'image': case 'shadow': case 'printImage': case 'mozPrintImage': case 'printShadow': case 'transparent': case 'dragCrossImage': $this->set_url($key, $value); break; case 'iconAnchor': case 'infoWindowAnchor': case 'infoShadowAnchor': case 'dragCrossAnchor': $this->set_point($key, $value); break; case 'iconSize': case 'shadowSize': case 'dragCrossSize': $this->set_size($key, $value); break; default: $this->options[$key] = json_encode($value); break; } } } } public function set_url($key, $url) { $this->options[$key] = (valid::url($url)) ? '"'.$url.'";' : '"'.url::site($url).'";'; } public function set_size($key, $val) { $this->options[$key] = 'new google.maps.Size('.implode(',', $val).');'; } public function set_point($key, $val) { $this->options[$key] = 'new google.maps.Point('.implode(',', $val).');'; } public function render($tabs = 0) { // Create the tabs $tabs = empty($tabs) ? '' : str_repeat("\t", $tabs); $output = array(); // Render each option $output[] = "var $this->name = ".((count($this->options) > 1) ? 'new google.maps.Icon();' : 'new google.maps.Icon(G_DEFAULT_ICON);'); foreach($this->options as $option => $value) { $output[] = "$this->name.$option = $value"; } return implode("\n".$tabs, $output); } } // End Gmap Icon./kohana/modules/gmaps/i18n/0000755000175000017500000000000011263472445015350 5ustar tokkeetokkee./kohana/modules/gmaps/i18n/en_US/0000755000175000017500000000000011263472445016361 5ustar tokkeetokkee./kohana/modules/gmaps/i18n/en_US/gmaps.php0000644000175000017500000000035111121324570020164 0ustar tokkeetokkee 'Invalid marker params (latitude: %s, longitude: %s)', 'invalid_dimensions' => 'Invalid map dimensions (width: %s, height: %s)', );./kohana/modules/gmaps/i18n/ru_RU/0000755000175000017500000000000011263472445016404 5ustar tokkeetokkee./kohana/modules/gmaps/i18n/ru_RU/gmaps.php0000644000175000017500000000050111121324570020204 0ustar tokkeetokkee 'Некорректные координаты маркера (широта: %s, долгота: %s)', 'invalid_dimensions' => 'Некорректные размеры карты (ширина: %s, высота: %s)', );./kohana/modules/gmaps/i18n/es_ES/0000755000175000017500000000000011263472445016346 5ustar tokkeetokkee./kohana/modules/gmaps/i18n/es_ES/gmaps.php0000644000175000017500000000041411121324570020151 0ustar tokkeetokkee 'Los parametros del marcador son incorrectos (latitud: %s, longitud: %s)', 'invalid_dimensions' => 'Las dimensones del mapa son incorrectas (ancho: %s, alto: %s)', );./kohana/modules/gmaps/i18n/pl_PL/0000755000175000017500000000000011263472445016356 5ustar tokkeetokkee./kohana/modules/gmaps/i18n/pl_PL/gmaps.php0000644000175000017500000000044211127703515020170 0ustar tokkeetokkee 'Nieprawidłowe parametry markera (szerokość geograficzna: %s, długość geograficzna: %s)', 'invalid_dimensions' => 'Nieprawidłowe wymiary mapy (szerokość: %s, wysokość: %s)', ); ./kohana/modules/gmaps/controllers/0000755000175000017500000000000011263472445017137 5ustar tokkeetokkee./kohana/modules/gmaps/controllers/gmaps_demo.php0000644000175000017500000001101311121324570021743 0ustar tokkeetokkee TRUE, )); // Set the map center point $map->center(0, 0, 1)->controls('large')->types('G_PHYSICAL_MAP', 'add'); // Add a custom marker icon $map->add_icon('tinyIcon', array ( 'image' => 'http://labs.google.com/ridefinder/images/mm_20_red.png', 'shadow' => 'http://labs.google.com/ridefinder/images/mm_20_shadow.png', 'iconSize' => array('12', '20'), 'shadowSize' => array('22', '20'), 'iconAnchor' => array('6', '20'), 'infoWindowAnchor' => array('5', '1') )); // Add a new marker $map->add_marker(44.9801, -93.2519, 'Minneapolis, MN

    Hello world!

    ', array('icon' => 'tinyIcon', 'draggable' => true, 'bouncy' => true)); View::factory('gmaps/api_demo')->set(array('api_url' => Gmap::api_url(), 'map' => $map->render()))->render(TRUE); } public function image_map() { $points = array('-37.814251' => '144.963169', '-33.867139' => '151.207114', '-27.467580' => '153.027892'); View::factory('gmaps/static_demo')->set(array('simple' => Gmap::static_map(44.9801, -93.2519),'multi' => Gmap::static_map($points)))->render(TRUE); } public function azmap() { // Create a new Gmap $map = new Gmap('map', array ( 'ScrollWheelZoom' => TRUE, )); // Set the map center point $map->center(0, 35, 2)->controls('large'); // Set marker locations foreach (ORM::factory('location')->find_all() as $location) { // Add a new marker $map->add_marker($location->lat, $location->lon, // Get the info window HTML View::factory('gmaps/info_window')->bind('location', $location)->render()); } header('Content-Type: text/javascript'); echo $map->render(); } public function admin() { $valid = ! empty($_POST); $_POST = Validation::factory($_POST) ->pre_filter('trim') ->add_rules('title', 'required', 'length[4,32]') ->add_rules('description', 'required', 'length[4,127]') ->add_rules('link', 'length[6,127]', 'valid::url') ->add_rules('address', 'required', 'length[4,127]') ->add_callbacks('address', array($this, '_admin_check_address')); if ($_POST->validate()) { // Create a new location $location = ORM::factory('location'); // foreach ($_POST->as_array() as $key => $val) { $location->$key = $val; } echo Kohana::debug($_POST->as_array()); } if ($errors = $_POST->errors()) { foreach ($errors as $input => $rule) { // Add the errors $_POST->message($input, Kohana::lang("gmaps.form.$input")); } } View::factory('gmaps/admin')->render(TRUE); } public function _admin_check_address(Validation $array, $input) { if ($array[$input] == '') return; // Fetch the lat and lon via Gmap list ($lat, $lon) = Gmap::address_to_ll($array[$input]); if ($lat === NULL OR $lon === NULL) { // Add an error $array->add_error($input, 'address'); } else { // Set the latitude and longitude $_POST['lat'] = $lat; $_POST['lon'] = $lon; } } public function jquery() { $map = new Gmap('map'); $map->center(0, 35, 16)->controls('large'); View::factory('gmaps/jquery')->set(array('api_url' => Gmap::api_url(), 'map' => $map->render('gmaps/jquery_javascript')))->render(TRUE); } public function xml() { // Get all locations $locations = ORM::factory('location')->find_all(); // Create the XML container $xml = new SimpleXMLElement(''); foreach ($locations as $location) { // Create a new mark $node = $xml->addChild('marker'); // Set the latitude and longitude $node->addAttribute('lon', sprintf('%F', $location->lon)); $node->addAttribute('lat', sprintf('%F', $location->lat)); $node->html = View::factory('gmaps/xml')->bind('location', $location)->render(); foreach ($location->as_array() as $key => $val) { // Skip the ID if ($key === 'id') continue; // Add the data to the XML $node->$key = $val; } } header('Content-Type: text/xml'); echo $xml->asXML(); } } // End Google Map Controller./kohana/modules/gmaps/config/0000755000175000017500000000000011263472445016036 5ustar tokkeetokkee./kohana/modules/gmaps/config/gmaps.php0000644000175000017500000000206711176461505017661 0ustar tokkeetokkee $methods) { echo "\n\n" . Kohana::lang('unit_test.class') . ': ' . $class . "\n\n"; printf('%s: %.2f%%', Kohana::lang('unit_test.score'), $stats[$class]['score']); echo ",\n" . Kohana::lang('unit_test.total'), ': ', $stats[$class]['total'] . ",\n"; echo Kohana::lang('unit_test.passed'), ': ', $stats[$class]['passed'] . ",\n"; echo Kohana::lang('unit_test.failed'), ': ', $stats[$class]['failed'] . ",\n"; echo Kohana::lang('unit_test.errors'), ': ', $stats[$class]['errors'] . "\n\n"; if (empty($methods)) { echo Kohana::lang('unit_test.no_tests_found'); } else { foreach ($methods as $method => $result) { // Hide passed tests from report if ($result === TRUE AND $hide_passed === TRUE) continue; echo Kohana::lang('unit_test.method') . ': ' . $method . ': '; if ($result === TRUE) { echo Kohana::lang('unit_test.passed') . "\n"; } else { echo Kohana::lang('unit_test.failed') . "\n\t" . $result->getMessage() . "\n"; } } } }./kohana/modules/unit_test/views/kohana_unit_test.php0000644000175000017500000000752111121324570022676 0ustar tokkeetokkee
    $methods): text::alternate(); ?> $result): // Hide passed tests from report if ($result === TRUE AND $hide_passed === TRUE) continue; ?>
    | , , ,
    getMessage()) ?>
    getFile()) ?> ( getLine() ?>) getDebug() !== NULL): ?>
    getDebug()), ') ', html::specialchars(var_export($result->getDebug(), TRUE)) ?>
    getMessage()) ?>
    getFile()) ?> ( getLine() ?>)
    ./kohana/modules/unit_test/libraries/0000755000175000017500000000000011263472446017455 5ustar tokkeetokkee./kohana/modules/unit_test/libraries/Unit_Test.php0000644000175000017500000003234711207327555022113 0ustar tokkeetokkeepaths = array_unique($paths); // Loop over each given test path foreach ($this->paths as $path) { // Validate test path if ( ! is_dir($path)) throw new Kohana_Exception('unit_test.invalid_test_path', $path); // Recursively iterate over each file in the test path foreach ( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME)) as $path => $file ) { // Normalize path $path = str_replace('\\', '/', $path); // Skip files without "_Test" suffix if ( ! $file->isFile() OR substr($path, -9) !== '_Test'.EXT) continue; // The class name should be the same as the file name $class = substr($path, strrpos($path, '/') + 1, -(strlen(EXT))); // Skip hidden files if ($class[0] === '.') continue; // Check for duplicate test class name if (class_exists($class, FALSE)) throw new Kohana_Exception('unit_test.duplicate_test_class', $class, $path); // Include the test class include_once $path; // Check whether the test class has been found and loaded if ( ! class_exists($class, FALSE)) throw new Kohana_Exception('unit_test.test_class_not_found', $class, $path); // Reverse-engineer Test class $reflector = new ReflectionClass($class); // Test classes must extend Unit_Test_Case if ( ! $reflector->isSubclassOf(new ReflectionClass('Unit_Test_Case'))) throw new Kohana_Exception('unit_test.test_class_extends', $class); // Skip disabled Tests if ($reflector->getConstant('DISABLED') === TRUE) continue; // Initialize setup and teardown method triggers $setup = $teardown = FALSE; // Look for valid setup and teardown methods foreach (array('setup', 'teardown') as $method_name) { if ($reflector->hasMethod($method_name)) { $method = new ReflectionMethod($class, $method_name); $$method_name = ($method->isPublic() AND ! $method->isStatic() AND $method->getNumberOfRequiredParameters() === 0); } } // Initialize test class results and stats $this->results[$class] = array(); $this->stats[$class] = array ( 'passed' => 0, 'failed' => 0, 'errors' => 0, 'total' => 0, 'score' => 0, ); // Loop through all the class methods foreach ($reflector->getMethods() as $method) { // Skip invalid test methods if ( ! $method->isPublic() OR $method->isStatic() OR $method->getNumberOfRequiredParameters() !== 0) continue; // Test methods should be suffixed with "_test" if (substr($method_name = $method->getName(), -5) !== '_test') continue; // Instantiate Test class $object = new $class; try { // Run setup method if ($setup === TRUE) { $object->setup(); } // Run the actual test $object->$method_name(); // Run teardown method if ($teardown === TRUE) { $object->teardown(); } $this->stats[$class]['total']++; // Test passed $this->results[$class][$method_name] = TRUE; $this->stats[$class]['passed']++; } catch (Kohana_Unit_Test_Exception $e) { $this->stats[$class]['total']++; // Test failed $this->results[$class][$method_name] = $e; $this->stats[$class]['failed']++; } catch (Exception $e) { $this->stats[$class]['total']++; // Test error $this->results[$class][$method_name] = $e; $this->stats[$class]['errors']++; } // Calculate score $this->stats[$class]['score'] = $this->stats[$class]['passed'] * 100 / $this->stats[$class]['total']; // Cleanup unset($object); } } } } /** * Generates nice test results. * * @param boolean hide passed tests from the report * @return string rendered test results html */ public function report($hide_passed = NULL) { // No tests found if (empty($this->results)) return Kohana::lang('unit_test.no_tests_found'); // Hide passed tests from the report? $hide_passed = (bool) (($hide_passed !== NULL) ? $hide_passed : Kohana::config('unit_test.hide_passed', FALSE, FALSE)); if (PHP_SAPI == 'cli') { $report = View::factory('kohana_unit_test_cli'); } else { $report = View::factory('kohana_unit_test'); } // Render unit_test report return $report->set('results', $this->results) ->set('stats', $this->stats) ->set('hide_passed', $hide_passed) ->render(); } /** * Magically convert this object to a string. * * @return string test report */ public function __toString() { return $this->report(); } /** * Magically gets a Unit_Test property. * * @param string property name * @return mixed variable value if the property is found * @return void if the property is not found */ public function __get($key) { if (isset($this->$key)) return $this->$key; } } // End Unit_Test_Core abstract class Unit_Test_Case { public function assert_true($value, $debug = NULL) { if ($value != TRUE) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_true', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_true_strict($value, $debug = NULL) { if ($value !== TRUE) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_true_strict', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_false($value, $debug = NULL) { if ($value != FALSE) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_false', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_false_strict($value, $debug = NULL) { if ($value !== FALSE) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_false_strict', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_equal($expected, $actual, $debug = NULL) { if ($expected != $actual) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_equal', gettype($expected), var_export($expected, TRUE), gettype($actual), var_export($actual, TRUE)), $debug); return $this; } public function assert_not_equal($expected, $actual, $debug = NULL) { if ($expected == $actual) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_equal', gettype($expected), var_export($expected, TRUE), gettype($actual), var_export($actual, TRUE)), $debug); return $this; } public function assert_same($expected, $actual, $debug = NULL) { if ($expected !== $actual) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_same', gettype($expected), var_export($expected, TRUE), gettype($actual), var_export($actual, TRUE)), $debug); return $this; } public function assert_not_same($expected, $actual, $debug = NULL) { if ($expected === $actual) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_same', gettype($expected), var_export($expected, TRUE), gettype($actual), var_export($actual, TRUE)), $debug); return $this; } public function assert_boolean($value, $debug = NULL) { if ( ! is_bool($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_boolean', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_not_boolean($value, $debug = NULL) { if (is_bool($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_boolean', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_integer($value, $debug = NULL) { if ( ! is_int($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_integer', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_not_integer($value, $debug = NULL) { if (is_int($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_integer', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_float($value, $debug = NULL) { if ( ! is_float($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_float', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_not_float($value, $debug = NULL) { if (is_float($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_float', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_array($value, $debug = NULL) { if ( ! is_array($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_array', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_array_key($key, $array, $debug = NULL) { if ( ! array_key_exists($key, $array)) { throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_array_key', gettype($key), var_export($key, TRUE)), $debug); } return $this; } public function assert_in_array($value, $array, $debug = NULL) { if ( ! in_array($value, $array)) { throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_in_array', gettype($value), var_export($value, TRUE)), $debug); } return $this; } public function assert_not_array($value, $debug = NULL) { if (is_array($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_array', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_object($value, $debug = NULL) { if ( ! is_object($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_object', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_not_object($value, $debug = NULL) { if (is_object($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_object', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_null($value, $debug = NULL) { if ($value !== NULL) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_null', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_not_null($value, $debug = NULL) { if ($value === NULL) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_null', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_empty($value, $debug = NULL) { if ( ! empty($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_empty', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_not_empty($value, $debug = NULL) { if (empty($value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_empty', gettype($value), var_export($value, TRUE)), $debug); return $this; } public function assert_pattern($value, $regex, $debug = NULL) { if ( ! is_string($value) OR ! is_string($regex) OR ! preg_match($regex, $value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_pattern', var_export($value, TRUE), var_export($regex, TRUE)), $debug); return $this; } public function assert_not_pattern($value, $regex, $debug = NULL) { if ( ! is_string($value) OR ! is_string($regex) OR preg_match($regex, $value)) throw new Kohana_Unit_Test_Exception(Kohana::lang('unit_test.assert_not_pattern', var_export($value, TRUE), var_export($regex, TRUE)), $debug); return $this; } } // End Unit_Test_Case class Kohana_Unit_Test_Exception extends Exception { protected $debug = NULL; /** * Sets exception message and debug info. * * @param string message * @param mixed debug info * @return void */ public function __construct($message, $debug = NULL) { // Failure message parent::__construct((string) $message); // Extra user-defined debug info $this->debug = $debug; // Overwrite failure location $trace = $this->getTrace(); $this->file = $trace[0]['file']; $this->line = $trace[0]['line']; } /** * Returns the user-defined debug info * * @return mixed debug property */ public function getDebug() { return $this->debug; } } // End Kohana_Unit_Test_Exception ./kohana/modules/unit_test/i18n/0000755000175000017500000000000011263472446016260 5ustar tokkeetokkee./kohana/modules/unit_test/i18n/en_US/0000755000175000017500000000000011263472446017271 5ustar tokkeetokkee./kohana/modules/unit_test/i18n/en_US/unit_test.php0000644000175000017500000000575711166735114022032 0ustar tokkeetokkee 'Class', 'method' => 'Method', 'invalid_test_path' => 'Failed to open test path: %s.', 'duplicate_test_class' => 'Duplicate test class named %s found in %s.', 'test_class_not_found' => 'No test class by the name of %s found in %s.', 'test_class_extends' => '%s must extend Unit_Test_Case.', 'no_tests_found' => 'No tests found', 'score' => 'Score', 'total' => 'Total', 'passed' => 'Passed', 'failed' => 'Failed', 'error' => 'Error', 'errors' => 'Errors', 'line' => 'line', 'assert_true' => 'assert_true: Expected true, but was given (%s) %s.', 'assert_true_strict' => 'assert_true_strict: Expected (boolean) true, but was given (%s) %s.', 'assert_false' => 'assert_false: Expected false, but was given (%s) %s.', 'assert_false_strict' => 'assert_false_strict: Expected (boolean) false, but was given (%s) %s.', 'assert_equal' => 'assert_equal: Expected (%s) %s, but was given (%s) %s.', 'assert_not_equal' => 'assert_not_equal: Expected not (%s) %s, but was given (%s) %s.', 'assert_same' => 'assert_same: Expected (%s) %s, but was given (%s) %s.', 'assert_not_same' => 'assert_not_same: Expected not (%s) %s, but was given (%s) %s.', 'assert_boolean' => 'assert_boolean: Expected a boolean, but was given (%s) %s.', 'assert_not_boolean' => 'assert_not_boolean: Expected not a boolean, but was given (%s) %s.', 'assert_integer' => 'assert_integer: Expected an integer, but was given (%s) %s.', 'assert_not_integer' => 'assert_not_integer: Expected not an integer, but was given (%s) %s.', 'assert_float' => 'assert_float: Expected a float, but was given (%s) %s.', 'assert_not_float' => 'assert_not_float: Expected not a float, but was given (%s) %s.', 'assert_array' => 'assert_array: Expected an array, but was given (%s) %s.', 'assert_array_key' => 'assert_array_key: Expected a valid key, but was given (%s) %s.', 'assert_in_array' => 'assert_in_array: Expected a valid value, but was given (%s) %s.', 'assert_not_array' => 'assert_not_array: Expected not an array, but was given (%s) %s.', 'assert_object' => 'assert_object: Expected an object, but was given (%s) %s.', 'assert_not_object' => 'assert_not_object: Expected not an object, but was given (%s) %s.', 'assert_null' => 'assert_null: Expected null, but was given (%s) %s.', 'assert_not_null' => 'assert_not_null: Expected not null, but was given (%s) %s.', 'assert_empty' => 'assert_empty: Expected an empty value, but was given (%s) %s.', 'assert_not_empty' => 'assert_not_empty: Expected not an empty value, but was given (%s) %s.', 'assert_pattern' => 'assert_pattern: Expected %s to match %s.', 'assert_not_pattern' => 'assert_not_pattern: Expected %s to not match %s.', ); ./kohana/modules/unit_test/i18n/fr_FR/0000755000175000017500000000000011263472446017256 5ustar tokkeetokkee./kohana/modules/unit_test/i18n/fr_FR/unit_test.php0000644000175000017500000000602111122713262021770 0ustar tokkeetokkee 'Impossible d\'ouvrir le répertoire de test : %s.', 'duplicate_test_class' => 'Nom de classe de test dupliqué %s dans %s.', 'test_class_not_found' => 'Aucune classe de test nommée %s trouvée dans %s.', 'test_class_extends' => '%s doit être une extension de Unit_Test_Case.', 'no_tests_found' => 'Aucun test trouvé', 'score' => 'Score', 'total' => 'Total', 'passed' => 'Passé', 'failed' => 'Echoué', 'error' => 'Erreur', 'errors' => 'Erreurs', 'line' => 'ligne', 'assert_true' => 'assert_true: Attendait true, mais obtenu (%s) %s.', 'assert_true_strict' => 'assert_true_strict: Attendait (boolean), mais obtenu (%s) %s.', 'assert_false' => 'assert_false: Attendait false, mais obtenu (%s) %s.', 'assert_false_strict' => 'assert_false_strict: Attendait (boolean) false, mais obtenu (%s) %s.', 'assert_equal' => 'assert_equal: Attendait (%s) %s, mais obtenu (%s) %s.', 'assert_not_equal' => 'assert_not_equal: N\'attendait pas (%s) %s, mais obtenu (%s) %s.', 'assert_same' => 'assert_same: Attendait (%s) %s, mais obtenu (%s) %s.', 'assert_not_same' => 'assert_not_same: N\'attendait pas (%s) %s, mais obtenu (%s) %s.', 'assert_boolean' => 'assert_boolean: Attendait un boolean, mais obtenu (%s) %s.', 'assert_not_boolean' => 'assert_not_boolean: N\'attendait pas un boolean, mais obtenu (%s) %s.', 'assert_integer' => 'assert_integer: Attendait un integer, mais obtenu (%s) %s.', 'assert_not_integer' => 'assert_not_integer: N\'attendait pas un integer, mais obtenu (%s) %s.', 'assert_float' => 'assert_float: Attendait un float, mais obtenu (%s) %s.', 'assert_not_float' => 'assert_not_float: N\'attendait pas un float, mais obtenu (%s) %s.', 'assert_array' => 'assert_array: Attendait un tableau, mais obtenu (%s) %s.', 'assert_array_key' => 'assert_array_key: Attendait une clé valide, mais obtenu (%s) %s.', 'assert_in_array' => 'assert_in_array: Attendait une valeur valide, mais obtenu (%s) %s.', 'assert_not_array' => 'assert_not_array: N\'attendait pas un tableau, mais obtenu (%s) %s.', 'assert_object' => 'assert_object: Attendait un objet, mais obtenu (%s) %s.', 'assert_not_object' => 'assert_not_object: N\'attendait pas un object, mais obtenu (%s) %s.', 'assert_null' => 'assert_null: Attendait null, mais obtenu (%s) %s.', 'assert_not_null' => 'assert_not_null: Attendait une valeur différente de null, mais obtenu (%s) %s.', 'assert_empty' => 'assert_empty: Attendait une valeur vide, mais obtenu (%s) %s.', 'assert_not_empty' => 'assert_not_empty: Attendait une valeur non vide, mais obtenu (%s) %s.', 'assert_pattern' => 'assert_pattern: Attendait que %s corresponde à %s.', 'assert_not_pattern' => 'assert_not_pattern: Attendait que %s ne corresponde pas à %s.', ); ./kohana/modules/unit_test/i18n/pt_BR/0000755000175000017500000000000011263472446017266 5ustar tokkeetokkee./kohana/modules/unit_test/i18n/pt_BR/unit_test.php0000644000175000017500000000530311121331011021765 0ustar tokkeetokkee 'Falha ao abrir o teste com o caminho: %s.', 'duplicate_test_class' => 'Classe de teste %s com nome duplicado encontrado em %s.', 'test_class_not_found' => 'No test class by the name of %s found in %s.', 'test_class_extends' => '%s deve herdar Unit_Test_Case.', 'no_tests_found' => 'Nenhum teste encontrado', 'passed' => 'Passou', 'failed' => 'Falhou', 'error' => 'Erro', 'errors' => 'Erros', 'line' => 'linha', 'assert_true' => 'assert_true: Expected true, but was given (%s) %s.', 'assert_true_strict' => 'assert_true_strict: Expected (boolean) true, but was given (%s) %s.', 'assert_false' => 'assert_false: Expected false, but was given (%s) %s.', 'assert_false_strict' => 'assert_false_strict: Expected (boolean) false, but was given (%s) %s.', 'assert_equal' => 'assert_equal: Expected (%s) %s, but was given (%s) %s.', 'assert_not_equal' => 'assert_not_equal: Expected not (%s) %s, but was given (%s) %s.', 'assert_same' => 'assert_same: Expected (%s) %s, but was given (%s) %s.', 'assert_not_same' => 'assert_not_same: Expected not (%s) %s, but was given (%s) %s.', 'assert_boolean' => 'assert_boolean: Expected a boolean, but was given (%s) %s.', 'assert_not_boolean' => 'assert_not_boolean: Expected not a boolean, but was given (%s) %s.', 'assert_integer' => 'assert_integer: Expected an integer, but was given (%s) %s.', 'assert_not_integer' => 'assert_not_integer: Expected not an integer, but was given (%s) %s.', 'assert_float' => 'assert_float: Expected a float, but was given (%s) %s.', 'assert_not_float' => 'assert_not_float: Expected not a float, but was given (%s) %s.', 'assert_array' => 'assert_array: Expected an array, but was given (%s) %s.', 'assert_not_array' => 'assert_not_array: Expected not an array, but was given (%s) %s.', 'assert_object' => 'assert_object: Expected an object, but was given (%s) %s.', 'assert_not_object' => 'assert_not_object: Expected not an object, but was given (%s) %s.', 'assert_null' => 'assert_null: Expected null, but was given (%s) %s.', 'assert_not_null' => 'assert_not_null: Expected not null, but was given (%s) %s.', 'assert_empty' => 'assert_empty: Expected an empty value, but was given (%s) %s.', 'assert_not_empty' => 'assert_not_empty: Expected not an empty value, but was given (%s) %s.', 'assert_pattern' => 'assert_pattern: Expected %s to match %s.', 'assert_not_pattern' => 'assert_not_pattern: Expected %s to not match %s.', ); ./kohana/modules/unit_test/i18n/ru_RU/0000755000175000017500000000000011263472446017314 5ustar tokkeetokkee./kohana/modules/unit_test/i18n/ru_RU/unit_test.php0000644000175000017500000000737611121331011022027 0ustar tokkeetokkee 'Не удалось открыть путь теста: %s.', 'duplicate_test_class' => 'Дубль тестового класса "%s" найден в %s.', 'test_class_not_found' => 'Тестовый класс с именем "%s" не найден в %s.', 'test_class_extends' => '%s должен быть наследником класса Unit_Test_Case.', 'no_tests_found' => 'Тесты не найдены', 'score' => 'Счёт', 'total' => 'Всего', 'passed' => 'Пройдено', 'failed' => 'Завалено', 'error' => 'Ошибка', 'errors' => 'Ошибок', 'line' => 'строка', 'assert_true' => 'assert_true: Ожидалась истина, получено (%s) %s.', 'assert_true_strict' => 'assert_true_strict: Ожидалась булевая истина, получено (%s) %s.', 'assert_false' => 'assert_false: Ожидалась ложь, получено (%s) %s.', 'assert_false_strict' => 'assert_false_strict: Ожидалась булевая истина, получено (%s) %s.', 'assert_equal' => 'assert_equal: Ожидалось (%s) %s, получено (%s) %s.', 'assert_not_equal' => 'assert_not_equal: Ожидалось не (%s) %s, получено (%s) %s.', 'assert_same' => 'assert_same: Ожидалось (%s) %s, получено (%s) %s.', 'assert_not_same' => 'assert_not_same: Ожидалось не (%s) %s, получено (%s) %s.', 'assert_boolean' => 'assert_boolean: Ожидалось булевое значение, получено (%s) %s.', 'assert_not_boolean' => 'assert_not_boolean: Ожидалось не булевое значение, получено (%s) %s.', 'assert_integer' => 'assert_integer: Ожидалось целочисленное значение, получено (%s) %s.', 'assert_not_integer' => 'assert_not_integer: Ожидалось не целочисленное значение, получено (%s) %s.', 'assert_float' => 'assert_float: Ожидалось значение с плавающей точкой, получено (%s) %s.', 'assert_not_float' => 'assert_not_float: Ожидалось не значение с плавающей точкой, получено (%s) %s.', 'assert_array' => 'assert_array: Ожидался массив, получено (%s) %s.', 'assert_array_key' => 'assert_array_key: Ожидался индекс массива, получено (%s) %s.', 'assert_in_array' => 'assert_in_array: Ожидался элемент массива, получено (%s) %s.', 'assert_not_array' => 'assert_not_array: Ожидался не элемент массива, получено (%s) %s.', 'assert_object' => 'assert_object: Ожидался объект, получено (%s) %s.', 'assert_not_object' => 'assert_not_object: Ожидался не объект, получено (%s) %s.', 'assert_null' => 'assert_null: Ожидался null, получено (%s) %s.', 'assert_not_null' => 'assert_not_null: Ожидался не null, получено (%s) %s.', 'assert_empty' => 'assert_empty: Ожидалось пустое значение, получено (%s) %s.', 'assert_not_empty' => 'assert_not_empty: Ожидалось не пустое значение, получено (%s) %s.', 'assert_pattern' => 'assert_pattern: Ожидалось %s равное %s.', 'assert_not_pattern' => 'assert_not_pattern: Ожидалось %s не равное %s.', ); ./kohana/modules/unit_test/i18n/es_ES/0000755000175000017500000000000011263472446017256 5ustar tokkeetokkee./kohana/modules/unit_test/i18n/es_ES/unit_test.php0000644000175000017500000000640711121331011021763 0ustar tokkeetokkee 'Fallo al abrir la ruta del test: %s.', 'duplicate_test_class' => 'Se ha encontrado un nombre de clase %s duplicado en %s.', 'test_class_not_found' => 'No se ha encontrado una clase de test con el nombre %s en %s.', 'test_class_extends' => '%s debe extender Unit_Test_Case.', 'no_tests_found' => 'No se ha encontraro el test', 'score' => 'Puntuación', 'total' => 'Total', 'passed' => 'Pasado', 'failed' => 'Fallo', 'error' => 'Error', 'errors' => 'Errores', 'line' => 'linea', 'assert_true' => 'assert_true: Se esperaba true, pero se ha entregado (%s) %s.', 'assert_true_strict' => 'assert_true_strict: Se esperaba (boolean) true, pero se ha entregado (%s) %s.', 'assert_false' => 'assert_false: Se esperaba false, pero se ha entregado (%s) %s.', 'assert_false_strict' => 'assert_false_strict: Se esperaba (boolean) false, pero se ha entregado (%s) %s.', 'assert_equal' => 'assert_equal: Se esperaba (%s) %s, pero se ha entregado (%s) %s.', 'assert_not_equal' => 'assert_not_equal: No se esperaba (%s) %s, pero se ha entregado (%s) %s.', 'assert_same' => 'assert_same: Se esperaba (%s) %s, pero se ha entregado (%s) %s.', 'assert_not_same' => 'assert_not_same: No se esperaba (%s) %s, pero se ha entregado (%s) %s.', 'assert_boolean' => 'assert_boolean: Se esperaba un valor boolean, pero se ha entregado (%s) %s.', 'assert_not_boolean' => 'assert_not_boolean: No se esperaba un valor boolean, pero se ha entregado (%s) %s.', 'assert_integer' => 'assert_integer: Se esperaba un entero, pero se ha entregado (%s) %s.', 'assert_not_integer' => 'assert_not_integer: No se esperaba un entero, pero se ha entregado (%s) %s.', 'assert_float' => 'assert_float: Se esperaba una coma flotante, pero se ha entregado (%s) %s.', 'assert_not_float' => 'assert_not_float: No se esperaba una cma flotante, pero se ha entregado (%s) %s.', 'assert_array' => 'assert_array: Se esperaba una matriz, pero se ha entregado (%s) %s.', 'assert_array_key' => 'assert_array_key: Se esperaba una clave valida, pero se ha entregado (%s) %s.', 'assert_in_array' => 'assert_in_array: Se esperaba un valor valido, pero se ha entregado (%s) %s.', 'assert_not_array' => 'assert_not_array: No se esperaba una matriz, pero se ha entregado (%s) %s.', 'assert_object' => 'assert_object: Se esperaba un objecto, pero se ha entregado (%s) %s.', 'assert_not_object' => 'assert_not_object: No se esperaba un objecto, pero se ha entregado (%s) %s.', 'assert_null' => 'assert_null: Se esperaba null, pero se ha entregado (%s) %s.', 'assert_not_null' => 'assert_not_null: No se esperaba null, pero se ha entregado (%s) %s.', 'assert_empty' => 'assert_empty: Se esperaba un valor vacio, pero se ha entregado (%s) %s.', 'assert_not_empty' => 'assert_not_empty: No se esperaba un valor vacio, pero se ha entregado (%s) %s.', 'assert_pattern' => 'assert_pattern: Se esperaba que %s coincidiera %s.', 'assert_not_pattern' => 'assert_not_pattern: Se esperaba que %s no coincidiera %s.', ); ./kohana/modules/unit_test/controllers/0000755000175000017500000000000011263472446020047 5ustar tokkeetokkee./kohana/modules/unit_test/controllers/unit_test.php0000644000175000017500000000072711121324570022567 0ustar tokkeetokkeesetup_has_run = TRUE; } public function setup_test() { $this->assert_true_strict($this->setup_has_run); } public function true_false_test() { $var = TRUE; $this ->assert_true($var) ->assert_true_strict($var) ->assert_false( ! $var) ->assert_false_strict( ! $var); } public function equal_same_test() { $var = '5'; $this ->assert_equal($var, 5) ->assert_not_equal($var, 6) ->assert_same($var, '5') ->assert_not_same($var, 5); } public function type_test() { $this ->assert_boolean(TRUE) ->assert_not_boolean('TRUE') ->assert_integer(123) ->assert_not_integer('123') ->assert_float(1.23) ->assert_not_float(123) ->assert_array(array(1, 2, 3)) ->assert_not_array('array()') ->assert_object(new stdClass) ->assert_not_object('X') ->assert_null(NULL) ->assert_not_null(0) ->assert_empty('0') ->assert_not_empty('1'); } public function pattern_test() { $var = "Kohana\n"; $this ->assert_pattern($var, '/^Kohana$/') ->assert_not_pattern($var, '/^Kohana$/D'); } public function array_key_test() { $array = array('a' => 'A', 'b' => 'B'); $this->assert_array_key('a', $array); } public function in_array_test() { $array = array('X', 'Y', 'Z'); $this->assert_in_array('X', $array); } public function debug_example_test() { foreach (array(1, 5, 6, 12, 65, 128, 9562) as $var) { // By supplying $var in the debug parameter, // we can see on which number this test fails. $this->assert_true($var < 100, $var); } } public function error_test() { throw new Exception; } } ./kohana/modules/unit_test/tests/Valid_Helper_Test.php0000644000175000017500000000666511121324570022711 0ustar tokkeetokkeeassert_true_strict(valid::email('address@domain.tld')) ->assert_false_strict(valid::email('address@domain')); } public function valid_email_rfc_test() { $this ->assert_true_strict(valid::email_rfc('address@domain')) ->assert_false_strict(valid::email_rfc('address.domain')); } public function valid_email_domain_test() { // not implemented on windows platform $var1 = (KOHANA_IS_WIN) ? TRUE : valid::email_domain('address@gmail.tld'); $var2 = (KOHANA_IS_WIN) ? FALSE : valid::email_domain('address@domain-should_not-exist.tld'); $this ->assert_true_strict($var1) ->assert_false_strict($var2); } public function valid_url_test() { $this ->assert_true_strict(valid::url('http://www.kohanaphp.com')) ->assert_false_strict(valid::url('www.kohanaphp.com')); } public function valid_ip_test() { $this ->assert_true_strict(valid::ip('75.125.175.50')) // valid - kohanaphp.com ->assert_true_strict(valid::ip('127.0.0.1')) // valid - local loopback ->assert_false_strict(valid::ip('256.257.258.259')) // invalid ip ->assert_false_strict(valid::ip('255.255.255.255')) // invalid - reserved range ->assert_false_strict(valid::ip('192.168.0.1')); // invalid - private range } public function valid_credit_card_test() { $this ->assert_true_strict(valid::credit_card('4222222222222')) // valid visa test nr ->assert_true_strict(valid::credit_card('4012888888881881')) // valid visa test nr ->assert_true_strict(valid::credit_card('5105105105105100')) // valid mastercard test nr ->assert_true_strict(valid::credit_card('6011111111111117')) // valid discover test nr ->assert_false_strict(valid::credit_card('6011111111111117', 'visa')); // invalid visa test nr } public function valid_phone_test() { $this ->assert_true_strict(valid::phone('0163634840')) ->assert_true_strict(valid::phone('+27173634840')) ->assert_false_strict(valid::phone('123578')); } public function valid_alpha_test() { $this ->assert_true_strict(valid::alpha('abc')) ->assert_false_strict(valid::alpha('123')); } public function valid_alpha_numeric_test() { $this ->assert_true_strict(valid::alpha_numeric('abc123')) ->assert_false_strict(valid::alpha_numeric('123*.*')); } public function valid_alpha_dash_test() { $this ->assert_true_strict(valid::alpha_dash('_ab-12')) ->assert_false_strict(valid::alpha_dash('ab_ 123 !')); } public function valid_digit_test() { $this ->assert_true_strict(valid::digit('123')) ->assert_false_strict(valid::digit('abc')); } public function valid_numeric_test() { $this ->assert_true_strict(valid::numeric(-12.99)) ->assert_false_strict(valid::numeric('123_4')); } public function valid_standard_text_test() { $this ->assert_true_strict(valid::standard_text('some valid_text-to.test 123')) ->assert_false_strict(valid::standard_text('some !real| ju0n_%k')); } public function valid_decimal_test() { $this ->assert_true_strict(valid::decimal(12.99)) ->assert_false_strict(valid::decimal(12,99)); } } // End Valid Helper Test Controller ./kohana/modules/unit_test/config/0000755000175000017500000000000011263472446016746 5ustar tokkeetokkee./kohana/modules/unit_test/config/unit_test.php0000644000175000017500000000045011121324570021457 0ustar tokkeetokkeeadd_data($set[0], $set[1], isset($set[2]) ? $set[2] : NULL); } // File data $data = implode('', $this->data); // Directory data $dirs = implode('', $this->dirs); $zipfile = $data. // File data $dirs. // Directory data "\x50\x4b\x05\x06\x00\x00\x00\x00". // Directory EOF pack('v', count($this->dirs)). // Total number of entries "on disk" pack('v', count($this->dirs)). // Total number of entries in file pack('V', strlen($dirs)). // Size of directories pack('V', strlen($data)). // Offset to directories "\x00\x00"; // Zip comment length if ($filename == FALSE) { return $zipfile; } if (substr($filename, -3) != 'zip') { // Append zip extension $filename .= '.zip'; } // Create the file in binary write mode $file = fopen($filename, 'wb'); // Lock the file flock($file, LOCK_EX); // Write the zip file $return = fwrite($file, $zipfile); // Unlock the file flock($file, LOCK_UN); // Close the file fclose($file); return (bool) $return; } public function add_data($file, $name, $contents = NULL) { // Determine the file type: 16 = dir, 32 = file $type = (substr($file, -1) === '/') ? 16 : 32; // Fetch the timestamp, using the current time if manually setting the contents $timestamp = date::unix2dos(($contents === NULL) ? filemtime($file) : time()); // Read the file or use the defined contents $data = ($contents === NULL) ? file_get_contents($file) : $contents; // Gzip the data, use substr to fix a CRC bug $zdata = substr(gzcompress($data), 2, -4); $this->data[] = "\x50\x4b\x03\x04". // Zip header "\x14\x00". // Version required for extraction "\x00\x00". // General bit flag "\x08\x00". // Compression method pack('V', $timestamp). // Last mod time and date pack('V', crc32($data)). // CRC32 pack('V', strlen($zdata)).// Compressed filesize pack('V', strlen($data)). // Uncompressed filesize pack('v', strlen($name)). // Length of file name pack('v', 0). // Extra field length $name. // File name $zdata; // Compressed data $this->dirs[] = "\x50\x4b\x01\x02". // Zip header "\x00\x00". // Version made by "\x14\x00". // Version required for extraction "\x00\x00". // General bit flag "\x08\x00". // Compression method pack('V', $timestamp). // Last mod time and date pack('V', crc32($data)). // CRC32 pack('V', strlen($zdata)).// Compressed filesize pack('V', strlen($data)). // Uncompressed filesize pack('v', strlen($name)). // Length of file name pack('v', 0). // Extra field length // End "local file header" // Start "data descriptor" pack('v', 0). // CRC32 pack('v', 0). // Compressed filesize pack('v', 0). // Uncompressed filesize pack('V', $type). // File attribute type pack('V', $this->offset). // Directory offset $name; // File name // Set the new offset $this->offset = strlen(implode('', $this->data)); } } // End Archive_Zip_Driver Class./kohana/modules/archive/libraries/drivers/Archive/Bzip.php0000644000175000017500000000215611121324570023523 0ustar tokkeetokkeeadd($set[0], $set[1]); } $gzfile = bzcompress($archive->create()); if ($filename == FALSE) { return $gzfile; } if (substr($filename, -8) !== '.tar.bz2') { // Append tar extension $filename .= '.tar.bz2'; } // Create the file in binary write mode $file = fopen($filename, 'wb'); // Lock the file flock($file, LOCK_EX); // Write the tar file $return = fwrite($file, $gzfile); // Unlock the file flock($file, LOCK_UN); // Close the file fclose($file); return (bool) $return; } public function add_data($file, $name, $contents = NULL) { return FALSE; } } // End Archive_Bzip_Driver Class./kohana/modules/archive/libraries/drivers/Archive/Tar.php0000644000175000017500000000531611121324570023346 0ustar tokkeetokkeeadd_data($set[0], $set[1], isset($set[2]) ? $set[2] : NULL); } $tarfile = implode('', $this->data).pack('a1024', ''); // EOF if ($filename == FALSE) { return $tarfile; } if (substr($filename, -3) != 'tar') { // Append tar extension $filename .= '.tar'; } // Create the file in binary write mode $file = fopen($filename, 'wb'); // Lock the file flock($file, LOCK_EX); // Write the tar file $return = fwrite($file, $tarfile); // Unlock the file flock($file, LOCK_UN); // Close the file fclose($file); return (bool) $return; } public function add_data($file, $name, $contents = NULL) { // Determine the file type $type = is_dir($file) ? 5 : (is_link($file) ? 2 : 0); // Get file stat $stat = stat($file); // Get path info $path = pathinfo($file); // File header $tmpdata = pack('a100', $name). // Name of file pack('a8', sprintf('%07o', $stat[2])). // File mode pack('a8', sprintf('%07o', $stat[4])). // Owner user ID pack('a8', sprintf('%07o', $stat[5])). // Owner group ID pack('a12', sprintf('%011o', $type === 2 ? 0 : $stat[7])). // Length of file in bytes pack('a12', sprintf('%011o', $stat[9])). // Modify time of file pack('a8', str_repeat(chr(32), 8)). // Reserved for checksum for header pack('a1', $type). // Type of file pack('a100', $type === 2 ? readlink($file) : ''). // Name of linked file pack('a6', 'ustar'). // USTAR indicator pack('a2', chr(32)). // USTAR version pack('a32', 'Unknown'). // Owner user name pack('a32', 'Unknown'). // Owner group name pack('a8', chr(0)). // Device major number pack('a8', chr(0)). // Device minor number pack('a155', $path['dirname'] === '.' ? '' : $path['dirname']). // Prefix for file name pack('a12', chr(0)); // End $checksum = pack('a8', sprintf('%07o', array_sum( array_map('ord', str_split(substr($tmpdata, 0, 512)))))); $this->data[] = substr_replace($tmpdata, $checksum, 148, 8) . str_pad(file_get_contents($file), (ceil($stat[7] / 512) * 512), chr(0)); } } // End Archive_Tar_Driver Class./kohana/modules/archive/libraries/drivers/Archive/Gzip.php0000644000175000017500000000215211121324570023524 0ustar tokkeetokkeeadd($set[0], $set[1]); } $gzfile = gzencode($archive->create()); if ($filename == FALSE) { return $gzfile; } if (substr($filename, -7) !== '.tar.gz') { // Append tar extension $filename .= '.tar.gz'; } // Create the file in binary write mode $file = fopen($filename, 'wb'); // Lock the file flock($file, LOCK_EX); // Write the tar file $return = fwrite($file, $gzfile); // Unlock the file flock($file, LOCK_UN); // Close the file fclose($file); return (bool) $return; } public function add_data($file, $name, $contents = NULL) { return FALSE; } } // End Archive_Gzip_Driver Class./kohana/modules/archive/libraries/Archive.php0000644000175000017500000000635011207327555021154 0ustar tokkeetokkeedriver = new $driver(); // Validate the driver if ( ! ($this->driver instanceof Archive_Driver)) throw new Kohana_Exception('core.driver_implements', $type, get_class($this), 'Archive_Driver'); Kohana::log('debug', 'Archive Library initialized'); } /** * Adds files or directories, recursively, to an archive. * * @param string file or directory to add * @param string name to use for the given file or directory * @param bool add files recursively, used with directories * @return object */ public function add($path, $name = NULL, $recursive = NULL) { // Normalize to forward slashes $path = str_replace('\\', '/', $path); // Set the name empty($name) and $name = $path; if (is_dir($path)) { // Force directories to end with a slash $path = rtrim($path, '/').'/'; $name = rtrim($name, '/').'/'; // Add the directory to the paths $this->paths[] = array($path, $name); if ($recursive === TRUE) { $dir = opendir($path); while (($file = readdir($dir)) !== FALSE) { // Do not add hidden files or directories if ($file[0] === '.') continue; // Add directory contents $this->add($path.$file, $name.$file, TRUE); } closedir($dir); } } else { $this->paths[] = array($path, $name); } return $this; } /** * Creates an archive and saves it into a file. * * @throws Kohana_Exception * @param string archive filename * @return boolean */ public function save($filename) { // Get the directory name $directory = pathinfo($filename, PATHINFO_DIRNAME); if ( ! is_writable($directory)) throw new Kohana_Exception('archive.directory_unwritable', $directory); if (is_file($filename)) { // Unable to write to the file if ( ! is_writable($filename)) throw new Kohana_Exception('archive.filename_conflict', $filename); // Remove the file unlink($filename); } return $this->driver->create($this->paths, $filename); } /** * Creates a raw archive file and returns it. * * @return string */ public function create() { return $this->driver->create($this->paths); } /** * Forces a download of a created archive. * * @param string name of the file that will be downloaded * @return void */ public function download($filename) { download::force($filename, $this->driver->create($this->paths)); } } // End Archive./kohana/modules/archive/i18n/0000755000175000017500000000000011263472444015661 5ustar tokkeetokkee./kohana/modules/archive/i18n/it_IT/0000755000175000017500000000000011263472444016671 5ustar tokkeetokkee./kohana/modules/archive/i18n/it_IT/archive.php0000644000175000017500000000062311121324570021011 0ustar tokkeetokkee 'La cartella in cui si è scelto di salvare il file, %s, è protetta in scrittura. Impostare opportunamente i permessi prima di ritentare.', 'filename_conflict' => 'L\'archivio richiesto, %s, è già esistente ed è protetto in scrittura. Ritentare dopo aver rimosso il file in conflitto.', );./kohana/modules/archive/i18n/zh_CN/0000755000175000017500000000000011263472444016662 5ustar tokkeetokkee./kohana/modules/archive/i18n/zh_CN/archive.php0000644000175000017500000000065711121331011020775 0ustar tokkeetokkee '请求的 %s 驱动,不支持.', 'driver_implements' => '请求的 %s 驱动, 未实现Archive_Driver接口.', 'directory_unwritable' => '请求写目录 %s 权限不足, 无写权限. 请设置好权限后重试.', 'filename_conflict' => '请求的文件 %s, 已存在且只读. 请删除冲突文件后重试.' );./kohana/modules/archive/i18n/mk_MK/0000755000175000017500000000000011263472444016657 5ustar tokkeetokkee./kohana/modules/archive/i18n/mk_MK/archive.php0000644000175000017500000000116011121331011020760 0ustar tokkeetokkee 'Во директориумот во кој сакате да ја зачувате датотеката, %s, неможе да се запишува. Корегирајте ги дозволите (permissions) и пробајте повторно.', 'filename_conflict' => 'Потребната архива со име, %s, веќе постои и не може да се запишува во неа. Избришете ја конфликтната датотека и пробајте повторно.' );./kohana/modules/archive/i18n/fi_FI/0000755000175000017500000000000011263472444016635 5ustar tokkeetokkee./kohana/modules/archive/i18n/fi_FI/archive.php0000644000175000017500000000054111121331011020740 0ustar tokkeetokkee 'Hakemisto %s johon yritit tallentaa tiedostoa ei voida kirjoittaa. Korjaa oikeudet ja yritä uudelleen.', 'filename_conflict' => 'Tiedosto %s on jo olemassa eikä siihen voida kirjoittaa. Poista olemassaoleva tiedosto ja yritä uudelleen.' );./kohana/modules/archive/i18n/nl_NL/0000755000175000017500000000000011263472444016663 5ustar tokkeetokkee./kohana/modules/archive/i18n/nl_NL/archive.php0000644000175000017500000000062211121331011020766 0ustar tokkeetokkee 'De directory die je opgaf om het bestand in op te slaan, %s, is niet schrijfbaar. Stel de correcte permissies in en probeer opnieuw.', 'filename_conflict' => 'De bestandsnaam die je opgaf voor het archief, %s, bestaat al en is niet schrijfbaar. Verwijder dat bestand en probeer opnieuw.', );./kohana/modules/archive/i18n/en_US/0000755000175000017500000000000011263472444016672 5ustar tokkeetokkee./kohana/modules/archive/i18n/en_US/archive.php0000644000175000017500000000057011121326741021015 0ustar tokkeetokkee 'The directory you requested to save the file in, %s, is unwritable. Please correct the permissions and try again.', 'filename_conflict' => 'The requested archive filename, %s, already exists and is not writable. Please remove the conflicting file and try again.' );./kohana/modules/archive/i18n/el_GR/0000755000175000017500000000000011263472444016651 5ustar tokkeetokkee./kohana/modules/archive/i18n/fr_FR/0000755000175000017500000000000011263472444016657 5ustar tokkeetokkee./kohana/modules/archive/i18n/fr_FR/archive.php0000644000175000017500000000064511121331011020767 0ustar tokkeetokkee 'Le répertoire spécifié %s pour la sauvegarde du fichier n\'est pas accessible en écriture. Veuillez corriger les permissions puis réessayer.', 'filename_conflict' => 'L\'archive %s demandée existe déjà et n\'est pas accessible en écriture. Veuillez supprimer le fichier en conflit puis réessayer.' );./kohana/modules/archive/i18n/de_DE/0000755000175000017500000000000011263472444016621 5ustar tokkeetokkee./kohana/modules/archive/i18n/de_DE/archive.php0000644000175000017500000000067511121326741020752 0ustar tokkeetokkee 'Das Verzeichnis %s, in dem die Datei gespeichert werden soll, ist nicht beschreibbar. Korrigieren Sie bitte die Zugriffsrechte und versuchen Sie es erneut.', 'filename_conflict' => 'Der für das Archiv gewählte Dateiname %s existiert bereits und ist nicht beschreibbar. Löschen Sie bitte diese Datei und versuchen Sie es erneut.' );./kohana/modules/archive/i18n/pt_BR/0000755000175000017500000000000011263472444016667 5ustar tokkeetokkee./kohana/modules/archive/i18n/pt_BR/archive.php0000644000175000017500000000067511121331011021002 0ustar tokkeetokkee 'O diretório que você requisitiou para salvar o arquivo, %s, não possui permissão para escrita. Por favor, corrija as permissões e tente novamente.', 'filename_conflict' => 'O nome de arquivo archive requisitado, %s, já existe e não possui permissão para escrita. Por favor, remova o arquivo conflitante e tente novamente.' ); ./kohana/modules/archive/i18n/ru_RU/0000755000175000017500000000000011263472444016715 5ustar tokkeetokkee./kohana/modules/archive/i18n/ru_RU/archive.php0000644000175000017500000000110711121331011021017 0ustar tokkeetokkee 'Директория "%s", в которую вы сохраняете файл, не доступна для записи. Пожалуйста, исправьте права доступа и повторите попытку.', 'filename_conflict' => 'Архив с именем "%s" уже существует и не доступен для записи. Пожалуйста, удалите конфликтный файл и повторите попытку.' ); ./kohana/modules/archive/i18n/es_ES/0000755000175000017500000000000011263472444016657 5ustar tokkeetokkee./kohana/modules/archive/i18n/es_ES/archive.php0000644000175000017500000000062611121324570021002 0ustar tokkeetokkee 'El directorio en el que intentas guardar el archivo, %s, no tiene permiso de escritura. Cambia los permisos de escritura e intentalo de nuevo.', 'filename_conflict' => 'El archivo, %s, ya existe y no tiene permiso de escritura. Por favor, borra el archivo en conflicto e intentalo de nuevo.', );./kohana/modules/archive/i18n/es_AR/0000755000175000017500000000000011263472444016652 5ustar tokkeetokkee./kohana/modules/archive/i18n/es_AR/archive.php0000644000175000017500000000110211121324570020763 0ustar tokkeetokkee 'El archivo del driver requerido, %s, no tiene soporte.', 'driver_implements' => 'El archivo del driver requerido, %s, no implementa Archive_Driver.', 'directory_unwritable' => 'El directorio en el que intentaste salvar el archivo, %s, no tiene permiso de escritura. Dale permiso de escritura e intenta de nuevo.', 'filename_conflict' => 'El archivo, %s, ya existe y no tiene permiso de escritura. Por favor, borrá el archivo en conflicto e intenta de nuevo.' );./kohana/modules/archive/i18n/pl_PL/0000755000175000017500000000000011263472444016667 5ustar tokkeetokkee./kohana/modules/archive/i18n/pl_PL/archive.php0000644000175000017500000000055111121331011020773 0ustar tokkeetokkee 'Katalog %s wybrany do zapisu pliku jest tylko do odczytu. Proszę zmienić uprawnienia i spróbować ponownie.', 'filename_conflict' => 'Wybrana nazwa archiwum %s, istnieje i nie może być zapisana. Proszę usunąć plik i spróbować ponownie.', );./kohana/modules/archive/i18n/en_GB/0000755000175000017500000000000011263472444016633 5ustar tokkeetokkee./kohana/modules/archive/i18n/en_GB/archive.php0000755000175000017500000000105211121326741020755 0ustar tokkeetokkee 'The requested Archive driver, %s, was not found.', 'driver_implements' => 'The requested Archive driver, %s, does not implement Archive_Driver.', 'directory_unwritable' => 'The directory you requested to save the file in, %s, is unwritable. Please correct the permissions and try again.', 'filename_conflict' => 'The requested archive filename, %s, already exists and is not writable. Please remove the conflicting file and try again.' );./kohana/modules/payment/0000755000175000017500000000000011263472445015137 5ustar tokkeetokkee./kohana/modules/payment/libraries/0000755000175000017500000000000011263472445017113 5ustar tokkeetokkee./kohana/modules/payment/libraries/drivers/0000755000175000017500000000000011263472445020571 5ustar tokkeetokkee./kohana/modules/payment/libraries/drivers/Payment/0000755000175000017500000000000011263472446022207 5ustar tokkeetokkee./kohana/modules/payment/libraries/drivers/Payment/Paypalpro.php0000644000175000017500000001300211121324570024646 0ustar tokkeetokkee FALSE, 'USER' => FALSE, 'PWD' => FALSE, 'SIGNATURE' => FALSE, 'VERSION' => FALSE, 'METHOD' => FALSE, 'PAYMENTACTION' => FALSE, 'CURRENCYCODE' => FALSE, // default is USD - only required if other currency needed 'AMT' => FALSE, // payment amount 'IPADDRESS' => FALSE, 'FIRSTNAME' => FALSE, 'LASTNAME' => FALSE, 'CREDITCARDTYPE' => FALSE, 'ACCT' => FALSE, // card number 'EXPDATE' => FALSE, 'CVV2' => FALSE ); private $fields = array ( 'ENDPOINT' => '', 'USER' => '', 'PWD' => '', 'SIGNATURE' => '', 'VERSION' => '', 'METHOD' => '', /* some possible values for METHOD : 'DoDirectPayment', 'RefundTransaction', 'DoAuthorization', 'DoReauthorization', 'DoCapture', 'DoVoid' */ 'PAYMENTACTION' => '', 'CURRENCYCODE' => '', 'AMT' => 0, // payment amount 'IPADDRESS' => '', 'FIRSTNAME' => '', 'LASTNAME' => '', 'CREDITCARDTYPE' => '', 'ACCT' => '', // card number 'EXPDATE' => '', // Format: MMYYYY 'CVV2' => '', // security code // -- OPTIONAL FIELDS -- 'STREET' => '', 'STREET2' => '', 'CITY' => '', 'STATE' => '', 'ZIP' => '', 'COUNTRYCODE' => '', 'SHIPTONAME' => '', 'SHIPTOSTREET' => '', 'SHIPTOSTREET2' => '', 'SHIPTOCITY' => '', 'SHIPTOSTATE' => '', 'SHIPTOZIP' => '', 'SHIPTOCOUNTRYCODE' => '', 'INVNUM' => '' // your internal order id / transaction id // other optional fields listed here: // https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/Appx_fieldreference.html#2145100 ); private $test_mode = TRUE; /** * Sets the config for the class. * * @param : array - config passed from the payment library constructor */ public function __construct($config) { $this->test_mode = $config['test_mode']; if ($this->test_mode) { $this->fields['USER'] = $config['SANDBOX_USER']; $this->fields['PWD'] = $config['SANDBOX_PWD']; $this->fields['SIGNATURE'] = $config['SANDBOX_SIGNATURE']; $this->fields['ENDPOINT'] = $config['SANDBOX_ENDPOINT']; } else { $this->fields['USER'] = $config['USER']; $this->fields['PWD'] = $config['PWD']; $this->fields['SIGNATURE'] = $config['SIGNATURE']; $this->fields['ENDPOINT'] = $config['ENDPOINT']; } $this->fields['VERSION'] = $config['VERSION']; $this->fields['CURRENCYCODE'] = $config['CURRENCYCODE']; $this->required_fields['USER'] = !empty($config['USER']); $this->required_fields['PWD'] = !empty($config['PWD']); $this->required_fields['SIGNATURE'] = !empty($config['SIGNATURE']); $this->required_fields['ENDPOINT'] = !empty($config['ENDPOINT']); $this->required_fields['VERSION'] = !empty($config['VERSION']); $this->required_fields['CURRENCYCODE'] = !empty($config['CURRENCYCODE']); $this->curl_config = $config['curl_config']; Kohana::log('debug', 'Paypalpro Payment Driver Initialized'); } /** *@desc set fields for nvp string */ public function set_fields($fields) { foreach ((array) $fields as $key => $value) { $this->fields[$key] = $value; if (array_key_exists($key, $this->required_fields) and !empty($value)) { $this->required_fields[$key] = TRUE; } } } /** *@desc process PayPal Website Payments Pro transaction */ public function process() { // Check for required fields if (in_array(FALSE, $this->required_fields)) { $fields = array(); foreach ($this->required_fields as $key => $field) { if (!$field) $fields[] = $key; } throw new Kohana_Exception('payment.required', implode(', ', $fields)); } // Instantiate curl and pass the API post url $ch = curl_init($this->fields['ENDPOINT']); foreach ($this->fields as $key => $val) { // don't include unset optional fields in the name-value pair request string if ($val==='' OR $key=='ENDPOINT') unset($this->fields[$key]); } $nvp_qstr = http_build_query($this->fields); // Set custom curl options curl_setopt_array($ch, $this->curl_config); // Set the curl POST fields curl_setopt($ch, CURLOPT_POSTFIELDS, $nvp_qstr); // Execute post and get results $response = curl_exec($ch); if (curl_errno($ch)) { $curl_error_no = curl_errno($ch); $curl_error_msg = curl_error($ch); throw new Kohana_Exception('curl.error:'.$curl_error_no.' - '.$curl_error_msg); } curl_close ($ch); if (!$response) throw new Kohana_Exception('payment.gateway_connection_error'); $nvp_res_array = array(); parse_str(urldecode($response),$nvp_res_array); return ($nvp_res_array['ACK'] == TRUE); } } // End Payment_Paypalpro_Driver Class./kohana/modules/payment/libraries/drivers/Payment/Trustcommerce.php0000644000175000017500000000665111121324570025547 0ustar tokkeetokkee TRUE, 'password' => TRUE, 'action' => TRUE, 'media' => TRUE, 'cc' => FALSE, 'exp' => FALSE, 'amount' => FALSE ); private $tclink_library = './path/to/library'; private $test_mode = TRUE; private $fields = array('demo' => 'n'); /** * Sets the config for the class. * * @param array config passed from the library */ public function __construct($config) { $this->test_mode = $config['test_mode']; $this->tclink_library = $config['tclink_library']; $this->fields['ip'] = $_SERVER['REMOTE_ADDR']; $this->fields['custid'] = $config['custid']; $this->fields['password'] = $config['password']; $this->fields['action'] = 'sale'; $this->fields['media'] = $config['media']; if (!extension_loaded('tclink')) { if (!dl($this->tclink_library)) { throw new Kohana_Exception('payment.no_dlib', $this->tclink_library); } } Kohana::log('debug', 'TrustCommerce Payment Driver Initialized'); } public function set_fields($fields) { foreach ((array) $fields as $key => $value) { // Do variable translation switch ($key) { case 'card_num': $key = 'cc'; break; case 'exp_date': $key = 'exp'; if (strlen($value) == 3) $value = '0'.$value; break; case 'amount': $value = $value * 100; break; case 'address': $key = 'address1'; break; case 'ship_to_address': $key = 'shipto_address1'; break; case 'ship_to_city': $key = 'shipto_city'; break; case 'ship_to_state': $key = 'shipto_state'; break; case 'ship_to_zip': $key = 'shipto_zip'; break; case 'cvv': $value = (int) $value; break; default: break; } $this->fields[$key] = $value; if (array_key_exists($key, $this->required_fields) and !empty($value)) { $this->required_fields[$key] = TRUE; } } } public function process() { if ($this->test_mode) $this->fields['demo'] = 'y'; $this->fields['name'] = $this->fields['first_name'].' '.$this->fields['last_name']; $this->fields['shipto_name'] = $this->fields['ship_to_first_name'].' '.$this->fields['ship_to_last_name']; unset($this->fields['first_name'], $this->fields['last_name'],$this->fields['ship_to_first_name'],$this->fields['ship_to_last_name']); // Check for required fields if (in_array(FALSE, $this->required_fields)) { $fields = array(); foreach ($this->required_fields as $key => $field) { if ( ! $field) { $fields[] = $key; } } throw new Kohana_Exception('payment.required', implode(', ', $fields)); } $result = tclink_send($this->fields); // Report status if ($result['status'] == 'approved') return TRUE; elseif ($result['status'] == 'decline') return Kohana::lang('payment.error', 'payment_Trustcommerce.decline.'.$result[$result['status'].'type']); else return Kohana::lang('payment.error', Kohana::lang('payment_Trustcommerce.'.$result['status'].'.'.$result['error'])); } } // End Payment_Trustcommerce_Driver Class./kohana/modules/payment/libraries/drivers/Payment/Authorize.php0000644000175000017500000001032311166737624024675 0ustar tokkeetokkee FALSE, 'x_version' => TRUE, 'x_delim_char' => TRUE, 'x_url' => TRUE, 'x_type' => TRUE, 'x_method' => TRUE, 'x_tran_key' => FALSE, 'x_relay_response' => TRUE, 'x_card_num' => FALSE, 'x_exp_date' => FALSE, 'x_amount' => FALSE, ); // Default required values private $authnet_values = array ( 'x_version' => '3.1', 'x_delim_char' => '|', 'x_delim_data' => 'TRUE', 'x_url' => 'FALSE', 'x_type' => 'AUTH_CAPTURE', 'x_method' => 'CC', 'x_relay_response' => 'FALSE', ); private $test_mode = TRUE; /** * Sets the config for the class. * * @param array config passed from the library */ public function __construct($config) { $this->authnet_values['x_login'] = $config['auth_net_login_id']; $this->authnet_values['x_tran_key'] = $config['auth_net_tran_key']; $this->required_fields['x_login'] = !empty($config['auth_net_login_id']); $this->required_fields['x_tran_key']= !empty($config['auth_net_tran_key']); $this->curl_config = $config['curl_config']; $this->test_mode = $config['test_mode']; Kohana::log('debug', 'Authorize.net Payment Driver Initialized'); } public function set_fields($fields) { foreach ((array) $fields as $key => $value) { $this->authnet_values['x_'.$key] = $value; if (array_key_exists('x_'.$key, $this->required_fields) and !empty($value)) $this->required_fields['x_'.$key] = TRUE; } } /** * Retreives the response array from a successful * transaction. * * @return array or Null */ public function get_response() { if (!$this->transaction) return $this->response; return NULL; } /** * Process a given transaction. * * @return boolean */ public function process() { // Check for required fields if (in_array(FALSE, $this->required_fields)) { $fields = array(); foreach ($this->required_fields as $key => $field) { if (!$field) $fields[] = $key; } throw new Kohana_Exception('payment.required', implode(', ', $fields)); } $fields = ''; foreach ( $this->authnet_values as $key => $value ) { $fields .= $key.'='.urlencode($value).'&'; } $post_url = ($this->test_mode) ? 'https://certification.authorize.net/gateway/transact.dll' : // Test mode URL 'https://secure.authorize.net/gateway/transact.dll'; // Live URL $ch = curl_init($post_url); // Set custom curl options curl_setopt_array($ch, $this->curl_config); // Set the curl POST fields curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim($fields, '& ')); //execute post and get results $response = curl_exec($ch); curl_close($ch); if (!$response) throw new Kohana_Exception('payment.gateway_connection_error'); // This could probably be done better, but it's taken right from the Authorize.net manual // Need testing to opimize probably $heading = substr_count($response, '|'); for ($i=1; $i <= $heading; $i++) { $delimiter_position = strpos($response, '|'); if ($delimiter_position !== False) { $response_code = substr($response, 0, $delimiter_position); $response_code = rtrim($response_code, '|'); if($response_code == '') throw new Kohana_Exception('payment.gateway_connection_error'); switch ($i) { case 1: $this->response = (($response_code == '1') ? explode('|', $response) : False); // Approved $this->transaction = TRUE; return $this->transaction; default: $this->transaction = FALSE; return $this->transaction; } } } } } // End Payment_Authorize_Driver Class./kohana/modules/payment/libraries/drivers/Payment/Yourpay.php0000644000175000017500000001147211121324570024360 0ustar tokkeetokkee FALSE, 'expiration_date' => FALSE, 'amount' => FALSE, 'tax' => FALSE, 'shipping' => FALSE, 'cvm_value' => FALSE ); // Default required values private $fields = array ( 'card_num' => '', 'expiration_date' => '', 'cvm_value' => '', 'amount' => 0, 'tax' => 0, 'shipping' => 0, 'billing_name' => '', 'billing_address' => '', 'billing_city' => '', 'billing_state' => '', 'billing_zip' => '', 'shipping_name' => '', 'shipping_address' => '', 'shipping_city' => '', 'shipping_state' => '', 'shipping_zip' => '' ); // The location of the certficate file. Set from the config private $certificate = './path/to/certificate'; private $test_mode = TRUE; /** * Sets the config for the class. * * @param array config passed from the library */ public function __construct($config) { // Check to make sure the certificate is valid $this->certificate = is_file($config['certificate']) ? $config['certificate'] : FALSE; if (!$this->certificate) throw new Kohana_Exception('payment.invalid_certificate', $config['certificate']); $this->curl_config = $config['curl_config']; $this->test_mode = $config['test_mode']; Kohana::log('debug', 'YourPay.net Payment Driver Initialized'); } public function set_fields($fields) { foreach ((array) $fields as $key => $value) { // Do variable translation switch ($key) { case 'exp_date': $key = 'expiration_date'; break; default: break; } $this->fields[$key] = $value; if (array_key_exists($key, $this->required_fields) and !empty($value)) $this->required_fields[$key] = TRUE; } } public function process() { // Check for required fields if (in_array(FALSE, $this->required_fields)) { $fields = array(); foreach ($this->required_fields as $key => $field) { if (!$field) $fields[] = $key; } throw new Kohana_Exception('payment.required', implode(', ', $fields)); } $xml =' SALE '.($this->test_mode) ? 'GOOD' : 'LIVE'.' '.$this->config['merchant_id'].' '.$this->fields['card_num'].' '.substr($this->fields['expiration_date'], 0, 2).' '.substr($this->fields['expiration_date'], 2, 2).' '.$this->fields['cvm_value'].' '.$this->fields['amount'].' '.$this->fields['tax'].' '.$this->fields['shipping'].' '.($this->fields['amount'] + $this->fields['tax'] + $this->fields['shipping']).' '.$this->fields['billing_name'].' '.$this->fields['billing_address'].' '.$this->fields['billing_city'].' '.$this->fields['billing_state'].' '.$this->fields['billing_zip'].' '.$this->fields['email'].' '.$this->fields['shipping_name'].' '.$this->fields['shipping_address'].' '.$this->fields['shipping_city'].' '.$this->fields['shipping_state'].' '.$this->fields['shipping_zip'].' '; $post_url = 'https://secure.linkpt.net:1129/LSGSXML'; $ch = curl_init($post_url); // Set custom curl options curl_setopt_array($ch, $this->curl_config); curl_setopt ($ch, CURLOPT_SSLCERT, $this->certificate); // Set the curl POST fields curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); if ($result = curl_exec ($ch)) { if (strlen($result) < 2) # no response throw new Kohana_Exception('payment.gateway_connection_error'); // Convert the XML response to an array preg_match_all ("/<(.*?)>(.*?)\ FALSE, 'xml_body' => FALSE ); private $fields = array ( 'google_API_key' => '', 'google_merchant_id' => '', 'google_sandbox_API_key' => '', 'google_sandbox_merchant_id' => '', 'action' => '', 'xml_body' => '' ); private $test_mode = TRUE; /** * Sets the config for the class. * * @param array config passed from the library */ public function __construct($config) { $this->fields['google_API_key'] = $config['google_API_key']; $this->fields['google_merchant_id'] = $config['google_merchant_id']; $this->fields['google_sandbox_API_key'] = $config['google_sandbox_API_key']; $this->fields['google_sandbox_merchant_id'] = $config['google_sandbox_merchant_id']; $this->curl_config = $config['curl_config']; $this->test_mode = $config['test_mode']; if($this->test_mode) { $base64encoding = base64_encode($this->fields['google_sandbox_merchant_id'].":".$this->fields['google_sandbox_API_key']); } else { $base64encoding = base64_encode($this->fields['google_merchant_id'].":".$this->fields['google_API_key']); } $this->xml_header = array("Authorization: Basic ".$base64encoding, "Content-Type: application/xml;charset=UTF-8", "Accept: application/xml;charset=UTF-8"); Kohana::Log('debug', 'Google Checkout Payment Driver Initialized'); } public function set_fields($fields) { foreach ((array) $fields as $key => $value) { $this->fields[$key] = $value; if (array_key_exists($key, $this->required_fields) and !empty($value)) $this->required_fields[$key] = TRUE; } } /** * Used to process any xml requests * * @return (string) xml string */ public function process() { $post_url = ($this->test_mode) ? 'https://sandbox.google.com/checkout/api/checkout/v2/'.$this->fields['action'].'/Merchant/'.$this->fields['google_sandbox_merchant_id'] // Test mode URL : 'https://checkout.google.com/api/checkout/v2/'.$this->fields['action'].'/Merchant/'.$this->fields['google_merchant_id']; // Live URL $ch = curl_init($post_url); //Set the curl config curl_setopt_array($ch, $this->curl_config); // Set custom curl options curl_setopt($ch, CURLOPT_POST, true); // Set the curl POST fields curl_setopt($ch, CURLOPT_HTTPHEADER, $this->xml_header); curl_setopt($ch, CURLOPT_POSTFIELDS, $this->fields['xml_body']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Execute post and get results $response = curl_exec($ch); curl_close ($ch); // Return a response if there was one return (!empty($response)) ? $response : Kohana::lang('payment.error', Kohana::lang('payment_GoogleCheckout.'.$response['error_code'])); } } // End Payment_GoogleCheckout_Driver Class./kohana/modules/payment/libraries/drivers/Payment/Moneybookers.php0000644000175000017500000001263411121507517025371 0ustar tokkeetokkee FALSE, 'script' => FALSE, 'currency' => FALSE, 'pay_to_email' => FALSE, 'test_pay_to_email' => FALSE, 'password' => FALSE, 'test_password' => FALSE, 'postdata' => FALSE, 'action' => FALSE ); private $fields = array ( 'payment_url' => '', 'script' => '', 'currency' => '', 'pay_to_email' => '', 'test_pay_to_email' => '', 'password' => '', 'test_password' => '', 'postdata' => '', 'action' => '', 'trn_id' => '', 'mb_trn_id' => '', 'rec_payment_id' => '', 'sid' => '' ); private $test_mode = TRUE; /** * Sets the config for the class. * * @param array config passed from the library */ public function __construct($config) { $this->test_mode = $config['test_mode']; $this->fields['payment_url'] = $config['payment_url']; $this->fields['currency'] = $config['currency']; if($this->test_mode) { $this->fields['test_pay_to_email'] = $config['test_pay_to_email']; $this->fields['test_password'] = $config['test_password']; } else { $this->fields['pay_to_email'] = $config['pay_to_email']; $this->fields['password'] = $config['password']; } $this->curl_config = $config['curl_config']; Kohana::Log('debug', 'MoneyBookers Payment Driver Initialized'); } public function set_fields($fields) { foreach ((array) $fields as $key => $value) { $this->fields[$key] = $value; if ( array_key_exists( $key, $this->required_fields ) and !empty( $value ) ) { $this->required_fields[$key] = TRUE; } } } public function process() { $post_url = ($this->test_mode) ? $this->fields['payment_url'].$this->fields['script'] // Test mode URL : $this->fields['payment_url'].$this->fields['script']; // Live URL $pay_to_email = ($this->test_mode) ? $this->fields['test_pay_to_email'] // Test mode email : $this->fields['pay_to_email']; // Live email $password = ($this->test_mode) ? $this->fields['test_password'] // Test mode password : $this->fields['password']; // Live password $this->fields['postdata']['action'] = $this->fields['action']; $config = Kohana::config('payment.MoneyBookers'); if($this->fields['script'] == $config['refund_script'] && $this->fields['action'] == "prepare") { $this->fields['postdata']['email'] = $pay_to_email; $this->fields['postdata']['password'] = md5($password); $this->fields['postdata']['trn_id'] = $this->fields['trn_id']; } elseif($this->fields['action'] == "prepare") { $this->fields['postdata']['email'] = $pay_to_email; $this->fields['postdata']['password'] = md5($password); $this->fields['postdata']['amount'] = $this->fields['amount']; $this->fields['postdata']['currency'] = $this->fields['currency']; $this->fields['postdata']['frn_trn_id'] = $this->fields['trn_id']; $this->fields['postdata']['rec_payment_id'] = $this->fields['rec_payment_id']; } elseif($this->fields['action'] == "refund") { $this->fields['postdata']['sid'] = $this->fields['sid']; } elseif($this->fields['action'] == "request") { $this->fields['postdata']['sid'] = $this->fields['sid']; } elseif($this->fields['action'] == "status_od") { $this->fields['postdata']['email'] = $pay_to_email; $this->fields['postdata']['password'] = md5($password); $this->fields['postdata']['trn_id'] = $this->fields['trn_id']; } elseif($this->fields['action'] == "status_trn") { $this->fields['postdata']['email'] = $pay_to_email; $this->fields['postdata']['password'] = md5($password); $this->fields['postdata']['mb_trn_id'] = $this->fields['trn_id']; } $ch = curl_init($post_url); curl_setopt($ch, CURLOPT_FAILONERROR, true); // the following disallows redirects curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // next we return into a variable curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_POST, 1); // Set the curl POST fields curl_setopt($ch, CURLOPT_POSTFIELDS, $this->fields['postdata']); // Execute post and get results $response = curl_exec($ch); // Get error messages. $info = curl_getinfo($ch); curl_close ($ch); if(!$response) { return false; } if($this->fields['action'] != "status_od" && $this->fields['action'] != "status_trn") { $xml = simplexml_load_string($response); } if($this->fields['action'] == "prepare") { return ($xml->{'sid'} != "") ? $xml : false; } if($this->fields['action'] == "request") { return ($xml->{'transaction'}->{'status_msg'} == "processed") ? $xml : false; } if($this->fields['action'] == "status_od") { return (strstr($response, "Status: 0")) ? true : false; } if($this->fields['action'] == "status_trn") { return (strstr($response, "OK")) ? $response : false; } if($this->fields['action'] == "refund") { return ($xml->{'status'} == 2) ? $xml : false; } } } // End Payment_MoneyBookers_Driver Class./kohana/modules/payment/libraries/drivers/Payment/Paypal.php0000644000175000017500000004002411147233740024137 0ustar tokkeetokkee FALSE, 'PWD' => FALSE, 'SIGNATURE' => FALSE, 'RETURNURL' => FALSE, 'CANCELURL' => FALSE, 'AMT' => FALSE, // payment amount ); //-- RESPONSE to setExpressCheckout calls will take the form: //-- https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={20 single byte character timestamped token} //-- this token is passed back and forth throughout the stages of the express checkout process private $set_express_checkout_fields = array ( //-- REQUIRED --// 'METHOD' => 'SetExpressCheckout', 'RETURNURL' => '', 'CANCELURL' => '', 'AMT' => '', // payment amount - MUST include decimal point followed by two further digits //-- OPTIONAL --// 'CURRENCYCODE' => '', // default is USD - only required if other currency needed 'MAXAMT' => '', // USERACTION defaults to 'continue' // if set to 'commit' the submit button on the paypal site transaction page is labelled 'Pay' // instead of 'continue' - meaning that you can just go ahead and call DoExpressCheckout // right away on the RETURNURL page on your site without needing a further order review page // with a 'pay now' button. 'USERACTION' => 'continue', 'INVNUM' => '', // Your own unique invoice / tracking number //-- set ADDROVERRIDE to '1' if you want to collect the shipping address on your site //-- and have that over-ride the user's stored details on paypal //-- if set to '1' you will of course also need to pass the shipping details! 'ADDROVERRIDE' => '0', 'SHIPTONAME' => '', 'SHIPTOSTREET' => '', 'SHIPTOSTREET2' => '', 'SHIPTOCITY' => '', 'SHIPTOSTATE' => '', 'SHIPTOZIP' => '', 'SHIPTOCOUNTRYCODE' => '', // list of country codes here: https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/countrycodes_new.html#1006794 'LOCALECODE' => 'US', // Defaults to 'US' - list of country codes here: https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/countrycodes_new.html#1006794 //-- If YOU WANT TO APPLY CUSTOM STYLING TO PAYAPAL PAGES - see under SetExpressCheckout Request for descriptions here: https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/Appx_fieldreference.html#2557853 'PAGESTYLE' => '', //set this to match the name of any page style you set up in the profile subtab of your paypal account 'HDRIMG' => '', //header image displayed top left, size: 750px x 90px. defaults to business name in text // there are several other optional settings supported // see under SetExpressCheckout Request here : https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/Appx_fieldreference.html#2557853 ); private $get_express_checkout_fields = array ( 'METHOD' => 'GetExpressCheckoutDetails', 'TOKEN' => '' // this token is retrieved from the response to the SetExpressCheckout call ); //-- associative array filled by the paypal api response to a call to the GetExpressCheckout method private $get_express_checkout_response = array(); // responses contain these fields: // TOKEN // EMAIL // PAYERID - paypal customer id - 13 single byte alpha numeric // PAYERSTATUS - verified or unverified // SALUTATION - 20 single byte characters // FIRSTNAME - 25 single byte characters // LASTNAME - 25 single byte characters // MIDDLENAME - 25 single byte characters // SUFFIX - payer's suffix - 12 single byte character // COUNTRYCODE - list of country codes here: https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/countrycodes_new.html#1006794 // BUSINESS - payer's business name // SHIPTONAME // SHIPTOSTREET // SHIPTOSTREET2 // SHIPTOCITY // SHIPTOSTATE // SHIPTOZIP // SHIPTOCOUNTRYCODE // ADDRESSSTATUS - status of the street address on file with paypal // CUSTOM - freeform field as optionally set by you in the setExpressCheckout call // INVNUM - invoice tracking number as optionally set by you in the setExpressCheckout call // PHONENUM - Note: PayPal returns a contact telephone number only if your Merchant account profile settings require that the buyer enter one. // REDIRECTREQUIRED - flag to indicate whether you need to redirect the customer to back to PayPal after completing the transaction. private $do_express_checkout_fields = array ( //-- REQUIRED -- 'METHOD' => 'DoExpressCheckoutPayment', 'TOKEN' => '', // this token is retrieved from the response to the setExpressCheckout call 'PAYERID' => '', 'AMT' => '', // payment amount - MUST include decimal point followed by two further digits 'PAYMENTACTION' => 'Sale', //-- OPTIONAL -- 'CURRENCYCODE' => '', // default is USD - only required if other currency needed 'INVNUM' => '', 'ITEMAMT' => '', // sum cost of all items in order not including shipping or handling 'SHIPPINGAMT' => '', 'HANDLINGAMT' => '', 'TAXAMT' => '', //-- OPTIONAL ORDER CONTENTS INFO /* these fileds would obviously need setting dynamically but shown here as an example 'L_NAME0' => '', // max 127 single-byte characters product/item name 'L_NUMBER0' => '', // max 127 single-byte characters product/item number 'L_QTY0' => '', // positive integer 'L_TAXAMT0' => '', // item sales tax amount 'L_AMT0' => '', // cost of item 'L_NAME1'... 'L_NAME2'... */ ); private $api_authroization_fields = array ( 'USER' => '', 'PWD' => '', 'SIGNATURE' => '', 'VERSION' => '3.2', ); private $api_connection_fields = array ( 'ENDPOINT' => 'https://api-3t.paypal.com/nvp', 'PAYPALURL' => 'https://www.paypal.com/webscr&cmd=_express-checkout&token=', 'ERRORURL' => '', 'GETDETAILS' => TRUE ); private $array_of_arrays; private $test_mode = TRUE; private $nvp_response_array = array(); // after successful transaction $nvp_response_array will contain // TOKEN - The timestamped token value that was returned by SetExpressCheckout // TRANSACTIONID - Unique transaction ID of the payment. 19 single-byte characters // TRANSACTIONTYPE - possible values: 'cart' or 'express-checkout' // PAYMENTTYPE - Indicates whether the payment is instant or delayed. possible values: 'non', 'echeck', 'instant' // ORDERTIME - Time/date stamp of payment // AMT - The final amount charged, including any generic shipping and taxes set in your Merchant Profile. // CURRENCYCODE - 3 char currency code: https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/Appx_fieldreference.html#2557565 // FEEAMT - PayPal fee amount charged for the transaction // SETTLEAMT - Amount deposited in your PayPal account after a currency conversion. // TAXAMT - Tax charged on the transaction. // EXCHANGERATE - Exchange rate if a currency conversion occurred. // PAYMENTSTATUS - possible values: 'Completed' or 'Pending' // PENDINGREASON - possible values: 'none', 'address', 'echeck', 'int1', 'multi-currency', 'verify', 'other' // REASONCODE - The reason for a reversal if TransactionType is reversal. possible values: 'none', 'chargeback', 'guarantee', 'buyer-complaint', 'refund', 'other' // for more info see : https://www.paypal.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/Appx_fieldreference.html#2557853 /** * Sets the config for the class. * * @param array config passed from the library */ public function __construct($config) { $this->array_of_arrays = array ( &$this->set_express_checkout_fields, &$this->get_express_checkout_fields, &$this->do_express_checkout_fields, &$this->api_authroization_fields, &$this->api_connection_fields ); $this->set_fields($config); $this->test_mode = $config['test_mode']; if ($this->test_mode) { $this->api_authroization_fields['USER'] = $config['SANDBOX_USER']; $this->api_authroization_fields['PWD'] = $config['SANDBOX_PWD']; $this->api_authroization_fields['SIGNATURE'] = $config['SANDBOX_SIGNATURE']; $this->api_connection_fields['ENDPOINT'] = $config['SANDBOX_ENDPOINT']; $this->api_connection_fields['PAYPALURL'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='; $this->api_connection_fields['ENDPOINT'] = 'https://api-3t.sandbox.paypal.com/nvp'; } $this->curl_config = $config['curl_config']; $this->session = Session::instance(); Kohana::log('debug', 'PayPal Payment Driver Initialized'); } /** *@desc set fields for nvp string */ public function set_fields($config) { foreach ($config as $key => $val) { // Handle any necessary field name translation switch ($key) { case 'amount': $key = 'AMT'; break; default: } if (array_key_exists($key, $this->required_fields) AND !empty($val)) { $this->required_fields[$key] = TRUE; } foreach ($this->array_of_arrays as &$arr) { if (array_key_exists($key, $arr)) { $arr[$key] = $val; } } } } public function process() { // Check for required fields if (in_array(FALSE, $this->required_fields)) { $fields = array(); foreach ($this->required_fields as $key => $field) { if ( ! $field) { $fields[] = $key; } } throw new Kohana_Exception('payment.required', implode(', ', $fields)); } // stage 1 - if no token yet set then we know we just need to run set_express_checkout $paypal_token = $this->session->get('paypal_token', FALSE); if ( ! $paypal_token) { $this->set_express_checkout(); return FALSE; } else { $this->set_fields(array('TOKEN' => $paypal_token)); } // stage 2 (optional) retrieve the user info from paypal and store it in the get_express_checkout_response array // -------------------------------------------------------------------------------- // *note: if you don't wish to record the user info (shipping address etc) // then you can skip this stage by setting GETDETAILS to FALSE // like so: // $this->payment = new Payment('Paypal'); // $this->payment->GETDETAILS = FALSE; // IMPORTANT - if you do choose to skip this step you will need to extract // the PayerID from the $_GET array in the method targeted by RETURNURL // and use the value to set the PAYERID value of your payment object // eg: // $this->payment = new Payment('Paypal'); // $this->payment->PAYERID = $this->input->get('PayerID'); // -------------------------------------------------------------------------------- if ($this->api_connection_fields['GETDETAILS']) { $this->get_express_checkout(); } // stage 3 if (empty($this->do_express_checkout_fields['PAYERID'])) { throw new Kohana_Exception('payment.required', 'PAYERID'); } $this->do_express_checkout_payment(); return (strtoupper($this->nvp_response_array['ACK']) == 'Success') ? TRUE : array_merge($this->nvp_response_array, $this->get_express_checkout_response); } /** * (stage 1) * Runs paypal authentication and sets up express checkout options (stage 1) */ protected function set_express_checkout() { $nvp_str = http_build_query($this->remove_empty_optional_fields($this->set_express_checkout_fields)); $response = $this->make_paypal_api_request($nvp_str); parse_str(urldecode($response),$response_array); if (strtoupper($response_array['ACK']) == 'SUCCESS') { $paypal_token = $response_array['TOKEN']; // Redirect to paypal.com here $this->session->set('paypal_token', urldecode($paypal_token)); // We are off to paypal to login! if ($this->set_express_checkout_fields['USERACTION']=='commit') { url::redirect($this->api_connection_fields['PAYPALURL'].$paypal_token.'&useraction=commit'); } else { url::redirect($this->api_connection_fields['PAYPALURL'].$paypal_token); } } else // Something went terribly wrong... { throw new Kohana_User_Exception('SetExpressCheckout ERROR', Kohana::debug($response_array)); Kohana::log('error', Kohana::debug('SetExpressCheckout response:'.$response_array)); //url::redirect($this->api_connection_fields['ERRORURL']); } } /** * (stage 2) * Retrieves all the user info from paypal and stores it in the get_express_checkout_response array * */ protected function get_express_checkout() { $nvp_str = http_build_query($this->get_express_checkout_fields); $response = $this->make_paypal_api_request($nvp_str); parse_str(urldecode($response),$this->get_express_checkout_response); if (strtoupper($this->get_express_checkout_response['ACK']) == 'SUCCESS') { $this->set_fields(array('PAYERID' => $this->get_express_checkout_response['PAYERID'])); } else // Something went terribly wrong... { throw new Kohana_User_Exception('GetExpressCheckout ERROR', Kohana::debug($this->get_express_checkout_response)); Kohana::log('error', Kohana::debug('GetExpressCheckout response:'.$response)); url::redirect($this->api_connection_fields['ERRORURL']); } } /** * (stage 3) * complete paypal transaction - store response in nvp_response_array * */ protected function do_express_checkout_payment() { $nvp_qstr = http_build_query($this->remove_empty_optional_fields($this->do_express_checkout_fields)); $response = $this->make_paypal_api_request($nvp_qstr); parse_str(urldecode($response),$this->nvp_response_array); if (strtoupper($this->nvp_response_array['ACK']) != 'SUCCESS') { throw new Kohana_User_Exception('DoExpressCheckoutPayment ERROR', Kohana::debug($this->nvp_response_array)); Kohana::log('error', Kohana::debug('GetExpressCheckout response:'.$response)); url::redirect($this->api_connection_fields['ERRORURL']); } } /** * Runs the CURL methods to communicate with paypal. * * @param string paypal API method to run * @param string any additional name-value-pair query string data to send to paypal * @return mixed */ protected function make_paypal_api_request($nvp_str) { $postdata = http_build_query($this->api_authroization_fields).'&'.$nvp_str; parse_str(urldecode($postdata),$nvpstr); Kohana::log('debug', 'Connecting to '.$this->api_connection_fields['ENDPOINT']); $ch = curl_init($this->api_connection_fields['ENDPOINT']); // Set custom curl options curl_setopt_array($ch, $this->curl_config); // Setting the nvpreq as POST FIELD to curl curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); // Getting response from server $response = curl_exec($ch); if (curl_errno($ch)) { throw new Kohana_User_Exception('CURL ERROR', Kohana::debug(array('curl_error_no' => curl_errno($ch), 'curl_error_msg' => curl_error($ch)))); // Moving to error page to display curl errors $this->session->set_flash(array('curl_error_no' => curl_errno($ch), 'curl_error_msg' => curl_error($ch))); url::redirect($this->api_connection_fields['ERRORURL']); } else { curl_close($ch); } return $response; } /** * What is says on the tin * @param array * @return edited array * */ protected function remove_empty_optional_fields($arr) { foreach ($arr as $key => $val) { // don't include unset optional fields in the name-value pair request string if ($val==='') unset($arr[$key]); } return $arr; } } // End Payment_Paypal_Driver Class ./kohana/modules/payment/libraries/drivers/Payment/Trident.php0000644000175000017500000000671411121324570024324 0ustar tokkeetokkee FALSE, 'profile_key' => FALSE, 'card_number' => FALSE, 'card_exp_date' => FALSE, 'transaction_amount' => FALSE, 'transaction_type' => FALSE ); private $fields = array ( 'profile_id' => '', 'profile_key' => '', 'card_number' => '', 'card_exp_date' => '', 'transaction_amount' => '', 'transaction_type' => '' ); private $test_mode = TRUE; /** * Sets the config for the class. * * @param array config passed from the library */ public function __construct($config) { $this->fields['profile_id'] = $config['profile_id']; $this->fields['profile_key'] = $config['profile_key']; $this->fields['transaction_type'] = $config['transaction_type']; $this->required_fields['profile_id'] = !empty($config['profile_id']); $this->required_fields['profile_key'] = !empty($config['profile_key']); $this->required_fields['transaction_type'] = !empty($config['transaction_type']); $this->curl_config = $config['curl_config']; $this->test_mode = $config['test_mode']; Kohana::log('debug', 'Trident Payment Driver Initialized'); } public function set_fields($fields) { foreach ((array) $fields as $key => $value) { // Do variable translation switch ($key) { case 'card_num': $key = 'card_number'; break; case 'exp_date': $key = 'card_exp_date'; break; case 'amount': $key = 'transaction_amount'; break; case 'tax': $key = 'tax_amount'; break; case 'cvv': $key = 'cvv2'; break; default: break; } $this->fields[$key] = $value; if (array_key_exists($key, $this->required_fields) and !empty($value)) $this->required_fields[$key] = TRUE; } } public function process() { // Check for required fields if (in_array(FALSE, $this->required_fields)) { $fields = array(); foreach ($this->required_fields as $key => $field) { if (!$field) $fields[] = $key; } throw new Kohana_Exception('payment.required', implode(', ', $fields)); } $fields = ''; foreach ( $this->fields as $key => $value ) { $fields .= $key.'='.urlencode($value).'&'; } $post_url = ($this->test_mode) ? 'https://test.merchante-solutions.com/mes-api/tridentApi' // Test mode URL : 'https://api.merchante-solutions.com/mes-api/tridentApi'; // Live URL $ch = curl_init($post_url); // Set custom curl options curl_setopt_array($ch, $this->curl_config); // Set the curl POST fields curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim( $fields, "& " )); // Execute post and get results $response = curl_exec($ch); curl_close ($ch); if (!$response) throw new Kohana_Exception('payment.gateway_connection_error'); $response = explode('&', $response); foreach ($response as $code) { $temp = explode('=', $code); $response[$temp[0]] = $temp[1]; } return ($response['error_code'] == '000') ? TRUE : Kohana::lang('payment.error', Kohana::lang('payment_Trident.'.$response['error_code'])); } } // End Payment_Trident_Driver Class./kohana/modules/payment/libraries/drivers/Payment.php0000644000175000017500000000114611121324570022705 0ustar tokkeetokkee value pairs to set */ public function set_fields($fields); /** * Runs the transaction. * * @return boolean */ public function process(); } // End Payment Driver Interface./kohana/modules/payment/libraries/Payment.php0000644000175000017500000000537111121324570021233 0ustar tokkeetokkee NULL, // Test mode is set to true by default 'test_mode' => TRUE, ); protected $driver = NULL; /** * Sets the payment processing fields. * The driver will translate these into the specific format for the provider. * Standard fields are (Providers may have additional or different fields): * * card_num * exp_date * cvv * description * amount * tax * shipping * first_name * last_name * company * address * city * state * zip * email * phone * fax * ship_to_first_name * ship_to_last_name * ship_to_company * ship_to_address * ship_to_city * ship_to_state * ship_to_zip * * @param array the driver string */ public function __construct($config = array()) { if (empty($config)) { // Load the default group $config = Kohana::config('payment.default'); } elseif (is_string($config)) { $this->config['driver'] = $config; } // Merge the default config with the passed config is_array($config) AND $this->config = array_merge($this->config, $config); // Set driver name $driver = 'Payment_'.ucfirst($this->config['driver']).'_Driver'; // Load the driver if ( ! Kohana::auto_load($driver)) throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this)); // Get the driver specific settings $this->config = array_merge($this->config, Kohana::config('payment.'.$this->config['driver'])); // Initialize the driver $this->driver = new $driver($this->config); // Validate the driver if ( ! ($this->driver instanceof Payment_Driver)) throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Payment_Driver'); } /** * Sets the credit card processing fields * * @param string field name * @param string value */ public function __set($name, $val) { $this->driver->set_fields(array($name => $val)); } /** * Bulk setting of payment processing fields. * * @param array array of values to set * @return object this object */ public function set_fields($fields) { $this->driver->set_fields((array) $fields); return $this; } /** * Runs the transaction * * @return TRUE|string TRUE on successful payment, an error string on failure */ public function process() { return $this->driver->process(); } } ./kohana/modules/payment/i18n/0000755000175000017500000000000011263472445015716 5ustar tokkeetokkee./kohana/modules/payment/i18n/it_IT/0000755000175000017500000000000011263472445016726 5ustar tokkeetokkee./kohana/modules/payment/i18n/it_IT/payment.php0000644000175000017500000000107611121324570021104 0ustar tokkeetokkee 'Alcuni campi obbligatori non sono stati forniti: %s', 'gateway_connection_error' => 'Si è verificato un errore durante la connessione alla piattaforma di pagamento. Se il problema persiste contattare l\'amministratore del sito.', 'invalid_certificate' => 'Certificato non valido: %s', 'no_dlib' => 'Impossibile caricare la libreria dinamica: %s', 'error' => 'Si è verificato un errore durante la transazione: %s', );./kohana/modules/payment/i18n/it_IT/payment_Trustcommerce.php0000644000175000017500000000555711121324570024030 0ustar tokkeetokkee array ( 'avs' => 'AVS Fallito; l\'indirizzo fornito non coincide con l\'indirizzo di fatturazione che appare alla banca.', 'cvv' => 'CVV Fallito; il numero fornito non è il numero di verifica corretto della carta.', 'call' => 'La carta tiene deve essere autorizzata per telefono. Puoi scegliere di chiamare al servizio clienti che appare sulla carta e richiedere un numero di autorizzazione offline, introducibile nel campo offlineauthcode.', 'expiredcard' => 'La carta è scaduta. Richiedi una modifica della data di scadenza all\'ente che ha emesso la carta.', 'carderror' => 'Numero della carta incorretto, potrebbe essere un errore di scrittura o in qualche caso una carta denunciata come rubata.', 'authexpired' => 'Si è cercato di autorizzare una autorizzazione prima che sia scaduta (più di 14 giorni).', 'fraud' => 'Il punteggio di frode di CrediGuard è sotto il limite richiesto.', 'blacklist' => 'Sono stati superati i valori della lista nera di CrediGuard.', 'velocity' => 'È stato superato il controllo di velocità di CrediGuard.', 'dailylimit' => 'È stato raggiunto il limite giornaliero di transazioni, per numero o ammontare.', 'weeklylimit' => 'È stato raggiunto il limite settimanale di transazioni, per numero o ammontare.', 'monthlylimit' => 'È stato raggiunto il limite mensile di transazioni, per numero o ammontare.', ), 'baddata' => array ( 'missingfields' => 'Non sono stati inviati uno o più paramentri obbligatori per questo tipo di transazione.', 'extrafields' => 'Sono stati inviati parametri non ammessi per questo tipo di transazione.', 'badformat' => 'Uno dei campi è stato compilato impropriamente, ad esempio un carattere alfabetico in un campo numerico.', 'badlength' => 'Uno dei campi è più grande o più piccolo del consentito.', 'merchantcantaccept' => 'Il venditore non accetta i dati introdotti in questo campo.', 'mismatch' => 'I dati di uno dei campi non soddisfa il controllo incrociato con con un\'altro dei campi.', ), 'error' => array ( 'cantconnect' => 'Impossibile connettersi alla piattaforma TrustCommerce. Controllare la connessione a Internet e assicurarsi che sia in funzione.', 'dnsfailure' => 'Il programma TCLink non è stato in grado di risolvere i nomi DNS. Assicurarsi di poter risolvere i nomi sulla macchina.', 'linkfailure' => 'È stata stabilita la connessione, ma si è interrotta prima che terminasse la transazione.', 'failtoprocess' => 'I server della Banca non sono in línea, pertanto risulta impossibile autorizzare le transazioni. Ritenta fa qualche minuto, oppure prova con una carta di un\'altra banca.', ), );./kohana/modules/payment/i18n/it_IT/payment_Trident.php0000644000175000017500000000766211121324570022604 0ustar tokkeetokkee 'Nessun errore - Transazione Approvata.', '001' => 'Chiamare', '002' => 'Chiamare', '003' => 'Errore nell\'Id del Venditore', '004' => 'Hold-call o Carta Pick Up', '005' => 'Declinato. Impossibile onorare.', '006' => 'Errore Generale nella Transazione.', '007' => 'Hold-call o Carta Pick Up', '012' => 'Transazione non valida', '013' => 'Errore nell\'ammontare', '014' => 'Errore nel Numero della Carta', '015' => 'No Such Issuer', '019' => 'Errore di comunicazione con Visa. L\'utente deve ripetere.', '021' => 'Nessuna azione sarà realizzata', '041' => 'Hold-call o Scheda Pick Up', '043' => 'Hold-call o Scheda Pick Up', '051' => 'Negato. Fondi insufficienti.', '054' => 'Carta scaduta', '055' => 'Serv Non Permesso', '058' => 'Serv Non Permesso', '062' => 'Negato. Codice di servizio invalido, ristretto.', '063' => 'Violazione di sicurezza', '065' => 'Negato. Superato il limite di attività.', '076' => 'Unsolic Reversal', '077' => 'Nessuna azione sarà realizzata. L\'ammontare ritornato supera l\'originale.', '078' => 'Conto inesistente', '079' => 'Operazione già annullata', '080' => 'Errore nella data', '082' => 'CVV sbagliato', '085' => 'Carta Corretta. Nessun motivo per negare.', '091' => 'Senza risposta', '092' => 'Invalid Routing', '093' => 'Negato. Violazione, non si può completare.', '094' => 'Transazione Duplicata', '096' => 'Errore del sistema. Funzionamento non corretto del sistema. Bug in Trident. Portare il problema agli sviluppatori.', '0N7' => 'CVV2 Mismatch', '101' => 'ID o Chiave del profilo incorretto.', '102' => 'Richiesta Incompleta.', '103' => 'Errore nelle dimensioni del numero di fattura.', '104' => 'Errore nelle dimensioni del numero di riferimento.', '105' => 'Errore nelle dimensioni dell\'indirizzo di AVS.', '106' => 'EErrore nelle dimensioni del zip di AVS.', '107' => 'Errore nelle dimensioni del nome del venditore.', '108' => 'Errore nelle dimensioni del comune del venditore.', '109' => 'Errore nelle dimensioni dello Stato del venditore.', '110' => 'Errore nelle dimensioni del zip del venditore.', '111' => 'Errore nelle dimensioni del codice della categoria del venditore.', '112' => 'Errore nelle dimensioni del telefono del venditore.', '113' => 'Il numero di riferimento deve essere numerico.', '114' => 'Conto del proprietario della carta non trovato.', '115' => 'Numero della carta non valido.', '116' => 'Non si accettano crediti.', '117' => 'Tipo di carta non supportato.', '118' => 'Tipo di valuta non supportata.', '201' => 'ID di transazione non valida.', '202' => 'Ammontare della transazione non valido.', '203' => 'Annullamento fallito.', '204' => 'Transazione in processo.', '205' => 'Transazione annullata.', '206' => 'Transazione rimborsata.', '207' => 'Rimborso fallito.', '208' => 'Fallita la ricezione di una risposta dal servente delle autorizzazioni.', '209' => 'Ammontare d\'imposta non corretto.', '210' => 'Il risultato di AVS è rifiutato dall\'utente.', '211' => 'Il risultato di CVV2 è rifiutato dall\'utente.', '212' => 'L\'ammontare rimborsato deve essere compreso tra zero e l\'ammontare originario.', '213' => 'Solo le transazioni di vendita possono essere rimborsate.', '214' => 'È consentito un solo tipo di carta per ogni richiesta.', '215' => 'ID della carta invalido.', '216' => 'Fallito il caricamento dei dati dalla carta, tentare con una nuova richiesta.', '217' => 'Fallito il salvataggio dei dati dalla carta, tentare con una nuova richiesta.', '218' => 'Questo tipo di transazioni non possono includere l\'ID della carta.', '300' => 'Fallita la cattura della transazione PayVision.', '301' => 'Fallito l\'annullamento della transazione PayVision.', '302' => 'Fallito il rimborso della transazione PayVision.', '303' => 'Verifica della carta non supportato.', '304' => 'Inversione di autorizzazione PayVision fallita.', '305' => 'Errore Interno.', );./kohana/modules/payment/i18n/zh_CN/0000755000175000017500000000000011263472445016717 5ustar tokkeetokkee./kohana/modules/payment/i18n/mk_MK/0000755000175000017500000000000011263472445016714 5ustar tokkeetokkee./kohana/modules/payment/i18n/mk_MK/payment.php0000644000175000017500000000135611121331011021057 0ustar tokkeetokkee 'Некои задолжителни полиња не се пополнети: %s', 'gateway_connection_error' => 'Се појави грешка при поврзување со payment gateway. Ве молиме контактирајте со вебмастерот ако овој проблем цело време се појавува.', 'invalid_certificate' => 'Сертификатот не е валиден: %s', 'no_dlib' => 'Динамичката библиотека не може да се вчита: %s', 'error' => 'Се појави грешка при процесирање на трансакцијата: %s', );./kohana/modules/payment/i18n/mk_MK/payment_Trustcommerce.php0000644000175000017500000000735211121331011023775 0ustar tokkeetokkee array ( 'avs' => 'Погрешен AVS; внесената адреса не е иста со наплатната адреса заведена во банката.', 'cvv' => 'Погрешен CVV; внесениот број не е точниот број за верификација на оваа картичка.', 'call' => 'Картичката мора мануелно да се авторизира преку телефон. Може да се јавите на бројот на сервисот за клиенти кој е напишан на картичката и да побарате offline authcode, кој потоа може да се напише во полето offlineauthcode.', 'expiredcard' => 'Картичката е истечена. Побарајте продолжување на датумот на валидност.', 'carderror' => 'Бројот на картичката е погрешен, можеби е згрешен или картичката е пријавена дека е украдена.', 'authexpired' => 'Пробавте да се пост-авторизирате со помината (повеќе од 14 дена) пред-авторизација.', 'fraud' => 'CrediGuard fraud score е под побараната граница.', 'blacklist' => 'Вклучена е CrediGuard blacklist вредност.', 'velocity' => 'Вклучен е CrediGuard velocity control.', 'dailylimit' => 'Достигнат е дневниот лимит на бројот на трансакции или на вредноста.', 'weeklylimit' => 'Достигнат е неделниот лимит на бројот на трансакции или на вредноста.', 'monthlylimit' => 'Достигнат е месечниот лимит на бројот на трансакции или на вредноста.' ), 'baddata' => array ( 'missingfields' => 'Еден или повеќе задолжителни параметри за овој тип на трансакција не се напишани.', 'extrafields' => 'Испратени се параметри кои не се дозволени за овој вид на трансакција.', 'badformat' => 'Полето неправилно е форматирано, како на пример, букви во нумеричко поле.', 'badlength' => 'Полето содржи подолга или пократка вредност дозволена од серверот.', 'merchantcantaccept' => 'Трговецот не го одобрува податокот од ова поле.', 'mismatch' => 'Податокот во едно од спорните полиња не е соодветно со другото.' ), 'error' => array ( 'cantconnect' => 'Не е остварено поврзување со TrustCommerce gateway. Проверете дали интернет конекцијата е во ред.', 'dnsfailure' => 'TCLink софтверот не можеше да ги добие имињата на DNS хостовите. Проверете дали ваква проверка е возможна на овој компјутер.', 'linkfailure' => 'Конекцијата беше остварена, но се прекина пред трансакцијата да заврши.', 'failtoprocess' => 'Банковните сервери се исклучени и не можат да овластат трансакции. Пробајте повторно за неколку минути или пробајте со картичка издадена од друга банка.', ) );./kohana/modules/payment/i18n/mk_MK/payment_Trident.php0000644000175000017500000000627111121331011022551 0ustar tokkeetokkee 'No errors - Transaction Approved.', '001' => 'Call', '002' => 'Call', '003' => 'Merch Id Error', '004' => 'Hold-call or Pick Up Card', '005' => 'Decline. Do not honor.', '006' => 'General Transaction Error.', '007' => 'Hold-call or Pick Up Card', '012' => 'Invalid Trans', '013' => 'Amount Error', '014' => 'Card No. Error', '015' => 'No Such Issuer', '019' => 'Communication error with Visa. Customer should retry.', '021' => 'No Action Taken', '041' => 'Hold-call or Pick Up Card', '043' => 'Hold-call or Pick Up Card', '051' => 'Decline. Insufficient funds.', '054' => 'Expired Card', '055' => 'Serv Not Allowed', '058' => 'Serv Not Allowed', '062' => 'Decline. Invalid service code, restricted.', '063' => 'Sec Violation', '065' => 'Decline. Activity limit exceeded.', '076' => 'Unsolic Reversal', '077' => 'No Action Taken. Reversal amount larger then original amount.', '078' => 'No Account', '079' => 'Already Reversed', '080' => 'Date Error', '082' => 'Incorrect CVV', '085' => 'Card OK. No reason to decline.', '091' => 'No Reply', '092' => 'Invalid Routing', '093' => 'Decline. Violation, cannot complete.', '094' => 'Duplicate Trans', '096' => 'System Error. System malfunction. A bug in Trident. Escalate issue to developers.', '0N7' => 'CVV2 Mismatch', '101' => 'Invalid Profile ID or Profile Key.', '102' => 'Incomplete Request.', '103' => 'Invoice Number Length Error.', '104' => 'Reference Number Length Error.', '105' => 'AVS Address Length Error.', '106' => 'AVS Zip Length Error.', '107' => 'Merchant Name Length Error.', '108' => 'Merchant City Length Error.', '109' => 'Merchant State Length Error.', '110' => 'Merchant Zip Length Error.', '111' => 'Merchant Category Code Length Error.', '112' => 'Merchant Phone Length Error.', '113' => 'Reference Number Must Be Numeric.', '114' => 'Missing Card Holder Account Data.', '115' => 'Invalid Card Number.', '116' => 'Credits Not Allowed.', '117' => 'Card Type Not Accepted.', '118' => 'Currency Type Not Accepted.', '201' => 'Invalid Transaction ID.', '202' => 'Invalid Transaction Amount.', '203' => 'Void Failed.', '204' => 'Transaction Already Settled.', '205' => 'Transaction Already Voided.', '206' => 'Transaction Already refunded.', '207' => 'Refund failed.', '208' => 'Failed to receive a response from auth host.', '209' => 'Invalid tax amount.', '210' => 'AVS result is declined by user.', '211' => 'CVV2 result is declined by user.', '212' => 'Refund amount must be between zero and the original amount.', '213' => 'Only sale transactions can be refunded.', '214' => 'Only one type of card data allowed per request.', '215' => 'Invalid Card ID.', '216' => 'Failed to load card data, retry request.', '217' => 'Failed to store card data, retry request.', '218' => 'Card ID parameter cannot be included in this type of transaction.', '300' => 'Failed to capture PayVision transaction.', '301' => 'Failed to void PayVision transaction.', '302' => 'Failed to refund PayVision transaction.', '303' => 'Card Verify not supported.', '304' => 'Failed to reverse PayVision authorization.', '305' => 'Internal Error.' );./kohana/modules/payment/i18n/nl_NL/0000755000175000017500000000000011263472445016720 5ustar tokkeetokkee./kohana/modules/payment/i18n/nl_NL/payment.php0000644000175000017500000000105511121331011021057 0ustar tokkeetokkee 'Sommige verplichte velden werden niet ingevuld: %s', 'gateway_connection_error' => 'Er ging iets mis bij het verbinden met de payment gateway. Contacteer a.u.b. de webmaster als dit probleem aanhoudt.', 'invalid_certificate' => 'Het certificaatsbestand is ongeldig: %s', 'no_dlib' => 'Kon de dynamische library niet laden: %s', 'error' => 'Er ging iets mis bij het verwerken van de transactie: %s', );./kohana/modules/payment/i18n/en_US/0000755000175000017500000000000011263472445016727 5ustar tokkeetokkee./kohana/modules/payment/i18n/en_US/payment.php0000644000175000017500000000101611121331011021063 0ustar tokkeetokkee 'Some required fields were not supplied: %s', 'gateway_connection_error' => 'An error occured connecting to the payment gateway. Please contact the webmaster if this problem persists.', 'invalid_certificate' => 'The certificate file is invalid: %s', 'no_dlib' => 'Could not load the dynamic library: %s', 'error' => 'There was an error processing the transaction: %s', );./kohana/modules/payment/i18n/en_US/payment_Trustcommerce.php0000644000175000017500000000451511121331011024006 0ustar tokkeetokkee array ( 'avs' => 'AVS failed; the address entered does not match the billing address on file at the bank.', 'cvv' => 'CVV failed; the number provided is not the correct verification number for the card.', 'call' => 'The card must be authorized manually over the phone. You may choose to call the customer service number listed on the card and ask for an offline authcode, which can be passed in the offlineauthcode field.', 'expiredcard' => 'The card has expired. Get updated expiration date from cardholder.', 'carderror' => 'Card number is invalid, which could be a typo, or sometimes a card reported stolen.', 'authexpired' => 'Attempt to postauth an expired (more than 14 days old) preauth.', 'fraud' => 'CrediGuard fraud score was below requested threshold.', 'blacklist' => 'CrediGuard blacklist value was triggered.', 'velocity' => 'CrediGuard velocity control was triggered.', 'dailylimit' => 'Daily limit in transaction count or amount as been reached.', 'weeklylimit' => 'Weekly limit in transaction count or amount as been reached.', 'monthlylimit' => 'Monthly limit in transaction count or amount as been reached.', ), 'baddata' => array ( 'missingfields' => 'One or more parameters required for this transaction type were not sent.', 'extrafields' => 'Parameters not allowed for this transaction type were sent.', 'badformat' => 'A field was improperly formatted, such as non-digit characters in a number field.', 'badlength' => 'A field was longer or shorter than the server allows.', 'merchantcantaccept' => 'The merchant can\'t accept data passed in this field.', 'mismatch' => 'Data in one of the offending fields did not cross-check with the other offending field.', ), 'error' => array ( 'cantconnect' => 'Couldn\'t connect to the TrustCommerce gateway. Check your Internet connection to make sure it is up.', 'dnsfailure' => 'The TCLink software was unable to resolve DNS hostnames. Make sure you have name resolving ability on the machine.', 'linkfailure' => 'The connection was established, but was severed before the transaction could complete.', 'failtoprocess' => 'The bank servers are offline and unable to authorize transactions. Try again in a few minutes, or try a card from a different issuing bank.', ) );./kohana/modules/payment/i18n/en_US/payment_Trident.php0000644000175000017500000000627111121331011022564 0ustar tokkeetokkee 'No errors - Transaction Approved.', '001' => 'Call', '002' => 'Call', '003' => 'Merch Id Error', '004' => 'Hold-call or Pick Up Card', '005' => 'Decline. Do not honor.', '006' => 'General Transaction Error.', '007' => 'Hold-call or Pick Up Card', '012' => 'Invalid Trans', '013' => 'Amount Error', '014' => 'Card No. Error', '015' => 'No Such Issuer', '019' => 'Communication error with Visa. Customer should retry.', '021' => 'No Action Taken', '041' => 'Hold-call or Pick Up Card', '043' => 'Hold-call or Pick Up Card', '051' => 'Decline. Insufficient funds.', '054' => 'Expired Card', '055' => 'Serv Not Allowed', '058' => 'Serv Not Allowed', '062' => 'Decline. Invalid service code, restricted.', '063' => 'Sec Violation', '065' => 'Decline. Activity limit exceeded.', '076' => 'Unsolic Reversal', '077' => 'No Action Taken. Reversal amount larger then original amount.', '078' => 'No Account', '079' => 'Already Reversed', '080' => 'Date Error', '082' => 'Incorrect CVV', '085' => 'Card OK. No reason to decline.', '091' => 'No Reply', '092' => 'Invalid Routing', '093' => 'Decline. Violation, cannot complete.', '094' => 'Duplicate Trans', '096' => 'System Error. System malfunction. A bug in Trident. Escalate issue to developers.', '0N7' => 'CVV2 Mismatch', '101' => 'Invalid Profile ID or Profile Key.', '102' => 'Incomplete Request.', '103' => 'Invoice Number Length Error.', '104' => 'Reference Number Length Error.', '105' => 'AVS Address Length Error.', '106' => 'AVS Zip Length Error.', '107' => 'Merchant Name Length Error.', '108' => 'Merchant City Length Error.', '109' => 'Merchant State Length Error.', '110' => 'Merchant Zip Length Error.', '111' => 'Merchant Category Code Length Error.', '112' => 'Merchant Phone Length Error.', '113' => 'Reference Number Must Be Numeric.', '114' => 'Missing Card Holder Account Data.', '115' => 'Invalid Card Number.', '116' => 'Credits Not Allowed.', '117' => 'Card Type Not Accepted.', '118' => 'Currency Type Not Accepted.', '201' => 'Invalid Transaction ID.', '202' => 'Invalid Transaction Amount.', '203' => 'Void Failed.', '204' => 'Transaction Already Settled.', '205' => 'Transaction Already Voided.', '206' => 'Transaction Already refunded.', '207' => 'Refund failed.', '208' => 'Failed to receive a response from auth host.', '209' => 'Invalid tax amount.', '210' => 'AVS result is declined by user.', '211' => 'CVV2 result is declined by user.', '212' => 'Refund amount must be between zero and the original amount.', '213' => 'Only sale transactions can be refunded.', '214' => 'Only one type of card data allowed per request.', '215' => 'Invalid Card ID.', '216' => 'Failed to load card data, retry request.', '217' => 'Failed to store card data, retry request.', '218' => 'Card ID parameter cannot be included in this type of transaction.', '300' => 'Failed to capture PayVision transaction.', '301' => 'Failed to void PayVision transaction.', '302' => 'Failed to refund PayVision transaction.', '303' => 'Card Verify not supported.', '304' => 'Failed to reverse PayVision authorization.', '305' => 'Internal Error.' );./kohana/modules/payment/i18n/el_GR/0000755000175000017500000000000011263472445016706 5ustar tokkeetokkee./kohana/modules/payment/i18n/fr_FR/0000755000175000017500000000000011263472445016714 5ustar tokkeetokkee./kohana/modules/payment/i18n/fr_FR/payment.php0000644000175000017500000000113211121331011021047 0ustar tokkeetokkee 'Des champs obligatoires n\'ont pas été remplis: %s', 'gateway_connection_error' => 'Une erreur de connexion à la plateforme de paiement est survenue. Veuillez contacter le Webmaster si le problème persiste.', 'invalid_certificate' => 'Le fichier de certificats suivant est invalide: %s', 'no_dlib' => 'Impossible de charger la librairie dynamique suivante: %s', 'error' => 'Une erreur s\'est produite lors de la transaction suivante: %s', ); ./kohana/modules/payment/i18n/fr_FR/payment_Trustcommerce.php0000755000175000017500000000604011121331011023771 0ustar tokkeetokkee array ( 'avs' => 'Le Service de Vrification d\'Adresse (AVS) a retourn une erreur. L\'adresse entre ne correspond pas l\'adresse de facturation du fichier bancaire.', 'cvv' => 'Le code de vrification (CVV) de votre carte n\'a pas t accept. Le numro que vous avez entr n\'est pas le bon ou ne correspond pas cette carte.', 'call' => 'La carte doit tre autorise par tlphone. Vous devez choisir ce numro d\'appel parmis ceux lists sur la carte et demander un code d\'authentification hors ligne (offline authcode). Celui-ci pourra ensuite tre entr dans le champ rserv cet effet (offlineauthcode).', 'expiredcard' => 'La carte a expire. Vous devez obtenir une carte possdant une date de validit valide auprs du fournisseur de celle-ci.', 'carderror' => 'Le numro de carte est invalide. Veuillez vrifier que vous avez correctement entr le numro, ou que cette carte n\'ait pas t reporte comme tant vole.', 'authexpired' => 'Tentative d\'autoriser une pr-autorisation qui a expire il y a plus de 14 jours..', 'fraud' => 'Le score de vrification est en dessous du score anti-fraude CrediGuard.', 'blacklist' => 'CrediGuard donne cette valeur comme tant sur liste noire (blackliste).', 'velocity' => 'Le seuil de contle CrediGuard a t atteint. Trop de transactions ont t effectus.', 'dailylimit' => 'La limite journalire des transactions de cette carte a t atteinte.', 'weeklylimit' => 'La limite hebdomadaire des transactions de cette carte a t atteinte.', 'monthlylimit' => 'La limite mensuelle des transactions de cette carte a t atteinte.', ), 'baddata' => array ( 'missingfields' => 'Un ou plusieurs paramtres requis pour ce type de transaction n\'a pas t transmis.', 'extrafields' => 'Des paramtres interdits pour ce type de transaction ont t envoys.', 'badformat' => 'Un champ n\'a pas t format correctement, comme par exemple des caractres alphabtiques insrs dans un champ numrique.', 'badlength' => 'Un champ est plus grand ou plus petit que la taille accepte par le serveur.', 'merchantcantaccept' => 'Le commerant ne peut accepter les donnes passes dans ce champ.', 'mismatch' => 'Les donnes de l\'un des champs erron ne correspond pas avec l\'autre champs.', ), 'error' => array ( 'cantconnect' => 'Impossible de se connecter la plateforme TrustCommerce ! Veuillez vous assurer que votre connexion internet fonctionne.', 'dnsfailure' => 'Le logiciel TCLink a t incapable de rsoudre l\'adresse DNS du serveur. Assurez-vous que votre machine possde la capacit de rsoudre les noms DNS.', 'linkfailure' => 'La connexion n\'a pas pu tre tablie et vous avez t dconnect avant que la transaction ne soit complte.', 'failtoprocess' => 'Les serveurs bancaires ne sont pas disponibles actuellement et ne peuvent donc accepter des transactions. Veuillez ressayer dans quelques minutes. Vous pouvez galement tester avec une autre carte d\'un autre organisme bancaire.', ) ); ./kohana/modules/payment/i18n/fr_FR/payment_Trident.php0000755000175000017500000001012411121331011022544 0ustar tokkeetokkee 'Aucunes erreurs - Transaction approuve.', '001' => 'Appel', '002' => 'Appel', '003' => 'Erreur avec l\'Identifiant du commerant', '004' => 'Hold-call or Pick Up Card', '005' => 'Decliner.', '006' => 'Erreur gnrale lors de la Transaction.', '007' => 'Hold-call or Pick Up Card', '012' => 'Transaction invalide', '013' => 'Erreur de quantit', '014' => 'Erreur avec le No de carte', '015' => 'L\'metteur n\'a pas t trouv', '019' => 'Erreur de communication avec Visa. Le client devrait ressayer.', '021' => 'Pas d\'action entreprises', '041' => 'Hold-call or Pick Up Card', '043' => 'Hold-call or Pick Up Card', '051' => 'Dcliner. Fonds insuffisants.', '054' => 'Carte expire', '055' => 'Serveur (Serv) non autoris', '058' => 'Serveur (Serv) non autoris', '062' => 'Dcliner. Code du service invalide.', '063' => 'Violation de scurit (Sec Violation)', '065' => 'Dcliner. La limite d\'activit a t dpasse.', '076' => 'Unsolic Reversal', '077' => 'Pas d\'actions entreprises. Reversal amount larger then original amount.', '078' => 'Pas de compte', '079' => 'Already Reversed', '080' => 'Erreur de date', '082' => 'Le code de vrification (CVV) est incorrect', '085' => 'Carte OK. Aucune raisons pour dcliner.', '091' => 'Pas de rponse', '092' => 'Route invalide', '093' => 'Dcliner. Violation, impossible de terminer.', '094' => 'Dupliquer la transaction', '096' => 'Erreur systme. Bug dans Trident. Remonter l\'erreur aux dveloppeurs.', '0N7' => 'Le code de vrification CVV2 ne concorde pas', '101' => 'L\'IDentifiant ou la cl du profil est invalide.', '102' => 'Demande incomplte.', '103' => 'Erreur avec la longueur du numro de facture.', '104' => 'Erreur avec la longueur du numro de rfrence.', '105' => 'Erreur avec la longueur de l\'adresse du service de vrification (AVS).', '106' => 'Erreur avec la longueur du code postal du service de vrification (AVS).', '107' => 'Erreur avec la longueur du nom du commerant.', '108' => 'Erreur avec la longueur de la ville du commerant.', '109' => 'Erreur avec la longueur de l\'tat (State) du commerant.', '110' => 'Erreur avec la longueur du code postal du commerant.', '111' => 'Erreur avec la longueur du code de la catgorie du commerant.', '112' => 'Erreur avec la longueur du tlphone du commerant.', '113' => 'Le numro de rfrence doit tre numrique.', '114' => 'Des informations sur le titulaire de la carte sont manquantes.', '115' => 'Numro de carte invalide.', '116' => 'Credits non autoriss.', '117' => 'Type de carte non accept.', '118' => 'Type de monnaie non accept.', '201' => 'Identifiant de Transaction invalide.', '202' => 'Montant de la Transaction invalide.', '203' => 'L\'annualtion a chou.', '204' => 'Transaction dj tablie.', '205' => 'Transaction dj annule.', '206' => 'Transaction dj rembourse.', '207' => 'Le remboursement a chou.', '208' => 'Aucune rponse reue de hte authentifi.', '209' => 'Montant de la taxe invalide.', '210' => 'Le rsultat du service de vrification (AVS) est refus par l\'utilisateur.', '211' => 'Le rsultat du code de vrification CVV2 est refus par l\'utilisateur.', '212' => 'Le montant rembours doit tre compris entre zro et le montant original.', '213' => 'Seules les transaction de vente peuvent tre rembourses.', '214' => 'Un seul type de carte n\'est autoris par demande.', '215' => 'L\'IDentifiant de carte invalide.', '216' => 'Impossbile de charger les donnes de la carte, ressayer la requte.', '217' => 'La sauvegarde des donnes de la carte a chou, ressayer la requte.', '218' => 'L\'IDentifiant de la carte ne peut pas tre inclus dans ce type de transaction.', '300' => 'La capture de la transaction PayVision a chou.', '301' => 'L\'annulation de la transaction PayVision a chou.', '302' => 'Le remboursement de la transaction PayVision a chou.', '303' => 'Aucun systme de vrification de la carte n\'est implment.', '304' => 'L\'annulation de l\'autorisation PayVision a chou.', '305' => 'Erreur interne.' ); ./kohana/modules/payment/i18n/de_DE/0000755000175000017500000000000011263472445016656 5ustar tokkeetokkee./kohana/modules/payment/i18n/de_DE/payment.php0000644000175000017500000000105511121331011021015 0ustar tokkeetokkee 'Einige benötigte Felder wurden nicht übergeben: %s', 'gateway_connection_error' => 'Fehler bei der Verbindung zum Bezahldienst aufgetreten. Sollte der Fehler weiterhin bestehen, kontaktieren Sie bitte den Webmaster.', 'invalid_certificate' => 'Das Zertifikat ist ungültig: %s', 'no_dlib' => 'Konnte die dynamische Bibliothek nicht laden: %s', 'error' => 'Fehler bei Transaktion aufgetreten: %s', );./kohana/modules/payment/i18n/de_DE/payment_Trustcommerce.php0000644000175000017500000000521411121331011023732 0ustar tokkeetokkee array ( 'avs' => 'AVS fehlgeschlagen; Die angegebene Adresse stimmt nicht mit der Rechnungsadresse in der Bank überein.', 'cvv' => 'CVV fehlgeschlagen; Die angegebene Zahl ist nicht die korrekte Prüfnummer der Karte.', 'call' => 'Die Karte muss über das Telefon autorisiert werden. Sie können die Kundenbetreung anrufen, um nach dem Offline-Autorisierungscode zu fragen, der in das entsprechende Feld eingetragen werden kann.', 'expiredcard' => 'Die Karte ist abgelaufen. Fragen Sie nach einem neuen Ablaufdatum bei dem Karteninhaber.', 'carderror' => 'Die Kartennummer ist ungültig. Das könnte ein Tippfehler oder manchmal die Karte als gestohlen gemeldet sein.', 'authexpired' => 'Versuch eine abgelaufene (mehr, als 14 Tage alt) Vorautorisation zu nachzuautorisieren.', 'fraud' => 'CrediGuard fraud score war unter dem gefordetem Schwellenwert.', 'blacklist' => 'CrediGuard Blacklist-Wert wurde ausgelöst.', 'velocity' => 'CrediGuard Geschwindigkeitsregelung wurde ausgelöst.', 'dailylimit' => 'Tageslimit oder der Transaktionen oder des Betrags wurde erreicht.', 'weeklylimit' => 'Wochenlimit oder der Transaktionen oder des Betrags wurde erreicht.', 'monthlylimit' => 'Monatslimit oder der Transaktionen oder des Betrags wurde erreicht.', ), 'baddata' => array ( 'missingfields' => 'Ein oder mehr Parameter, die für diese Transaktion benötigt werden, wurden nicht gesendet.', 'extrafields' => 'Parameter, die für diese Transaktion gesendet wurden, sind nicht erlaubt.', 'badformat' => 'Ein Feld ist nicht sachgemäß formatiert worden. Es könnten zum Beispiel Buchstaben in einem Zahlenfeld vogekommen sein.', 'badlength' => 'Ein Feld war länger oder kürzer, als es der Server erlaubt.', 'merchantcantaccept' => 'Der Händler kann diese übergebenen Daten in diesem Feld nicht akzeptieren.', 'mismatch' => 'Daten in einem der folgenden Felder stimmen nicht mit einem anderen Feld überein.', ), 'error' => array ( 'cantconnect' => 'Konnte keine Verbindung zu TrustCommerce aufbauen. Kontrollieren Sie ihre Internetverbindung, um sicherzustellen, dass diese funktioniert.', 'dnsfailure' => 'Das Programm TCLink konnte die DNS-Hostnamen nicht auflösen. Stellen Sie sicher, dass sie die Rechte dafür besitzen.', 'linkfailure' => 'Die hergestellte Verbindung wurde unterbrochen, bevor die Transaktion beendet werden konnte.', 'failtoprocess' => 'Die Server der Bank sind offline und nicht in der Lage die Transaktion zu autorisieren. Versuchen Sie es in einigen Minuten noch ein mal oder benutzen Sie eine Karte einer anderen Bank.', ) );./kohana/modules/payment/i18n/de_DE/payment_Trident.php0000644000175000017500000000720711121331011022513 0ustar tokkeetokkee 'Keine Fehler - Transaktion bestätigt.', '001' => 'Anruf', '002' => 'Anruf', '003' => 'Händler-ID-Fehler', '004' => 'Hold-call or Pick Up Card', '005' => 'Decline. Do not honor.', '006' => 'Allgemeiner Transaktions-Fehler.', '007' => 'Hold-call or Pick Up Card', '012' => 'Ungültige Transaktion', '013' => 'Betragsfehler', '014' => 'Kartennummer-Fehler', '015' => 'Kein Aussteller', '019' => 'Kommunikationsfehler mit Visa. Der Kunde sollte erneut versuchen.', '021' => 'Keine Aktion getätigt', '041' => 'Hold-call or Pick Up Card', '043' => 'Hold-call or Pick Up Card', '051' => 'Decline. Insufficient funds.', '054' => 'Karte abgelaufen', '055' => 'Serv nicht erlaubt', '058' => 'Serv nicht erlaubt', '062' => 'Decline. Invalid service code, restricted.', '063' => 'Sec Violation', '065' => 'Decline. Activity limit exceeded.', '076' => 'Unsolic Reversal', '077' => 'Transaktion nicht getätigt. Rückbetrag gräßer, als der Original-Betrag.', '078' => 'Kein Konto', '079' => 'Bereits rückgängig gemacht', '080' => 'Datumsfehler', '082' => 'Fehlerhafte CVV', '085' => 'Karte OK. Kein Grund zu verweigern.', '091' => 'Keine Antwort', '092' => 'Ungültige Route', '093' => 'Verweigere. Misbrauch. Konnte nicht beenden.', '094' => 'Doppelte Transaktion', '096' => 'Systemfehler. Fehler in Trident. Entwickler benachrichtigen.', '0N7' => 'Unterschied in CVV2', '101' => 'Üngültige Profil-ID oder Profilschlüssel.', '102' => 'Nich vollendeter Aufruf.', '103' => 'Fehler in der Länge der Rechnungsnummer.', '104' => 'Fehler in der Länge der Referenznummer.', '105' => 'Fehler in der Länge der AVS-Adresse.', '106' => 'Fehler in der Länge der AVS-PLZ.', '107' => 'Fehler in der Länge des Händler-Namens.', '108' => 'Fehler in der Länge der Händler-Stadt.', '109' => 'Fehler in der Länge des Händler-Bundeslandes.', '110' => 'Fehler in der Länge der Händler-PLZ.', '111' => 'Fehler in der Länge des Händer-Kategorie-Codes.', '112' => 'Fehler in der Länge der Händler-Telefonnummer.', '113' => 'Referenznummer muss numerisch sein.', '114' => 'Kontodaten des Karteninhabers fehlen.', '115' => 'Ungültige Kartennummer.', '116' => 'Kredite nicht zulässig.', '117' => 'Kartentyp nicht zulässig.', '118' => 'Währung nicht zulässig.', '201' => 'Ungültige Transactions-ID.', '202' => 'Ungültiger Transaction-Betrag.', '203' => 'Storno fehlgeschlagen.', '204' => 'Transaction bereits bestätigt.', '205' => 'Transaction bereits storniert.', '206' => 'Transaction bereits erstattet.', '207' => 'Erstattung fehlgeschlagen.', '208' => 'Antwort vom Auth-Host nicht erhalten.', '209' => 'Ungültiger Steuer-Betrag.', '210' => 'AVS-Ergebnisse vom Benutzer nicht akzeptiert.', '211' => 'CVV2-Ergebnisse vom Benutzer nicht akzeptiert.', '212' => 'Erstattungsbetrag muss zwischen Null und dem Originalbetrag liegen.', '213' => 'Nur Verkaufs-Transaktionen können erstattet werden.', '214' => 'Nur ein Typ der Karten-Daten pro Aufruf erlaubt.', '215' => 'Ungültige Karten-ID.', '216' => 'Kartendaten konnten icht geladen werden. Bitte erneut versuchen.', '217' => 'Kartendaten konnten nicht gespeichert werden. Bitte erneut versuchen.', '218' => 'Parameter der Karten-ID sind in dieser Transaktions-Art nicht enthalten.', '300' => 'Konnte PayVision-Transaktion nicht entgegen nehmen.', '301' => 'Konnte PayVision-Transaktion nicht stornieren.', '302' => 'Konnte PayVision-Transaktion nicht erstatten.', '303' => 'Kartenprüfung nicht unterstützt.', '304' => 'Konnte Payvision-Authorisation nicht zurücknehmen.', '305' => 'Interner Fehler.' );./kohana/modules/payment/i18n/pt_BR/0000755000175000017500000000000011263472445016724 5ustar tokkeetokkee./kohana/modules/payment/i18n/pt_BR/payment.php0000644000175000017500000000105411121331011021062 0ustar tokkeetokkee 'Alguns campos necessários não foram prenchidos: %s', 'gateway_connection_error' => 'Um erro aconteceu ao conectar ao gateway de pagamento. Por favor conatte o webmaster se o problema persistir.', 'invalid_certificate' => 'O arquivo de certificado é inválido: %s', 'no_dlib' => 'Não foi possível carregar a biblioteca dinâmica: %s', 'error' => 'Houve um erro ao processar a transação: %s', );./kohana/modules/payment/i18n/pt_BR/payment_Trustcommerce.php0000644000175000017500000000451511121331011024003 0ustar tokkeetokkee array ( 'avs' => 'AVS failed; the address entered does not match the billing address on file at the bank.', 'cvv' => 'CVV failed; the number provided is not the correct verification number for the card.', 'call' => 'The card must be authorized manually over the phone. You may choose to call the customer service number listed on the card and ask for an offline authcode, which can be passed in the offlineauthcode field.', 'expiredcard' => 'The card has expired. Get updated expiration date from cardholder.', 'carderror' => 'Card number is invalid, which could be a typo, or sometimes a card reported stolen.', 'authexpired' => 'Attempt to postauth an expired (more than 14 days old) preauth.', 'fraud' => 'CrediGuard fraud score was below requested threshold.', 'blacklist' => 'CrediGuard blacklist value was triggered.', 'velocity' => 'CrediGuard velocity control was triggered.', 'dailylimit' => 'Daily limit in transaction count or amount as been reached.', 'weeklylimit' => 'Weekly limit in transaction count or amount as been reached.', 'monthlylimit' => 'Monthly limit in transaction count or amount as been reached.', ), 'baddata' => array ( 'missingfields' => 'One or more parameters required for this transaction type were not sent.', 'extrafields' => 'Parameters not allowed for this transaction type were sent.', 'badformat' => 'A field was improperly formatted, such as non-digit characters in a number field.', 'badlength' => 'A field was longer or shorter than the server allows.', 'merchantcantaccept' => 'The merchant can\'t accept data passed in this field.', 'mismatch' => 'Data in one of the offending fields did not cross-check with the other offending field.', ), 'error' => array ( 'cantconnect' => 'Couldn\'t connect to the TrustCommerce gateway. Check your Internet connection to make sure it is up.', 'dnsfailure' => 'The TCLink software was unable to resolve DNS hostnames. Make sure you have name resolving ability on the machine.', 'linkfailure' => 'The connection was established, but was severed before the transaction could complete.', 'failtoprocess' => 'The bank servers are offline and unable to authorize transactions. Try again in a few minutes, or try a card from a different issuing bank.', ) );./kohana/modules/payment/i18n/pt_BR/payment_Trident.php0000644000175000017500000000632611121331011022562 0ustar tokkeetokkee 'Sem Erros - Transação Aprovada.', '001' => 'Call', '002' => 'Call', '003' => 'Merch Id Error', '004' => 'Hold-call or Pick Up Card', '005' => 'Decline. Do not honor.', '006' => 'Erro geral de transação.', '007' => 'Hold-call or Pick Up Card', '012' => 'Invalid Trans', '013' => 'Amount Error', '014' => 'Card No. Error', '015' => 'No Such Issuer', '019' => 'Erro de comunicação com a Visa. O consumidor deve tentar novamente.', '021' => 'Nenhuma ação realizada', '041' => 'Hold-call or Pick Up Card', '043' => 'Hold-call or Pick Up Card', '051' => 'Decline. Insufficient funds.', '054' => 'Cartão expirado', '055' => 'Serv Not Allowed', '058' => 'Serv Not Allowed', '062' => 'Decline. Invalid service code, restricted.', '063' => 'Sec Violation', '065' => 'Decline. Activity limit exceeded.', '076' => 'Unsolic Reversal', '077' => 'No Action Taken. Reversal amount larger then original amount.', '078' => 'No Account', '079' => 'Already Reversed', '080' => 'Date Error', '082' => 'Incorrect CVV', '085' => 'Card OK. No reason to decline.', '091' => 'No Reply', '092' => 'Invalid Routing', '093' => 'Decline. Violation, cannot complete.', '094' => 'Duplicate Trans', '096' => 'System Error. System malfunction. A bug in Trident. Escalate issue to developers.', '0N7' => 'CVV2 Mismatch', '101' => 'Invalid Profile ID or Profile Key.', '102' => 'Incomplete Request.', '103' => 'Invoice Number Length Error.', '104' => 'Reference Number Length Error.', '105' => 'AVS Address Length Error.', '106' => 'AVS Zip Length Error.', '107' => 'Merchant Name Length Error.', '108' => 'Merchant City Length Error.', '109' => 'Merchant State Length Error.', '110' => 'Merchant Zip Length Error.', '111' => 'Merchant Category Code Length Error.', '112' => 'Merchant Phone Length Error.', '113' => 'Reference Number Must Be Numeric.', '114' => 'Missing Card Holder Account Data.', '115' => 'Invalid Card Number.', '116' => 'Credits Not Allowed.', '117' => 'Card Type Not Accepted.', '118' => 'Currency Type Not Accepted.', '201' => 'Invalid Transaction ID.', '202' => 'Invalid Transaction Amount.', '203' => 'Void Failed.', '204' => 'Transaction Already Settled.', '205' => 'Transaction Already Voided.', '206' => 'Transaction Already refunded.', '207' => 'Refund failed.', '208' => 'Failed to receive a response from auth host.', '209' => 'Invalid tax amount.', '210' => 'AVS result is declined by user.', '211' => 'CVV2 result is declined by user.', '212' => 'Refund amount must be between zero and the original amount.', '213' => 'Only sale transactions can be refunded.', '214' => 'Only one type of card data allowed per request.', '215' => 'Invalid Card ID.', '216' => 'Failed to load card data, retry request.', '217' => 'Failed to store card data, retry request.', '218' => 'Card ID parameter cannot be included in this type of transaction.', '300' => 'Failed to capture PayVision transaction.', '301' => 'Failed to void PayVision transaction.', '302' => 'Failed to refund PayVision transaction.', '303' => 'Card Verify not supported.', '304' => 'Failed to reverse PayVision authorization.', '305' => 'Internal Error.' );./kohana/modules/payment/i18n/ru_RU/0000755000175000017500000000000011263472445016752 5ustar tokkeetokkee./kohana/modules/payment/i18n/ru_RU/payment.php0000644000175000017500000000132011121331011021104 0ustar tokkeetokkee 'Поля, обязатеьные для заполения: %s', 'gateway_connection_error' => 'Ошибка при подключении к шлюзу оплаты. Если это повторится, пожалуйста, уведомите администрацию сайта.', 'invalid_certificate' => 'Файл сертификата недействителен: %s', 'no_dlib' => 'Ошибка при загрузке динамической библиотеки: %s', 'error' => 'Ошибка при обработке транзакции: %s', ); ./kohana/modules/payment/i18n/ru_RU/payment_Trustcommerce.php0000644000175000017500000000642311121331011024031 0ustar tokkeetokkee array ( 'avs' => 'Ошибка AVS; указанный адрес не совпадает с данными банка.', 'cvv' => 'Ошибка CVV; указанный номер не является корректным проверочным номером карты.', 'call' => 'Карта должна быть авторизована телефонным звонком. Вы можете позвонить по указанному номеру поддержки клиентов и попросить код авторизации.', 'expiredcard' => 'Срок действия карты истёк. Активизируйте карту в банке.', 'carderror' => 'Номер карты недействителен. Возможно, вы ошиблись при вводе номера, или карта заявлена украденной.', 'authexpired' => 'Повторной авторизация не удалась.', 'fraud' => 'CrediGuard оценивает эту транзакцию как попытку мошенничества.', 'blacklist' => 'CrediGuard обнаружил значения в чёрном списке.', 'velocity' => 'CrediGuard velocity control активирована.', 'dailylimit' => 'Достигнуто ограничение количества транзакций в день.', 'weeklylimit' => 'Достигнуто ограничение количества транзакций в неделю.', 'monthlylimit' => 'Достигнуто ограничение количества транзакций в месяц.', ), 'baddata' => array ( 'missingfields' => 'Недостаточно параметров для выполнения этой транзакции.', 'extrafields' => 'Были переданы параметры, запрещённые для этого типа транзакции.', 'badformat' => 'Параметр имеет некорректный формат, например буквы в численном параметре.', 'badlength' => 'Длина параметра не соответствует разрешённым пределам.', 'merchantcantaccept' => 'Посредник не принимает данные, переданные этим параметром.', 'mismatch' => 'Данные одного из параметров не соответствуют данным других параметров.', ), 'error' => array ( 'cantconnect' => 'Не удалось подключиться к шлюзу TrustCommerce. Проверьте подключение к сети.', 'dnsfailure' => 'TCLink не удалось преобразовать доменное имя в IP-адрес. Убедитесь, что служба DNS доступна на этом компьютере.', 'linkfailure' => 'Соединение было установлено, но оборвалось до завершения транзакции.', 'failtoprocess' => 'Серверы банка недоступны. Попробуйте повторить попытку позже, или использовать карточку другого банка.', ) ); ./kohana/modules/payment/i18n/ru_RU/payment_Trident.php0000644000175000017500000001060411121331011022602 0ustar tokkeetokkee 'Транзакция успешно подтверждена.', '001' => 'Звонок', '002' => 'Звонок', '003' => 'Ошибка идентификатора посредника', '004' => 'Hold-call or Pick Up Card', '005' => 'Decline. Do not honor.', '006' => 'General Transaction Error.', '007' => 'Hold-call or Pick Up Card', '012' => 'Некорректная транзакция', '013' => 'Ошибка суммы', '014' => 'Номер карты некорректен', '015' => 'Издатель не существует', '019' => 'Не удалось связаться с Visa. Повторите попытку.', '021' => 'Действия не предприняты', '041' => 'Hold-call or Pick Up Card', '043' => 'Hold-call or Pick Up Card', '051' => 'Отказано. Недостаточно средств.', '054' => 'Карта просрочена', '055' => 'Serv Not Allowed', '058' => 'Serv Not Allowed', '062' => 'Decline. Invalid service code, restricted.', '063' => 'Sec Violation', '065' => 'Отказ. Превышен предел активности.', '076' => 'Unsolic Reversal', '077' => 'No Action Taken. Reversal amount larger then original amount.', '078' => 'Нет счёта', '079' => 'Already Reversed', '080' => 'Ошибка даты', '082' => 'Incorrect CVV', '085' => 'Карта в порядке. Нет повода для отказа.', '091' => 'Нет ответа', '092' => 'Invalid Routing', '093' => 'Отказ. Нарушение, не могу продолжить.', '094' => 'Duplicate Trans', '096' => 'Системная ошибка в ПО Trident. Уведомите разработчиков.', '0N7' => 'CVV2 Mismatch', '101' => 'Invalid Profile ID or Profile Key.', '102' => 'Неполный запрос.', '103' => 'Invoice Number Length Error.', '104' => 'Reference Number Length Error.', '105' => 'AVS Address Length Error.', '106' => 'AVS Zip Length Error.', '107' => 'Некорректная длина имени посредника.', '108' => 'Некорректная длина города посредника.', '109' => 'Некорректная длина штата посредника.', '110' => 'Некорректная длина почтового индекса посредника.', '111' => 'Некорректная длина кода категории посредника.', '112' => 'Некорректная длина номера телефона посредника.', '113' => 'Reference Number Must Be Numeric.', '114' => 'Missing Card Holder Account Data.', '115' => 'Некорректный номер карты.', '116' => 'Кредиты не разрешены.', '117' => 'Тип карты не принят.', '118' => 'Тип валюты не принят.', '201' => 'Некорректный идентификатор транзакции.', '202' => 'Некорректная сумма транзакции.', '203' => 'Аннулирование не удалось.', '204' => 'Transaction Already Settled.', '205' => 'Транзакция уже аннулирована.', '206' => 'Transaction Already refunded.', '207' => 'Refund failed.', '208' => 'Не получен ответ от узла аутентификации.', '209' => 'Invalid tax amount.', '210' => 'AVS result is declined by user.', '211' => 'CVV2 result is declined by user.', '212' => 'Refund amount must be between zero and the original amount.', '213' => 'Only sale transactions can be refunded.', '214' => 'Only one type of card data allowed per request.', '215' => 'Некорректный идентификатор карты.', '216' => 'Не удалось загрузить данные о карте, повторите попытку.', '217' => 'Не удалось сохранить данные о карте, повторите попытку.', '218' => 'Card ID parameter cannot be included in this type of transaction.', '300' => 'Failed to capture PayVision transaction.', '301' => 'Failed to void PayVision transaction.', '302' => 'Failed to refund PayVision transaction.', '303' => 'Подтверждение карты не поддерживается.', '304' => 'Failed to reverse PayVision authorization.', '305' => 'Внутренняя ошибка.' ); ./kohana/modules/payment/i18n/es_ES/0000755000175000017500000000000011263472445016714 5ustar tokkeetokkee./kohana/modules/payment/i18n/es_ES/payment.php0000644000175000017500000000144011121331011021051 0ustar tokkeetokkee 'No se encuentra el driver, %s, requerido por la librería Payment.', 'driver_implements' => 'El driver solicitado por la libreria Payments, %s, no implementa la interface Payment_Driver.', 'required' => 'Uno o más campos requeridos no han sido rellenados: %s', 'gateway_connection_error' => 'Ocurrió un error al conectar con la pasarela de pagos. Por favor, contacte con el responsable del sitio web si el problema persiste.', 'invalid_certificate' => 'El certificado es invalido: %s', 'no_dlib' => 'No es posible cargar la librería dinamica: %s', 'error' => 'Ha ocurrido un error procesando la transacción: %s', );./kohana/modules/payment/i18n/es_ES/payment_Trustcommerce.php0000644000175000017500000000574211121331011023776 0ustar tokkeetokkee array ( 'avs' => 'Fallo AVS; la dirección introducida no coincide con la dirección de facturación que aparece en el fichero del banco.', 'cvv' => 'Fallo CVV; el número provisto no es el número de verificación correcto para la tarjeta.', 'call' => 'La tarjeta tiene que ser autorizada manualmente mediante telefono. Puedes elegir llamar al servicio de atencion al cliente que aparece en la tarjeta y solicitar un número de autorizacón &8220;offline&8221;, que puede ser introducido en el campo &8220;offlineauthcode&8221;.', 'expiredcard' => 'La tarjeta ha caducado. Solicite una apliación de la fecha de caducidad a la entidad emisora.', 'carderror' => 'Numero de tarjeta incorrecto, lo que podria ser un error de escritura, o en algunos casos una tarjeta denunciada como robada.', 'authexpired' => 'Intentando volver a autorizar una autorización previa que ha expirado (mas de 14 dias de antiguedad).', 'fraud' => 'La puntuación de fraude de CrediGuard esta por debajo del limite solicitad.', 'blacklist' => 'Se han superado los valores para la lista negra de CrediGuard.', 'velocity' => 'Se ha superado el control de velocidad de CrediGuard.', 'dailylimit' => 'Se ha alcanzado el limite diario de transacciones, ya sea por numero o cantidad.', 'weeklylimit' => 'Se ha alcanzado el limite semanal de transacciones, ya sea por numero o cantidad.', 'monthlylimit' => 'Se ha alcanzado el limite mensual de transacciones, ya sea por numero o cantidad.', ), 'baddata' => array ( 'missingfields' => 'No ha enviado uno o más parametros requeridos para este tipo de transacción.', 'extrafields' => 'Se han enviado parametros no permitidos para este tipo de transacción.', 'badformat' => 'Uno de los campos se ha rellenado de manera incorrecta, por ejemplo un caractér no númerico en un campo númerico.', 'badlength' => 'Uno de los campos es más largo o más corto de lo que permite el servidor.', 'merchantcantaccept' => 'El comerciante no acepta los datos introducidos en este campo.', 'mismatch' => 'Los datos de uno de los campos no coincide con el del otro.', ), 'error' => array ( 'cantconnect' => 'Imposible conectar con la pasarela TrustCommerce. Comprueba tu conexión a Internet y asegura que este en funcionamiento.', 'dnsfailure' => 'El programa TCLink no ha sido capaz de resolver los nombres DNS. Asegurate de poder resolver en la maquina.', 'linkfailure' => 'La conexión se ha establecido , pero se ha interrumpido antes de que la transacción finalizase.', 'failtoprocess' => 'Los servidores del Banco estan fuera de línea por lo que resulta imposible autorizar transacciones. Vuelva a intentarlo dentro de unos minutos, o intentelo con una tarjeta de otra entidad bancaria.', ), );./kohana/modules/payment/i18n/es_ES/payment_Trident.php0000644000175000017500000000755511121331011022557 0ustar tokkeetokkee 'Sin errores - Transaccion Aprobada.', '001' => 'Llamar', '002' => 'Llamar', '003' => 'Error en la Id de Marchante', '004' => 'Hold-call o Tarjeta Pick Up', '005' => 'Denegado. Do not honor.', '006' => 'Error General en la Transaccion.', '007' => 'Hold-call o Tarjeta Pick Up', '012' => 'Transaccion no valida', '013' => 'Error en la cantidad', '014' => 'Error en el Numero de la Tarjeta', '015' => 'No Such Issuer', '019' => 'Error de comunicacion con Visa. El usuario debe repetir.', '021' => 'No se realizara ninguna accion', '041' => 'Hold-call o Tarjeta Pick Up', '043' => 'Hold-call o Tarjeta Pick Up', '051' => 'Denegado. Fondos insuficientes.', '054' => 'Tarjeta caducada', '055' => 'Serv No Permitido', '058' => 'Serv No Permitido', '062' => 'Denegado. Codigo de servicio invalido, restringido.', '063' => 'Violación de seguridad', '065' => 'Denegado. Sobrepasado limite de actividad.', '076' => 'Unsolic Reversal', '077' => 'No se realizara ninguna accion. La cantidad anulada supera la cantidad original.', '078' => 'Cuenta no existente', '079' => 'Operacion ya anulada', '080' => 'Error en la fecha', '082' => 'Incorrect CVV', '085' => 'Tarjeta Correcta. No existe razón para denegar.', '091' => 'Sin respuesta', '092' => 'Recorrido Incorrecto', '093' => 'Denegado. Violación, no se puede completar.', '094' => 'Transaccion Duplicada', '096' => 'Error del sistema. Funcionamiento incorrecto del sistema. A fallo en Trident. Trasapase el problema a los desarrolladores.', '0N7' => 'CVV2 Mismatch', '101' => 'ID o Key del perfil incorrecto.', '102' => 'Petición Incompleta.', '103' => 'Error en el tamaño del número de factura.', '104' => 'Error en el tamaño del número de referencia.', '105' => 'Error en el tamaño de la direccion de AVS.', '106' => 'Error en el tamaño del zip de AVS.', '107' => 'Error en el tamaño del nombre del comerciante.', '108' => 'Error en el tamaño de la ciudad del comerciante.', '109' => 'Error en el tamaño de el Estado del comerciante.', '110' => 'Error en el tamaño del zip del comerciante.', '111' => 'Error en el tamaño del codigo de la categoría del comerciante.', '112' => 'Error en el tamaño del telefono del comerciante.', '113' => 'El numero de referencia debe de ser numerico.', '114' => 'Cuenta del propietario de la tarjeta no encontrada.', '115' => 'Numero de tarjeta no valido.', '116' => 'No se aceptan creditos.', '117' => 'Tipo de tarjeta no aceptado.', '118' => 'Tipo de moneda no aceptado.', '201' => 'ID de la transacción no valida.', '202' => 'Cantidad de la transacción no valida.', '203' => 'Fallo en la anulacion.', '204' => 'Transacción en proceso.', '205' => 'Transacción anulada.', '206' => 'Transactción devuelta.', '207' => 'Fallo en la devolución.', '208' => 'Fallo al recibir una respuesta del servidor de autorización.', '209' => 'Cantidad de inpuestos incorrecta.', '210' => 'El resultado de AVS es rechazado por usuario.', '211' => 'El resultado de CVV2 es rechazado por usuario.', '212' => 'La cantidad de la devolución tiene que estar entre cero y la cantidad original.', '213' => 'Solo las transacciones de ventas pueden ser devueltas.', '214' => 'Solo se admite un tipo de tarjeta por solicitud.', '215' => 'ID de la tarjeta invalida.', '216' => 'Fallo al cargar los datos de la tarjeta, reintenta la solicitud.', '217' => 'Fallo al gurdar los datos de la tarjeta, reintenta la solicitud.', '218' => 'Este tipo de transacciones no pueden incluir la ID de la tarjeta.', '300' => 'Fallo al capturar la transacción PayVision.', '301' => 'Fallo al anular la transacción PayVision.', '302' => 'Fallo al devolver la transacción PayVision.', '303' => 'Verificacion de tarjeta no soportadad.', '304' => 'Fallo al invertir la autorización de PayVision.', '305' => 'Error Interno.', );./kohana/modules/payment/i18n/es_AR/0000755000175000017500000000000011263472445016707 5ustar tokkeetokkee./kohana/modules/payment/i18n/pl_PL/0000755000175000017500000000000011263472445016724 5ustar tokkeetokkee./kohana/modules/payment/i18n/pl_PL/payment.php0000644000175000017500000000111311121331011021056 0ustar tokkeetokkee 'Nie dostarczono wymaganych pól takich jak: %s.', 'gateway_connection_error' => 'Wystąpił błąd w czasie łączenia z obsługą płatności. Proszę skontaktować się z administratorem jeśli nadal występuje problem.', 'invalid_certificate' => 'Certyfikat jest nieprawidłowy.', 'no_dlib' => 'Nie można załadować dynamicznej biblioteki: %s', 'error' => 'Wystąpił błąd podczas przetwarzania operacji płatności: %s', );./kohana/modules/payment/i18n/en_GB/0000755000175000017500000000000011263472445016670 5ustar tokkeetokkee./kohana/modules/payment/i18n/en_GB/payment.php0000755000175000017500000000114111121331011021026 0ustar tokkeetokkee 'The requested Payment driver, %s, was not found.', 'required' => 'Some required fields were not supplied: %s', 'gateway_connection_error' => 'An error occured connecting to the payment gateway. Please contact the webmaster if this problem persists.', 'invalid_certificate' => 'The certificate file is invalid: %s', 'no_dlib' => 'Could not load the dynamic library: %s', 'error' => 'There was an error processing the transaction: %s', );./kohana/modules/payment/i18n/en_GB/payment_Trustcommerce.php0000755000175000017500000000451511121331011023752 0ustar tokkeetokkee array ( 'avs' => 'AVS failed; the address entered does not match the billing address on file at the bank.', 'cvv' => 'CVV failed; the number provided is not the correct verification number for the card.', 'call' => 'The card must be authorised manually over the phone. You may choose to call the customer service number listed on the card and ask for an offline authcode, which can be passed in the offlineauthcode field.', 'expiredcard' => 'The card has expired. Get updated expiration date from cardholder.', 'carderror' => 'Card number is invalid, which could be a typo, or sometimes a card reported stolen.', 'authexpired' => 'Attempt to postauth an expired (more than 14 days old) preauth.', 'fraud' => 'CrediGuard fraud score was below requested threshold.', 'blacklist' => 'CrediGuard blacklist value was triggered.', 'velocity' => 'CrediGuard velocity control was triggered.', 'dailylimit' => 'Daily limit in transaction count or amount as been reached.', 'weeklylimit' => 'Weekly limit in transaction count or amount as been reached.', 'monthlylimit' => 'Monthly limit in transaction count or amount as been reached.', ), 'baddata' => array ( 'missingfields' => 'One or more parameters required for this transaction type were not sent.', 'extrafields' => 'Parameters not allowed for this transaction type were sent.', 'badformat' => 'A field was improperly formatted, such as non-digit characters in a number field.', 'badlength' => 'A field was longer or shorter than the server allows.', 'merchantcantaccept' => 'The merchant can\'t accept data passed in this field.', 'mismatch' => 'Data in one of the offending fields did not cross-check with the other offending field.', ), 'error' => array ( 'cantconnect' => 'Couldn\'t connect to the TrustCommerce gateway. Check your Internet connection to make sure it is up.', 'dnsfailure' => 'The TCLink software was unable to resolve DNS hostnames. Make sure you have name resolving ability on the machine.', 'linkfailure' => 'The connection was established, but was severed before the transaction could complete.', 'failtoprocess' => 'The bank servers are offline and unable to authorise transactions. Try again in a few minutes, or try a card from a different issuing bank.', ) );./kohana/modules/payment/i18n/en_GB/payment_Trident.php0000755000175000017500000000627111121331011022530 0ustar tokkeetokkee 'No errors - Transaction Approved.', '001' => 'Call', '002' => 'Call', '003' => 'Merch Id Error', '004' => 'Hold-call or Pick Up Card', '005' => 'Decline. Do not honor.', '006' => 'General Transaction Error.', '007' => 'Hold-call or Pick Up Card', '012' => 'Invalid Trans', '013' => 'Amount Error', '014' => 'Card No. Error', '015' => 'No Such Issuer', '019' => 'Communication error with Visa. Customer should retry.', '021' => 'No Action Taken', '041' => 'Hold-call or Pick Up Card', '043' => 'Hold-call or Pick Up Card', '051' => 'Decline. Insufficient funds.', '054' => 'Expired Card', '055' => 'Serv Not Allowed', '058' => 'Serv Not Allowed', '062' => 'Decline. Invalid service code, restricted.', '063' => 'Sec Violation', '065' => 'Decline. Activity limit exceeded.', '076' => 'Unsolic Reversal', '077' => 'No Action Taken. Reversal amount larger then original amount.', '078' => 'No Account', '079' => 'Already Reversed', '080' => 'Date Error', '082' => 'Incorrect CVV', '085' => 'Card OK. No reason to decline.', '091' => 'No Reply', '092' => 'Invalid Routing', '093' => 'Decline. Violation, cannot complete.', '094' => 'Duplicate Trans', '096' => 'System Error. System malfunction. A bug in Trident. Escalate issue to developers.', '0N7' => 'CVV2 Mismatch', '101' => 'Invalid Profile ID or Profile Key.', '102' => 'Incomplete Request.', '103' => 'Invoice Number Length Error.', '104' => 'Reference Number Length Error.', '105' => 'AVS Address Length Error.', '106' => 'AVS Zip Length Error.', '107' => 'Merchant Name Length Error.', '108' => 'Merchant City Length Error.', '109' => 'Merchant State Length Error.', '110' => 'Merchant Zip Length Error.', '111' => 'Merchant Category Code Length Error.', '112' => 'Merchant Phone Length Error.', '113' => 'Reference Number Must Be Numeric.', '114' => 'Missing Card Holder Account Data.', '115' => 'Invalid Card Number.', '116' => 'Credits Not Allowed.', '117' => 'Card Type Not Accepted.', '118' => 'Currency Type Not Accepted.', '201' => 'Invalid Transaction ID.', '202' => 'Invalid Transaction Amount.', '203' => 'Void Failed.', '204' => 'Transaction Already Settled.', '205' => 'Transaction Already Voided.', '206' => 'Transaction Already refunded.', '207' => 'Refund failed.', '208' => 'Failed to receive a response from auth host.', '209' => 'Invalid tax amount.', '210' => 'AVS result is declined by user.', '211' => 'CVV2 result is declined by user.', '212' => 'Refund amount must be between zero and the original amount.', '213' => 'Only sale transactions can be refunded.', '214' => 'Only one type of card data allowed per request.', '215' => 'Invalid Card ID.', '216' => 'Failed to load card data, retry request.', '217' => 'Failed to store card data, retry request.', '218' => 'Card ID parameter cannot be included in this type of transaction.', '300' => 'Failed to capture PayVision transaction.', '301' => 'Failed to void PayVision transaction.', '302' => 'Failed to refund PayVision transaction.', '303' => 'Card Verify not supported.', '304' => 'Failed to reverse PayVision authorisation.', '305' => 'Internal Error.' );./kohana/modules/payment/config/0000755000175000017500000000000011263472445016404 5ustar tokkeetokkee./kohana/modules/payment/config/payment.php0000644000175000017500000001677711121511343020574 0ustar tokkeetokkee 'Authorize', 'test_mode' => TRUE, 'curl_config' => array(CURLOPT_HEADER => FALSE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_SSL_VERIFYPEER => FALSE) ); /** * Authorize.net Options: * auth_net_login_id - the transaction login ID; provided by gateway provider * auth_net_tran_key - the transaction key; provided by gateway provider */ $config['Authorize'] = array ( 'auth_net_login_id' => '', 'auth_net_tran_key' => '' ); /** * YourPay.net Options: * merchant_id - the merchant ID number * certificate - the location on your server of the certificate file. */ $config['Yourpay'] = array ( 'merchant_id' => '', 'certificate' => './path/to/certificate.pem' ); /** * TrustCommerce Options: * custid - the customer ID assigned to you by TrustCommerce * password - the password assigned to you by TrustCommerce * media - "cc" for credit card or "ach" for ACH. * tclink_library - the location of the tclink library (relative to your index file) you need to compile to get this driver to work. */ $config['Trustcommerce'] = array ( 'custid' => '', 'password' => '', 'media' => 'cc', 'tclink_library' => './path/to/library.so' ); /** * TridentGateway Options: * profile_id - the profile ID assigned to you by Merchant e-Services * profile_key - the profile password assigned to you by Merchant e-Services * transaction_type - D=Sale, C=Credit, P=Pre-Auth, O=Offline, V-Void, S=Settle Pre-Auth, U=Refund, T= Store card data., X=Delete Card Store Data */ $config['Trident'] = array ( 'profile_id' => '', 'profile_key' => '', 'transaction_type' => 'D' ); /** * PayPal Options: * API_UserName - the username to use * API_Password - the password to use * API_Signature - the api signature to use * ReturnUrl - the URL to send the user to after they login with paypal * CANCELURL - the URL to send the user to if they cancel the paypal transaction * CURRENCYCODE - the Currency Code to to the transactions in (What do you want to get paid in?) */ $config['Paypal'] = array ( 'USER' => '-your-paypal-api-username', 'PWD' => '-your-paypal-api-password', 'SIGNATURE' => '-your-paypal-api-security-signiature', 'ENDPOINT' => 'https://api-3t.paypal.com/nvp', 'RETURNURL' => 'http://yoursite.com', 'CANCELURL' => 'http://yoursite.com/canceled', // -- sandbox authorization details are generic 'SANDBOX_USER' => 'sdk-three_api1.sdk.com', 'SANDBOX_PWD' => 'QFZCWN5HZM8VBG7Q', 'SANDBOX_SIGNATURE' => 'A.d9eRKfd1yVkRrtmMfCFLTqa6M9AyodL0SJkhYztxUi8W9pCXF6.4NI', 'SANDBOX_ENDPOINT' => 'https://api-3t.sandbox.paypal.com/nvp', 'VERSION' => '3.2', 'CURRENCYCODE' => 'USD', ); /** * PayPalpro Options: * USER - API user name to use * PWD - API password to use * SIGNATURE - API signature to use * * ENDPOINT - API url used by live transaction * * SANDBOX_USER - User name used in test mode * SANDBOX_PWD - Pass word used in test mode * SANDBOX_SIGNATURE - Security signiature used in test mode * SANDBOX_ENDPOINT - API url used for test mode transaction * * VERSION - API version to use * CURRENCYCODE - can only currently be USD * */ $config['Paypalpro'] = array ( 'USER' => '-your-paypal-api-username', 'PWD' => '-your-paypal-api-password', 'SIGNATURE' => '-your-paypal-api-security-signiature', 'ENDPOINT' => 'https://api-3t.paypal.com/nvp', // -- sandbox authorization details are generic 'SANDBOX_USER' => 'sdk-three_api1.sdk.com', 'SANDBOX_PWD' => 'QFZCWN5HZM8VBG7Q', 'SANDBOX_SIGNATURE' => 'A.d9eRKfd1yVkRrtmMfCFLTqa6M9AyodL0SJkhYztxUi8W9pCXF6.4NI', 'SANDBOX_ENDPOINT' => 'https://api-3t.sandbox.paypal.com/nvp', 'VERSION' => '3.2', 'CURRENCYCODE' => 'USD', 'curl_config' => array ( CURLOPT_HEADER => FALSE, CURLOPT_SSL_VERIFYPEER => FALSE, CURLOPT_SSL_VERIFYHOST => FALSE, CURLOPT_VERBOSE => TRUE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_POST => TRUE ) ); /** * GoogleCheckoutGateway Options: * google_API_key - the profile ID assigned to you by Merchant e-Services * google_merchant_id - the profile password assigned to you by Merchant e-Services * google_sandbox_API_key - D=Sale, C=Credit, P=Pre-Auth, O=Offline, V-Void, S=Settle Pre-Auth, U=Refund, T= Store card data., X=Delete Card Store Data */ $config['GoogleCheckout'] = array ( 'google_API_key' => '-your-google-checkout-api-key', 'google_merchant_id' => '-your-google-checkout-merchant-id', 'google_sandbox_API_key' => '-your-google-checkout-sandbox-api-key', 'google_sandbox_merchant_id' => '-your-google-checkout-sandbox-merchant-id', 'currency_code' => 'USD', 'action' => '', 'xml_body' => '', 'test_mode' => false, 'curl_config' => array ( CURLOPT_HEADER => FALSE, CURLOPT_SSL_VERIFYPEER => FALSE, CURLOPT_SSL_VERIFYHOST => FALSE, CURLOPT_VERBOSE => TRUE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_POST => TRUE ) ); /** * Moneybookers Options: * Full api documentation available from https://www.moneybookers.com/app/help.pl?s=m_manual */ $config['MoneyBookers'] = array ( 'payment_url' => 'https://www.moneybookers.com/app/', 'payment_script' => 'payment.pl', 'query_script' => 'query.pl', 'ondemand_script' => 'ondemand_request.pl', 'refund_script' => 'refund.pl', 'test_payment_script' => 'test_payment.pl', 'pay_to_email' => 'your@email.address', 'logo_url' => '', 'transaction_id' => '', 'pay_to_email' => '', 'password' => '', 'test_pay_to_email' => 'your@test.email.address', 'test_password' => '', 'return_url' => '', 'status_url' => '', 'cancel_url' => '', 'recipient_description' => '', 'hide_login' => '1', 'language' => 'EN', 'amount' => '', 'currency' => 'USD', 'ondemand_max_amount' => '600', 'ondemand_max_currency' => 'USD', 'ondemand_note' => 'For faster transactions for future payments, accept on demand payment as an option.', 'test_mode' => false, 'payment_methods' => '', 'payment_method_types' => array ( 'UK' => array('VSD' => 'Visa Delta/Debit', 'MAE' => 'Maestro', 'SLO' => 'Solo'), 'US' => array('WLT' => 'Bank'), 'DE' => array('GIR' => 'Giropay', 'DID' => 'Direct Debit', 'SFT' => 'Sofortueberweisung', 'WLT' => 'Bank'), 'AU' => array('PLI' => 'POLi', 'WLT' => 'Bank'), 'NZ' => array('WLT' => 'Bank'), 'ZA' => array('WLT' => 'Bank'), 'IE' => array('LSR' => 'Laser', 'WLT' => 'Bank'), 'NL' => array('IDL' => 'iDeal', 'WLT' => 'Bank'), 'AT' => array('NPY' => 'Netpay', 'WLT' => 'Bank'), 'SE' => array('EBT' => 'Norda Solo', 'WLT' => 'Bank'), 'SG' => array('ENT' => 'eNets', 'WLT' => 'Bank'), ), 'curl_config' => array ( CURLOPT_HEADER => FALSE, CURLOPT_SSL_VERIFYPEER => FALSE, CURLOPT_SSL_VERIFYHOST => FALSE, CURLOPT_VERBOSE => TRUE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_POST => TRUE ) ); ./kohana/modules/kodoc/0000755000175000017500000000000011263472444014560 5ustar tokkeetokkee./kohana/modules/kodoc/views/0000755000175000017500000000000011263472444015715 5ustar tokkeetokkee./kohana/modules/kodoc/views/kodoc/0000755000175000017500000000000011263472444017014 5ustar tokkeetokkee./kohana/modules/kodoc/views/kodoc/method.php0000644000175000017500000000463011121324570020775 0ustar tokkeetokkee

    ' ?>

    Parameters:

    $param): if ( ! empty($comment['param'][$i])): // Extract the type and information list ($type, $info) = explode(' ', $comment['param'][$i], 2); $type = Kodoc::humanize_type($type).' '; $info = trim($info); else: $type = ''; $info = ''; endif; ?>
    ('.Kodoc::humanize_value($param['default']).') '; endif; // Parameter information echo $info; ?>
    $vals): switch ($tag): case 'throws': case 'return': foreach ($vals as $i => $val): if (strpos($val, ' ') !== FALSE): // Extract the type from the val list ($type, $val) = explode(' ', $val, 2); // Add the type to the val $val = Kodoc::humanize_type($type).' '.$val; else: $val = ''.$val.''; endif; // Put the val back into the array $vals[$i] = $val; endforeach; break; endswitch; ?>

    :

    • \n
    • ", $vals) ?>

    ./kohana/modules/kodoc/views/kodoc/template.php0000644000175000017500000000445711121324570021337 0ustar tokkeetokkee <?php echo empty($title) ? '' : $title.' – ' ?> Kohana API Documentation
    ./kohana/modules/kodoc/views/kodoc/file_config.php0000644000175000017500000000074511121324570021764 0ustar tokkeetokkee

    Default value:

    ./kohana/modules/kodoc/views/kodoc/class.php0000644000175000017500000000163411121324570020623 0ustar tokkeetokkee

    Class:

    ./kohana/modules/kodoc/views/kodoc/menu.php0000644000175000017500000000136011121324570020456 0ustar tokkeetokkee ./kohana/modules/kodoc/views/kodoc/documentation.php0000644000175000017500000000120611121324570022362 0ustar tokkeetokkeekodoc) OR count($docs = $this->kodoc->get()) < 1): ?>

    Kodoc not loaded

    ./kohana/modules/kodoc/views/kodoc/media/0000755000175000017500000000000011263472444020073 5ustar tokkeetokkee./kohana/modules/kodoc/views/kodoc/media/js/0000755000175000017500000000000011263472444020507 5ustar tokkeetokkee./kohana/modules/kodoc/views/kodoc/media/js/effects.js0000644000175000017500000000176010723733063022465 0ustar tokkeetokkee// $Id: effects.js 486 2007-09-04 01:49:02Z Shadowhand $ $(document).ready(function(){ // Opacity animations in an element with an opacity of 1.0 cause Firefox bugs $('#menu').css('opacity', 0.9999); // Apply menu sliding effect $('#menu li.first').click(function(){ // Clicks to the same menu will do nothing if ($(this).is('.active') == false){ // Hide the current submenu $('#menu li.active').removeClass('active') .find('ul').not('.expanded') .animate({height: 'hide', opacity: 'hide'}, 200, 'easeOutQuad'); // Show the clicked submenu $(this).addClass('active') .find('ul').not('.expanded') .slideDown({height: 'show', opacity: 'show'}, 200, 'easeInQuad'); } }) // Find and hide the sub menus that are not in the active menu .not('.active').find('ul').hide(); $('#menu li ul.expanded').each(function(i) { var sub = $(this).hide(); var top = sub.parents('li:first'); top.hover(function() { sub.show(); }, function() { sub.hide(); }); }); });./kohana/modules/kodoc/views/kodoc/media/js/jquery.js0000644000175000017500000013254510723733063022373 0ustar tokkeetokkee/* * jQuery 1.2.1 - New Wave Javascript * * Copyright (c) 2007 John Resig (jquery.com) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $ * $Rev: 3353 $ */ (function(){if(typeof jQuery!="undefined")var _jQuery=jQuery;var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);};if(typeof $!="undefined")var _$=$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(typeof selector=="string"){var m=quickExpr.exec(selector);if(m&&(m[1]||!context)){if(m[1])selector=jQuery.clean([m[1]],context);else{var tmp=document.getElementById(m[3]);if(tmp)if(tmp.id!=m[3])return jQuery().find(selector);else{this[0]=tmp;this.length=1;return this;}else selector=[];}}else return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.1",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret;},setArray:function(a){this.length=0;Array.prototype.push.apply(this,a);return this;},each:function(fn,args){return jQuery.each(this,fn,args);},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i;});return pos;},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value;}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));});},css:function(key,value){return this.attr(key,value,"curCSS");},text:function(e){if(typeof e!="object"&&e!=null)return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return t;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,1,function(a){this.appendChild(a);});},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);});},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);});},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);});return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]:this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);})||jQuery.multiFilter(t,this));},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;}));},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;},hasClass:function(expr){return this.is("."+expr);},val:function(val){if(val==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,val)>=0);else if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);});if(!tmp.length)this.selectedIndex=-1;}else this.value=val;});},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);},replaceWith:function(val){return this.after(val).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,dir,fn){var clone=this.length>1,a;return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);if(dir<0)a.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;if(!evalScript(0,elem))fn.call(obj,elem);});});}};function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");if(script){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}else if(elem.nodeType==1)jQuery("script",elem).each(evalScript);return script;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};}if(al==1){target=this;a=0;}var prop;for(;a-1;}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i];}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i];},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0;});jQuery.swap(e,old,function(){if(jQuery(e).is(':visible')){oHeight=e.offsetHeight;oWidth=e.offsetWidth;}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position")||"static";if(parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e);}});return p=="height"?oHeight:oWidth;}return jQuery.curCSS(e,p);},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];function color(a){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(a,null);return!ret||ret.getPropertyValue("color")=="";}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(prop.match(/float/i))prop=styleFloat;if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i))prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur&&!color(elem))ret=cur.getPropertyValue(prop);else{for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(a=0;a]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+">";});var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];var wrap=!s.indexOf("",""]||!s.indexOf("",""]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!s.indexOf("",""]||(!s.indexOf("",""]||!s.indexOf("",""]||jQuery.browser.msie&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+arg+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){if(!s.indexOf(""&&s.indexOf("=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n]);if(/^\s/.test(arg))div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);}arg=jQuery.makeArray(div.childNodes);}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select")))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options)r.push(arg);else r=jQuery.merge(r,arg);});return r;},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(t){return(t||"").replace(/^\s+|\s+$/g,"");},makeArray:function(a){var r=[];if(typeof a!="array")for(var i=0,al=a.length;i\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"im[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","first-child":"a.parentNode.getElementsByTagName('*')[0]==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",parent:"a.firstChild",empty:"!a.firstChild",contains:"(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",visible:'"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"'text'==a.type",radio:"'radio'==a.type",checkbox:"'checkbox'==a.type",file:"'file'==a.type",password:"'password'==a.type",submit:"'submit'==a.type",image:"'image'==a.type",reset:"'reset'==a.type",button:'"button"==a.type||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)",has:"jQuery.find(m[3],a).length",header:"/h\\d/i.test(a.nodeName)",animated:"jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&!context.nodeType)context=null;context=context||document;var ret=[context],done=[],last;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){var nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName.toUpperCase()))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var nodeName=m[2],merge={};m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=jQuery.filter(m[3],r,true).r;else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(\d*)n\+?(\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"n+"+m[3]||m[3]),first=(test[1]||1)-0,last=test[2]-0;for(var i=0,rl=r.length;i<\/script>");var script=document.getElementById("__ie_init");if(script)script.onreadystatechange=function(){if(this.readyState!="complete")return;jQuery.ready();};script=null;}else if(jQuery.browser.safari)jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);jQuery.safariTimer=null;jQuery.ready();}},10);jQuery.event.add(window,"load",jQuery.ready);}jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url))return this.bind("load",url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);setTimeout(function(){self.each(callback,[res.responseText,status,res]);},13);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null},lastModified:{},ajax:function(s){var jsonp,jsre=/=(\?|%3F)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=s.data.replace(jsre,"="+jsonp);s.url=s.url.replace(jsre,"="+jsonp);s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get")s.url+=(s.url.match(/\?/)?"&":"?")+"_="+(new Date()).getTime();if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if(!s.url.indexOf("http")&&s.dataType=="script"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(!jsonp&&(s.success||s.complete)){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async);if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();return xml;function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock?this.oldblock:"";if(jQuery.css(this,"display")=="none")this.style.display="block";}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");if(this.oldblock=="none")this.oldblock="block";this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var opt=jQuery.speed(speed,easing,callback);return this[opt.queue===false?"each":"queue"](function(){opt=jQuery.extend({},opt);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(){var timers=jQuery.timers;return this.each(function(){for(var i=0;i-10000?r:parseFloat(jQuery.css(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(){return self.step();}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timers.length==1){var timer=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var absolute=jQuery.css(elem,"position")=="absolute",parent=elem.parentNode,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522;if(elem.getBoundingClientRect){box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));if(msie){var border=jQuery("html").css("borderWidth");border=(border=="medium"||jQuery.boxModel&&parseInt(version)>=7)&&2||border;add(-border,-border);}}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&/^t[d|h]$/i.test(parent.tagName)||!safari2)border(offsetParent);if(safari2&&!absolute&&jQuery.css(offsetParent,"position")=="absolute")absolute=true;offsetParent=offsetParent.offsetParent;}while(parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table-row.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if(safari2&&absolute)add(-doc.body.offsetLeft,-doc.body.offsetTop);}results={top:top,left:left};}return results;function border(elem){add(jQuery.css(elem,"borderLeftWidth"),jQuery.css(elem,"borderTopWidth"));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}};})();./kohana/modules/kodoc/views/kodoc/media/js/plugins.js0000644000175000017500000000747610723733063022541 0ustar tokkeetokkee/* * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ * * Uses the built In easIng capabilities added In jQuery 1.1 * to offer multiple easIng options * * Copyright (c) 2007 George Smith * Licensed under the MIT License: * http://www.opensource.org/licenses/mit-license.php */ jQuery.easing['jswing']=jQuery.easing['swing'];jQuery.extend(jQuery.easing,{def:'easeOutQuad',swing:function(x,t,b,c,d){return jQuery.easing[jQuery.easing.def](x,t,b,c,d);},easeInQuad:function(x,t,b,c,d){return c*(t/=d)*t+b;},easeOutQuad:function(x,t,b,c,d){return-c*(t/=d)*(t-2)+b;},easeInOutQuad:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b;},easeInCubic:function(x,t,b,c,d){return c*(t/=d)*t*t+b;},easeOutCubic:function(x,t,b,c,d){return c*((t=t/d-1)*t*t+1)+b;},easeInOutCubic:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t+b;return c/2*((t-=2)*t*t+2)+b;},easeInQuart:function(x,t,b,c,d){return c*(t/=d)*t*t*t+b;},easeOutQuart:function(x,t,b,c,d){return-c*((t=t/d-1)*t*t*t-1)+b;},easeInOutQuart:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t*t+b;return-c/2*((t-=2)*t*t*t-2)+b;},easeInQuint:function(x,t,b,c,d){return c*(t/=d)*t*t*t*t+b;},easeOutQuint:function(x,t,b,c,d){return c*((t=t/d-1)*t*t*t*t+1)+b;},easeInOutQuint:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t*t*t+b;return c/2*((t-=2)*t*t*t*t+2)+b;},easeInSine:function(x,t,b,c,d){return-c*Math.cos(t/d*(Math.PI/2))+c+b;},easeOutSine:function(x,t,b,c,d){return c*Math.sin(t/d*(Math.PI/2))+b;},easeInOutSine:function(x,t,b,c,d){return-c/2*(Math.cos(Math.PI*t/d)-1)+b;},easeInExpo:function(x,t,b,c,d){return(t==0)?b:c*Math.pow(2,10*(t/d-1))+b;},easeOutExpo:function(x,t,b,c,d){return(t==d)?b+c:c*(-Math.pow(2,-10*t/d)+1)+b;},easeInOutExpo:function(x,t,b,c,d){if(t==0)return b;if(t==d)return b+c;if((t/=d/2)<1)return c/2*Math.pow(2,10*(t-1))+b;return c/2*(-Math.pow(2,-10*--t)+2)+b;},easeInCirc:function(x,t,b,c,d){return-c*(Math.sqrt(1-(t/=d)*t)-1)+b;},easeOutCirc:function(x,t,b,c,d){return c*Math.sqrt(1-(t=t/d-1)*t)+b;},easeInOutCirc:function(x,t,b,c,d){if((t/=d/2)<1)return-c/2*(Math.sqrt(1-t*t)-1)+b;return c/2*(Math.sqrt(1-(t-=2)*t)+1)+b;},easeInElastic:function(x,t,b,c,d){var s=1.70158;var p=0;var a=c;if(t==0)return b;if((t/=d)==1)return b+c;if(!p)p=d*.3;if(a */ /** * Provides self-generating documentation about Kohana. */ class Kodoc_Core { protected static $types = array ( 'core', 'config', 'helpers', 'libraries', 'models', 'views' ); public static function get_types() { return self::$types; } public static function get_files() { // Extension length $ext_len = -(strlen(EXT)); $files = array(); foreach (self::$types as $type) { $files[$type] = array(); foreach (Kohana::list_files($type, TRUE) as $file) { // Not a source file if (substr($file, $ext_len) !== EXT) continue; // Remove the dirs from the filename $file = preg_replace('!^.+'.$type.'/(.+)'.EXT.'$!', '$1', $file); // Skip utf8 function files if ($type === 'core' AND substr($file, 0, 5) === 'utf8/') continue; if ($type === 'libraries' AND substr($file, 0, 8) === 'drivers/') { // Remove the drivers directory from the file $file = explode('_', substr($file, 8)); if (count($file) === 1) { // Driver interface $files[$type][current($file)][] = current($file); } else { // Driver is class suffix $driver = array_pop($file); // Library is everything else $library = implode('_', $file); // Library driver $files[$type][$library][] = $driver; } } else { $files[$type][$file] = NULL; } } } return $files; } public static function remove_docroot($file) { return preg_replace('!^'.preg_quote(DOCROOT, '!').'!', '', $file); } public static function humanize_type($types) { $types = is_array($types) ? $types : explode('|', $types); $output = array(); while ($t = array_shift($types)) { $output[] = ''.trim($t).''; } return implode(' or ', $output); } public static function humanize_value($value) { if ($value === NULL) { return 'NULL'; } elseif (is_bool($value)) { return $value ? 'TRUE' : 'FALSE'; } elseif (is_string($value)) { return 'string '.$value; } elseif (is_numeric($value)) { return (is_int($value) ? 'int' : 'float').' '.$value; } elseif (is_array($value)) { return 'array'; } elseif (is_object($value)) { return 'object '.get_class($value); } } // All files to be parsed protected $file = array(); public function __construct($type, $filename) { // Parse the file $this->file = $this->parse($type, $filename); } /** * Fetch documentation for all files parsed. * * Returns: * array: file documentation */ public function get() { return $this->file; } /** * Parse a file for Kodoc commands, classes, and methods. * * Parameters: * string: file type * string: absolute filename path */ protected function parse($type, $filename) { // File definition $file = array ( 'type' => $type, 'comment' => '', 'file' => self::remove_docroot($filename), ); // Read the entire file into an array $data = file($filename); foreach ($data as $line) { if (strpos($line, 'class') !== FALSE AND preg_match('/(?:class|interface)\s+([a-z0-9_]+).+{$/i', $line, $matches)) { // Include the file if it has not already been included class_exists($matches[1], FALSE) or include_once $filename; // Add class to file info $file['classes'][] = $this->parse_class($matches[1]); } } if (empty($file['classes'])) { $block = NULL; $source = NULL; foreach ($data as $line) { switch (substr(trim($line), 0, 2)) { case '/*': $block = ''; continue 2; break; case '*/': $source = TRUE; continue 2; break; } if ($source === TRUE) { if (preg_match('/\$config\[\'(.+?)\'\]\s+=\s+([^;].+)/', $line, $matches)) { $source = array ( $matches[1], $matches[2] ); } else { $source = array(); } $file['comments'][] = array_merge($this->parse_comment($block), array('source' => $source)); $block = NULL; $source = FALSE; } elseif (is_string($block)) { $block .= $line; } } } return $file; } protected function parse_comment($block) { if (($block = trim($block)) == '') return $block; // Explode the lines into an array and trim them $block = array_map('trim', explode("\n", $block)); if (current($block) === '/**') { // Remove comment opening array_shift($block); } if (end($block) === '*/') { // Remove comment closing array_pop($block); } // Start comment $comment = array(); while ($line = array_shift($block)) { // Remove * from the line $line = trim(substr($line, 2)); if ($line[0] === '$' AND substr($line, -1) === '$') { // Skip SVN property inserts continue; } if ($line[0] === '@') { if (preg_match('/^@(.+?)\s+(.+)$/', $line, $matches)) { $comment[$matches[1]][] = $matches[2]; } } else { $comment['about'][] = $line; } } if ( ! empty($comment['about'])) { $token = ''; $block = ''; $about = ''; foreach ($comment['about'] as $line) { if (strpos($line, '`') !== FALSE) { $line = preg_replace('/`([^`].+?)`/', '$1', $line); } if (substr($line, 0, 2) === '- ') { if ($token !== 'ul') { $about .= $this->comment_block($token, $block); $block = ''; } $token = 'ul'; $line = '
  • '.trim(substr($line, 2)).'
  • '."\n"; } elseif (preg_match('/(.+?)\s+-\s+(.+)/', $line, $matches)) { if ($token !== 'dl') { $about .= $this->comment_block($token, $block); $block = ''; } $token = 'dl'; $line = '
    '.$matches[1].'
    '."\n".'
    '.$matches[2].'
    '."\n"; } else { $token = 'p'; $line .= ' '; } if (trim($line) === '') { $about .= $this->comment_block($token, $block); $block = ''; } else { $block .= $line; } } if ( ! empty($block)) { $about .= $this->comment_block($token, $block); } $comment['about'] = $about; } return $comment; } protected function comment_block($token, $block) { if (empty($token) OR empty($block)) return ''; $block = trim($block); if ($block[0] === '<') { // Insert newlines before and after the block $block = "\n".$block."\n"; } return '<'.$token.'>'.$block.''."\n"; } protected function parse_class($class) { // Use reflection to find information $reflection = new ReflectionClass($class); // Class definition $class = array ( 'name' => $reflection->getName(), 'comment' => $this->parse_comment($reflection->getDocComment()), 'final' => $reflection->isFinal(), 'abstract' => $reflection->isAbstract(), 'interface' => $reflection->isInterface(), 'extends' => '', 'implements' => array(), 'methods' => array() ); if ($implements = $reflection->getInterfaces()) { foreach ($implements as $interface) { // Get implemented interfaces $class['implements'][] = $interface->getName(); } } if ($parent = $reflection->getParentClass()) { // Get parent class $class['extends'] = $parent->getName(); } if ($methods = $reflection->getMethods()) { foreach ($methods as $method) { // Don't try to document internal methods if ($method->isInternal()) continue; $class['methods'][] = array ( 'name' => $method->getName(), 'comment' => $this->parse_comment($method->getDocComment()), 'class' => $class['name'], 'final' => $method->isFinal(), 'static' => $method->isStatic(), 'abstract' => $method->isAbstract(), 'visibility' => $this->visibility($method), 'parameters' => $this->parameters($method) ); } } return $class; } /** * Finds the parameters for a ReflectionMethod. * * @param object ReflectionMethod * @return array */ protected function parameters(ReflectionMethod $method) { $params = array(); if ($parameters = $method->getParameters()) { foreach ($parameters as $param) { // Parameter data $data = array ( 'name' => $param->getName() ); if ($param->isOptional()) { // Set default value $data['default'] = $param->getDefaultValue(); } $params[] = $data; } } return $params; } /** * Finds the visibility of a ReflectionMethod. * * @param object ReflectionMethod * @return string */ protected function visibility(ReflectionMethod $method) { $vis = array_flip(Reflection::getModifierNames($method->getModifiers())); if (isset($vis['public'])) { return 'public'; } if (isset($vis['protected'])) { return 'protected'; } if (isset($vis['private'])) { return 'private'; } return FALSE; } } // End Kodoc class Kodoc_xCore { /** * libraries, helpers, etc */ protected $files = array ( 'core' => array(), 'config' => array(), 'helpers' => array(), 'libraries' => array(), 'models' => array(), 'views' => array() ); /** * $classes[$name] = array $properties; * $properties = array * ( * 'drivers' => array $drivers * 'properties' => array $properties * 'methods' => array $methods * ) */ protected $classes = array(); // Holds the current data until parsed protected $current_class; // $packages[$name] = array $files; protected $packages = array(); // PHP's visibility types protected static $php_visibility = array ( 'public', 'protected', 'private' ); public function __construct() { if (isset(self::$php_visibility[0])) { self::$php_visibility = array_flip(self::$php_visibility); } foreach ($this->files as $type => $files) { foreach (Kohana::list_files($type) as $filepath) { // Get the filename with no extension $file = pathinfo($filepath, PATHINFO_FILENAME); // Skip indexes and drivers if ($file === 'index' OR strpos($filepath, 'libraries/drivers') !== FALSE) continue; // Add the file $this->files[$type][$file] = $filepath; // Parse the file $this->parse_file($filepath); } } Kohana::log('debug', 'Kodoc Library initialized'); } public function get_docs($format = 'html') { switch ($format) { default: // Generate HTML via a View $docs = new View('kodoc_html'); $docs->set('classes', $this->classes)->render(); break; } return $docs; } protected function parse_file($file) { $file = fopen($file, 'r'); $i = 1; while ($line = fgets($file)) { if (substr(trim($line), 0, 2) === '/*') { // Reset vars unset($current_doc, $section, $p); // Prepare for a new doc section $current_doc = array(); $closing_tag = '*/'; $current_block = 'description'; $p = 0; // Assign the current doc $this->current_doc =& $current_doc; } elseif (isset($closing_tag)) { if (substr(trim($line), 0, 1) === '*') { // Remove the leading comment $line = substr(ltrim($line), 2); if (preg_match('/^([a-z ]+):/i', $line, $matches)) { $current_block = trim($matches[1]); } elseif (isset($current_doc)) { $line = ltrim($line); if (preg_match('/^\-\s+(.+)/', $line, $matches)) { // An unordered list $current_doc['html'][$current_block]['ul'][] = $matches[1]; } elseif (preg_match('/^[0-9]+\.\s+(.+)/', $line, $matches)) { // An ordered list $current_doc['html'][$current_block]['ol'][] = $matches[1]; } elseif (preg_match('/^([a-zA-Z ]+)\s+\-\s+(.+)/', $line, $matches)) { // Definition list $current_doc['html'][$current_block]['dl'][trim($matches[1])] = trim($matches[2]); } else { if (trim($line) === '') { // Start a new paragraph $p++; } else { // Make sure the current paragraph is set if ( ! isset($current_doc['html'][$current_block]['p'][$p])) { $current_doc['html'][$current_block]['p'][$p] = ''; } // Add to the current paragraph $current_doc['html'][$current_block]['p'][$p] .= str_replace("\n", ' ', $line); } } } } else { switch (substr(trim($line), 0, 2)) { case '//': case '* ': break; default: $line = trim($line); if ($this->is_function($line) OR $this->is_property($line) OR $this->is_class($line)) { $clear = NULL; $this->current_doc =& $clear; // Restarts searching unset($closing_tag, $current_doc); } break; } } } $i++; } // Close the file fclose($file); } /** * Method: * Checks if a line is a class, and parses the data out. * * Parameters: * line - a line from a file * * Returns: * TRUE or FALSE. */ protected function is_class($line) { if (strpos($line, 'class') === FALSE) { return FALSE; } $line = explode(' ', trim($line)); $class = array ( 'name' => '', 'final' => FALSE, 'extends' => FALSE, 'drivers' => FALSE ); if (current($line) === 'final') { $class['final'] = (bool) array_shift($line); } if (current($line) === 'class') { // Remove "class" array_shift($line); $name = array_shift($line); } if (count($line) > 1) { // Remove "extends" array_shift($line); $class['extends'] = array_shift($line); } if (isset($name)) { // Add the class into the docs $this->classes[$name] = array_merge($this->current_doc, $class); // Set the current class $this->current_class =& $this->classes[$name]; return TRUE; } return FALSE; } /** * Method: * Checks if a line is a property, and parses the data out. * * Parameters: * line - a line from a file * * Returns: * TRUE or FALSE. */ protected function is_property($line) { static $preg_vis; if ($preg_vis === NULL) { $preg_vis = 'var|'.implode('|', self::$php_visibility); } if (strpos($line, '$') === FALSE OR ! preg_match('/^(?:'.$preg_vis.')/', $line)) return FALSE; $line = explode(' ', $line); $var = array ( 'visibility' => FALSE, 'static' => FALSE, 'default' => NULL ); if (current($line) === 'var') { // Remove "var" array_shift($line); $var['visibility'] = 'public'; } if (current($line) === 'static') { $var['visibility'] = (bool) array_shift($line); } // If the visibility is not set, this is not a if ($var['visibility'] === FALSE) return FALSE; if (substr(current($line), 0, 1) === '$') { $name = substr(array_shift($line), 1); $name = rtrim($name, ';'); } if (count($line) AND current($line) === '=') { array_shift($line); $var['default'] = implode(' ', $line); } if (isset($name)) { // Add property to class $this->current_class['properties'][$name] = array_merge($this->current_doc, $var); return TRUE; } return FALSE; } /** * Method: * Checks if a line is a function, and parses the data out. * * Parameters: * line - a line from a file * * Returns: * TRUE or FALSE. */ protected function is_function($line) { if (strpos($line, 'function') === FALSE) { return FALSE; } $line = explode(' ', trim(strtolower($line))); $func = array ( 'final' => FALSE, 'visibility' => 'public', 'static' => FALSE, ); if (current($line) === 'final') { $func['final'] = TRUE; } if (isset(self::$php_visibility[current($line)])) { $func['visibility'] = array_shift($line); } if (current($line) === 'static') { $func['static'] = (bool) array_shift($line); } if (current($line) === 'function') { // Remove "function" array_shift($line); // Get name $name = array_shift($line); // Remove arguments if (strpos($name, '(') !== FALSE) { $name = current(explode('(', $name, 2)); } // Register the method $this->current_class['methods'][$name] = array_merge($this->current_doc, $func); return TRUE; } return FALSE; } } // End Kodoc./kohana/modules/kodoc/controllers/0000755000175000017500000000000011263472444017126 5ustar tokkeetokkee./kohana/modules/kodoc/controllers/kodoc.php0000644000175000017500000000453111121324570020726 0ustar tokkeetokkeeuri->segment(2) ? $this->uri->segment(2) : 'core'; // Add the menu to the template $this->template->menu = new View('kodoc/menu', array('active' => $active)); } public function index() { $this->template->content = 'hi'; } public function media() { if (isset($this->profiler)) $this->profiler->disable(); // Get the filename $file = implode('/', $this->uri->segment_array(1)); $ext = strrchr($file, '.'); if ($ext !== FALSE) { $file = substr($file, 0, -strlen($ext)); $ext = substr($ext, 1); } // Disable auto-rendering $this->auto_render = FALSE; try { // Attempt to display the output echo new View('kodoc/'.$file, NULL, $ext); } catch (Kohana_Exception $e) { Event::run('system.404'); } } public function __call($method, $args) { if (count($segments = $this->uri->segment_array(1)) > 1) { // Find directory (type) and filename $type = array_shift($segments); $file = implode('/', $segments); if (substr($file, -(strlen(EXT))) === EXT) { // Remove extension $file = substr($file, 0, -(strlen(EXT))); } if ($type === 'config') { if ($file === 'config') { // This file can only exist in one location $file = APPPATH.$type.'/config'.EXT; } else { foreach (array_reverse(Kohana::include_paths()) as $path) { if (is_file($path.$type.'/'.$file.EXT)) { // Found the file $file = $path.$type.'/'.$file.EXT; break; } } } } else { // Get absolute path to file $file = Kohana::find_file($type, $file); } if (in_array($type, Kodoc::get_types())) { // Load Kodoc $this->kodoc = new Kodoc($type, $file); // Set the title $this->template->title = implode('/', $this->uri->segment_array(1)); // Load documentation for this file $this->template->content = new View('kodoc/documentation'); // Exit this method return; } } // Nothing to document url::redirect('kodoc'); } } // End Kodoc Controller