3 namespace AppBundle\DataFixtures\ORM
; 
   5 #Article.php  ArticleTranslation.php  Author.php  Keyword.php  KeywordTranslation.php  Language.php  Site.php  SiteTranslation.php 
   7 class Fixtures 
extends \Doctrine\Bundle\FixturesBundle\Fixture 
{ 
   8         public function load(\Doctrine\Common\Persistence\ObjectManager 
$manager) { 
  31                 foreach($langTree as $langs) { 
  32                         $language = new \Rapsys\BlogBundle\Entity\
Language(); 
  33                         $language->setIso6391($langs['iso6391']); 
  34                         $language->setIso6393($langs['iso6393']); 
  35                         $language->setCreated(new \
DateTime('now')); 
  36                         $language->setUpdated(new \
DateTime('now')); 
  37                         $manager->persist($language); 
  38                         $languages[$langs['iso6391']] = $language; 
  42                 //Flush to get the ids 
  45                 //Create language translations 
  46                 foreach($langTree as $target => $langs) { 
  47                         foreach($langs['locales'] as $lang => $title) { 
  48                                 $languageTranslation = new \Rapsys\BlogBundle\Entity\
LanguageTranslation(); 
  49                                 $languageTranslation->setTitle($title); 
  50                                 $languageTranslation->setLanguage($languages[$lang]); 
  51                                 $languageTranslation->setLanguageId($languages[$lang]->getId()); 
  52                                 $languageTranslation->setTarget($languages[$target]); 
  53                                 $languageTranslation->setTargetId($languages[$target]->getId()); 
  54                                 $languageTranslation->setCreated(new \
DateTime('now')); 
  55                                 $languageTranslation->setUpdated(new \
DateTime('now')); 
  56                                 $manager->persist($languageTranslation); 
  58                                 unset($languageTranslation); 
  64                 foreach(array('blog.rapsys.eu', 'www.rapsys.eu', 'www.aoihime.eu') as $domain) { 
  65                         $site = new \Rapsys\BlogBundle\Entity\
Site(); 
  66                         $site->setDomain($domain); 
  67                         $site->setCreated(new \
DateTime('now')); 
  68                         $site->setUpdated(new \
DateTime('now')); 
  69                         $manager->persist($site); 
  76                         'Ernest Hemingway' => array( 
  77                                 'fr' => 'Né le 21 juillet 1899 à Oak Park dans l\'Illinois aux États-Unis, mort le 2 juillet 1961 à Ketchum, fût un écrivain, journaliste et correspondant de guerre américain.', 
  78                                 'en' => 'Born on July 21, 1899 in Oak Park, Illinois, deceased on July 2, 1961 in Ketchum, was an American novelist, short story writer and journalist.' 
  80                         'William Shakespeare' => array( 
  81                                 'fr' => 'Baptisé le 26 avril 1564 à Stratford-upon-Avon et mort le 23 avril 1616 dans la même ville, est considéré comme l\'un des plus grands poètes, dramaturges et écrivains de la culture anglaise.', 
  82                                 'en' => 'Baptised on April 26, 1564, deceased on April 23, 1616, was an English poet, playwright and actor, widely regarded as the greatest writer in the English language and the world\'s pre-eminent dramatist.' 
  84                         'George Orwell' => array( 
  85                                 'fr' => 'Eric Arthur Blair, né le 25 juin 1903 à Motihari pendant la période du Raj britannique et mort le 21 janvier 1950 à Londres, plus connu sous son nom de plume, est un écrivain et journaliste anglais.', 
  86                                 'en' => 'Eric Arthur Blair, born on June 25, 1903, deceased on January 21, 1950, better known by his pen name, was an English novelist, essayist, journalist, and critic.' 
  92                 foreach($authorTree as $name => $data) { 
  93                         $author = new \Rapsys\BlogBundle\Entity\
Author(); 
  94                         $author->setName($name); 
  95                         $author->setCreated(new \
DateTime('now')); 
  96                         $author->setUpdated(new \
DateTime('now')); 
  97                         $manager->persist($author); 
 100                         $authors[] = $author; 
 101                         foreach($data as $lang => $description) { 
 102                                 $authorTranslation = new \Rapsys\BlogBundle\Entity\
AuthorTranslation(); 
 103                                 $authorTranslation->setDescription($description); 
 104                                 $authorTranslation->setAuthor($author); 
 105                                 $authorTranslation->setAuthorId($author->getId()); 
 106                                 $authorTranslation->setLanguage($languages[$lang]); 
 107                                 $authorTranslation->setLanguageId($languages[$lang]->getId()); 
 108                                 $authorTranslation->setCreated(new \
DateTime('now')); 
 109                                 $authorTranslation->setUpdated(new \
DateTime('now')); 
 110                                 $manager->persist($authorTranslation); 
 116                 $keywordTree = array( 
 126                                 'fr' => 'Agrégation d\'adresses IP', 
 127                                 'en' => 'IP addresses aggregation' 
 133                 foreach($keywordTree as $name => $data) { 
 134                         $keyword = new \Rapsys\BlogBundle\Entity\
Keyword(); 
 135                         $keyword->setCreated(new \
DateTime('now')); 
 136                         $keyword->setUpdated(new \
DateTime('now')); 
 137                         $manager->persist($keyword); 
 138                         //Flush to get the id 
 140                         $keywords[] = $keyword; 
 141                         foreach($data as $lang => $title) { 
 142                                 $keywordTranslation = new \Rapsys\BlogBundle\Entity\
KeywordTranslation(); 
 143                                 $keywordTranslation->setTitle($title); 
 144                                 $keywordTranslation->setKeyword($keyword); 
 145                                 $keywordTranslation->setKeywordId($keyword->getId()); 
 146                                 $keywordTranslation->setLanguage($languages[$lang]); 
 147                                 $keywordTranslation->setLanguageId($languages[$lang]->getId()); 
 148                                 $keywordTranslation->setCreated(new \
DateTime('now')); 
 149                                 $keywordTranslation->setUpdated(new \
DateTime('now')); 
 150                                 $manager->persist($keywordTranslation); 
 156                 $articleTree = array( 
 159                                         'title' => 'Comment détecter la tranparence dans des images PNG en PHP de manière fiable', 
 160                                         'description' => 'J\'ai récemment du trouver comment détecter en PHP les images PNG transparentes. 
 161 Les codes trouvés ne semblaient pas fonctionner de manière satisfaisante pour les différents types de PNG à contrôler. 
 162 J\'ai fini par utiliser la fonction suivante.', 
 163                                         'body' => 'J\'ai récemment du trouver comment détecter en PHP les images PNG transparentes. 
 164 Les codes trouvés ne semblaient pas fonctionner de manière satisfaisante pour les différents types de PNG à contrôler. 
 165 J\'ai fini par utiliser la fonction suivante: 
 167 function png_has_transparency($im) { 
 168         //Retrieve content from imagick object 
 169         $content = $im->getImageBlob(); 
 171         //Detect 32bit png (each pixel has tranparency level) 
 172         if (ord(substr($content, 25, 1)) & 4) { 
 174                 $p = $im->getPixelIterator(); 
 178                         //Loop on each row pixel 
 179                         foreach($r as $pix) { 
 180                                 //Check if pixel has partial transparency 
 181                                 if ($pix->getColorValue(Imagick::COLOR_ALPHA) != 1) { 
 186         //Check 8bit png transparency 
 187         } elseif (stripos($content, \'PLTE\') !== false || stripos($content, \'tRNS\') !== false) { 
 191         //Didn\'t found clue of transparency 
 196 Cette fonction fonctionne avec les deux seules possibilitées : PNG 32bit et 8bit. 
 198 Le premier cas est un PNG 32bit avec transparence activé, on doit alors vérifier l\'opacité de chaque pixel savoir si l\'image a de la transparence ou non. 
 200 Le second cas est un PNG 8 bit, on a simplement à détecter un marqueur de transparence dans le contenu du fichier. 
 202 Dans cette configuration de fonction, on lit seulement une partie du PNG 32bit jusqu\'à détection d\'un pixel transparent ou on analyse le contenu jusqu\'à trouver un marqueur de transparence dans un PNG 8bit. 
 204 Les pires cas seront un PNG 32bit avec marqueur de transparence sans pixel transparent ou PNG 8bit sans marqueur de transparence. 
 206 Selon les probabilités de rencontrer les différents cas de transparence vous pouvez être intéressé pour renverser l\'ordre des tests de cette fonction. 
 208 Un grand merci à ces articles qui expliquent plus en détail comment fonctionne les différentes parties de ce code: 
 210 [li]https://www.jonefox.com/blog/2011/04/15/how-to-detect-transparency-in-png-images/[/li] 
 211 [li]http://camendesign.com/code/uth1_is-png-32bit[/li] 
 212 [li]https://stackoverflow.com/questions/5495275/how-to-check-if-an-image-has-transparency-using-gd[/li] 
 215 En espérant que ça aidera quelqu\'un quelque part.' 
 218                                         'title' => 'How to reliably detect PNG image transparency with PHP', 
 219                                         'description' => 'I recently had to find out if a PNG has transparency using PHP. 
 220 All the code I found didn\'t seemed to work correctly for the various kind of PNG I had to deal with. 
 221 I finished using the following function.', 
 222                                         'body' => 'I recently had to find out if a PNG has transparency using PHP. 
 223 All the code I found didn\'t seemed to work correctly for the various kind of PNG I had to deal with. 
 225 I finished using the following function: 
 227 function png_has_transparency($im) { 
 228         //Retrieve content from imagick object 
 229         $content = $im->getImageBlob(); 
 231         //Detect 32bit png (each pixel has tranparency level) 
 232         if (ord(substr($content, 25, 1)) & 4) { 
 234                 $p = $im->getPixelIterator(); 
 238                         //Loop on each row pixel 
 239                         foreach($r as $pix) { 
 240                                 //Check if pixel has partial transparency 
 241                                 if ($pix->getColorValue(Imagick::COLOR_ALPHA) != 1) { 
 246         //Check 8bit png transparency 
 247         } elseif (stripos($content, \'PLTE\') !== false || stripos($content, \'tRNS\') !== false) { 
 251         //Didn\'t found clue of transparency 
 256 This function works with the only two transparency possibilities: 32bit and 8bit PNG. 
 258 The first case is a 32bit PNG with transparency enabled, we have then to check every pixel to detect if it has transparent part or not. 
 260 The second case is a 8bit PNG, then we only have to look the file content for transparency markers. 
 262 In this function configuration, we only read part of the file in 32bit PNG until we detect one transparent pixel or parse content until transparency marker is detected in 8bit PNG. 
 264 The worst case scenario will be 32bit PNG with transparency flag without transparency or 8bit PNG without transparency flag. 
 266 Depending on how likely you are to have transparency in each cases you might want to reverse the flow of this function. 
 268 Big thanks to these articles which expains how these parts work in a bit more detail: 
 270 [li]https://www.jonefox.com/blog/2011/04/15/how-to-detect-transparency-in-png-images/[/li] 
 271 [li]http://camendesign.com/code/uth1_is-png-32bit[/li] 
 272 [li]https://stackoverflow.com/questions/5495275/how-to-check-if-an-image-has-transparency-using-gd[/li] 
 275 Hope this helps someone else out there.' 
 280                                         'title' => 'Mise en cache de webservice avec varnish', 
 281                                         'description' => 'J\'ai eu récemment à trouver comment mettre en cache les réponse d\'un webservice. 
 282 Voici la configuration varnish qui a répondu à mes besoins.', 
 283                                         'body' => 'J\'ai eu récemment à trouver comment mettre en cache les réponse d\'un webservice. 
 285 L\'API RESTfull du webservice sert de passerelle entre un API privé HATEOAS et un client générant plus de 500 000 requêtes par jour. 
 287 La première surprise est qu\'un client bien élevé, envoyant un en-tête Authorization: Bearer <token>, ne sera pas mis en cache par Varnish par défaut ! 
 289 Forçons le fonctionnement standard avec l\'en-tête pour le préfixe de l\'uri de notre webservice: 
 292         # Force la mise en cache de la réponse même avec req.http.Authorization présent 
 293         if (req.http.Authorization) { 
 294                 if (req.url ~ "^/webservice/uri/prefix/") { 
 301 Ce changement a des conséquences sur la sécurité, n\'importe qui autorisé à interroger Varnish sera en mesure de récupérer un résultat en cache sans s\'identifier. 
 303 Il peut être une bonne idée de valider la valeur de l\'en-tête Authorization avant de fournir le résultat en cache. 
 305 Notre webservice a trois réponses possibles : 
 307 [li]200: les données en JSON[/li] 
 308 [li]404: données non trouvées[/li] 
 309 [li]410: données plus jamais disponibles[/li] 
 312 Mettons en cache les résultats selon le code de retour : 
 315        if (req.url ~ "^/webservice/uri/prefix/") { 
 316                 if (beresp.status == 404) { 
 319                 if (beresp.status == 410) { 
 322                 if (beresp.status == 200) { 
 323                         set beresp.ttl = 24h; 
 329 Avec cette configuration, on a divisé par 5 la quantité de demandes sur notre passerelle 
 330 pour le client qui n\'était pas en mesure de mettre en cache lui-même nos résultats.' 
 333                                         'title' => 'Caching webservice with varnish', 
 334                                         'description' => 'I recently had to find a way to cache a webservice anwsers. 
 335 Here is the Varnish configuration fitting my needs.', 
 336                                         'body' => 'I recently had to find a way to cache a webservice anwsers. 
 338 The webservice is a RESTfull API serving as a gateway between a private HATEOAS API and a client generating more than 500 000 requests a day. 
 340 The first surprise is that if your well educated client, sending you a header Authorization: Bearer <token>, will not be cached by default by Varnish ! 
 342 Let\'s force back the standard behaviour with this header for our webservice uri prefix: 
 345         # Force cache response even with req.http.Authorization set 
 346         if (req.http.Authorization) { 
 347                 if (req.url ~ "^/webservice/uri/prefix/") { 
 354 This has security implication, now anyone allowed to request varnish will be able to retrieve a cached result without authentification. 
 356 It may be a good idea to validate the Authorization header value before serving the cached result. 
 358 Now, our webservice has three possibles answers : 
 360 [li]200: the data in JSON[/li] 
 361 [li]404: data was not found[/li] 
 362 [li]410: data is not available anymore[/li] 
 365 Let\'s cache our results depending on the reponse code: 
 368        if (req.url ~ "^/webservice/uri/prefix/") { 
 369                 if (beresp.status == 404) { 
 372                 if (beresp.status == 410) { 
 375                 if (beresp.status == 200) { 
 376                         set beresp.ttl = 24h; 
 382 With this configuration, we divided by 5 the quantity of request on our gateway 
 383 from the client who was not able to cache our result himself.' 
 388                                         'title' => 'Gestion des plages d\'IP en PHP/MySQL', 
 389                                         'description' => 'J\'ai récemment du ', 
 390                                         'description' => 'J\'ai eu récemment à trouver comment restreindre l\'accès à un service en ligne à certaines plages d\'IP. Voici la solution qui a répondu à mes besoins.', 
 391                                         'body' => 'J\'ai récemment du autoriser l\'accès à un service en ligne à seulement quelques plages d\'IP. 
 393 Premièrement, voyons comment calculer la première et la dernière adresse IP d\'une plage (bloc CIDR) avec sa base et son masque : 
 395 $range = array(\'127.0.0.1\', 8); 
 396 function rangeBegin($range) { 
 399 function rangeEnd($range) { 
 400         return long2ip(ip2long($range[0]) | ((1 << (32 - $range[1])) - 1)); 
 404 Maintenant comment vérifier si une IP est présente dans une plage (bloc CIDR) : 
 407 $range = array(\'127.0.0.1\', 8); 
 408 function ipInRange($ip, $range) { 
 409         if (ip2long($range[0]) <= ip2long($ip) && ip2long($ip) <= (ip2long($range[0]) | ((1 << (32 - $range[1])) - 1))) { 
 416 En premier bonus, comment récupérer les plages d\'IP d\'amazon : 
 418 function fetchAmazonRange() { 
 420         $amazonRanges = array(); 
 422         $ctx = stream_context_create( 
 425                                 \'method\' => \'GET\', 
 426                                 \'max_redirects\' => 0, 
 428                                 \'ignore_errors\' => false, 
 430                                         \'Connection: close\', 
 431                                         \'Accept: application/json\' 
 438         if (($json = file_get_contents(\'https://ip-ranges.amazonaws.com/ip-ranges.json\', false, $ctx)) === false) { 
 443         if (($json = json_decode($json)) === null || empty($json->prefixes)) { 
 448         foreach($json->prefixes as $range) { 
 449                 //Skip ipv6 and invalid ranges 
 450                 if (empty($range->ip_prefix)||!preg_match(\'/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/([0-9]+)$/\', $range->ip_prefix, $matche 
 455                 array_shift($matches); 
 457                 $amazonRanges[] = $matches; 
 461         return $amazonRanges; 
 465 Urls pour les plages d\'IP de Microsoft Azure : 
 467 [li]https://www.microsoft.com/en-us/download/details.aspx?id=41653[/li] 
 468 [li]https://msdn.microsoft.com/library/mt757330.aspx[/li] 
 472                                         'title' => 'Dealing with IP range in PHP/MySQL', 
 473                                         'description' => 'I recently had to deal with CIDR blocks to tighten some webservice security. 
 474 Here is how I designed it to fulfill my needs.', 
 475                                         'body' => 'I recently had to deal with CIDR blocks to tighten some webservice security. 
 477 First let\'s see how to compute the first and last address of an IP range with just the block base IP and mask: 
 479 $range = array(\'127.0.0.1\', 8); 
 480 function rangeBegin($range) { 
 483 function rangeEnd($range) { 
 484         return long2ip(ip2long($range[0]) | ((1 << (32 - $range[1])) - 1)); 
 488 How to detect if an IP is present in a CIDR block: 
 491 $range = array(\'127.0.0.1\', 8); 
 492 function ipInRange($ip, $range) { 
 493         if (ip2long($range[0]) <= ip2long($ip) && ip2long($ip) <= (ip2long($range[0]) | ((1 << (32 - $range[1])) - 1))) { 
 500 As a first bonus, how to retrieve amazon IP ranges: 
 502 function fetchAmazonRange() { 
 504         $amazonRanges = array(); 
 506         $ctx = stream_context_create( 
 509                                 \'method\' => \'GET\', 
 510                                 \'max_redirects\' => 0, 
 512                                 \'ignore_errors\' => false, 
 514                                         \'Connection: close\', 
 515                                         \'Accept: application/json\' 
 522         if (($json = file_get_contents(\'https://ip-ranges.amazonaws.com/ip-ranges.json\', false, $ctx)) === false) { 
 527         if (($json = json_decode($json)) === null || empty($json->prefixes)) { 
 532         foreach($json->prefixes as $range) { 
 533                 //Skip ipv6 and invalid ranges 
 534                 if (empty($range->ip_prefix)||!preg_match(\'/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/([0-9]+)$/\', $range->ip_prefix, $matche 
 539                 array_shift($matches); 
 541                 $amazonRanges[] = $matches; 
 545         return $amazonRanges; 
 549 Microsoft Azure Ip ranges urls: 
 551 [li]https://www.microsoft.com/en-us/download/details.aspx?id=41653[/li] 
 552 [li]https://msdn.microsoft.com/library/mt757330.aspx[/li] 
 559                 foreach($articleTree as $i => $data) { 
 560                         $article = new \Rapsys\BlogBundle\Entity\
Article(); 
 561                         $article->setCreated(new \
DateTime('now')); 
 562                         $article->setUpdated(new \
DateTime('now')); 
 563                         $article->addKeyword($keywords[$i]); 
 564                         $article->setSite($sites[$i]); 
 565                         $article->setAuthor($authors[$i]); 
 566                         $manager->persist($article); 
 567                         //Flush to get the id 
 569                         $articles[] = $article; 
 570                         foreach($data as $lang => $datas) { 
 571                                 $articleTranslation = new \Rapsys\BlogBundle\Entity\
ArticleTranslation(); 
 572                                 $articleTranslation->setTitle($datas['title']); 
 573                                 $articleTranslation->setDescription($datas['description']); 
 574                                 $articleTranslation->setBody($datas['body']); 
 575                                 $articleTranslation->setArticle($article); 
 576                                 $articleTranslation->setArticleId($article->getId()); 
 577                                 $articleTranslation->setLanguage($languages[$lang]); 
 578                                 $articleTranslation->setLanguageId($languages[$lang]->getId()); 
 579                                 $articleTranslation->setCreated(new \
DateTime('now')); 
 580                                 $articleTranslation->setUpdated(new \
DateTime('now')); 
 581                                 $manager->persist($articleTranslation); 
 591 //- add disqus article 
 592 //- add code for ip range detection 
 593 //- add code for amazon ip range detection 
 594 //- add code for microsoft ip range detection 
 595 //- add ??? article*/