Web development all-around, including PHP, CSS, HTML, Hosting, MySQL, Symfony, Drupal and Wordpress.
Wednesday, December 26, 2012
Run a script with lowest priority
Friday, December 21, 2012
Choosing the best wireless router for a small office
After some unsuccessful searches, I asked the question on Reddit and I worked from there.
Our setup:
- 20~25 wired computers
- 20~25 wireless computers
- ~25 smartphones
- ~500 GB download/month
- ~300 GB upload/month
- Google Apps (Docs, Spreadsheet, Gmail, etc.) – A lot of AJAX requests
- SSH – Needs very low latency
- Skype – High bandwidth usage
- Dropbox – Moderate bandwidth usage
- Sending and receiving >5GB files
- Syncing thousands of files over FTP
- Dlink DIR-655 acting as the gateway: http://goo.gl/TXXs0[1]
- WRT54 acting as a router and a wifi AP, configured with DD-WRT: http://goo.gl/Wu89u[2]
I knew I wanted some sort of QoS to prioritize usage. Ex: Skype > SSH > Browsers > FTP and at our location, good quality connections at a decent price is pretty hard to find so I was looking forward to a Dual-WAN setup.
Upload speed
Network link speed negotiation
AP
Router
I had heard good comments about Draytek and so Reddit confirmed it. They are pretty solid, easy to configure and a much cheaper alternative than their Cisco counterparts. I finally went for a Draytek 2920n. This is about 250$, supports balancing and failover with a second Internet connection and it is managed in about the same fashion as a common router. The big difference is that it is much more powerful and can handle a traffic of a hundred devices without struggling. It was a godsend, we didn’t even need to upgrade the Internet connection, check it out.Other options
Monday, December 17, 2012
Varnish 3 configuration
However, there is some things that can be done to improve cacheability:
- Ignore Google Analytics cookies
- Remove empty Cookie line
- Normalize Accept-Encoding header
- Allow replying with a stale response if the backend is slow
- Remove some headers to reduce header size and hide some details about the server (security).
- Add a debug header to help understand why a request is cached or not.
How to properly create and destroy a PHP session
The idea is that since a cookie can be used by the backend to modify the reply, like being logged in as a user, the shared does not take the chance and refuse to cache it. This behaviour can be modified, especially in the case of Google Analytics cookies, but for the PHP session cookie, you will typically want it.
However, it is important, for a useful usage of your shared cache, to only start a session when you really need it and destroy it when it is not needed anymore. PHP’s session_start specifically mentions that is does not unset the associated cookie.
So the idea is to start a session when you need it; for example, in a login page. This will send a header to the client, setting a cookie and the cookie will get sent back on every request. Therefore, in some global file, you can detect this cookie and reload the session. At last, on the logout, clear everything.
Wednesday, December 5, 2012
Generate Lorem Ipsum using loripsum.net API
Seeing this, I thought it would be nice to use it to generate data fixtures that are meant to be used as blog posts, pages, comments, etc. I started a prototype for Wordpress, I should come up with a post about it soon enough, but in the mean time, I thought it would be valuable to share this little interface.
It is pretty straight forward and the options are documented in the code itself. Have fun!
Wednesday, November 21, 2012
Automatic LESS compilation using mod_rewrite and lessphp
Using lessphp, I made a simple script that will compile your LESS files, do some caching, gzip, etc.
It works by checking that a .css file exists. If not, it checks if the corresponding .less exists. If so, it fires up lessphp.
It is not perfect, but is worth using on simple projects.
Tuesday, November 20, 2012
The little quirks of using Twitter Bootstrap
input[type="file"] { height: 30px; line-height: 30px; }On Chrome and Firefox, I had problems where the Browse button was not correctly vertically aligned.
h1,h2,h3,h4,h5,h6 { text-rendering: initial; }May cause some troubles with custom fonts.
I noticed this problem with Google Webfont Advent Pro.
img { max-width: 100%; }May cause some troubles if your wrapper box is smaller.
You may also see flicker and reflows during loading while the size is readjusting.
To correct this problem, you should always specify height and width attributes, but sometimes it is not possible.
button, input { line-height: normal; }Will cause button and input not to inherit the line-height specfied in parent.
h1 { font-size: 36px; line-height: 40px; }Occurs with all headers. Since the line-height is not in em, you will need to update it manually if you change the font-size.
input, select, textarea { &[readonly], &[disabled] { cursor: not-allowed; } }This is not a problem in itself, but you may not want this cursor.
I stumbled upon it when I was trying to style an input as a seemlessly inline element.
And of course all of the rules for text-shadow, border-radius, box-shadow, etc.
All in all, I found myself using rules like theses quite often.
The exact rules will depend on your usage, but you can see the point.
They are not specific to Twitter Bootstrap.
.reset-font { font-size: inherit; font-family: inherit; line-height: inherit; } .reset-size { height: auto; width: auto; max-height: auto; max-width: auto; } .reset-effects { text-shadow: none; box-shadow: none; border-radius: none; }
Monday, November 19, 2012
Generate a multi-resolution favicon using ImageMagick
Thursday, November 1, 2012
Simple templating system using Bash
Hence, for very simple needs, I started using simple scripts that would only replace variables and give me a basic template to start with. This is however not very flexible and needs to be adapted for each case. And so I did a templater that replaces variables with the value in the environment. It also supports defining default values and variable interpolation.
Example with Apache + FPM
{{LOG_DIR=/var/log/apache2}} {{RUN_DIR=/var/run/php-fpm}} {{FCGI=$RUN_DIR/$DOMAIN.fcgi}} {{SOCKET=$RUN_DIR/$DOMAIN.sock}} {{EMAIL=$USER@$DOMAIN}} {{DOC_ROOT=/home/$USER/sites/$DOMAIN/htdocs}} <VirtualHost *:80> ServerAdmin {{EMAIL}} ServerName {{DOMAIN}} ServerAlias www.{{DOMAIN}} DocumentRoot "{{DOC_ROOT}}" <Directory "{{DOC_ROOT}}"> AllowOverride All Order allow,deny Allow From All </Directory> AddHandler php-script .php Action php-script /php5.fastcgi virtual Alias /php5.fastcgi {{FCGI}} FastCGIExternalServer {{FCGI}} -socket {{SOCKET}} LogLevel warn CustomLog {{LOG_DIR}}/{{DOMAIN}}.access.log combined ErrorLog {{LOG_DIR}}/{{DOMAIN}}.error.log </VirtualHost>
Invocation
Help
Friday, October 26, 2012
Using a public CDN versus hosting custom libraries
The plus side of using a public CDN
The down side
Testing the difference
- jQuery
- jQuery UI (including core and dependencies)
- Dialog
- Datepicker
- Twitter Bootstrap
- No responsive
- Alert
- Button
- Modal
- Tooltip
- Tab
Results breakdown
Custom | Hosted | Public CDN | Half/CDN | |
---|---|---|---|---|
Gzipped size | 82.91 KB | 110.13 KB | 128.93 KB | 36 % |
Exec time | 15 ms | 22 ms | 22 ms | 32 % |
Cached | 110 ms | 130 ms | 150 ms | 27 % |
304 | 125 ms | 155 ms | 195 ms | 36 % |
No cache | 220 ms | 240 ms | 250 ms | 12 % |
Developer tools screenshots
Conclusion
CDN resources
Thursday, October 25, 2012
Mind blowing jQuery plugin: Scroll Path
The result is stunning; it is smooth, mostly compatible and pretty flexible. This is a wonderful alternative to building a PowerPoint to show your ideas.
I have not used it yet, but it seems pretty easy. Check out the live demo!
Wednesday, October 24, 2012
Automatic cache busting using Git commit in Symfony2
Cache busting
Symfony
Symfony includes a cache busting mechanism which appends a GET parameter to your asset, but you must remember to increment it and it could quickly become a pain.Incrementing using Git version
The idea is to use the current Git commit as a version number using git rev-parse --short HEAD. We can call this in the command line using PHP. Don’t worry, in production mode, Symfony caches the compiled configs, so it won’t be checked until you clear the cache.Caveats
- All assets will be reset with every commit. Not a big deal since when you deploy, you usually touch a lot of assets.
- By default, Symfony uses a GET parameter, which is not cached by all CDNs.
However, Amazon CloudFront now supports them.
Otherwise, it is possible to rewrite using a folder prefix, but it can get tricky. - You must be using Git (!), including on your production server. Otherwise, it could be possible to achieve something similar by adding a Git hook on commits, writing version in a file, and loading this file instead.
Friday, October 12, 2012
bcrypt with ircmaxell and how to use it
It is common knowledge that md5 is not secure for password hashing. It is almost worst than plaintext because it may falsly induce the impression of security. People aware of this usually also consider sha1 insecure and straightly go to sha256. Some techniques exist to add further security like adding a salt or hashing multiple times but ultimately the flaw remains: those methods are too quick. If you can hash a password in a fraction of a second, a standard bruteforce can as well. That’s why strong password security involves slow algorithms.
I was aware of all those principles, but @ircmaxell, contributor to PHP, made a video on password hashing with a nice comparison of different hashing functions and it struck me how quickly even a sha512 is computed quickly. Before, I often considered bcrypt as a nice feature to add to a backend but I now realise it is a must.
And be sure to check his blog post with the slides and some other discussion (yes, we have the same blog template).
Now, this is all very cute, but Anthony talks about an easy API coming in PHP 5.5 so it will not be usable anytime soon.
Here are plugins/ways to integrate bcrypt into several platforms:
- PHPass
- PHP-PasswordLib (5.3+)
Wednesday, October 10, 2012
Git tutorial and global configs
Sure, you can take a week off and read the official Git Book but I wanted to give a crash course where I work so it was a bit lengthy. Don’t get me wrong, the Git Book is wonderfully written and anyone serious about Git should read it at least diagonally. However, if you don’t feel it at the moment, head over at http://www.vogella.com/articles/Git/article.html
Also, here is my setup for gitconfig and gitignore. Just copy gitignore to /etc/gitignore – or ~/.gitignore and change the corresponding path.
Batch update modules or themes of Drupal 6/7 in command line
I wrote a simple script that parse the module's page and install or update the most up-to-date version.
This works for themes as well. To use it, simply go into a modules or themes folder and run one of the tool.
Valid folders are:
- /modules
- /themes
- /sites/all/modules
- /sites/all/themes
- /sites/*/modules
- /sites/*/themes
drupal-install-module.sh will install or update one module, drupal-update-modules.sh will batch update all modules in current folder.
Tuesday, October 9, 2012
Verifying DNS propagation
Finding your nameserver (NS)
Query your NS directly
Verifying NS propagation
Verifying world propagation
Clearing local and domain cache
- Windows: ipconfig /flushdns
- Mac: dscacheutil -flushcache or lookupd -flushcache
- Linux: Restart nscd and/or dnsmasq or equivalent
Contacting your ISP or bypassing them
Google:
- 8.8.8.8
- 8.8.4.4
OpenDNS:
- 208.67.222.222
- 208.67.220.220
Testing your Regex skills
Now that you know that you must not use it everywhere, nothing stops you from trying. For example, when using a text editor, you might want to write a simple Regex to match some HTML just to find where it is in all your code, it does not have to be perfect, just good enough. @callumacrae has made a nice website where he posts a challenge every tuesday. http://callumacrae.github.com/regex-tuesday/
Here are my answers so far. They are not perfect, I have taken quite a few shortcuts, but it should get you started.
WebPlatform.org – When giants get together
The correct way is always changing. One of the worst is to embed a video. Do we use a Flash player, a video tag, or both ? Perhaps a javascript fallback on top of it ? What about codecs and fullscreen ? These things always evolve, adjusting with new technology and new hacks that are found.
Now, giants have decided to do something about it and help us, poor souls. Featuring big companies and big names, here is the launch video of a new wiki called WebPlatform.org. It is really at an alpha stage, but with all those names on it, they could have as well called it thedocumentation.org.
Also, as a bonus, check out a TED talk from Tim Berners Lee, whom we attribute merely the invention of the World Wide Web: http://www.ted.com/talks/tim_berners_lee_on_the_next_web.html
Wednesday, October 3, 2012
Going further
Anyway, now that it is over, it is time to put it into practice. I worked for 4 years in a mid-size Web company and now I decided to associate myself with a rather new startup and hop in head first. I worked with them for a while as a consultant and they do business the way I like it: great company spirit, nice ideas, will of using the new and open-source technologies and decent business hours. Come and see us!
I always told myself that a nice work environment where you feel comfortable and continuously challenged is the most important. Hence, I will continue in the same path, sharing the interesting stuff I find while exploring the different Web technologies and trying to make some sense of all this HTML/CSS/JS/PHP/SQL/WTV.
Also, I finally decided to create myself a LinkedIn and a professional Twitter.
See you on the Interwebs!
Tuesday, September 18, 2012
Protect Webserver against DOS attacks using UFW
Typical setup of ufw is to allow HTTP(S), limit SSH and shut everything else. This is not a UFW or iptables tutorial, you may find a lot of online help to guide you through all your needs. However, I personally had a lot of difficulties to find good documentation on how to protect yourself against HTTP attacks.
A lot of HTTP requests is normal
The problem is that HTTP can get very noisy. A typical Web page can easily have up to a hundred of assets but usually, if you receive 100 requests in a second, it means you are under siege. If you really need to have 100 assets on a single Web page, you need a CDN, not as better server.Rate limiting
Connections per IP
Connections per Class C
Packets per IP
Configuring UFW
The following instructions are targeted at UFW, but it is really just a wrapper so it should be easy to adapt them for a generic system.Edit /etc/ufw/before.rules, putting each part where it belongs
Make sure ufw runs and reload everything using ufw reload.
Testing the results
- http://ha.ckers.org/slowloris/
Written in Perl, features a lot of common attacks, including HTTPS - http://www.sectorix.com/2012/05/17/hulk-web-server-dos-tool/
Written in Python, basic multi-threaded attack, very easy to use. - http://www.joedog.org/siege-home/
Compiled, available in Ubuntu repositories, very good to benchmark - http://blitz.io/
Online service when you can test freely with up to 250 concurrent users
Friday, September 14, 2012
Generate missing Nginx mime types using /usr/share/mime/globs
Linux uses a glob pattern to match a filename while Nginx matches only extension, but we can still use every glob in the format of *.ext
So here is a small PHP script converting/sorting/filtering/formatting everything in a nice output.
Wednesday, September 12, 2012
Configure ElasticSearch on a single shared host and reduce memory usage
However, you may want to use ElasticSearch on a single host, mixed with your Web server, database and everything. The problem is that ES is quite a CPU and memory hog by default. Here’s what I found through trial and error and some heavy search.
This idea is to give ES some power, but leave some for the rest of the services. At the same time, if you tell ES that it can grab half of your memory and the OS needs some, ES will get killed, which isn’t nice.
My host was configured this way:
- ElasticSearch 0.19.9, official .deb package
- Ubuntu 12.04
- 1.5GB of RAM
- Dual-Core 2.6ghz
- LEMP stack
- Allow user elasticsearch to lock memory
- Edit /etc/security/limits.conf and add:
elasticsearch hard memlock 100000 - Edit the init script: /etc/init.d/elasticsearch
- Change ES_HEAP_SIZE to 10-20% of your machine, I used 128m
ChangeMAX_OPEN_FILESto something sensible.Default is 65536, I used 15000
Update: I asked the question on ElasticSearch group and it may be a bad idea, without giving any advantage.- Change MAX_LOCKED_MEMORY to 100000 (~100MB)
Be sure to set it at the same value as 1.1 - Change JAVA_OPTS to "-server"
I don’t exactly know why, but if you check in the logs, you will see Java telling you to do so. - Edit the config file: /etc/elasticsearch/elasticsearch.yml
- Disable replication capabilities
- index.number_of_shards: 1
- index.number_of_replicas: 0
- Reduce memory usage
- index.term_index_interval: 256
- index.term_index_divisor: 5
- Ensure ES is binded to localhost
network.host: 127.0.0.1 - Enable blocking TCP because you are always on localhost
network.tcp.block: true - Flush and restart the server
- curl localhost:9200/_flush
- /etc/init.d/elasticsearch restart
Monday, September 10, 2012
Make your dev machine public using a VPN and a proxy
- Developing a Facebook App
- Developing an OAuth authentication
- Make a quick showcase for your client
You will need
- A public Linux box with root access
- A domain name where you can setup a wildcard
Instructions, tested on Ubuntu 12.04
- Install apache or nginx and pptpd (you can follow this tutorial for the VPN or this one if you are using ufw)
- In you /etc/ppp/chap-secrets file, be sure to specify a fixed address for yourself (4th column)
- It must fit the IP range specified in /etc/pptpd.conf
- Create a DNS wildcard pointing to your server
- Ex: CNAME *.dev.lavoie.sl => server.lavoie.sl
- Create an Apache or Ngnix proxy to match a server wildcard and redirect it to the VPN IP decided before
- Create the same wildcard on your machine to answer correctly.
Security considerations
Configuration example for Apache and Nginx
Monday, August 27, 2012
MySQL becoming more and more closed source, thanks to Oracle
Oracle has an history of sabotaging opensource projects, it does not work well with their business model.
- 2010, OpenSolaris
- 2010, Java / Android
- 2010, The Document Foundation feared for OpenOffice and forked it as LibreOffice. Oracle finally donated the project after seeing its market share sink rapidly.
- 2012, MySQL is starting to lose its independence.
PHP frameworks and CMS with support for PostgreSQL
- Drupal
- Wordpress, as a plugin, might be unstable
- Doctrine which makes Symfony compatible
- CodeIgniter
Harvard cracks DNA storage, crams 700 terabytes of data into a single gram
Monday, August 20, 2012
Convertir le calendrier UdeM au format iCal
- Utiliser Chrome
- Aller sur le guichet étudiant et consulter votre horaire.
- Rendu sur la page de l’horaire, ouvrir le menu développeur de Chrome: Ctrl-Shift-I
Sur Mac, c’est Cmd-Alt-I. - Cliquer sur le dernier onglet qui s’appelle “Console”
- Là où le curseur clignote, coller ceci:
Si ça ne fonctionne pas, dîtes-moi le !
Monday, August 13, 2012
PHP Coding standards
The group is name PHP Framework Interoperability Group and is composed of, but not limited to, authors from these projects:
- phpBB
- PEAR
- Doctrine
- Composer / Packagist
- Joomla
- Drupal
- CakePHP
- Amazon Web Services SDK
- Symfony
- Zend Framework
Why coding standards?
You may be a fan, for example of naming your functions with underscore or use tab indentation, but really this is not point. The goal is to be able to use code from other authors and projects without having to "fix" the code style to be consistent with your project.In the future, the group also aims at providing some interfaces so implementations from different can work together.
Accepted standards
I don’t want to rewrite all my code!
You can try PHP_CodeSniffer, but personally a find it a pain to use because it only 'validates' and make some errors. It should probably need a rewrite.
Some editors have plugins:
You can also add a Git commit hook to patch on-the-fly.
Further reading
Great blog post from Paul M. Jones.Reducing the load of all those social plugins
Most of these libraries suggest to load them in async.
Library examples
- Google Analytics
- Google Maps
- Google Plus
- Facebook Like
- Twitter button
Problems with existing solution
- A lot of ugly script tag with semi-minified code.
- Most of the library suggest the same trick so we see code duplication.
- You have to go copy-paste the code each time you start a new project.
- If you have multiple libraries, they will all fire at the same time, possibly causing a stress on the browser
- While the libraries are loading (usually with a lot of dependencies) the browser is sluggish and users probably want to read that article before clicking on 'Like'.
Solution
- Load each library with a function taking an id, a url and a delay.
- Allow each library to have a different delay.
- You may want Google Maps to load only 200ms after the page, but the Facebook Like can wait a bit more.
- Code on Github
- Working example on jsfiddle
Wednesday, August 1, 2012
Is the online ad industry a fraud?
A blank banner ad received more clicks than the average Facebook ad, twice as many as your average “branded” display ad (a static ad which promotes a brand rather than a specific offer or call to action), and only one click in ten thousand less than the average banner ad.While we all hate advertising when browsing, it provides nice revenues and is often how a website is able to live.
What the ARF shows us is that the companies paying for advertising may be paying for air or, what is more likely to be true, inflated data.
They also asked the users if it was a mistake or if they were curious about a “blank”:
The average click-through rate across half a million ads served was 0.08%, which would be good for a brand campaign, and so-so for a direct response campaign. We detected no click fraud in the data we counted. Half the clickers told us they were curious, the other half admitted to a mistaken click.The conclusions are yours to make.
Solving complex network problems using… fungus
The part I am talking about is at 1:03:45 and demonstrates a slime mold searching for its food, optimizing the network path between food sources and even creating some backup routes.
This is quite interesting considering that network resolution is a hard problem that requires quite a bit of processing.
P.s. The rest of the show is quite fascinating as well
Generate a random string of non-ambiguous numbers and letters.
Doing md5(microtime()) is nice but it is 32 chars long. I could use base64, but it contains weird characters like "/" and "=".
So how do I restrain the encoding to alphanumeric ? I found the inspiration from Ross Duggan and I added a random function. He also removes a couple ambiguous chars, which I think is a nice touch.
The choice of random could be discussed but the idea is there.
UPDATE: As suggested by a friend, it is simpler and a better use of the range of available entropy to generate each character separately. You can see the old version in the Gist.
Tests included
Friday, July 13, 2012
Introducing Dotfiles Builder
Managing bashrc sucks
We all have our nice little bashrc that we are proud of. It tests for files, programs and terminal features, detect your OS version, builds a PATH, etc. For all of our OS and different setups, various solutions exist.
Keeping several versions
Pros:
- Ultimate fine-tuning
- Easy to understand
- Usually optimized for every setup
Cons:
- Very time consuming to manage
- Hard to “backport” new ideas
Keep a single unusable file with everything and edit accordingly
Pros:
- Easy to backport, you just need to rembember to do it
- Good performance
- Since you edit at each deployment, nice fine-tuning capability
Cons:
- The single file can become unbearably cluttered.
- You eventually end up managing several version.
- Tedious to edit at each deployment
Include several subfiles
Pros:
- Still have a lot fine-tuning capabilities
- If well constructed, can be easy to understand
- Easy to deploy new features
Cons:
- Hard to detect which file to include
- Multiplicates the number of files to manage
- Slow performance
- Until recently, this was my prefered method.
Wanted features
So, what does a good bashrc have?
Should have:
- Good performance. On a busy server, you really don't want to wait 5 seconds for your new terminal because your IO is sky rocketing.
- Reduce number of included files
- Reduce tests for environment features
- Reduce tests for program and files
- High flexibility
- Cross-OS compatible
- A lot of feature detection
- Ideally, configuration files
- Ease and speed of configuration
- It should not take more than a minute to setup a new bashrc
- If you need to specify your developer email, it would be nice to do it only once.
Yes, you read right, reduce tests AND do a lot of feature detection. You don't want to do Java specific configuration or set an empty variable if Java is not even installed, but you do want Java to be automatically detected.
Generating a bashrc
Let's face it, you will install or remove Java way less often then you will start a new shell. Why then test for Java at each new shell?
This is where I introduce the Dotfiles Builder. The script runs in Bash and outputs the wanted bashrc.
This way, instead of doing:
if [ -d "$HOME/bin" ]; then PATH="$HOME/bin:$PATH" fi
You would do:
if [ -d "$HOME/bin" ]; then echo "PATH=\"$HOME/bin:$PATH\"" fi
And the result would simply be
PATH="$HOME/bin:$PATH"
But constructing PATH is a rather common task and you want to make sure the folder is not already on your PATH. Why not wrap it up ?
Take a look at the alpha version:
https://github.com/lavoiesl/dotfiles-builder/
As well as the example output.
This is a very alpha version of the intended program, but I still want to share what I have and maybe get some feedback and collaborators along the way. Currently, it only generates a bashrc, but expect more to come.
Thursday, July 12, 2012
Use credentials in /etc/mysql/debian.cnf to export MySQL database
Quite a usual task is to dump a database to do backups. You may even want to do this in a cronjob to snapshots, etc.
A very bad solution
A very bad solution is to hardcode the root password in the cronjob or in your backup script; doing so have a very high chance of exposing your password.
- It may appear in the cron.log
- It may be sent by email if you have an error
- It may appear in your history
- It is a bad idea to your backups using the root account
A better solution
You could create an account with read-only access to all your databases and use it to to your backups. This is indeed better but can lead to the same issues mentioned above
Putting the password in a file
The safest way to use passwords on the command line is to store them in a file and have a script load them when needed. You then just need to make sure those files have the correct permissions
An “already done for me” solution
As it turns out, installations of dbconfig on Debian/Ubuntu creates a user called debian-sys-maintainer. It is used to do MySQL management, mainly through the package manager. Well, this user has all the needed privileges to backup your database and you are sure it will always work. Unless, of course, you manually change the password without updating the file.
This script uses sudo so it will ask your password even if you forgot to prepend sudo.
Typical usage
$ export-database.sh my_database [mysqldump options] | gzip > /tmp/my_database.sql.gz
PHP script to replace site url in Wordpress database dump, even with WPML
The only solution is really just to edit the database. At least, I haven't found a better solution.
Usage
wordpress-change-url.php http://old-domain.com https://new-domain.com < database.orig.sql > database.new.sql
Or
wordpress-change-url.php database.orig.sql https://new-domain.com > database.new.sql
Apache VirtualHost Template with variable replacement
This is in no way a robust solution for deploying a real web hosting infrastructure, but sometimes, you just need basic templates. I use this simple template on my dev server.
Remove temporary and junk files from Windows and OS X
One of the most annoying things with being able to see all files in the terminal is that… you see all the files. That includes backups, swap and temp files.
Well, it’s a rather good thing, it remembers you to remove them once in a while.
Monday, July 9, 2012
Document Root fix in .htaccess when using VirtualDocumentRoot
# RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ app.php [QSA,L]
The RewriteBase has to be enabled if you are using a VirtualDocumentRoot but when you are sharing code, developers may all have different setups.
By checking the content of DOCUMENT_ROOT, we can guess which setup we are using and prepend a / when necessary.
Note however that this method is heavy on string comparison which is slow and should not go on production.
Writing a PHPUnit test for Symfony2 to test email sending
We generate a fake unique content and loop through all sent emails to verify that is was sent.
Note that this does not actually test if the email is sent to the server but merely tells you if Symfony is trying to send it.
Inspiration: http://docs.behat.org/cookbook/using_the_profiler_with_minkbundle.html
Sunday, July 8, 2012
Validating emails using SMTP queries
Regex validation
MX record check
Downside: You do not test if there is actually a mail server accepting emails at this domain and the full address is not validated.
Real validation using a confirmation email.
Introducing SMTP query
- This email is known, server replies 250 => Email is valid.
- Email is greylisted or some minor occurs: 450 or 451 => Email should be valid.
- Other error => Email is invalid.
Conclusion
- Handle common format issues using client-side and/or server-side regex validation.
- MX record check
- SMTP query
- Send a confirmation email, not asking for any validation but explaining to the user that he should contact you if he doesn't receive an email.