composer add-on! Not tested on a web-server !
This commit is contained in:
parent
880b6111f8
commit
9826db088c
|
@ -1,395 +0,0 @@
|
||||||
<?php
|
|
||||||
/*
|
|
||||||
Copyright (c) 2008 Sebastián Grignoli
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. 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.
|
|
||||||
3. Neither the name of copyright holders 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 COPYRIGHT HOLDERS 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author "Sebastián Grignoli" <grignoli@gmail.com>
|
|
||||||
* @package Encoding
|
|
||||||
* @version 2.0
|
|
||||||
* @link https://github.com/neitanod/forceutf8
|
|
||||||
* @example https://github.com/neitanod/forceutf8
|
|
||||||
* @license Revised BSD
|
|
||||||
*/
|
|
||||||
class Encoding
|
|
||||||
{
|
|
||||||
|
|
||||||
const ICONV_TRANSLIT = "TRANSLIT";
|
|
||||||
const ICONV_IGNORE = "IGNORE";
|
|
||||||
const WITHOUT_ICONV = "";
|
|
||||||
|
|
||||||
protected static $win1252ToUtf8 = array(
|
|
||||||
128 => "\xe2\x82\xac",
|
|
||||||
|
|
||||||
130 => "\xe2\x80\x9a",
|
|
||||||
131 => "\xc6\x92",
|
|
||||||
132 => "\xe2\x80\x9e",
|
|
||||||
133 => "\xe2\x80\xa6",
|
|
||||||
134 => "\xe2\x80\xa0",
|
|
||||||
135 => "\xe2\x80\xa1",
|
|
||||||
136 => "\xcb\x86",
|
|
||||||
137 => "\xe2\x80\xb0",
|
|
||||||
138 => "\xc5\xa0",
|
|
||||||
139 => "\xe2\x80\xb9",
|
|
||||||
140 => "\xc5\x92",
|
|
||||||
|
|
||||||
142 => "\xc5\xbd",
|
|
||||||
|
|
||||||
|
|
||||||
145 => "\xe2\x80\x98",
|
|
||||||
146 => "\xe2\x80\x99",
|
|
||||||
147 => "\xe2\x80\x9c",
|
|
||||||
148 => "\xe2\x80\x9d",
|
|
||||||
149 => "\xe2\x80\xa2",
|
|
||||||
150 => "\xe2\x80\x93",
|
|
||||||
151 => "\xe2\x80\x94",
|
|
||||||
152 => "\xcb\x9c",
|
|
||||||
153 => "\xe2\x84\xa2",
|
|
||||||
154 => "\xc5\xa1",
|
|
||||||
155 => "\xe2\x80\xba",
|
|
||||||
156 => "\xc5\x93",
|
|
||||||
|
|
||||||
158 => "\xc5\xbe",
|
|
||||||
159 => "\xc5\xb8"
|
|
||||||
);
|
|
||||||
|
|
||||||
protected static $brokenUtf8ToUtf8 = array(
|
|
||||||
"\xc2\x80" => "\xe2\x82\xac",
|
|
||||||
|
|
||||||
"\xc2\x82" => "\xe2\x80\x9a",
|
|
||||||
"\xc2\x83" => "\xc6\x92",
|
|
||||||
"\xc2\x84" => "\xe2\x80\x9e",
|
|
||||||
"\xc2\x85" => "\xe2\x80\xa6",
|
|
||||||
"\xc2\x86" => "\xe2\x80\xa0",
|
|
||||||
"\xc2\x87" => "\xe2\x80\xa1",
|
|
||||||
"\xc2\x88" => "\xcb\x86",
|
|
||||||
"\xc2\x89" => "\xe2\x80\xb0",
|
|
||||||
"\xc2\x8a" => "\xc5\xa0",
|
|
||||||
"\xc2\x8b" => "\xe2\x80\xb9",
|
|
||||||
"\xc2\x8c" => "\xc5\x92",
|
|
||||||
|
|
||||||
"\xc2\x8e" => "\xc5\xbd",
|
|
||||||
|
|
||||||
|
|
||||||
"\xc2\x91" => "\xe2\x80\x98",
|
|
||||||
"\xc2\x92" => "\xe2\x80\x99",
|
|
||||||
"\xc2\x93" => "\xe2\x80\x9c",
|
|
||||||
"\xc2\x94" => "\xe2\x80\x9d",
|
|
||||||
"\xc2\x95" => "\xe2\x80\xa2",
|
|
||||||
"\xc2\x96" => "\xe2\x80\x93",
|
|
||||||
"\xc2\x97" => "\xe2\x80\x94",
|
|
||||||
"\xc2\x98" => "\xcb\x9c",
|
|
||||||
"\xc2\x99" => "\xe2\x84\xa2",
|
|
||||||
"\xc2\x9a" => "\xc5\xa1",
|
|
||||||
"\xc2\x9b" => "\xe2\x80\xba",
|
|
||||||
"\xc2\x9c" => "\xc5\x93",
|
|
||||||
|
|
||||||
"\xc2\x9e" => "\xc5\xbe",
|
|
||||||
"\xc2\x9f" => "\xc5\xb8"
|
|
||||||
);
|
|
||||||
|
|
||||||
protected static $utf8ToWin1252 = array(
|
|
||||||
"\xe2\x82\xac" => "\x80",
|
|
||||||
|
|
||||||
"\xe2\x80\x9a" => "\x82",
|
|
||||||
"\xc6\x92" => "\x83",
|
|
||||||
"\xe2\x80\x9e" => "\x84",
|
|
||||||
"\xe2\x80\xa6" => "\x85",
|
|
||||||
"\xe2\x80\xa0" => "\x86",
|
|
||||||
"\xe2\x80\xa1" => "\x87",
|
|
||||||
"\xcb\x86" => "\x88",
|
|
||||||
"\xe2\x80\xb0" => "\x89",
|
|
||||||
"\xc5\xa0" => "\x8a",
|
|
||||||
"\xe2\x80\xb9" => "\x8b",
|
|
||||||
"\xc5\x92" => "\x8c",
|
|
||||||
|
|
||||||
"\xc5\xbd" => "\x8e",
|
|
||||||
|
|
||||||
|
|
||||||
"\xe2\x80\x98" => "\x91",
|
|
||||||
"\xe2\x80\x99" => "\x92",
|
|
||||||
"\xe2\x80\x9c" => "\x93",
|
|
||||||
"\xe2\x80\x9d" => "\x94",
|
|
||||||
"\xe2\x80\xa2" => "\x95",
|
|
||||||
"\xe2\x80\x93" => "\x96",
|
|
||||||
"\xe2\x80\x94" => "\x97",
|
|
||||||
"\xcb\x9c" => "\x98",
|
|
||||||
"\xe2\x84\xa2" => "\x99",
|
|
||||||
"\xc5\xa1" => "\x9a",
|
|
||||||
"\xe2\x80\xba" => "\x9b",
|
|
||||||
"\xc5\x93" => "\x9c",
|
|
||||||
|
|
||||||
"\xc5\xbe" => "\x9e",
|
|
||||||
"\xc5\xb8" => "\x9f"
|
|
||||||
);
|
|
||||||
|
|
||||||
static function toISO8859($text, $option = self::WITHOUT_ICONV)
|
|
||||||
{
|
|
||||||
return self::toWin1252($text, $option);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function toWin1252($text, $option = self::WITHOUT_ICONV)
|
|
||||||
{
|
|
||||||
if (is_array($text)) {
|
|
||||||
foreach ($text as $k => $v) {
|
|
||||||
$text[$k] = self::toWin1252($v, $option);
|
|
||||||
}
|
|
||||||
return $text;
|
|
||||||
} elseif (is_string($text)) {
|
|
||||||
return static::utf8_decode($text, $option);
|
|
||||||
} else {
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function utf8_decode($text, $option = self::WITHOUT_ICONV)
|
|
||||||
{
|
|
||||||
if ($option == self::WITHOUT_ICONV || !function_exists('iconv')) {
|
|
||||||
$o = utf8_decode(
|
|
||||||
str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text))
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$o = iconv("UTF-8", "Windows-1252" . ($option == self::ICONV_TRANSLIT ? '//TRANSLIT' : ($option == self::ICONV_IGNORE ? '//IGNORE' : '')), $text);
|
|
||||||
}
|
|
||||||
return $o;
|
|
||||||
}
|
|
||||||
|
|
||||||
static function toUTF8($text)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Function \ForceUTF8\Encoding::toUTF8
|
|
||||||
*
|
|
||||||
* This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8.
|
|
||||||
*
|
|
||||||
* It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1.
|
|
||||||
*
|
|
||||||
* It may fail to convert characters to UTF-8 if they fall into one of these scenarios:
|
|
||||||
*
|
|
||||||
* 1) when any of these characters: ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
|
|
||||||
* are followed by any of these: ("group B")
|
|
||||||
* ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶•¸¹º»¼½¾¿
|
|
||||||
* For example: %ABREPRESENT%C9%BB. «REPRESENTÉ»
|
|
||||||
* The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB)
|
|
||||||
* is also a valid unicode character, and will be left unchanged.
|
|
||||||
*
|
|
||||||
* 2) when any of these: àáâãäåæçèéêëìíîï are followed by TWO chars from group B,
|
|
||||||
* 3) when any of these: ðñòó are followed by THREE chars from group B.
|
|
||||||
*
|
|
||||||
* @name toUTF8
|
|
||||||
* @param string $text Any string.
|
|
||||||
* @return string The same string, UTF8 encoded
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (is_array($text)) {
|
|
||||||
foreach ($text as $k => $v) {
|
|
||||||
$text[$k] = self::toUTF8($v);
|
|
||||||
}
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_string($text)) {
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
$max = self::strlen($text);
|
|
||||||
|
|
||||||
$buf = "";
|
|
||||||
for ($i = 0; $i < $max; $i++) {
|
|
||||||
$c1 = $text{$i};
|
|
||||||
if ($c1 >= "\xc0") { //Should be converted to UTF8, if it's not UTF8 already
|
|
||||||
$c2 = $i + 1 >= $max ? "\x00" : $text{$i + 1};
|
|
||||||
$c3 = $i + 2 >= $max ? "\x00" : $text{$i + 2};
|
|
||||||
$c4 = $i + 3 >= $max ? "\x00" : $text{$i + 3};
|
|
||||||
if ($c1 >= "\xc0" & $c1 <= "\xdf") { //looks like 2 bytes UTF8
|
|
||||||
if ($c2 >= "\x80" && $c2 <= "\xbf") { //yeah, almost sure it's UTF8 already
|
|
||||||
$buf .= $c1 . $c2;
|
|
||||||
$i++;
|
|
||||||
} else { //not valid UTF8. Convert it.
|
|
||||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
|
||||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
|
||||||
$buf .= $cc1 . $cc2;
|
|
||||||
}
|
|
||||||
} elseif ($c1 >= "\xe0" & $c1 <= "\xef") { //looks like 3 bytes UTF8
|
|
||||||
if ($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf") { //yeah, almost sure it's UTF8 already
|
|
||||||
$buf .= $c1 . $c2 . $c3;
|
|
||||||
$i = $i + 2;
|
|
||||||
} else { //not valid UTF8. Convert it.
|
|
||||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
|
||||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
|
||||||
$buf .= $cc1 . $cc2;
|
|
||||||
}
|
|
||||||
} elseif ($c1 >= "\xf0" & $c1 <= "\xf7") { //looks like 4 bytes UTF8
|
|
||||||
if ($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf") { //yeah, almost sure it's UTF8 already
|
|
||||||
$buf .= $c1 . $c2 . $c3 . $c4;
|
|
||||||
$i = $i + 3;
|
|
||||||
} else { //not valid UTF8. Convert it.
|
|
||||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
|
||||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
|
||||||
$buf .= $cc1 . $cc2;
|
|
||||||
}
|
|
||||||
} else { //doesn't look like UTF8, but should be converted
|
|
||||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
|
||||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
|
||||||
$buf .= $cc1 . $cc2;
|
|
||||||
}
|
|
||||||
} elseif (($c1 & "\xc0") == "\x80") { // needs conversion
|
|
||||||
if (isset(self::$win1252ToUtf8[ord($c1)])) { //found in Windows-1252 special cases
|
|
||||||
$buf .= self::$win1252ToUtf8[ord($c1)];
|
|
||||||
} else {
|
|
||||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
|
||||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
|
||||||
$buf .= $cc1 . $cc2;
|
|
||||||
}
|
|
||||||
} else { // it doesn't need conversion
|
|
||||||
$buf .= $c1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function strlen($text)
|
|
||||||
{
|
|
||||||
return (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload')) & 2) ?
|
|
||||||
mb_strlen($text, '8bit') : strlen($text);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function fixUTF8($text, $option = self::WITHOUT_ICONV)
|
|
||||||
{
|
|
||||||
if (is_array($text)) {
|
|
||||||
foreach ($text as $k => $v) {
|
|
||||||
$text[$k] = self::fixUTF8($v, $option);
|
|
||||||
}
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_string($text)) {
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
$last = "";
|
|
||||||
while ($last <> $text) {
|
|
||||||
$last = $text;
|
|
||||||
$text = self::toUTF8(static::utf8_decode($text, $option));
|
|
||||||
}
|
|
||||||
$text = self::toUTF8(static::utf8_decode($text, $option));
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
static function UTF8FixWin1252Chars($text)
|
|
||||||
{
|
|
||||||
// If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1
|
|
||||||
// (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
|
|
||||||
// See: http://en.wikipedia.org/wiki/Windows-1252
|
|
||||||
|
|
||||||
return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function removeBOM($str = "")
|
|
||||||
{
|
|
||||||
if (substr($str, 0, 3) == pack("CCC", 0xef, 0xbb, 0xbf)) {
|
|
||||||
$str = substr($str, 3);
|
|
||||||
}
|
|
||||||
return $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function encode($encodingLabel, $text)
|
|
||||||
{
|
|
||||||
$encodingLabel = self::normalizeEncoding($encodingLabel);
|
|
||||||
if ($encodingLabel == 'ISO-8859-1') return self::toLatin1($text);
|
|
||||||
return self::toUTF8($text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function normalizeEncoding($encodingLabel)
|
|
||||||
{
|
|
||||||
$encoding = strtoupper($encodingLabel);
|
|
||||||
$encoding = preg_replace('/[^a-zA-Z0-9\s]/', '', $encoding);
|
|
||||||
$equivalences = array(
|
|
||||||
'ISO88591' => 'ISO-8859-1',
|
|
||||||
'ISO8859' => 'ISO-8859-1',
|
|
||||||
'ISO' => 'ISO-8859-1',
|
|
||||||
'LATIN1' => 'ISO-8859-1',
|
|
||||||
'LATIN' => 'ISO-8859-1',
|
|
||||||
'UTF8' => 'UTF-8',
|
|
||||||
'UTF' => 'UTF-8',
|
|
||||||
'WIN1252' => 'ISO-8859-1',
|
|
||||||
'WINDOWS1252' => 'ISO-8859-1'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (empty($equivalences[$encoding])) {
|
|
||||||
return 'UTF-8';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $equivalences[$encoding];
|
|
||||||
}
|
|
||||||
|
|
||||||
static function toLatin1($text, $option = self::WITHOUT_ICONV)
|
|
||||||
{
|
|
||||||
return self::toWin1252($text, $option);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****/
|
|
||||||
|
|
||||||
public static function destructionH4x0RChaine($chaine)
|
|
||||||
{
|
|
||||||
return preg_replace('#[\x00-\x1F\x7F-\x9F/\\\\]#', '', $chaine);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function protectionDoubleQuote($chaine)
|
|
||||||
{
|
|
||||||
$chaine = preg_replace('/"(\w+)"/', '« ${1} »', $chaine);
|
|
||||||
$chaine = preg_replace('#"#', '_', $chaine);
|
|
||||||
return $chaine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function protectionSimpleQuote($chaine)
|
|
||||||
{
|
|
||||||
$chaine = preg_replace("#'#", '_', $chaine);
|
|
||||||
return $chaine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function myUrlEncode($string)
|
|
||||||
{
|
|
||||||
$replacements = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D'/*, '%2B'*/, '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
|
|
||||||
$entities = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "="/*, "+"*/, "$", ",", "/", "?", "%", "#", "[", "]");
|
|
||||||
$string = urlencode($string);
|
|
||||||
$string = str_replace($entities, $replacements, $string);
|
|
||||||
return $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function myUrlDecode($string)
|
|
||||||
{
|
|
||||||
$entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D'/*, '%2B'*/, '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
|
|
||||||
$replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "="/*, "+"*/, "$", ",", "/", "?", "%", "#", "[", "]");
|
|
||||||
$string = str_replace($entities, $replacements, $string);
|
|
||||||
$string = urldecode($string);
|
|
||||||
return $string;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
forceutf8
|
|
||||||
=========
|
|
||||||
|
|
||||||
PHP Class Encoding featuring popular \ForceUTF8\Encoding::toUTF8() function --formerly known as forceUTF8()-- that fixes mixed encoded strings.
|
|
||||||
|
|
||||||
Description
|
|
||||||
===========
|
|
||||||
|
|
||||||
If you apply the PHP function utf8_encode() to an already-UTF8 string it will return a garbled UTF8 string.
|
|
||||||
|
|
||||||
This class addresses this issue and provides a handy static function called \ForceUTF8\Encoding::toUTF8().
|
|
||||||
|
|
||||||
You don't need to know what the encoding of your strings is. It can be Latin1 (ISO 8859-1), Windows-1252 or UTF8, or the string can have a mix of them. \ForceUTF8\Encoding::toUTF8() will convert everything to UTF8.
|
|
||||||
|
|
||||||
Sometimes you have to deal with services that are unreliable in terms of encoding, possibly mixing UTF8 and Latin1 in the same string.
|
|
||||||
|
|
||||||
Update:
|
|
||||||
|
|
||||||
I've included another function, \ForceUTF8\Encoding::fixUTF8(), which will fix the double (or multiple) encoded UTF8 string that looks garbled.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
======
|
|
||||||
|
|
||||||
use \ForceUTF8\Encoding;
|
|
||||||
|
|
||||||
$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);
|
|
||||||
|
|
||||||
$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);
|
|
||||||
|
|
||||||
also:
|
|
||||||
|
|
||||||
$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
use \ForceUTF8\Encoding;
|
|
||||||
|
|
||||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
|
||||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
|
||||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
|
||||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
|
||||||
|
|
||||||
will output:
|
|
||||||
|
|
||||||
Fédération Camerounaise de Football
|
|
||||||
Fédération Camerounaise de Football
|
|
||||||
Fédération Camerounaise de Football
|
|
||||||
Fédération Camerounaise de Football
|
|
||||||
|
|
||||||
Options:
|
|
||||||
========
|
|
||||||
By default, `Encoding::fixUTF8` will use the `Encoding::WITHOUT_ICONV` flag, signalling that iconv should not be used to fix garbled UTF8 strings.
|
|
||||||
|
|
||||||
This class also provides options for iconv processing, such as `Encoding::ICONV_TRANSLIT` and `Encoding::ICONV_IGNORE` to enable these flags when the iconv class is utilized. The functionality of such flags are documented in the [PHP iconv documentation](http://php.net/manual/en/function.iconv.php).
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
use \ForceUTF8\Encoding;
|
|
||||||
|
|
||||||
$str = "Fédération Camerounaise—de—Football\n"; // Uses U+2014 which is invalid ISO8859-1 but exists in Win1252
|
|
||||||
echo Encoding::fixUTF8($str); // Will break U+2014
|
|
||||||
echo Encoding::fixUTF8($str, Encoding::ICONV_IGNORE); // Will preserve U+2014
|
|
||||||
echo Encoding::fixUTF8($str, Encoding::ICONV_TRANSLIT); // Will preserve U+2014
|
|
||||||
|
|
||||||
will output:
|
|
||||||
|
|
||||||
Fédération Camerounaise?de?Football
|
|
||||||
Fédération Camerounaise—de—Football
|
|
||||||
Fédération Camerounaise—de—Football
|
|
||||||
|
|
||||||
while:
|
|
||||||
|
|
||||||
use \ForceUTF8\Encoding;
|
|
||||||
|
|
||||||
$str = "čęėįšųūž"; // Uses several characters not present in ISO8859-1 / Win1252
|
|
||||||
echo Encoding::fixUTF8($str); // Will break invalid characters
|
|
||||||
echo Encoding::fixUTF8($str, Encoding::ICONV_IGNORE); // Will remove invalid characters, keep those present in Win1252
|
|
||||||
echo Encoding::fixUTF8($str, Encoding::ICONV_TRANSLIT); // Will trasliterate invalid characters, keep those present in Win1252
|
|
||||||
|
|
||||||
will output:
|
|
||||||
|
|
||||||
????????
|
|
||||||
šž
|
|
||||||
ceeišuuž
|
|
||||||
|
|
||||||
|
|
||||||
Install via composer:
|
|
||||||
=====================
|
|
||||||
Edit your composer.json file to include the following:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"require": {
|
|
||||||
"neitanod/forceutf8": "~2.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Tips:
|
|
||||||
=====
|
|
||||||
You can tip me with Bitcoin if you want. :)
|
|
||||||
|
|
||||||
<img src="resources/wallet.jpg" width="225" alt="1Awfu4TZpy99H7Pyzt1mooxU1aP2mJVdHP">
|
|
|
@ -1,324 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* A Compatibility library with PHP 5.5's simplified password hashing API.
|
|
||||||
*
|
|
||||||
* @author Anthony Ferrara <ircmaxell@php.net>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @copyright 2012 The Authors
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
if (!defined('PASSWORD_BCRYPT')) {
|
|
||||||
/**
|
|
||||||
* PHPUnit Process isolation caches constants, but not function declarations.
|
|
||||||
* So we need to check if the constants are defined separately from
|
|
||||||
* the functions to enable supporting process isolation in userland
|
|
||||||
* code.
|
|
||||||
*/
|
|
||||||
define('PASSWORD_BCRYPT', 1);
|
|
||||||
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
|
|
||||||
define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!function_exists('password_hash')) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash the password using the specified algorithm
|
|
||||||
*
|
|
||||||
* @param string $password The password to hash
|
|
||||||
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
|
|
||||||
* @param array $options The options for the algorithm to use
|
|
||||||
*
|
|
||||||
* @return string|false The hashed password, or false on error.
|
|
||||||
*/
|
|
||||||
function password_hash($password, $algo, array $options = array())
|
|
||||||
{
|
|
||||||
if (!function_exists('crypt')) {
|
|
||||||
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (is_null($password) || is_int($password)) {
|
|
||||||
$password = (string)$password;
|
|
||||||
}
|
|
||||||
if (!is_string($password)) {
|
|
||||||
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!is_int($algo)) {
|
|
||||||
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$resultLength = 0;
|
|
||||||
switch ($algo) {
|
|
||||||
case PASSWORD_BCRYPT:
|
|
||||||
$cost = PASSWORD_BCRYPT_DEFAULT_COST;
|
|
||||||
if (isset($options['cost'])) {
|
|
||||||
$cost = (int)$options['cost'];
|
|
||||||
if ($cost < 4 || $cost > 31) {
|
|
||||||
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The length of salt to generate
|
|
||||||
$raw_salt_len = 16;
|
|
||||||
// The length required in the final serialization
|
|
||||||
$required_salt_len = 22;
|
|
||||||
$hash_format = sprintf("$2y$%02d$", $cost);
|
|
||||||
// The expected length of the final crypt() output
|
|
||||||
$resultLength = 60;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$salt_req_encoding = false;
|
|
||||||
if (isset($options['salt'])) {
|
|
||||||
switch (gettype($options['salt'])) {
|
|
||||||
case 'NULL':
|
|
||||||
case 'boolean':
|
|
||||||
case 'integer':
|
|
||||||
case 'double':
|
|
||||||
case 'string':
|
|
||||||
$salt = (string)$options['salt'];
|
|
||||||
break;
|
|
||||||
case 'object':
|
|
||||||
if (method_exists($options['salt'], '__tostring')) {
|
|
||||||
$salt = (string)$options['salt'];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'array':
|
|
||||||
case 'resource':
|
|
||||||
default:
|
|
||||||
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
|
|
||||||
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
|
|
||||||
return null;
|
|
||||||
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
|
|
||||||
$salt_req_encoding = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$buffer = '';
|
|
||||||
$buffer_valid = false;
|
|
||||||
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
|
|
||||||
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
|
|
||||||
if ($buffer) {
|
|
||||||
$buffer_valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
|
|
||||||
$strong = false;
|
|
||||||
$buffer = openssl_random_pseudo_bytes($raw_salt_len, $strong);
|
|
||||||
if ($buffer && $strong) {
|
|
||||||
$buffer_valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$buffer_valid && @is_readable('/dev/urandom')) {
|
|
||||||
$file = fopen('/dev/urandom', 'r');
|
|
||||||
$read = 0;
|
|
||||||
$local_buffer = '';
|
|
||||||
while ($read < $raw_salt_len) {
|
|
||||||
$local_buffer .= fread($file, $raw_salt_len - $read);
|
|
||||||
$read = PasswordCompat\binary\_strlen($local_buffer);
|
|
||||||
}
|
|
||||||
fclose($file);
|
|
||||||
if ($read >= $raw_salt_len) {
|
|
||||||
$buffer_valid = true;
|
|
||||||
}
|
|
||||||
$buffer = str_pad($buffer, $raw_salt_len, "\0") ^ str_pad($local_buffer, $raw_salt_len, "\0");
|
|
||||||
}
|
|
||||||
if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
|
|
||||||
$buffer_length = PasswordCompat\binary\_strlen($buffer);
|
|
||||||
for ($i = 0; $i < $raw_salt_len; $i++) {
|
|
||||||
if ($i < $buffer_length) {
|
|
||||||
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
|
|
||||||
} else {
|
|
||||||
$buffer .= chr(mt_rand(0, 255));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$salt = $buffer;
|
|
||||||
$salt_req_encoding = true;
|
|
||||||
}
|
|
||||||
if ($salt_req_encoding) {
|
|
||||||
// encode string with the Base64 variant used by crypt
|
|
||||||
$base64_digits =
|
|
||||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
||||||
$bcrypt64_digits =
|
|
||||||
'./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
||||||
|
|
||||||
$base64_string = base64_encode($salt);
|
|
||||||
$salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
|
|
||||||
}
|
|
||||||
$salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
|
|
||||||
|
|
||||||
$hash = $hash_format . $salt;
|
|
||||||
|
|
||||||
$ret = crypt($password, $hash);
|
|
||||||
|
|
||||||
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get information about the password hash. Returns an array of the information
|
|
||||||
* that was used to generate the password hash.
|
|
||||||
*
|
|
||||||
* array(
|
|
||||||
* 'algo' => 1,
|
|
||||||
* 'algoName' => 'bcrypt',
|
|
||||||
* 'options' => array(
|
|
||||||
* 'cost' => PASSWORD_BCRYPT_DEFAULT_COST,
|
|
||||||
* ),
|
|
||||||
* )
|
|
||||||
*
|
|
||||||
* @param string $hash The password hash to extract info from
|
|
||||||
*
|
|
||||||
* @return array The array of information about the hash.
|
|
||||||
*/
|
|
||||||
function password_get_info($hash)
|
|
||||||
{
|
|
||||||
$return = array(
|
|
||||||
'algo' => 0,
|
|
||||||
'algoName' => 'unknown',
|
|
||||||
'options' => array(),
|
|
||||||
);
|
|
||||||
if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
|
|
||||||
$return['algo'] = PASSWORD_BCRYPT;
|
|
||||||
$return['algoName'] = 'bcrypt';
|
|
||||||
list($cost) = sscanf($hash, "$2y$%d$");
|
|
||||||
$return['options']['cost'] = $cost;
|
|
||||||
}
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the password hash needs to be rehashed according to the options provided
|
|
||||||
*
|
|
||||||
* If the answer is true, after validating the password using password_verify, rehash it.
|
|
||||||
*
|
|
||||||
* @param string $hash The hash to test
|
|
||||||
* @param int $algo The algorithm used for new password hashes
|
|
||||||
* @param array $options The options array passed to password_hash
|
|
||||||
*
|
|
||||||
* @return boolean True if the password needs to be rehashed.
|
|
||||||
*/
|
|
||||||
function password_needs_rehash($hash, $algo, array $options = array())
|
|
||||||
{
|
|
||||||
$info = password_get_info($hash);
|
|
||||||
if ($info['algo'] !== (int)$algo) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
switch ($algo) {
|
|
||||||
case PASSWORD_BCRYPT:
|
|
||||||
$cost = isset($options['cost']) ? (int)$options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST;
|
|
||||||
if ($cost !== $info['options']['cost']) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a password against a hash using a timing attack resistant approach
|
|
||||||
*
|
|
||||||
* @param string $password The password to verify
|
|
||||||
* @param string $hash The hash to verify against
|
|
||||||
*
|
|
||||||
* @return boolean If the password matches the hash
|
|
||||||
*/
|
|
||||||
function password_verify($password, $hash)
|
|
||||||
{
|
|
||||||
if (!function_exists('crypt')) {
|
|
||||||
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$ret = crypt($password, $hash);
|
|
||||||
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$status = 0;
|
|
||||||
for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
|
|
||||||
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $status === 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace PasswordCompat\binary {
|
|
||||||
|
|
||||||
if (!function_exists('PasswordCompat\\binary\\_strlen')) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count the number of bytes in a string
|
|
||||||
*
|
|
||||||
* We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
|
|
||||||
* In this case, strlen() will count the number of *characters* based on the internal encoding. A
|
|
||||||
* sequence of bytes might be regarded as a single multibyte character.
|
|
||||||
*
|
|
||||||
* @param string $binary_string The input string
|
|
||||||
*
|
|
||||||
* @return int The number of bytes
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
function _strlen($binary_string)
|
|
||||||
{
|
|
||||||
if (function_exists('mb_strlen')) {
|
|
||||||
return mb_strlen($binary_string, '8bit');
|
|
||||||
}
|
|
||||||
return strlen($binary_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a substring based on byte limits
|
|
||||||
*
|
|
||||||
* @param string $binary_string The input string
|
|
||||||
* @param int $start
|
|
||||||
* @param int $length
|
|
||||||
*
|
|
||||||
* @return string The substring
|
|
||||||
* @internal
|
|
||||||
* @see _strlen()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function _substr($binary_string, $start, $length)
|
|
||||||
{
|
|
||||||
if (function_exists('mb_substr')) {
|
|
||||||
return mb_substr($binary_string, $start, $length, '8bit');
|
|
||||||
}
|
|
||||||
return substr($binary_string, $start, $length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if current PHP version is compatible with the library
|
|
||||||
*
|
|
||||||
* @return boolean the check result
|
|
||||||
*/
|
|
||||||
function check()
|
|
||||||
{
|
|
||||||
static $pass = NULL;
|
|
||||||
|
|
||||||
if (is_null($pass)) {
|
|
||||||
if (function_exists('crypt')) {
|
|
||||||
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
|
|
||||||
$test = crypt("password", $hash);
|
|
||||||
$pass = $test == $hash;
|
|
||||||
} else {
|
|
||||||
$pass = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
password_compat
|
|
||||||
===============
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/ircmaxell/password_compat.png?branch=master)](https://travis-ci.org/ircmaxell/password_compat) [![Code Climate](https://codeclimate.com/github/ircmaxell/password_compat/badges/gpa.svg)](https://codeclimate.com/github/ircmaxell/password_compat)
|
|
||||||
|
|
||||||
This library is intended to provide forward compatibility with the [password_*](http://php.net/password) functions that ship with PHP 5.5.
|
|
||||||
|
|
||||||
See [the RFC](https://wiki.php.net/rfc/password_hash) for more detailed information.
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
============
|
|
||||||
|
|
||||||
This library requires `PHP >= 5.3.7` OR a version that has the `$2y` fix backported into it (such as RedHat provides). Note that Debian's 5.3.3 version is **NOT** supported.
|
|
||||||
|
|
||||||
The runtime checks have been removed due to this version issue. To see if password_compat is available for your system, run the included `version-test.php`. If it outputs "Pass", you can safely use the library. If not, you cannot.
|
|
||||||
|
|
||||||
If you attempt to use password-compat on an unsupported version, attempts to create or verify hashes will return `false`. You have been warned!
|
|
||||||
|
|
||||||
The reason for this is that PHP prior to 5.3.7 contains a [security issue with its BCRYPT implementation](http://php.net/security/crypt_blowfish.php). Therefore, it's highly recommended that you upgrade to a newer version of PHP prior to using this layer.
|
|
||||||
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
To install, simply `require` the `password.php` file under `lib`.
|
|
||||||
|
|
||||||
You can also install it via `Composer` by using the [Packagist archive](http://packagist.org/packages/ircmaxell/password-compat).
|
|
||||||
|
|
||||||
Usage
|
|
||||||
=====
|
|
||||||
|
|
||||||
**Creating Password Hashes**
|
|
||||||
|
|
||||||
To create a password hash from a password, simply use the `password_hash` function.
|
|
||||||
````PHP
|
|
||||||
$hash = password_hash($password, PASSWORD_BCRYPT);
|
|
||||||
````
|
|
||||||
Note that the algorithm that we chose is `PASSWORD_BCRYPT`. That's the current strongest algorithm supported. This is the `BCRYPT` crypt algorithm. It produces a 60 character hash as the result.
|
|
||||||
|
|
||||||
`BCRYPT` also allows for you to define a `cost` parameter in the options array. This allows for you to change the CPU cost of the algorithm:
|
|
||||||
````PHP
|
|
||||||
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));
|
|
||||||
````
|
|
||||||
That's the same as the default. The cost can range from `4` to `31`. I would suggest that you use the highest cost that you can, while keeping response time reasonable (I target between 0.1 and 0.5 seconds for a hash, depending on use-case).
|
|
||||||
|
|
||||||
Another algorithm name is supported:
|
|
||||||
````PHP
|
|
||||||
PASSWORD_DEFAULT
|
|
||||||
````
|
|
||||||
This will use the strongest algorithm available to PHP at the current time. Presently, this is the same as specifying `PASSWORD_BCRYPT`. But in future versions of PHP, it may be updated to use a stronger algorithm if one is introduced. It can also be changed if a problem is identified with the BCRYPT algorithm. Note that if you use this option, you are **strongly** encouraged to store it in a `VARCHAR(255)` column to avoid truncation issues if a future algorithm increases the length of the generated hash.
|
|
||||||
|
|
||||||
It is very important that you should check the return value of `password_hash` prior to storing it, because `false` or `null` may be returned if it encountered an error.
|
|
||||||
|
|
||||||
**Verifying Password Hashes**
|
|
||||||
|
|
||||||
To verify a hash created by `password_hash`, simply call:
|
|
||||||
````PHP
|
|
||||||
if (password_verify($password, $hash)) {
|
|
||||||
/* Valid */
|
|
||||||
} else {
|
|
||||||
/* Invalid */
|
|
||||||
}
|
|
||||||
````
|
|
||||||
That's all there is to it.
|
|
||||||
|
|
||||||
**Rehashing Passwords**
|
|
||||||
|
|
||||||
From time to time you may update your hashing parameters (algorithm, cost, etc). So a function to determine if rehashing is necessary is available:
|
|
||||||
````PHP
|
|
||||||
if (password_verify($password, $hash)) {
|
|
||||||
if (password_needs_rehash($hash, $algorithm, $options)) {
|
|
||||||
$hash = password_hash($password, $algorithm, $options);
|
|
||||||
/* Store new hash in db */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
````
|
|
||||||
|
|
||||||
Security Vulnerabilities
|
|
||||||
========================
|
|
||||||
|
|
||||||
If you have found a security issue, please contact the author directly at [ircmaxell@php.net](mailto:ircmaxell@php.net).
|
|
42
app/class/stringcompat.class.php
Normal file
42
app/class/stringcompat.class.php
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class StringCompat
|
||||||
|
{
|
||||||
|
public static function destructionH4x0RChaine($chaine)
|
||||||
|
{
|
||||||
|
return preg_replace('#[\x00-\x1F\x7F-\x9F/\\\\]#', '', $chaine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function protectionDoubleQuote($chaine)
|
||||||
|
{
|
||||||
|
$chaine = preg_replace('/"(\w+)"/', '« ${1} »', $chaine);
|
||||||
|
$chaine = preg_replace('#"#', '_', $chaine);
|
||||||
|
return $chaine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function protectionSimpleQuote($chaine)
|
||||||
|
{
|
||||||
|
$chaine = preg_replace("#'#", '_', $chaine);
|
||||||
|
return $chaine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function myUrlEncode($string)
|
||||||
|
{
|
||||||
|
$replacements = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D'/*, '%2B'*/, '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
|
||||||
|
$entities = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "="/*, "+"*/, "$", ",", "/", "?", "%", "#", "[", "]");
|
||||||
|
$string = urlencode($string);
|
||||||
|
$string = str_replace($entities, $replacements, $string);
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function myUrlDecode($string)
|
||||||
|
{
|
||||||
|
$entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D'/*, '%2B'*/, '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
|
||||||
|
$replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "="/*, "+"*/, "$", ",", "/", "?", "%", "#", "[", "]");
|
||||||
|
$string = str_replace($entities, $replacements, $string);
|
||||||
|
$string = urldecode($string);
|
||||||
|
return $string;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
app/page/Gougou-search-results.php
Normal file
6
app/page/Gougou-search-results.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
$title = 'Attendez! Gougou<inf>cherche</sup>Le And co© cherche le résultat pour vous';
|
||||||
|
$metaDesc = 'Voici le résultat de votre recherche a partir d\'une Bide-Badass page';
|
||||||
|
|
||||||
|
$dateCreation = '20150517';
|
||||||
|
$dateRevision = '20150517';
|
11
app/page/Gougou-search-results.phtml
Normal file
11
app/page/Gougou-search-results.phtml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<h2><?php echo $title?></h2>
|
||||||
|
<div id="cse-search-results"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var googleSearchIframeName = "cse-search-results";
|
||||||
|
var googleSearchFormName = "cse-search-box";
|
||||||
|
var googleSearchFrameWidth = 800;
|
||||||
|
var googleSearchDomain = "www.google.fr";
|
||||||
|
var googleSearchPath = "/cse";
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="http://www.google.com/afsonline/show_afs_search.js"></script>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<textarea class='span8' name=message id=message tabindex="1" cols="80" rows="5"
|
<textarea class='span8' name=message id=message tabindex="1" cols="80" rows="5"
|
||||||
required><?php if (isset($_GET['message'])) {
|
required><?php if (isset($_GET['message'])) {
|
||||||
echo Encoding::myUrlDecode($_GET['message']);
|
echo StringCompat::myUrlDecode($_GET['message']);
|
||||||
} ?></textarea>
|
} ?></textarea>
|
||||||
|
|
||||||
<div class="clearfix" style="padding: 14px 200px;">
|
<div class="clearfix" style="padding: 14px 200px;">
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<i>( entendez par là : « La Mémoire est <u>la</u> grande des connaissances actuelles« )</i>
|
<i>( entendez par là : « La Mémoire est <u>la</u> grande des connaissances actuelles« )</i>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<form action="<?php echo Url::link_rewrite_slashParam('Gougou-search-results'); ?>" id="cse-search-box">
|
<form action="/Google-search-result.php" id="cse-search-box">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input type="hidden" name="cx" value="partner-pub-3240142213869705:7035975563"/>
|
<input type="hidden" name="cx" value="partner-pub-3240142213869705:7035975563"/>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<i>( entendez par là : « La Patience est <u>une</u> mère de sureté« )</i>
|
<i>( entendez par là : « La Patience est <u>une</u> mère de sureté« )</i>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<form action="<?php echo Url::link_rewrite_slashParam('Gougou-search-results'); ?>" id="cse-search-box">
|
<form action="/Google-search-result.php" id="cse-search-box">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input type="hidden" name="cx" value="partner-pub-3240142213869705:7035975563"/>
|
<input type="hidden" name="cx" value="partner-pub-3240142213869705:7035975563"/>
|
||||||
|
|
11
composer.json
Normal file
11
composer.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"\\":"./app/class"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"neitanod/forceutf8": "~2.0",
|
||||||
|
"ircmaxell/password-compat": "^1.0"
|
||||||
|
}
|
||||||
|
}
|
20
public/Google-search-result.php
Normal file
20
public/Google-search-result.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require dirname(dirname(__FILE__)). DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR . "autoload.php";
|
||||||
|
|
||||||
|
define('PUBLIC_PATH', dirname(__FILE__));
|
||||||
|
define('APPLICATION_PATH', dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "app");
|
||||||
|
define('PAGES_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "page");
|
||||||
|
define('LAYOUT_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "layout");
|
||||||
|
|
||||||
|
require APPLICATION_PATH . DIRECTORY_SEPARATOR . 'session.php';
|
||||||
|
|
||||||
|
|
||||||
|
//pour chaque page et mise en tampon
|
||||||
|
ob_start();
|
||||||
|
require_once PAGES_PATH . DIRECTORY_SEPARATOR . 'Gougou-search-results.php';
|
||||||
|
require_once PAGES_PATH . DIRECTORY_SEPARATOR . 'Gougou-search-results.phtml';
|
||||||
|
$content = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
require_once LAYOUT_PATH . DIRECTORY_SEPARATOR . $layout . '.phtml';
|
|
@ -1,13 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require dirname(dirname(__FILE__)). DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR . "autoload.php";
|
||||||
|
|
||||||
define('PUBLIC_PATH', dirname(__FILE__));
|
define('PUBLIC_PATH', dirname(__FILE__));
|
||||||
define('APPLICATION_PATH', dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "app");
|
define('APPLICATION_PATH', dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "app");
|
||||||
define('CLASS_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "class");
|
|
||||||
define('PAGES_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "page");
|
define('PAGES_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "page");
|
||||||
define('LAYOUT_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "layout");
|
define('LAYOUT_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "layout");
|
||||||
|
|
||||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'password.class.php';
|
|
||||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'encoding.class.php';
|
|
||||||
require APPLICATION_PATH . DIRECTORY_SEPARATOR . 'session.php';
|
require APPLICATION_PATH . DIRECTORY_SEPARATOR . 'session.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require dirname(dirname(__FILE__)). DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR . "autoload.php";
|
||||||
|
|
||||||
define('PUBLIC_PATH', dirname(__FILE__));
|
define('PUBLIC_PATH', dirname(__FILE__));
|
||||||
define('APPLICATION_PATH', dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "app");
|
define('APPLICATION_PATH', dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "app");
|
||||||
define('CLASS_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "class");
|
define('CLASS_PATH', APPLICATION_PATH . DIRECTORY_SEPARATOR . "class");
|
||||||
|
|
||||||
require APPLICATION_PATH . DIRECTORY_SEPARATOR . "parameters.php";
|
require APPLICATION_PATH . DIRECTORY_SEPARATOR . "parameters.php";
|
||||||
require APPLICATION_PATH . DIRECTORY_SEPARATOR . 'session.php';
|
require APPLICATION_PATH . DIRECTORY_SEPARATOR . 'session.php';
|
||||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'password.class.php';
|
|
||||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'encoding.class.php';
|
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
|
@ -68,7 +68,7 @@ function extractText($message)
|
||||||
/**************************************************************************************************************/
|
/**************************************************************************************************************/
|
||||||
/******************* TEST COTÉ SERVEUR POUR L'ENVOI DU MESSAGE *********************************************/
|
/******************* TEST COTÉ SERVEUR POUR L'ENVOI DU MESSAGE *********************************************/
|
||||||
|
|
||||||
$message = Encoding::fixUTF8(Encoding::protectionDoubleQuote(Encoding::protectionSimpleQuote($_POST['message'])));
|
$message = Encoding::fixUTF8(StringCompat::protectionDoubleQuote(StringCompat::protectionSimpleQuote($_POST['message'])));
|
||||||
|
|
||||||
if (passValide($_POST['password']) && $_POST['message'] != "") {
|
if (passValide($_POST['password']) && $_POST['message'] != "") {
|
||||||
|
|
||||||
|
@ -147,6 +147,6 @@ EOD;
|
||||||
if (isset($_POST['ajax'])) {
|
if (isset($_POST['ajax'])) {
|
||||||
echo "Votre Lien n'as pas été transmis. Veuillez vérifiez les informations que vous avez saisies ...";
|
echo "Votre Lien n'as pas été transmis. Veuillez vérifiez les informations que vous avez saisies ...";
|
||||||
} else {
|
} else {
|
||||||
header("Location: /index.php?envoiDuMessage=non&message=" . Encoding::myUrlEncode($message));
|
header("Location: /index.php?envoiDuMessage=non&message=" . StringCompat::myUrlEncode($message));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue