<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="https://chierchia.fr/wp-content/plugins/pretty-rss-feeds/xslt/pretty-feed.xsl" type="text/xsl" media="screen" ?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>back-end - Ange Chierchia</title>
	<atom:link href="https://chierchia.fr/tag/back-end/feed/" rel="self" type="application/rss+xml" />
	<link>https://chierchia.fr/tag/back-end/</link>
	<description>Développeur Web full-stack</description>
	<lastBuildDate>Sun, 13 Oct 2024 10:59:29 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://chierchia.fr/wp-content/uploads/cropped-16350293-SSDKVqo3-32x32.jpg</url>
	<title>back-end - Ange Chierchia</title>
	<link>https://chierchia.fr/tag/back-end/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
					<title>Générer automatiquement le titre d&#8217;un post dans WordPress</title>
					<link>https://chierchia.fr/2024/03/generer-automatiquement-le-titre-dun-post-dans-wordpress/</link>
					<comments>https://chierchia.fr/2024/03/generer-automatiquement-le-titre-dun-post-dans-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Sat, 16 Mar 2024 17:16:18 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://chierchia.fr/?p=2519</guid>

					<description><![CDATA[Suite à tous mes posts de ce matin, j&#8217;ai cherché une façon de générer un titre à mes notes, que je publie généralement via la Web app quill.p3k.io développée par Aaron Pareki. Il existe de nombreux filtres pour agir sur le contenu d&#8217;un post ou d&#8217;une page, mais la plupart sont exécutés à l&#8217;affichage comme [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>
<p>Suite à tous mes posts de ce matin, j&rsquo;ai cherché une façon de générer un titre à mes notes, que je publie généralement via la Web app <a href="https://quill.p3k.io">quill.p3k.io</a> développée par <a href="https://aaronparecki.com/">Aaron Pareki</a>.</p>



<span id="more-2519"></span>



<p>Il existe de nombreux filtres pour agir sur le contenu d&rsquo;un post ou d&rsquo;une page, mais la plupart sont exécutés à l&rsquo;affichage comme <code>the_title</code> ou <code>the_content</code>, ou encore à la modification comme le filtre <code>save_post</code>.</p>



<p>On pourrait très bien générer notre titre après l&rsquo;enregistrement dans la base de données, mais dans mon cas je souhaitais définir le titre et le permalien avant, simplement pour éviter que le partage sur Mastodon se fasse sans titre défini dans les metadonnées utilisées par OpenGraph.</p>



<p>Heureusement, il existe un filtre sur lequel agir pour ça : <code>wp_insert_post_data</code>.</p>



<p>Voici comment j&rsquo;ai reussi :</p>



<pre class="wp-block-code"><code>function generate_post_title($data)
{
    if (empty($data&#91;'post_title'])) {

        $content = $data&#91;'post_content'];

        $pieces = explode(" ", $content);
        $first_part = implode(" ", array_splice($pieces, 0, 5));

        $data&#91;'post_title'] = $first_part; // Defines post title
        $data&#91;'post_name'] = sanitize_title($first_part); // Defines post slug
    }
    return $data; // Returns the modified data.
}
add_filter('wp_insert_post_data', 'generate_post_title', '99', 1);</code></pre>



<p>Je pourrais toujours l&rsquo;améliorer par la suite, par exemple :</p>



<ul class="wp-block-list">
<li>en prenant la première phrase de mon contenu, plutôt que les cinq premiers mots actuellement,</li>



<li>en ajoutant des points de suspensions lorsque la première phrase dépasse les six mots.</li>
</ul>



<p>J&rsquo;espère que ce petit morceau de code vous aidera.</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f44b.png" alt="👋" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2024/03/generer-automatiquement-le-titre-dun-post-dans-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Créer des virtual hosts pour notre serveur local</title>
					<link>https://chierchia.fr/2023/03/creer-des-virtual-hosts-pour-notre-serveur-local/</link>
					<comments>https://chierchia.fr/2023/03/creer-des-virtual-hosts-pour-notre-serveur-local/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Thu, 23 Mar 2023 22:32:27 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[vhost]]></category>
		<category><![CDATA[virtual host]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2023/03/creer-des-virtual-hosts-pour-notre-serveur-local</guid>

					<description><![CDATA[Dans cet article, qui fait suite à mon article Configurer un serveur local avec Homebrew, je vais vous montrer la méthode que j’utilise pour créer les virtual hosts des projets sur lesquels je travaille. Si vous n’avez pas lu la première partie, je vous invite à le faire avant de continuer. Minute papillon ! Qu’est-ce [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Dans cet article, qui fait suite à mon article <a href="https://chierchia.fr/blog/configurer-un-serveur-local-avec-homebrew/">Configurer un serveur local avec Homebrew</a>, je vais vous montrer la méthode que j’utilise pour créer les virtual hosts des projets sur lesquels je travaille. Si vous n’avez pas lu la première partie, je vous invite à le faire avant de continuer.</p>
<p><span id="more-1324"></span></p>
<h2 id="minute-papillon-">Minute papillon !</h2>
<h3 id="quest-ce-quon-va-faire-exactement">Qu’est-ce qu’on va faire exactement?</h3>
<p>Voilà comment ça va se passer : d’abord on va modifier notre fichier de configuration Apache pour activer et utiliser des hôtes virtuels. Une fois ceci fait, on pourra définir des URLs personnalisés que l’on attribuera aux différents dossiers présents dans notre dossier <code class="language-plaintext highlighter-rouge">Repositories</code>.</p>
<p>Une fois qu’on aura fait ça, on va nettoyer un peu le bazard en séparant nos vhosts dans plusieurs fichiers pour que tout ça soit le plus facile possible à maintenir.</p>
<p>Aller, go !</p>
<h3 id="un-peu-de-préparation">Un peu de préparation</h3>
<p>D’abord, on va ouvrir les quelques fichiers dont on va avoir besoin pour configurer nos hôtes virtuels. Ouvrez les fichiers suivants dans votre éditeur :</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">/usr/local/etc/httpd/httpd.conf</code></li>
<li><code class="language-plaintext highlighter-rouge">/usr/local/etc/httpd/extra/httpd-vhosts.conf</code></li>
<li><code class="language-plaintext highlighter-rouge">/etc/hosts</code></li>
</ul>
<p><strong>Attention !</strong> Si vous avez un Mac avec un processeur Apple (M1, M2, etc.) les fichiers dans lesquels on travaillera seront ceux-ci :</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">/opt/homebrew/etc/httpd/httpd.conf</code></li>
<li><code class="language-plaintext highlighter-rouge">/opt/homebrew/etc/httpd/extra/httpd-vhosts.conf</code></li>
<li><code class="language-plaintext highlighter-rouge">/private/etc/hosts</code></li>
</ul>
<p>Si vous n’avez pas déjà des projets dans votre dossier <code class="language-plaintext highlighter-rouge">Repositories</code>, créez en quelques uns :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>Repositories/
|_ nighcrawl/
|  |_ html/
|  |_ logs/
|
|_ cv/
   |_ html/
   |_ logs/
</code></pre>
</div>
</div>
<h2 id="nos-premiers-virtual-hosts">Nos premiers virtual hosts</h2>
<p>Nous allons maintenant créer nos tout premiers hôtes virtuels. Ils auront chacun une URL et un “document root” (le dossier dans lequel l’URL pointera) qui leur seront propres. L’URL <a href="http://nighcrawl.local">http://nighcrawl.local</a> pointera sur le dossier <code class="language-plaintext highlighter-rouge">~/Repositories/nighcrawl/html/</code> tandis que <a href="http://cv.local">http://cv.local</a> pointera sur <code class="language-plaintext highlighter-rouge">~/Repositories/cv/html/</code>.</p>
<h3 id="dans-httpdconf">Dans <code class="language-plaintext highlighter-rouge">httpd.conf</code></h3>
<p>Trouvez la ligne suivante et décommentez la (il suffit de supprimer le <code class="language-plaintext highlighter-rouge">#</code> devant la ligne) :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>#LoadModule vhost_alias_module lib/httpd/modules/mod_vhost_alias.so
</code></pre>
</div>
</div>
<p>Faites de même pour la ligne suivante :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>#Include /usr/local/etc/httpd/extra/httpd-vhosts.conf
</code></pre>
</div>
</div>
<p><strong>Attention !</strong> Pour les processeurs Apple, la ligne à décommenter sera celle-ci :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>#Include /opt/homebrew/etc/httpd/extra/httpd-vhosts.conf
</code></pre>
</div>
</div>
<h3 id="dans-le-fichier-httpd-vhostsconf">Dans le fichier <code class="language-plaintext highlighter-rouge">httpd-vhosts.conf</code></h3>
<p>Si votre fichier contient déjà des configs, vous pouvez les supprimer si vous êtes certain qu’elles ne vous servent pas. On peut ajouter les configs suivantes pour déclarer nos virtual hosts <a href="http://nighcrawl.local">http://nighcrawl.local</a> et <a href="http://cv.local">http://cv.local</a> :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>
    DocumentRoot "/Users/YOUR_USERNAME/Repositories/nighcrawl/html"
    ServerName nighcrawl.local
    ErrorLog "/Users/YOUR_USERNAME/Repositories/nighcrawl/logs/error_log"
    CustomLog "/Users/YOUR_USERNAME/Repositories/nighcrawl/logs/access_log" common



    DocumentRoot "/Users/YOUR_USERNAME/Repositories/cv/html"
    ServerName bar.lo
    ErrorLog "/Users/YOUR_USERNAME/Repositories/cv/logs/error_log"
    CustomLog "/Users/YOUR_USERNAME/Repositories/cv/logs/access_log" common

</code></pre>
</div>
</div>
<h3 id="modification-du-fichier-hosts">Modification du fichier <code class="language-plaintext highlighter-rouge">hosts</code></h3>
<p>Pour que vos nouvelles URLs personnalisées soient reconnues, il va falloir leur dire sur quelle adresse IP elles devront pointer. Comme ces deux sites Web sont en local sur votre machine, leur adresse IP sera donc 127.0.0.1. Il faut alors ajouter ces deux ligne à la fin de votre fichier :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>127.0.0.1   nighcrawl.local
127.0.0.1   cv.local
</code></pre>
</div>
</div>
<p>Après avoir effectué tout ces changements, on relancera Apache avec la commande suivante dans un Terminal :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$ brew services restart httpd
</code></pre>
</div>
</div>
<p>Vous devriez alors voir un beau message “Index of /” si vous ouvrez <a href="http://nighcrawl.local">http://nighcrawl.local</a> et <a href="http://cv.local">http://cv.local</a> dans votre navigateur.</p>
<p><strong>Ça fonctionne !</strong> Vous n’avez plus qu’à mettre les fichiers HTML/PHP/JS/etc.. dans chaque projet .</p>
<h2 id="ranger-le-bazard">Ranger le bazard</h2>
<p>Maintenant que nos vhosts fonctionnent, il est temps de prévoir le futur et de faire quelques ajustements afin qu’il soit beaucoup plus facile de créer ou modifier des vhosts sans risquer de se perdre.</p>
<p>Moi par exemple, j’ai plus de 50 virtual hosts configurés sur ma machine… Un peu chaud de s’y retrouver si il faut modifier un vhost.</p>
<p>C’est pourquoi on va créer un fichier par virtual host plutôt que de les avoir tous dans un seul fichier, ce sera beaucoup plus maintenable.</p>
<h3 id="un-fichier-par-virtual-host">Un fichier par virtual host</h3>
<p>J’ai l’habitude de rassembler tous mes fichiers de vhosts dans un dossier <code class="language-plaintext highlighter-rouge">sites-available/</code> dans le dossier <code class="language-plaintext highlighter-rouge">/usr/local/etc/httpd/</code> ( <code class="language-plaintext highlighter-rouge">/opt/homebrew/etc/httpd/</code> pour les processeurs Apple).</p>
<p>Du coup on va déplacer nos configs pour <a href="http://nighcrawl.local">http://nighcrawl.local</a> dans un fichier <code class="language-plaintext highlighter-rouge">/usr/local/etc/httpd/sites-available/nighcrawl.conf</code></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code># nighcrawl.conf

    DocumentRoot "/Users/YOUR_USERNAME/Repositories/nighcrawl/html"
    ServerName nighcrawl.local
    ErrorLog "/Users/YOUR_USERNAME/Repositories/nighcrawl/logs/error_log"
    CustomLog "/Users/YOUR_USERNAME/Repositories/nighcrawl/logs/access_log" common

</code></pre>
</div>
</div>
<p>et celle pour <a href="http://cv.local">http://cv.local</a> dans un fichier <code class="language-plaintext highlighter-rouge">/usr/local/etc/httpd/sites-available/cv.conf</code>.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code># cv.conf

    DocumentRoot "/Users/YOUR_USERNAME/Repositories/cv/html"
    ServerName bar.lo
    ErrorLog "/Users/YOUR_USERNAME/Repositories/cv/logs/error_log"
    CustomLog "/Users/YOUR_USERNAME/Repositories/cv/logs/access_log" common

</code></pre>
</div>
</div>
<p><strong>Attention à adapter si vous avez un processeur Apple .</strong></p>
<h3 id="mettre-à-jour-httpd-vhostsconf">Mettre à jour <code class="language-plaintext highlighter-rouge">httpd-vhosts.conf</code></h3>
<p>Maintenant que nos hôtes virtuels ont leur propre fichier de config, on peu les supprimer du fichier <code class="language-plaintext highlighter-rouge">httpd-vhosts.conf</code>.</p>
<p>Après ça, on va simplement inclure chaque fichier <code class="language-plaintext highlighter-rouge">.conf</code>présent dans notre dossier <code class="language-plaintext highlighter-rouge">sites-available/</code> grâce à cette ligne :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code># Pour les processeurs Intel
Include /usr/local/etc/httpd/sites-available/*.conf

# Pour les processeurs Apple
Include /opt/homebrew/etc/httpd/sites-available/*.conf
</code></pre>
</div>
</div>
<p>On redémarre à nouveau le services Apache avec <code class="language-plaintext highlighter-rouge">brew services restart httpd</code> et tout devrait rouler comme avant, mais en mieux.</p>
<h2 id="aller-encore-plus-loin">Aller encore plus loin</h2>
<p>Pour aller plus loin et gagner du temps lors de la création d’un nouvel hôte virtuel, j’utilise un script bash qui me permet de faire tout ceci en une seule ligne de commande.</p>
<p>Voici une version édulcorée de mon script <code class="language-plaintext highlighter-rouge">vhost.sh</code> :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>#!/bin/bash
USER="achierchia"
CONF_FOLDER="/opt/homebrew/etc/httpd/sites-available/"
SITES_FOLDER="Repositories"

if [ "$USER" == "" ] || [ "$CONF_FOLDER" == "" ] || [ "$SITES_FOLDER" == "" ]; then
	echo "You must set the variables USER, CONF_FOLDER and SITES_FOLDER in the script!"
	echo ""
	exit
fi

if [ "$(whoami)" != "root" ]; then
    echo -ne "e[0;101m You must be root to use this script! e[0;49m "
    echo ""
    exit
fi

domain=""
createFolder="N"

while getopts d:f: flag 
do
	case "${flag}" in
		d) domain=${OPTARG};;
		f) createFolder=${OPTARG};;
	esac
done

if [[ "$createFolder" =~ ^[Yy]$ ]]; 
then
    echo "Création du dossier ${domain} dans ${SITES_FOLDER}..."
    cd /Users/${USER}/${SITES_FOLDER}/
	mkdir $domain
	cd /Users/${USER}/${SITES_FOLDER}/${domain}/
	mkdir logs
fi

accessLog="${domain}_access"
errorLog="${domain}_error"

echo "Création du fichier de config..."
cd $CONF_FOLDER
sudo -u $USER -i -- cat &gt;&gt; ${domain}.conf &lt;&lt; EOF

	ServerName ${domain}.local

	DocumentRoot /Users/${USER}/${SITES_FOLDER}/${domain}
	DirectoryIndex index.php index.html
	
		Options -Indexes +FollowSymLinks +MultiViews
		AllowOverride All
		Require all granted
	

	LogLevel warn

	ErrorLog /Users/${USER}/${SITES_FOLDER}/${domain}/logs/${errorLog}.log
	CustomLog /Users/${USER}/${SITES_FOLDER}/${domain}/logs/${accessLog}.log combined

EOF

echo "Mise à jour du fichier hosts..."
HOSTURL=$domain".local"
HOSTCONF="127.0.0.1t"$HOSTURL"twww."$HOSTURL
sed -i -- "s/# local end/"$HOSTCONF"n# local end/g" /etc/hosts

echo "Modification des privileges du fichier conf"
cd ${CONF_FOLDER}
sudo chown $USER "${domain}.conf"
cd /Users/${USER}/${SITES_FOLDER}/${domain}/logs/
sudo chown $USER "${accessLog}.log" "${errorLog}.log"

echo "Redémarrage du serveur Apache..."
sudo -u $USER -i -- brew services restart httpd

</code></pre>
</div>
</div>
<p>Pour l’utiliser il suffit d’executer cette commande :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$ sudo sh vhost.sh -d monsiteweb -f Y
</code></pre>
</div>
</div>
<p>Ce script permet de :</p>
<ul>
<li>Créer un dossier <code class="language-plaintext highlighter-rouge">monsiteweb/</code> dans le dossier <code class="language-plaintext highlighter-rouge">$SITES_FOLDER</code> paramétré.</li>
<li>Créer le fichier de config vhost <code class="language-plaintext highlighter-rouge">monsiteweb.conf</code> dans le dossier <code class="language-plaintext highlighter-rouge">$CONF_FOLDER</code>.</li>
<li>Déclarer <code class="language-plaintext highlighter-rouge">monsiteweb.local</code> dans le fichier <code class="language-plaintext highlighter-rouge">hosts</code></li>
<li>Relancer le serveur Apache</li>
</ul>
<p>Si on ne souhaite pas créer le dossier du projet, par exemple parce qu’il existe déjà, on peux lancer cette commande :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$ sudo sh vhost.sh -d monsiteweb -f N
</code></pre>
</div>
</div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2023/03/creer-des-virtual-hosts-pour-notre-serveur-local/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Configurer un serveur local avec Homebrew</title>
					<link>https://chierchia.fr/2021/10/configurer-un-serveur-local-avec-homebrew/</link>
					<comments>https://chierchia.fr/2021/10/configurer-un-serveur-local-avec-homebrew/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Wed, 27 Oct 2021 10:49:38 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[homebrew]]></category>
		<category><![CDATA[localhost]]></category>
		<category><![CDATA[serveur]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2021/10/configurer-un-serveur-local-avec-homebrew</guid>

					<description><![CDATA[Dans cet article on va voir comment installer PHP et Apache pour configurer un serveur Web local sur Mac grâce au gestionnaire de paquets Homebrew, afin de se passer d’un outil comme MAMP. Lorsque je travaillais chez Ibakus Europe, on développait des projets Symfony, du coup on n’avait pas besoin d’un MAMP pour faire tourner [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Dans cet article on va voir comment installer PHP et Apache pour configurer un serveur Web local sur Mac grâce au gestionnaire de paquets Homebrew, afin de se passer d’un outil comme MAMP.</p>
<p><span id="more-1330"></span></p>
<p>Lorsque je travaillais chez Ibakus Europe, on développait des projets Symfony, du coup on n’avait pas besoin d’un MAMP pour faire tourner le projet, compiler les fichiers Sass et/ou JavaScript. Webpack s’en chargeait.</p>
<p>En arrivant chez Concept Factory, MAMP Pro était déjà bien utilisé dans l’équipe Front. Parfois lorsqu’on travaille avec l’équipe Symfony sur un projet, on démarre Vagrant ou Docker dans lequel tout est déjà installé pour faire tourner le projet, seulement voilà, il faut arrêter MAMP pour pouvoir ensuite démarrer la machine virtuelle, va savoir pourquoi… Probablement une histoire de ports utilisés</p>
<p>Un moment donné je me suis dit “Et si j’abandonnais complètement MAMP et que j’installais un serveur local qui tournerai non-stop sur ma machine, ça me ferai gagner du temps, non ?”. Du coup, on va maintenant voir comment j’ai configuré mon serveur local.</p>
<h2 id="pré-requis">Pré-requis</h2>
<p>Avant de se lancer dans ce gros projet, il va falloir décider de l’emplacement où seront stockés les fichiers des différents sites Web que l’on créera sur notre serveur de développement. Ça n’est pas une étape très compliquée, mais c’est l’une des plus importante.</p>
<h3 id="choisir-où-placer-nos-fichiers-php-et-html">Choisir où placer nos fichiers PHP et HTML</h3>
<p>Personnellement, j’ai un dossier <code class="language-plaintext highlighter-rouge">Repositories</code> à la racine de mon dossier utilisateur, dans lequel se trouvent les différents projets sur lesquels je travail. Puis dans ce dossier se trouve un fichier <code class="language-plaintext highlighter-rouge">ìndex.html</code> avec le message “Hello World!” dedans afin de vérifier que ma configuration Apache fonctionne. Je vous invite à faire de même, ou d’adapter en conséquences :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span><span class="nb">mkdir</span> ~/Repositories
<span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"Hello World!"</span> <span class="o">&gt;</span> ~/Repositories/index.html
</code></pre>
</div>
</div>
<p>L’autre information importante qu’il nous faut, c’est notre nom d’utilisateur (en général, le nom de votre dossier dans <code class="language-plaintext highlighter-rouge">/Users</code>). Pour le connaitre, la commande <code class="language-plaintext highlighter-rouge">$ whoami</code> fera le boulot. Pour moi, par exemple c’est <code class="language-plaintext highlighter-rouge">achierchia</code></p>
<h3 id="installer-homebrew">Installer Homebrew</h3>
<p>Tout d’abord, il nous faut Homebrew pour aller plus loin. Cette étape est super simple, dans l’application Terminal on lance cette commande :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>/bin/bash <span class="nt">-c</span> <span class="s2">"</span><span class="si">$(</span>curl <span class="nt">-fsSL</span> https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh<span class="si">)</span><span class="s2">"</span>
</code></pre>
</div>
</div>
<p>Si tout se passe bien, la commande <code class="language-plaintext highlighter-rouge">brew --version</code> devrait afficher quelque chose comme ça :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>brew <span class="nt">--version</span>
Homebrew 3.3.1
Homebrew/homebrew-core <span class="o">(</span>git revision b97b0465deb<span class="p">;</span> last commit 2021-10-26<span class="o">)</span>
Homebrew/homebrew-cask <span class="o">(</span>git revision f2232d8993<span class="p">;</span> last commit 2021-10-26<span class="o">)</span>
</code></pre>
</div>
</div>
<p>On est prêt à installer notre serveur local ! Passons à l’installation d’Apache.</p>
<h2 id="installer-apache">Installer Apache</h2>
<p>Par défaut, chaque version de macOS est fournie avec Apache et PHP préinstallés, mais pour des raisons pratique on préfèrera désactiver celles-ci et gérer nous même l’installation et la configuration des versions que l’on souhaite pour notre environement de développement.</p>
<h3 id="stopper-et-décharger-la-version-dapache-pré-installée">Stopper et décharger la version d’Apache pré-installée</h3>
<p>Afin de pouvoir installer notre propre serveur Apache, il faut d’abord arrêter celui qui tourne actuellement. Pour cela, rien de plus simple, il suffit d’exécuter les deux commandes suivantes dans votre Terminal :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>apachectl stop
</code></pre>
</div>
</div>
<p>Cette commande permet de stopper le serveur Apache, la suivante permettra de ne plus le démarrer la tâche de fond à l’ouverture de session :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>launchctl unload <span class="nt">-w</span> /Systems/Library/LaunchDaemons/org.apache.httpd.plist
</code></pre>
</div>
</div>
<h3 id="installation-du-paquet-httpd-via-homebrew">Installation du paquet httpd via Homebrew</h3>
<p>Maintenant qu’on a désactivé la version préinstallée d’Apache, on peut installer celle qu’on souhaite via la commande suivante :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>brew <span class="nb">install </span>httpd
</code></pre>
</div>
</div>
<p>Cette commande installera la version courante d’Apache (v2.4.51 au moment où j’écris ces lignes).</p>
<p>Il faudra ensuite démarrer Apache en tâche de fond (gérée maintenant via Homebrew) grâce à cette commande :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>brew services start httpd
</code></pre>
</div>
</div>
<p>Si vous allez maintenant sur <a href="http://localhost:8080/">http://localhost:8080/</a> via votre navigateur Web préféré vous devriez voir un superbe “It works!”.</p>
<p>Bravo Apache est installé et fonctionne, on va pouvoir adapter la configuration et lui dire où aller chercher nos fichiers !</p>
<h3 id="configurer-apache">Configurer Apache</h3>
<p>Ici on va devoir modifier pas mal de petites choses, et c’est en général à ce moment là que ça pète si on ne fait pas bien attention.</p>
<p>On va donc ouvrir le fichier de configuration d’Apache dans l’éditeur de texte de notre choix, pour moi c’est VSCode :).</p>
<p>Si vous avez un Mac avec un processeur Intel, le fichier se trouvera à cet endroit : <code class="language-plaintext highlighter-rouge">/usr/local/etc/httpd/httpd.conf</code>. <strong>Pour les Mac avec un processeur Apple (M1, M1 Pro, M1 Max)</strong>, il faudra ouvrir ce fichier <code class="language-plaintext highlighter-rouge">/opt/homebrew/etc/httpd/httpd.conf</code>.</p>
<p>Il faudra remplacer les choses suivantes :</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">Listen 8080</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">Listen 80</code></li>
<li><code class="language-plaintext highlighter-rouge">DocumentRoot "/usr/local/var/www"</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">DocumentRoot "/Users/VOTRE_USERNAME/Repositories"</code></li>
<li><code class="language-plaintext highlighter-rouge">&lt;Directory "/usr/local/var/www"&gt;</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">&lt;Directory "/Users/VOTRE_USERNAME/Repositories"&gt;</code></li>
<li>Dans la section <code class="language-plaintext highlighter-rouge"></code>qu’on a modifié à l’instant : <code class="language-plaintext highlighter-rouge">AllowOverride None</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">AllowOverride All</code></li>
<li><code class="language-plaintext highlighter-rouge">#LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so</code></li>
<li><code class="language-plaintext highlighter-rouge">User _www</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">User VOTRE_USERNAME</code></li>
<li><code class="language-plaintext highlighter-rouge">Group _www</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">Group staff</code></li>
<li><code class="language-plaintext highlighter-rouge">#ServerName www.example.com:8080</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code class="language-plaintext highlighter-rouge">ServerName localhost:80</code></li>
</ul>
<p>Et voilà, Apache est installé et configuré ! Pour que ces changements soient pris en compte, enregistrerez le fichier httpd.conf puis relancez le service :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>brew services restart httpd
</code></pre>
</div>
</div>
<p>Si vous vous rendez maintenant sur <a href="http://localhost/">http://localhost/</a> vous devriez voir votre “Hello World!”, confirmation que tout fonctionne comme vous l’aviez souhaité !</p>
<h2 id="installation-du-paquet-php">Installation du paquet php</h2>
<h3 id="installer-php">Installer PHP</h3>
<p>Maintenant que notre serveur Apache fonctionne comme on le souhaite, il nous reste à installer PHP. Pour cela une commande suffit :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>brew <span class="nb">install </span>php
</code></pre>
</div>
</div>
<p>Cette commande installera la version courante de PHP (v8.0.12). Si vous souhaitez installer une version différente, vous trouverez les anciennes versions qu’il est possible d’installer ici : https://formulae.brew.sh/formula/php. Moi, par exemple j’ai installé PHP 7.4.x, plutôt que PHP 8.x. J’ai donc exécuté cette commande :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>brew <span class="nb">install </span>php@7.4
</code></pre>
</div>
</div>
<p>Une fois que PHP est installé, démarrons la tâche de fond :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>brew services start php
<span class="c"># ou pour PHP 7.4</span>
<span class="nv">$ </span>brew services start php@7.4
</code></pre>
</div>
</div>
<h3 id="configurer-php">Configurer PHP</h3>
<p>Attention, là ça va aller pas mal vite !</p>
<p>Ouvrez à nouveau votre fichier de configuration Apache (<code class="language-plaintext highlighter-rouge">/usr/local/etc/httpd/httpd.conf</code> ou <code class="language-plaintext highlighter-rouge">/opt/homebrew/etc/httpd/httpd.conf</code> pour les processeurs M1).</p>
<p>Cherchez la dernière ligne <code class="language-plaintext highlighter-rouge">LoadModule</code> (ce sera probablement celle du <code class="language-plaintext highlighter-rouge">mod_rewrite.so</code>) et ajouter cette ligne juste après :</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="c"># Si vous avez installé PHP 8 sur processeur Intel</span>
LoadModule php_module /usr/local/opt/php/lib/httpd/modules/libphp.so
<span class="c"># Sinon pour PHP 7.4 </span>
LoadModule php7_module /usr/local/opt/php@7.4/lib/httpd/modules/libphp7.so

<span class="c"># Pour les processeurs M1, PHP 8</span>
LoadModule php_module /opt/homebrew/opt/php/lib/httpd/modules/libphp.so
<span class="c"># ou PHP 7.4</span>
LoadModule php7_module /opt/homebrew/opt/php@7.4/lib/httpd/modules/libphp7.so
</code></pre>
</div>
</div>
<p>Recherchez ensuite la ligne <code class="language-plaintext highlighter-rouge">DirectoryIndex index.html</code> et remplacez-la par <code class="language-plaintext highlighter-rouge">DirectoryIndex index.html index.php</code>.</p>
<p>Après le <code class="language-plaintext highlighter-rouge">DirectoryIndex</code> que l’on vient de modifier et juste avant la section concernant les fichiers htaccess, ajoutez cette section :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>
    SetHandler application/x-httpd-php

</code></pre>
</div>
</div>
<p>Et enfin, relancez le serveur Apache avec un magnifique <code class="language-plaintext highlighter-rouge">$ brew services restart httpd</code></p>
<p>Youpi ! PHP est installé et prêt à être utilisé. Pour vérifier que le serveur interprète bien les fichiers PHP, créez un fichier <code class="language-plaintext highlighter-rouge">ìnfo.php</code> dans votre dossier <code class="language-plaintext highlighter-rouge">Repositories</code> contenant la ligne suivante :</p>
<div class="language-php highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><!--?php &lt;/span&gt; &lt;span class="nb"&gt;phpinfo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="cp"&gt;?-->
</code></pre>
</div>
</div>
<p>Rendez-vous à l’adresse <a href="http://localhost/info.php">http://localhost/info.php</a> dans votre navigateur. Si vous voyez le logo PHP ainsi qu’un enorme tableau de données concernant votre version de PHP, c’est gagné, vous avez votre propre serveur de développement !</p>
<h2 id="et-ensuite-">Et ensuite ?</h2>
<p>Dans un prochain article, je partagerai ici ma méthode pour créer des virtual hosts rapidement et simplement, pour par exemple visiter l’URL <a href="http://monsiteweb.local/">http://monsiteweb.local/</a> et quand même voir le site web stocké dans le dossier <code class="language-plaintext highlighter-rouge">Repositories/monsiteweb</code>.</div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2021/10/configurer-un-serveur-local-avec-homebrew/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Scraper un site Web en Python</title>
					<link>https://chierchia.fr/2017/11/scraper-web-avec-python/</link>
					<comments>https://chierchia.fr/2017/11/scraper-web-avec-python/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Fri, 17 Nov 2017 11:49:38 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scraper]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2017/11/scraper-web-avec-python</guid>

					<description><![CDATA[Aujourd’hui on va voir comment utiliser Python afin de scraper une page ou un site Web afin de récupérer les informations qui nous intéressent et ainsi se constituer une base de données. Le scraping de sites Web fait partie de mon quotidien chez Ibakus Europe ces derniers mois, dans le cadre du développement d’une fonctionnalité [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Aujourd’hui on va voir comment utiliser Python afin de scraper une page ou un site Web afin de récupérer les informations qui nous intéressent et ainsi se constituer une base de données.</p>
<p><span id="more-1333"></span></p>
<p>Le scraping de sites Web fait partie de mon quotidien chez Ibakus Europe ces derniers mois, dans le cadre du développement d’une fonctionnalité de notre application dédiée à la lutte contre le blanchiment d’argent et le financement du terrorisme.<br />
Le scraping de différentes sources nous a permit de constituer une base de données des sociétés européennes, permettant à nos utilisateurs de compléter leur fichier KYC avec les informations publiques dont on dispose sur leurs clients, en plus des informations qu’ils ont en leur possession.</p>
<p>Assez parlé d’Ibakus, passons au vif du sujet : la création d’un scraper web.</p>
<h2 id="création-du-scraper">Création du scraper</h2>
<p>Le but du scraper que l’on va écrire ici sera de récupérer les informations concernant les nouvelles sociétés luxembourgeoises créées. Nous allons donc faire un scraping du <a href="https://www.rcsl.lu/">site du RCSL</a>.</p>
<p>Pour cela nous allons utiliser la librairie Splinter, qui permettra à notre script de parcourir les pages comme si on le faisait nous même. Je vous invite à lire <a href="http://splinter.readthedocs.io/en/latest/">la documentation de la librairie</a> pour ce qui concerne son installation et les différentes fonctions disponibles.</p>
<p>Nous allons enregistrer le code source de notre scraper dans un fichier <code class="language-plaintext highlighter-rouge">scraper.py</code> en déclarant que nous voulons utiliser l’encodage <code class="language-plaintext highlighter-rouge">UTF-8</code> et utiliser la fonction <code class="language-plaintext highlighter-rouge">Browser()</code> de la librairie Splinter. Notre fichier débutera alors comme ça :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code># coding: utf8
from splinter import browser
</code></pre>
</div>
</div>
<p>Tout ce qui va se passer ensuite sera executer comme si on naviguait vraiment depuis une fenêtre de navigateur Web. On appelle alors la fonction <code class="language-plaintext highlighter-rouge">Browser()</code> puis on se rend sur le site Web à scraper comme suit :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>with Browser() as browser:
    url = "https://www.rcsl.lu"
    browser.visit(url)
</code></pre>
</div>
</div>
<p>Attention, il est important de bien faire attention à l’indentation du code. Ici, si on avait appellé la méthode <code class="language-plaintext highlighter-rouge">visit()</code> de l’objet <code class="language-plaintext highlighter-rouge">browser</code> sans l’indenter, ça n’aurait pas fonctionné car <code class="language-plaintext highlighter-rouge">browser</code> ne serait pas définit.<br />
On aurait par contre pu écrire ceci :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>browser = Browser()
browser.visit(url)
</code></pre>
</div>
</div>
<p>Notre scraper se trouve maintenant sur la page d’accueil du site Web du RCSL. Pour récupérer la liste des sociétés consituées aujourd’hui, il faut que l’on clique sur le lien “Journal des publications” que l’on peut trouver au bas de la page. La librairie Splinter dispose de plusieurs fonctions permettant de <a href="http://splinter.readthedocs.io/en/latest/finding.html">retrouver un élément dans le DOM</a> et d’<a href="http://splinter.readthedocs.io/en/latest/elements-in-the-page.html">intéragir avec</a>. Dans notre cas nous aurons besoin des fonctions <code class="language-plaintext highlighter-rouge">is_element_present_by_css()</code>, <code class="language-plaintext highlighter-rouge">find_by_css()</code> et <code class="language-plaintext highlighter-rouge">click_link_by_partial_href()</code>.</p>
<p>Le lien que l’on cherche à cliquer contient la chaîne <code class="language-plaintext highlighter-rouge">DisplayOfficialJournalAction</code> dans son attribut <code class="language-plaintext highlighter-rouge">href</code>, nous allons donc cliquer dessus en faisant appelle à <code class="language-plaintext highlighter-rouge">click_link_by_partial_href()</code> ce qui nous amènera sur la page voulue :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>browser.click_link_by_partial_href('mjrcs/jsp/DisplayOfficialJournalAction')
</code></pre>
</div>
</div>
<p>Dans cette nouvelle page on veut cliquer sur l’icône de téléchargement du fichier XML le plus récent (en haut de la liste).<br />
Pour être certain qu’il y a bien une liste de fichiers disponibles présente sur la page, on vérifie qu’un élément <code class="language-plaintext highlighter-rouge">table</code> ayant la classe <code class="language-plaintext highlighter-rouge">commonTable</code> existe dans le DOM. Si il existe, on récupère alors le quatrième élément <code class="language-plaintext highlighter-rouge">a</code> qu’il contient puis on visite l’URL contenue dans son attribut <code class="language-plaintext highlighter-rouge">href</code></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>if browser.is_element_present_by_css('table.commonTable'):
    # Récupère l'URL vers le fichier XML des publications du jour
    xmlfile = browser.find_by_css('table.commonTable')
                    .find_by_css('tbody')
                    .find_by_css('a')[3]
    browser.visit(xmlfile['href'])
</code></pre>
</div>
</div>
<p>On enregistre ensuite le contenu du fichier en local.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>response = browser.html.encode('utf8', 'xmlcharrefreplace')
with open('notices.xml', 'w') as fh:
    fh.write(response)
</code></pre>
</div>
</div>
<p>Une fois le fichier récupéré en local, on peut imaginer un script Python ou PHP qui traiterai le contenu du fichier XML pour l’enregistrer dans une base de données.</p>
<p>Voilà le code source complet de notre scraper en Python :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code># coding: utf8
from splinter import Browser # importe l'objet Browser de la librairie

with Browser() as browser:
    url = "https://www.rcsl.lu"
    browser.visit(url)
    # Effectue un clic sur le lien vers les publications du journal officiel
    browser.click_link_by_partial_href('mjrcs/jsp/DisplayOfficialJournalAction')
    # Vérifie que le tableau ayant la classe `commonTable` existe avant de passer à la suite
    if browser.is_element_present_by_css('table.commonTable'):
        # Récupère l'URL vers le fichier XML des publications du jour
        xmlfile = browser.find_by_css('table.commonTable')
                        .find_by_css('tbody')
                        .find_by_css('a')[3]
        browser.visit(xmlfile['href'])
        response = browser.html.encode('utf8', 'xmlcharrefreplace')
        # Enregistre le contenu du fichier XML dans un fichier en local
        with open('notices.xml', 'w') as fh:
            fh.write(response)
</code></pre>
</div>
</div>
<p>J’espère que cet article vous aura appris quelque chose et comme toujours, si vous avez des remarques ou des conseils pour l’améliorer, n’hésitez pas à m’en faire part sur Twitter ou dans les commentaires.</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2017/11/scraper-web-avec-python/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Déployer Jekyll sur un VPS avec GitHub</title>
					<link>https://chierchia.fr/2017/04/deployer-jekyll-sur-un-vps-avec-github/</link>
					<comments>https://chierchia.fr/2017/04/deployer-jekyll-sur-un-vps-avec-github/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Wed, 12 Apr 2017 10:52:41 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[jekyll]]></category>
		<category><![CDATA[static site generator]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2017/04/deployer-jekyll-sur-un-vps-avec-github</guid>

					<description><![CDATA[Il y a deux mois j’ai totalement abandonné WordPress pour passer à Jekyll, une solution beaucoup moins lourde et plus en phase avec ma façon actuelle de publier sur mon blog. Dans mon précédent billet, j’avais évoqué la possibilité pour moi d’abandonner mon mutualisé OVH en faveur de GitHub Pages. Je me suis donc amusé [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Il y a deux mois <a href="https://chierchia.fr/blog/jekyll/">j’ai totalement abandonné WordPress</a> pour passer à Jekyll, une solution beaucoup moins lourde et plus en phase avec ma façon actuelle de publier sur mon blog. Dans mon précédent billet, j’avais évoqué la possibilité pour moi d’abandonner mon mutualisé OVH en faveur de GitHub Pages.<br />
Je me suis donc amusé beaucoup plus qu’à l’accoutumée avec GitHub et GitHub Pages ces derniers mois, pour voir si la plateforme répondrait à mes attentes.<span id="more-1335"></span></p>
<p>Pour la faire courte, la réponse est : non, pour l’instant.</p>
<h2 id="pourquoi-github-pages-ne-me-convient-pas-">Pourquoi GitHub Pages ne me convient pas ?</h2>
<p>La plateforme est géniale, la mise à jour du blog sous Jekyll est instantanée à chaque <code class="language-plaintext highlighter-rouge">git push origin master</code>, plus besoin de lancer un <code class="language-plaintext highlighter-rouge">jekyll build</code> pour générer le site mis à jour, GitHub Pages s’occupe de tout !</p>
<p>Malheureusement, même si il est possible de forcer le HTTPS sur les pages du site, celui-ci doit obligatoirement avoir une URL du style <code class="language-plaintext highlighter-rouge">https://username.github.io/repository</code>. Impossible de forcer HTTPS si on veut utiliser son propre nom de domaine. Et comme j’avais déjà passé mon site en HTTPS il était hors de question de revenir en arrière, par principe.</p>
<p>Et puis, comme ça l’air de rien une petite newsletter OVH tombe dans ma boîte mail, proposant un nom de domaine en <code class="language-plaintext highlighter-rouge">.me</code> à -70%, du coup je me laisse tenter et puis une chose en entrainant une autre, je décide de prendre un petit VPS à pas cher…</p>
<h2 id="déployer-jekyll-via-github">Déployer Jekyll via GitHub</h2>
<p>J’aime beaucoup GitHub, je m’en sert principalement pour sauvegarder quelques projets et ça m’évite de garder une copie sur un disque externe, je souhaitais donc pouvoir l’utiliser comme relai entre ma machine et le serveur, comme ça si il me prend l’envie de tout remettre à zéro, j’ai mes projets sauvés sur GitHub, un <code class="language-plaintext highlighter-rouge">git clone</code> et on en parle plus.</p>
<p>N’ayant jamais vraiment utilisé Linux, je me suis dit que c’était l’occasion. J’ai donc choisi de configurer mon VPS en distribution nue sous Debian 8 pour pouvoir installer uniquement ce dont j’avais besoin et laisser le plus de place possible pour mon site sur le disque dur. En gros : Apache, Git, Ruby et Let’s Encrypt.</p>
<p>Ici je n’expliquerai pas comment j’ai installé Apache, Git, Ruby et Let’s Encrypt. Je me contenterai de partager ma méthode pour déployer Jekyll.</p>
<h3 id="créer-le-dépôt-git-distant">Créer le dépôt Git distant</h3>
<p>La première étape de ma méthode a consistée à créer un dépôt Git à la racine du VPS avec la commande suivante :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code># connexion au VPS
ssh git@mon.vps
# création du dépôt distant
git clone --bare https://github.com/nighcrawl/jekyll-blog.git blog.git
</code></pre>
</div>
</div>
<p>Avec cette commande on clone le dépôt GitHub nu sur le VPS, c’est à dire en ne gardant que les fichiers normalement contenus dans <code class="language-plaintext highlighter-rouge">.git/</code> dans le dossier <code class="language-plaintext highlighter-rouge">blog.git/</code>. Le dossier <code class="language-plaintext highlighter-rouge">blog.git</code> ressemble alors à ceci :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>blog.git/
|_ HEAD/
|_ branches/
|_ config/
|_ description/
|_ hooks/
|  |_ post-receive
|  |_ post-update
|  |_ ...
|_ infos/
|_ objects/
|_ refs/
</code></pre>
</div>
</div>
<p>Le fichier intéressant ici est <code class="language-plaintext highlighter-rouge">post-receive</code> du dossier <code class="language-plaintext highlighter-rouge">hooks/</code> car il va nous permettre d’executer un script bash à chaque fois qu’un <code class="language-plaintext highlighter-rouge">git push</code> sur le dépôt aura été complété.</p>
<p>Pour nous, il faudra lancer la génération du site avec Jekyll à chaque nouveau <code class="language-plaintext highlighter-rouge">git push</code>, le fichier <code class="language-plaintext highlighter-rouge">post-receive</code> contiendra alors le script suivant :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>GIT_REPO=$HOME/blog.git
TMP_GIT_CLONE=$HOME/tmp/blog
PUBLIC_WWW=/var/www/blog

git clone $GIT_REPO $TMP_GIT_CLONE
bundle exec jekyll build -s $TMP_GIT_CLONE -d $PUBLIC_WWW
rm -Rf $TMP_GIT_CLONE
exit
</code></pre>
</div>
</div>
<p>Ici on déclare plusieurs variable en début de script:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">GIT_REPO</code> contient le chemin vers le dépôt Git,</li>
<li><code class="language-plaintext highlighter-rouge">TMP_GIT_CLONE</code> permet de définir où sera cloné le dépôt</li>
<li><code class="language-plaintext highlighter-rouge">PUBLIC_WWW</code> contiendra les fichiers du site une fois compilés avec Jekyll</li>
</ul>
<p>Une fois le dépôt Git cloné dans <code class="language-plaintext highlighter-rouge">$TMP_GIT_CLONE</code>, on lance la commande de compilation des fichier <code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code> en spécifiant le dossier <code class="language-plaintext highlighter-rouge">$TMP_GIT_CLONE</code> comme étant la source et <code class="language-plaintext highlighter-rouge">$PUBLIC_WWW</code> comme destination, puis on supprime le dossier <code class="language-plaintext highlighter-rouge">$TMP_GIT_CLONE</code> avec la commande <code class="language-plaintext highlighter-rouge">rm -Rf $TMP_GIT_CLONE</code>.</p>
<h3 id="créer-le-dépôt-git-local">Créer le dépôt Git local</h3>
<p>Une fois le dépôt distant créé et le fichier <code class="language-plaintext highlighter-rouge">post-receive</code> modifié, il ne reste plus qu’à cloné le dépôt sur l’ordinateur avec la commande</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>git clone https://github.com/nighcrawl/jekyll-blog.git
</code></pre>
</div>
</div>
<p>puis d’y ajouter votre dépôt distant comme <code class="language-plaintext highlighter-rouge">remote</code> supplémentaire avec la commande</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>git remote add deploy ssh://git@mon.vps:/blog.git
</code></pre>
</div>
</div>
<h2 id="déployer-en-production">Déployer en production</h2>
<p>Pour pousser les mises à jour vers le VPS il suffira alors de faire un <code class="language-plaintext highlighter-rouge">git push</code> en spécifiant le dépôt distant dans lequel vous souhaitez envoyer vos commits.</p>
<p>Ici le dépôt GitHub s’appelle <code class="language-plaintext highlighter-rouge">origin</code> et mon dépôt de production (sur le VPS) s’appelle <code class="language-plaintext highlighter-rouge">deploy</code>. La commande de mise à jour du VPS sera alors</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>git push deploy master
</code></pre>
</div>
</div>
<h2 id="fin">Fin</h2>
<p>La méthode de déploiement que j’utilise ici est assez basique et pourra probablement être améliorée, alors n’hésitez pas à la partager, ou mieux me donner votre avis et/ou vos conseils sur Twitter.</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2017/04/deployer-jekyll-sur-un-vps-avec-github/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Nettoyer une chaîne de caractères avec PHP</title>
					<link>https://chierchia.fr/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien/</link>
					<comments>https://chierchia.fr/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Sun, 27 Mar 2016 13:10:26 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien</guid>

					<description><![CDATA[Quoi de plus simple que de nettoyer une chaîne de caractères pour l’utiliser comme URL vers une page, un article ou tout autre contenu publié sur Internet en général ? Et pourtant… Bien que très simple à mettre en place dans les faits, quand vient l’heure de nettoyer une chaîne de caractères pleine d’accents, de [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Quoi de plus simple que de nettoyer une chaîne de caractères pour l’utiliser comme URL vers une page, un article ou tout autre contenu publié sur Internet en général ? Et pourtant…</p>
<p>Bien que très simple à mettre en place dans les faits, quand vient l’heure de nettoyer une chaîne de caractères pleine d’accents, de signes de ponctuation et autres caractères spéciaux, c’est la galère.<span id="more-1339"></span></p>
<p>Voici la fonction que j’utilise pour nettoyer mes chaînes de caractères et les utiliser comme <a href="https://fr.wikipedia.org/wiki/Permalien" target="_blank" rel="noopener">permalien</a></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>function clean($string) {
	$string = html_entity_decode(preg_replace('/&amp;([a-zA-Z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);/i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8');
	$string = strtolower(trim(preg_replace('/[^0-9a-z]+/i', '-', $string), '-'));

	return $string;
}
</code></pre>
</div>
</div>
<p>Le principe ici est très simple. D’abord on converti tout les caractères qui peuvent l’être en entités HTML à l’aide de la fonction <code class="language-plaintext highlighter-rouge">htmlentities()</code>, ensuite on remplace chaque caractère par son équivalent sans accent, cédille, etc.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>preg_replace('/&amp;([a-zA-Z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);/i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8');
</code></pre>
</div>
</div>
<p>En appliquant la fonction <code class="language-plaintext highlighter-rouge">html_entity_decode()</code> sur la chaîne nettoyée de tout caractère accentué, on transforme à nouveau les entités HTML restantes en caractères normaux.</p>
<p>Enfin, on remplace tous les caractères n’étant pas des lettres ou des chiffres par un tiret, puis on supprime les tirets en trop à l’aide de la fonction <code class="language-plaintext highlighter-rouge">trim()</code>.</p>
<p>J’espère que ce petit morceau de code vous aura été utile :).</p>
<p>N’hésitez pas à partager votre solution, ou vos remarques dans les commentaires.</p>
<p>Tchô !</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Créer un pixel de suivi</title>
					<link>https://chierchia.fr/2016/03/creer-un-pixel-de-suivi/</link>
					<comments>https://chierchia.fr/2016/03/creer-un-pixel-de-suivi/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Tue, 08 Mar 2016 18:10:44 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pixel]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2016/03/creer-un-pixel-de-suivi</guid>

					<description><![CDATA[Ces dernières semaines, j’ai essentiellement travaillé sur la conception d’un cookie/pixel de suivi et le traitement des informations récupérées, pour en faire des tableaux statistiques et autres graphiques de fréquentation par la suite. Je vous parlerai peut-être de mon expérience avec la librairie JavaScript C3.js dans un prochain article. L’intérêt d’un tel dispositif est de pouvoir [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Ces dernières semaines, j’ai essentiellement travaillé sur la conception d’un cookie/pixel de suivi et le traitement des informations récupérées, pour en faire des tableaux statistiques et autres graphiques de fréquentation par la suite. Je vous parlerai peut-être de mon expérience avec <a href="http://c3js.org/" target="_blank" rel="noopener">la librairie JavaScript C3.js</a> dans un prochain article.</p>
<p>L’intérêt d’un tel dispositif est de pouvoir « tracker » ce qu’un visiteur fait lorsqu’il parcours votre site Web, ou encore de savoir si une campagne emailing a bien été ouverte.<span id="more-1341"></span></p>
<h2 id="pixel-de-suivi">Pixel de suivi</h2>
<p>Le code partagé ici est un exemple basique est ne reflète pas exactement la solution que j’ai utilisé pour tracker les visiteurs de nos sites Internet, mais le principe reste le même.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>&lt;?php
// On récupère d'abord l'adresse IP du visiteur
$ip = !empty($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);

// Navigateur utilisé
$browser = $_SERVER['HTTP_USER_AGENT'];

// URL de la page visité
$url = $_SERVER['REQUEST_URI'];

// Enregistrement dans un fichier de log
$handle = fopen('log.txt', 'a+');
$log_data = date('Y-m-d H:i:s') . ' -- ' . $ip . ' -- ' . $brower . ' -- '. $url . "\r\n";
fwrite($handle, $log_data);
fclose($handle);

// Création du pixel de suivi
$pixel = imagecreate(1,1);
$pixel = imagecolorallocatealpha($pixel, 255, 255, 255, 0);

// Enfin, on affiche le pixel de suivi
header('Content-Type: image/png');
imagepng($pixel);
imagedestroy($pixel)
?&gt;
</code></pre>
</div>
</div>
<h2 id="intégrer-le-pixel-de-suivi">Intégrer le pixel de suivi</h2>
<p>Maintenant que notre image de 1 pixel sur 1 pixel est créée, il ne reste plus qu’à l’insérer dans le code HTML des pages que l’on souhaite suivre. Une simple balise <code class="language-plaintext highlighter-rouge">img</code> juste avant la balise <code class="language-plaintext highlighter-rouge">&lt;/body&gt;</code> suffira !</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>&lt;img src="pixel.php" width="1" height="1" /&gt;
</code></pre>
</div>
</div>
<p>Eh voilà ! J’espère que ce petit bout de code vous aura plu. Si vous avez d’autres solutions, n’hésitez pas à les partager dans les commentaires.</p>
<p>Tchô !</p>
<p>&nbsp;</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2016/03/creer-un-pixel-de-suivi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Créer son framework PHP Objet</title>
					<link>https://chierchia.fr/2016/01/creer-son-framework-php-objet/</link>
					<comments>https://chierchia.fr/2016/01/creer-son-framework-php-objet/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Mon, 11 Jan 2016 07:40:21 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programmation objet]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2016/01/creer-son-framework-php-objet</guid>

					<description><![CDATA[Pour faire suite à un article que j’avais écrit il y a un peu plus de quatre ans maintenant sur la création d’un framework PHP, je vous propose de créer un framework PHP Objet en utilisant les principes MVC. Lorsque je travaillais encore chez CBC Informatique, nous n’utilisions pas les principes de la programmation orientée [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Pour faire suite à un article que j’avais écrit il y a un peu plus de quatre ans maintenant sur la <a href="http://chierchia.fr/blog/creer-son-framework-php/">création d’un framework PHP</a>, je vous propose de créer un framework PHP Objet en utilisant les principes MVC.<span id="more-1344"></span></p>
<p>Lorsque je travaillais encore chez CBC Informatique, nous n’utilisions pas les principes de la programmation orientée Objet et nous préférions développer nous même les sites Web de nos clients plutôt que de s’appuyer sur des solutions toutes faites, afin de garder la maitrise de notre code. C’est dans cette optique que j’avais développé <a href="https://github.com/nighcrawl/custom-cms" target="_blank" rel="noopener">notre mini-framework/CMS</a>.</p>
<p>Depuis presque 1 an maintenant,  je travaille chez Ibakus Europe et à nouvelle équipe nouvelle façon de travailler. Pour concevoir les nouvelles applications Web IBAKUS, nous utilisons la programmation orientée Objet et les principes du MVC. Nos applications gérant des données plutôt sensibles, il a été décidé de développer notre propre framework PHP Objet, afin de garder au maximum la main sur le code et pouvoir le modifier plus facilement.</p>
<h2 id="les-bases-du-framework-php-objet">Les bases du framework PHP Objet</h2>
<p>D’abord, nous avons écrit une classe maîtresse que l’on a appelée <em>Container</em>. Elle nous permet entre autre d’initialiser le framework avec un fichier de configuration, de définir les différentes routes et de charger les différents Modèles et Contrôleurs.</p>
<p>Une <strong>classe abstraite</strong> <em>Model</em> définit les méthodes utilisées pour agir sur la base de données puis chacun de nos modèles étendent cette classe afin de gérer les spécificités qui leur sont propres.</p>
<p>Mon but n’étant pas de publier le code source de notre framework, je m’intéresserai uniquement aux méthodes CRUD de notre classe abstraite <em>Model</em>.</p>
<h2 id="structure-de-la-classe-abstraite-model">Structure de la classe abstraite <em>Model</em></h2>
<p>La classe abstraite <em>Model</em> est définie par deux propriétés <code class="language-plaintext highlighter-rouge">$db</code> et <code class="language-plaintext highlighter-rouge">$table</code> et cinq méthodes : <code class="language-plaintext highlighter-rouge">get()</code>, <code class="language-plaintext highlighter-rouge">getDatas()</code>, <code class="language-plaintext highlighter-rouge">set()</code>, <code class="language-plaintext highlighter-rouge">delete()</code> et <code class="language-plaintext highlighter-rouge">save()</code>.</p>
<p>La propriété <code class="language-plaintext highlighter-rouge">$db</code> est une instance de la classe PDO établissant la connexion à notre base de données, <code class="language-plaintext highlighter-rouge">$table</code> quand à elle contient le nom de la table sur laquelle les opérations des méthodes <code class="language-plaintext highlighter-rouge">save()</code> et <code class="language-plaintext highlighter-rouge">delete()</code> vont être faites. Voici la structure de notre classe :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>abstract class Model {
  protected $db;
  protected $table;
  
  public function __construct() {
    $this -&gt; db = Container::getDb();
    $this -&gt; table = $this; 
  }
  
  /**
   * Un echo de $this retournera le nom de la table associée au modèle.
   * Par exemple 'pages' pour le modèle 'PagesModel'
   */
  public function __toString() {
    return strtolower(substr(get_class($this), 0, -5));
  }
  
  // GETTERS
  public function get($attr) {
    return $this -&gt; $attr;
  }
  
  /**
   * Retourne tous les attributs de l'objet
   */
  public function getDatas() {
    $datas = array();
    foreach (get_object_vars($this) as $key =&gt; $value)
        $datas[$key] = $value;
    
    return $datas;
  }
  
  // SETTER
  public function set($attr, $data) {
    if (property_exists($this, $attr)
        $this -&gt; $attr = $data;
  }
  
  // METHODES
  public function delete() {}
  
  public function save() {}
}
</code></pre>
</div>
</div>
<h3 id="la-méthode-save">La méthode <code class="language-plaintext highlighter-rouge">save()</code></h3>
<p>cette méthode permet d’enregistrer l’objet dans la base de données, que ce soit pour son insertion ou lors de sa modification. Pour définir si l’on va faire un <code class="language-plaintext highlighter-rouge">INSERT</code> ou un <code class="language-plaintext highlighter-rouge">UPDATE</code>, on testera la valeur de l’attribut <code class="language-plaintext highlighter-rouge">id</code> de l’objet courant. Si elle n’est pas nulle on souhaite modifier l’objet, sinon on crée une nouvelle entrée dans la base.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>public function save($type = null) {
  if ($this -&gt; get('id') == null) {
    $query = 'INSERT INTO ' . $this -&gt; get('table') . ' SET';
    $nbDatas = count($this -&gt; getDatas());

    $i = 0;
    foreach ($this -&gt; getDatas() as $key =&gt; $value) {
      $i++;
      $query .= ' ' . $key . ' = :' . $key;
      if ($i &lt; $nbDatas) $query .= ','; else $query .= ';'; } } else { $query = 'UPDATE ' . $this -&gt; get('table') . ' SET';
    $nbDatas = count($this -&gt; getDatas());

    $i = 0;
    foreach ($this -&gt; getDatas() as $key =&gt; $value) {
      $i++;
      if ($key != 'id') {
        $query .= ' ' . $key . ' = :' . $key;
        if ($i &lt; $nbDatas) $query .= ','; } } $query .= ' WHERE id = :id;'; } $query = $this -&gt; get('db') -&gt; prepare($query);

  foreach ($this -&gt; getDatas() as $key =&gt; $value)
    $query -&gt; bindValue(':' . $key, $value);

  $executed = $query -&gt; execute();

  if ($executed &amp;&amp; $this -&gt; get('id') == null)
    $this -&gt; set('id', $this -&gt; get('db') -&gt; lastInsertId());

  return $executed;
}
</code></pre>
</div>
</div>
<h3 id="la-méthode-delete">La méthode <code class="language-plaintext highlighter-rouge">delete()</code></h3>
<p>Pour supprimer les données de l’objet enregistré, rien de vraiment compliqué, on execute simplement une requête préparée avec la classe PDO et on supprime l’enregistrement dont <code class="language-plaintext highlighter-rouge">id</code> correspond à l’attribut <code class="language-plaintext highlighter-rouge">id</code> de l’objet courant.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>public function delete() {
  $query = $this -&gt; get('db') -&gt; prepare('DELETE FROM ' . $this -&gt; get('table') . ' WHERE id = :id;');
  $query -&gt; bindValue(':id', $this -&gt; get('id'));
  
  return $query -&gt; execute();
}
</code></pre>
</div>
</div>
<h2 id="pour-finir--construire-un-cms">Pour finir : construire un CMS</h2>
<p>Construire un CMS sur base d’une classe abstraite comme celle-ci permet d’écrire très simplement les différents modules dont on aura besoin.</p>
<p>Si l’on souhaite gérer des pages de contenu, il suffira d’écrire un modèle héritant de la classe <em>Model</em>, par exemple <em>pagesModel</em> et d’y définir les attributs de l’objet en regard de la structure de la table <em>pages</em> de la base de données.</p>
<p>Cette classe héritant de la classe abstraite, nous n’auront pas besoin de réécrire nos méthodes <code class="language-plaintext highlighter-rouge">save()</code> et <code class="language-plaintext highlighter-rouge">delete()</code> et l’on pourra se concentrer sur des méthodes permettant par exemple, de retourner un menu de navigation, des méta-tags pour le référencement naturel, etc.</p>
<p>Bien sûr, il faudra écrire un contrôleur permettant de traiter les données à passer au modèle, qui se chargera ensuite de les enregistrer en base de données, mais ça se fait rapidement  .</p>
<p>Là dessus, bonne semaine (et bonne année) !</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2016/01/creer-son-framework-php-objet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Faire un str_replace() avec MySQL</title>
					<link>https://chierchia.fr/2014/08/faire-str_replace-mysql/</link>
					<comments>https://chierchia.fr/2014/08/faire-str_replace-mysql/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Wed, 27 Aug 2014 07:46:49 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2014/08/faire-str_replace-mysql</guid>

					<description><![CDATA[Lorsque je conçois les sites Web de nos clients, une fois mon travail terminé, je le met en ligne sur un domaine temporaire afin que le client puisse voir, utiliser et surtout alimenter le site Web en contenu avant de l’installer sur son domaine définitif. Une fois le client satisfait, il nous donne le « Go » pour la [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Lorsque je conçois les sites Web de nos clients, une fois mon travail terminé, je le met en ligne sur un domaine temporaire afin que le client puisse voir, utiliser et surtout alimenter le site Web en contenu avant de l’installer sur son domaine définitif.</p>
<p>Une fois le client satisfait, il nous donne le « Go » pour la mise en ligne, nous transférons alors les fichiers et la base de données sur le domaine final. Parfois, les URLs générées dans le contenu des pages sont erronées suite au transfert sur le domaine définitif, et bien entendu les liens foirent… En PHP, on pourrait faire un bête <code class="language-plaintext highlighter-rouge">str_replace()</code>, ou un <code class="language-plaintext highlighter-rouge">preg_match_all()</code>. Mais en MySQL ? C’est là que la requête qui suit va nous sauver :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>UPDATE pages SET contenu = REPLACE(contenu, 'http://ancienne.url', 'http://nouvelle.url') WHERE contenu LIKE '%ancienne.url%';
</code></pre>
</div>
</div>
<p>C’est bidon, mais j’ai toujours du mal à m’en souvenir. Le publier ici me permettra de retrouver ça facilement. Après tout, ce blog est avant tout pour moi et si ça peut aider quelqu’un d’autre… </p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2014/08/faire-str_replace-mysql/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Créer son propre framework PHP, pourquoi ?</title>
					<link>https://chierchia.fr/2011/12/creer-son-framework-php/</link>
					<comments>https://chierchia.fr/2011/12/creer-son-framework-php/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Mon, 12 Dec 2011 07:15:50 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2011/12/creer-son-framework-php</guid>

					<description><![CDATA[Cela fait maintenant presque deux ans que je suis entré dans la vie active en tant que développeur et designer Web. Et en tant que tel, je suis souvent (comprenez : tout le temps) amené à faire quasiment les mêmes choses, bien que chaque projet soit différent. Personnellement j’aime passer du temps à peaufiner un [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Cela fait maintenant presque deux ans que je suis entré dans la vie active en tant que développeur et designer Web. Et en tant que tel, je suis souvent (comprenez : tout le temps) amené à faire quasiment les mêmes choses, bien que chaque projet soit différent.</p>
<p>Personnellement j’aime passer du temps à peaufiner un design. je déteste réécrire les mêmes fonctions pour chaque projet. Alors oui, il des frameworks PHP, mais pourquoi utiliser un bazooka lorsqu’on doit abattre une mouche ?<span id="more-1364"></span></p>
<p class="author_note"><strong>MAJ 11/01/2016 : Si le PHP Objet vous parle, vous pouvez lire <a href="http://chierchia.fr/blog/creer-son-framework-php-objet/">Créer son framework PHP Objet</a> qui est <em>un peu</em> plus récent </strong></p>
<p class="author_note">Attention, l’article est un chouilla trop long (beaucoup de lignes de code).</p>
<p>Oui utiliser une CMS déjà tout fait c’est bien, oui utiliser un framework en PHP Objet c’est bien. Seulement parfois, utiliser une arme de destruction massive n’est pas la bonne méthode à appliquer pour régler les choses les plus simples.</p>
<p>Ces dernier mois, au fil des projets qui le permettaient, j’ai pu me construire ma propre bibliothèque de fonctions, en essayant de l’améliorer à chaque itérations, tout en restant le plus générique possible pour permettre une très bonne portabilité de projet en projet. Bien sûr je n’ai pas hésité à piquer des idées dans les frameworks PHP, mais plutôt que de me trimballer toute la clique, j’ai maintenant un petit « framework » qui me permet de faire juste ce dont j’ai besoin. Cela m’a aussi permis de monter facilement notre propre CMS, lui aussi très basique.</p>
<p>Aujourd’hui j’ai donc envie de partager avec vous quelques unes de mes fonctions, car ça fait un petit moment que je n’ai pas publié un peut de code PHP dans mes pages.</p>
<h2 id="mes-fonctions-de-crud">Mes fonctions de CRUD</h2>
<p>Etape obligatoire lorsqu’on souhaite agir sur des informations stockées en base de données, les célèbres fonctions INSERT, SELECT, UPDATE et DELETE. Après plusieurs itérations je suis arrivé à des fonctions quasiment utilisable par n’importe quel projet, même si je pense qu’elles ne sont pas encore parfaites, pour le moment elles me suffisent. Cependant, si vous avez de quoi les améliorer n’hésitez pas à me donner votre avis !</p>
<h3 id="ajouter-un-enregistrement-dans-une-table">Ajouter un enregistrement dans une table</h3>
<p>Après pas mal de projet dans lesquels j’avais une fonction d’ajout pour chaque type de contenu (page, article, etc.) enregistrés dans des tables différentes, j’ai essayé de trouver un moyen simple d’ajouter n’importe quelle données dans n’importe quelle table. Je suis donc passé de plusieurs fonction plus ou moins lourde à une bête fonction d’une quinzaine de ligne avec laquelle je peux faire ce que je veux, simplement en lui passant un tableau des données à ajouter, et le nom de la table dans laquelle faire cet INSERT.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  insert des données dans la table en paramètre
 *  @datas  tableau des données à insérer dont la clé et le nom du champs dans la table
 *  @table  table dans laquelle insérer les données
 */
function add($datas, $table){
  $bdd = db(); //on ouvre la connexion à la base de données

  foreach($datas as $key =&gt; $value){
    $keys[] = $key;
    $values[] = $value;
  }

  $strSQL = "INSERT INTO ".$table." (";
  foreach($keys as $ky =&gt; $k){ $strSQL .= $k . ","; }

  $strSQL = substr($strSQL,0,-1) . ") VALUES(";
  foreach($values as $vl =&gt; $v){ $strSQL .= "?,"; }

  $strSQL = substr($strSQL,0,-1) . ")";

  $query = $bdd-&gt;prepare($strSQL);
  if($query-&gt;execute($values)) return $bdd-&gt;lastInsertId();
  else return false;
}
</code></pre>
</div>
</div>
<p><strong>Comment utiliser la fonction ?</strong></p>
<p>Après avoir vérifiées, échappées, etc., les informations soumisent à mon formulaire, il me suffit de créer un tableau dont les clés seront les noms des champs que je veux renseigner pendant mon INSERT.</p>
<p><em><span style="text-decoration: underline;">Exemple :</span> je veux renseigner le nom, l’adresse email et le commentaire dans la table « comments ».</em></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$datas = array(
  'nom' =&gt; $nom,
  'email' =&gt; $email,
  'commentaire' =&gt; $commentaire
);

if(add($datas,'comments')) {
  return "cool";
} else return "pas cool";
</code></pre>
</div>
</div>
<p>Si tout c’est bien passé, la fonction <code class="language-plaintext highlighter-rouge">add()</code> me renvoie l’ID de l’enregistrement créé.</p>
<h3 id="mettre-à-jour-les-informations-dun-enregistrement">Mettre à jour les informations d’un enregistrement</h3>
<p>Là aussi, c’est une fonction vraiment très simple. comme ma fonction add(), ma fonction update() requiert un tableau des données et le nom de la table à modifier. Seul petit changement, on doit aussi fournir l’ID de l’enregistrement à modifier.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  met à jour les données de l'ID dans la table en paramètre
 *  @id identifiant de la ligne à modifier
 *  @datas  tableau des données à insérer dont la clé et le nom du champs dans la table
 *  @table  table dans laquelle insérer les données
 */
function update($id, $datas, $table){
  $bdd = db();
  foreach($datas as $key =&gt; $value){
    $keys[] = $key;
    $values[] = $value;
  }

  $strSQL = "UPDATE ".$table." SET ";
  foreach($datas as $key =&gt; $value){
    $strSQL .= $key . " = ?,";
  } $strSQL = substr($strSQL,0,-1) . " WHERE id = ?";
  $values[] = $id;
  $query = $bdd-&gt;prepare($strSQL);
  if($query-&gt;execute($values)) return true;
  else return false;
}
</code></pre>
</div>
</div>
<h3 id="supprimer-un-enregistrement">Supprimer un enregistrement</h3>
<p>Rien de bien compliqué là non plus, on supprime l’enregistrement dont l’ID est passé en paramètre dans la table elle aussi en paramètre.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  supprime les données correspondant à l'ID dans la table en paramètre
 *  @id   identifiant de la ligne à supprimer
 *  @table  table sur laquelle on applique la suppression
 */
function delete($id, $table){
  $bdd = db();
  $strSQL = "DELETE FROM ".$table." WHERE id = ?";
  $query = $bdd-&gt;prepare($strSQL);
  //print_r(array($id));

  if($query-&gt;execute(array($id))) return true;
  else return false;
}
</code></pre>
</div>
</div>
<h3 id="retourner-une-liste-denregistrements">Retourner une liste d’enregistrements</h3>
<p>Cette dernière est l’une des fonctions que j’ai eu le plus de mal à rendre générique tout en me permettant de faire beaucoup de choses avec, comme par exemple préparer le terrain pour l’utiliser dans le cadre des données scindées sur plusieurs pages.</p>
<p>Ici ma fonction me permet de récupérer à la fois les enregistrements de ma requête, le total d’enregistrements que retournerai ma requête si aucun paramètre LIMIT n’était renseigné, la requête exécutée (pour les tests en phase de développement) ou les erreurs possibles quant à l’exécution de cette requête.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  retourne le resultat d'un select
 *  @columns  colonnes à selectionner pour la requête (ex: array('champ1','champ2') ou '*')
 *  @table    nom de la table sur laquelle faire la requête
 *  @where    champs sur lequels appliquer des conditions ( ex: array( 'champ1 =' =&gt; 'valeur', 'champ2 LIKE' =&gt; 'valeur%') )
 *  @concats  [ AND | OR ]
 *  @order    champs sur lequels appliquer le tri, et l'ordre pour chaque champs (ex: array('champ1' =&gt; 'ASC','champ2' =&gt; 'DESC') )
 *  @limit    limit[0] =&gt; debut de la liste, limit[1] =&gt; nombre d'éléments dans la liste retournée (ex: array('0','20') )
 *
 *  return @retour  : tableau contenant la requête executée, les éventuelles erreurs et le resultat de la requête
 */
function get($columns = null, $table = null, $where = null, $concats = "AND", $order = null, $limit = null){
  $bdd = db();
  $retour = array(); //variable de type tableau, retournée par la fonction
  $rows = "";
  $clause = "";
  $sort = "";
  $limitStr = "";

  if(!is_null($columns) &amp;&amp; !is_null($table)){

    // si $rows est un tableau ou égale à * tout va bien.
    if(is_array($columns)){
      foreach($columns as $column) { $rows .= $column .', '; }
      $rows = substr($rows,0,-2);
    } elseif($columns == '*'){
      $rows = '*';
    } else {
      $retour['erreur'] = "Les champs selectionné doivent être appelé depuis une variable Tableau";
    }

    if(!in_array(strtolower($concats),array('and','or'))){
      $retour['erreur'] = "&lt;strong&gt;".$concats."&lt;/strong&gt; n'est pas une valeur autorisée pour concaténer des conditions. Utilisez 'OR' ou 'AND'.";
    }

    /*
    si @where est renseigné, on filtre les résultats grâce au tableau @where construit comme suit :
      array ('colname operateur' =&gt; 'valeur');
      ex: array('page_id =' =&gt; 5);
    sinon, on ne filtre pas les résultats
    */
    if(!is_null($where) &amp;&amp; is_array($where)){
      foreach($where as $k =&gt; $v){
        $clause .= $k." ? ".$concats." ";
        $values[] = $v;
      }
      $clause = " WHERE ".substr($clause,0,(-(strlen($concats)+2)));
    } elseif(!is_null($where) &amp;&amp; !is_array($where)){
      $retour['erreur'] = "La clause WHERE doit être construite via une variable Tableau";
    } else {
      $clause = "";
    }

    //si $order est un tableau et n'est pas null
    if(!is_null($order) &amp;&amp; is_array($order)){
      foreach($order as $k =&gt; $v){ $sort .= $k." ".$v.", "; }
      $sort = " ORDER BY ".substr($sort,0,-2);
    } elseif(!is_null($order) &amp;&amp; !is_array($order)) {
      $retour['erreur'] = "ORDER BY doit être construit via une variable Tableau";
    } else {
      $sort = "";
    }

    if(!is_null($limit) &amp;&amp; is_array($limit) &amp;&amp; is_numeric($limit[0]) &amp;&amp; is_numeric($limit[1])){
      $debut = $limit[0];
      $nbRows = $limit[1];
      $limitStr = " LIMIT " . $debut . "," . $nbRows;
    } elseif(!is_null($limit) &amp;&amp; !is_array($limit)){
      $retour['erreur'] = "LIMIT doit être construit via un tableau de deux entiers";
    } else {
      $limitStr = "";
    }

    // on construit la requête
    $strSQL = "SELECT ".$rows." FROM ".$table.$clause.$sort.$limitStr;
    if(empty($retour['erreur'])){
      $query = $bdd-&gt;prepare($strSQL);
      $query-&gt;execute(@$values);
      $retour['requete'] = $strSQL;
      $retour['reponse'] = $query-&gt;fetchAll(PDO::FETCH_ASSOC);

      $sqlTotal = "SELECT COUNT(*) as total FROM ".$table.$clause.$sort;
      $q = $bdd-&gt;prepare($sqlTotal);
      $q-&gt;execute(@$values);
      $tot = $q-&gt;fetchAll(PDO::FETCH_ASSOC);
      $retour['total'] = $tot[0]['total'];
    }

  } else {
    $retour['erreur'] = "Impossible de créer la requete, les champs à selectionner et la table sont vide";
  }

  return $retour;
}
</code></pre>
</div>
</div>
<p><strong>Comment utiliser la fonction ?</strong></p>
<p><em><span style="text-decoration: underline;">Exemple :</span> Je veux récupérer les cinq articles les plus récents écrits par nighcrawl dont le titre contient le mot « framework » publié depuis la date à laquelle la requête est exécutée.</em></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$champs = array('id','titre','nom','contenu');
$conditions = array(
  'nom =' =&gt; 'nighcrawl',
  'date &lt; =' =&gt; date('Y-m-d H:i:s'),
  'titre LIKE' =&gt; '%framework%'
);
$trier = array('date' =&gt; 'DESC');
$limite = array(0, 5);

$resultat = get($champs,'articles',$conditions,"AND",$trier,$limite);
if(isset($resultat['reponse'])){
  foreach($resultat['reponse'] as $row){
    echo "&lt;article&gt;
    &lt;header&gt;
      &lt;h1&gt;".$row['titre']."&lt;/h1&gt;
    &lt;/header&gt;
    &lt;div&gt;".$row['contenu']."&lt;/div&gt;
    &lt;footer&gt;Auteur : ".$row['nom']."&lt;/footer&gt;
    &lt;/article&gt;";
  }
}
else echo $resultat['erreur'];
</code></pre>
</div>
</div>
<h2 id="mettre-en-place-un-système-de-pagination">Mettre en place un système de pagination</h2>
<p>Je m’arrêterai ici parce que l’article est déjà pas mal long, et si vous êtes arrivé jusqu’ici je vous dis chapeau. Personnellement je me serai déjà arrêté :). On fini donc avec une fonction très utile pour générer rapidement des liens de pagination afin de répartir les données d’une requête sur plusieurs pages. Voici donc la belle fonction :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  génère des liens de pagination : numeros de pages, 'suivants', 'précédents'
 *  @total  nombre total d'enregistremnts à paginer
 *  @nbpp nombre d'enregistrements à afficher par page
 *  @link chaine qui servira à construire les liens vers les différentes pages
 */
function pagination($total, $nbpp, $link){
  echo"&lt;div class='pagination'&gt;";
    /** Pagination **/
    //calcul du nombre de pages
    $nbLiens = ceil($total/$nbpp);

    if($nbLiens &gt; 1){
      /** précédents **/
      if(isset($_GET['d']) &amp;&amp; $_GET['d'] &gt; 0){
        echo "&lt;a href='".$link.($_GET['d']-$nbpp)."'&gt;« Précédents&lt;/a&gt;";
      } else {
        echo "&lt;span&gt;« Précédents&lt;/span&gt;";
      }
      /** pages ***/
      for($i = 0; $i &lt; $nbLiens; $i++){
        if($_GET['d'] == ($i*$nbpp)){
          echo "&lt;span class='active_pagi'&gt;".($i+1)."";
        } else {
          echo "&lt;a href='".$link.($i*$nbpp)."'&gt;".($i+1)."&lt;/a&gt;";
        }
      }

      /** suivants **/
      if(isset($_GET['d']) &amp;&amp; $_GET['d'] &gt;= 0 &amp;&amp; $_GET['d'] &lt; ($total-$nbpp)){
        echo "&lt;a href='".$link.($_GET['d']+$nbpp)."'&gt;Suivants »&lt;/a&gt;";
      } else {
        echo "&lt;span&gt;Suivants »&lt;/span&gt;";
      }
    }
  echo "&lt;/div&gt;";
}
</code></pre>
</div>
</div>
<p>La pagination va s’effectuée en deux temps, d’abord l’appel de la fonction get(), puis l’appel de la fonction pagination(). Si on réutilise l’exemple précédent :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$nbpp = 5; //5 articles par page
$limite = array(intval($_GET['d']),$nbpp);
$resultat = get($champs,'articles',$conditions,"AND",$trier,$limite);

if(isset($resultat['reponse'])){
  foreach ($resultat as $row) {
    //affichage des articles
    ...
  }
  pagination($resultat['total'],$nbpp,'index.php?parametre=valeur&amp;d=');
} else echo $resultat['erreur'];
</code></pre>
</div>
</div>
<h2 id="fin-">Fin !</h2>
<p>Merci de m’avoir lu jusqu’au bout. Je vous libère ici ! En espérant que ces quelques fonctions puissent vous être utiles. Elles ne sont pas parfaites et certaines pourraient être encore améliorées, alors si vous avez des idées, n’hésitez pas à les partager dans les commentaires.</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2011/12/creer-son-framework-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
