3 namespace Rapsys\UserBundle\Utils
; 
   5 use Symfony\Component\DependencyInjection\ContainerInterface
; 
  17         //The alpha array key number 
  20         //The offset reduced from secret 
  23         //Retrieve secret and set offset from reduction 
  24         public function __construct(ContainerInterface 
$container) { 
  26                 $this->secret 
= $_SERVER['APP_SECRET'] ?? $container->getParameter('kernel.secret'); 
  28                 //Pseudo-random alphabet 
  29                 //XXX: use array flip and keys to workaround php "smart" that cast range('0', '9') as int instead of string 
  30                 //XXX: The key count mismatch, count(alpha)>count(rev), resulted in a data corruption due to duplicate numeric values 
  31                 //TODO: set this as a parameter generated once in a command ? 
  32                 $this->alpha 
= array_keys(array_flip(array_merge( 
  59                 $this->count = count($rev = $this->rev = array_flip($this->alpha)); 
  62                 $split = str_split($this->secret); 
  65                 $this->offset = array_reduce($split, function ($res, $a) use ($rev) { return $res += $rev[$a]; }, count($split)) % $this->count; 
  69          * Flatten recursively an array 
  71          * @param array $data The data tree 
  72          * @param string|null $current The current prefix 
  73          * @param string $sep The key separator 
  74          * @param string $prefix The key prefix 
  75          * @param string $suffix The key suffix 
  76          * @return array The flattened data 
  78         public function flatten($data, $current = null, $sep = '.', $prefix = '', $suffix = '') { 
  83                 if (is_array($data)) { 
  85                         foreach($data as $k => $v) { 
  86                                 //Merge flattened value in return array 
  87                                 $ret += $this->flatten($v, empty($current) ? $k : $current.$sep.$k, $sep, $prefix, $suffix); 
  91                         //Store data in flattened key 
  92                         $ret[$prefix.$current.$suffix] = $data; 
 100          * Crypt and base64uri encode string 
 102          * @param string $data The data string 
 103          * @return string The hashed data 
 105         public function hash(string $data): string { 
 107                 //XXX: we use hash_hmac with md5 hash 
 108                 //XXX: crypt was dropped because it provided identical signature for string starting with same pattern 
 109                 return str_replace(['+
','/'], ['-','_
'], base64_encode(hash_hmac('md5
', $data, $this->secret, true))); 
 113          * Serialize then short 
 115          * @param array $data The data array 
 116          * @return string The serialized and shorted data 
 118         public function serialize(array $data): string { 
 119                 //Return shorted serialized data 
 120                 return $this->short(serialize($data)); 
 126          * @param string $data The data string 
 127          * @return string The shorted data 
 129         public function short(string $data): string { 
 133                 //Iterate on each character 
 134                 foreach(str_split($data) as $k => $c) { 
 135                         if (isset($this->rev[$c]) && isset($this->alpha[($this->rev[$c]+$this->offset)%$this->count])) { 
 136                                 //XXX: Remap char to an other one 
 137                                 $ret .= chr(($this->rev[$c] - $this->offset + $this->count) % $this->count); 
 142                 return str_replace(['+
','/'], ['-','_
'], base64_encode($ret)); 
 146          * Convert string to safe slug 
 148          * @param string $data The data string 
 149          * @return string The slugged data 
 151         function slug(string $data): string { 
 152                 //Use Transliterator if available 
 153                 if (class_exists('Transliterator
')) { 
 154                         $trans = \Transliterator::create('Any
-Latin
; Latin
-ASCII
; Lower()'); 
 155                         return preg_replace(['/[^a
-zA
-Z0
-9]+
/', '/(^
-+
|-+$
)/'], ['-', ''], $trans->transliterate($data)); 
 157                 return preg_replace('/[\
/_
|+ -]+
/', '-', strtolower(trim(preg_replace('/[^a
-zA
-Z0
-9\
/_
|+ -]/', '', str_replace(['\'
', '"'], ' ', iconv('UTF-8', 'ASCII//TRANSLIT', $data))), '-'))); 
 161          * Unshort then unserialize 
 163          * @param string $data The data string 
 164          * @return array The unshorted and unserialized data 
 166         public function unserialize(string $data): array { 
 167                 //Return unshorted unserialized string 
 168                 return unserialize($this->unshort($data)); 
 174          * @param string $data The data string 
 175          * @return string The unshorted data 
 177         public function unshort(string $data): string { 
 181                 //Iterate on each character 
 182                 foreach(str_split(base64_decode(str_replace(['-','_'], ['+','/'], $data))) as $c) { 
 183                         //XXX: Reverse map char to an other one 
 184                         $ret .= $this->alpha[(ord($c) + $this->offset) % $this->count];