Author Archives: astaz3l

Tips for choosing right server

How to choose right server for your app?

I need to start with the short statement - you probably don't need hosting or server. This article is dedicated mostly to tech people. If you are looking for tips how to pick a server for your website and you don't know what Shell, SSH or FTP is, please read only the chapter below:) If you want to jump to strictly tech stuff - click here.

You don't need hosting/server

If you are just starting a blog, small business website or e-commerce, don't bother looking for hosting and a developer who can create your website. These days we have great alternatives that will take care of your website from start to finish.

They will care about server infrastructure, security, backups, servers performance, updates to CMS, bug fixes and everything you need for having website up and running. You won't have to ask a developer to fix a bug or change a text on your website.

If you are just starting and you don't want to spend hundred of $$$ for a website you can try some services I will mention about. All you need is to have some time to configure everything. Most of them have free trial, so you can try it first for free. Some of them offers free features that are sufficient for lot of websites. Remember, you can always change it in the future to your self-hosted website.

If you plan to go with a blog and you want to focus on writing I suggest you get yourself familiar with https://wordpress.com and https://medium.com/

Medium is awesome alternative to popular WordPress. IMHO they have much nicer editor. If you care only about writing, try it first before going with WordPress:) You can always try both and decide which works better for you.

If you want to sell stuff online, go with https://www.shopify.com/  Super useful e-commerce with number of options. In general you need to buy a plan. Cheapest one is 29$ per month, but it's still cheaper and safer than running custom e-commerce like WooCommerce or Magento. They also have trial version:)

If you want to create a website for your business/company try WIX first - http://www.wix.com/ It's a website builder when you can create your own site with Drag&Drop. Lot of small businesses have websites build with WIX.

If you are fine with features that mentioned services are offering, you can stop reading here. Such services are great until you really need something custom. The feature that none of the services can offer. In such case you need to find someone who can build your website. You will need a hosting or server. If you need to look for server for your small website, make sure that you will choose right hosting plan.

If the website is small and it won't receive lot of traffic you should only pay attention to few details. I know that price will be important here, but remember. Sometimes the cheap comes out as expensive.

If you decide to go with shared hosting, your website will be slow or even unaccessible if lot of visitors will go to your website at the same time. You will need to change plan to something better or go with VPS/dedicated server. Make sure that you will choose such server with management (your server will have dedicated administrator). Trust me, if you don't know a thing about server administration and security, you don't want to choose unmanaged server:)

Make sure that they have backup plan, or do your own from time to time. Recently in Poland we have situation when one of the bigger hosting provider deleted all websites and thousands of people lost they websites permanently. They hosting plans were quite cheap so they got lot of clients. But after the incident all websites was down for 2 months. People who made backups on they own, rescued they websites quite fast, but rest lost their websites forever.

You can stop reading here. Rest of the things are for tech people! Unless you want to get some knowledge about servers:)

To cloud, or not to cloud?

Yes, you should go with cloud, but only if your website earns money. And I mean MONEY, not few dollars every month. Cloud is not cheap. It's expensive. And sometimes it can get really expensive. Like hundred of dollars every month. You pay the price, but you get a value.

We had a website that was mostly image based and got quite a lot of traffic. We were using Amazon AWS. Two EC2 instances (prod + stage), Elastic IP, S3. We paid around 500-600$ every month. Most of costs were traffic (around 2-3TB every month) and EC2. I felt like that's a lot of money for such website. Fortunately we didn't pay for it. Our client was big, was cloud oriented and money didn't matter, so we used AWS. But for my personal website and for lot of other websites 500$ every months is a killer.

So can you lower the costs somehow and still use cloud? Yes, you can. But first thing first.

Serverless maybe?

First you need to think about two important points.

  1. Do you have time to take care about server architecture, regular updates, configuration etc?
  2. Think about your application. Does it need specific server architecture, or you only care to have it up and running?

Most of people thinks - installing LAMP stack and setting some basic configuration is no brainer. Well, server management is unfortunately not that easy. Of course, your server will work for some time until you will get hacked or you will get some performance issues. And trust me, you will if you won't pay attention to your servers. We've been hacked twice, because we thought that server management doesn't require time and attention. Our servers has enormous load because of older version of few libraries. We were not even able to SSH to our servers;/

So if you only care about your app, try Heroku first. It's running in the cloud (on AWS actually), has support for tons of technologies and you don't need to care about server infrastructure at all. They will care everything for you. It feels that it might be expensive, but think if setting custom server + hiring server admin will not be more expensive?

Heroku is super convenient and powerful. You can setup and deploy your up within minutes. Their uptime is pretty good, scalability is nice and easy to configure. Give it a shot (they have free trial), maybe it will be much better than setting up a server 😀

Our solution

We go with old fashion way, with servers that we manage on our side. Downsides? We need to spend time to configure and maintain them. But from the other side we have full control of our server. And we don't pay $$$$$$$$$$$ for them:)

We adapt infrastructure to our projects. But in most cases it goes like that - VPS/Dedicated server/Cloud based server + Amazon S3 + CDN/Amazon CloudFlare.

Server features

When we are looking for server we are looking mostly at such features:

  1. SSH+Root
  2. OS and OS version
  3. CPU
  4. RAM
  5. SSD
  6. Transfer
  7. Additional IP address

SSH+Root - server must have SSH access. Era of FTP and manually uploaded files to server is fortunately behind us. So if server doesn't have SSH access it's not the right choice. Also, pay attention for full root access. We saw servers where you can login via SSH and do only basic stuff like GIT, creating files etc. But it was not possible to install anything. If it doesn't have root, you shouldn't use it.

OS - It's important to see what operating system they support. We are mostly looking for CentOS 7, as this is our OS of choice. If you want to go with Ubuntu, that's OK. We prefer CentOS. Version of the system is really important. Sometimes you can't install latest available version, like CentOS 7. If for instance latests supported version for server is CentOS6, we are looking for something different. Also make sure that it is x64 os. 32 has lot of limitations and you should avoid it.

CPU - we are mostly looking for processors with 2 or more cores. 1 core is enough if you want to run small app or only one website. But if you plan to go with something bigger, 2 or more cores will get you significant performance boost.

RAM - 1GB is minimum, but if it has much more RAM it's great. We avoid 512MB, it's way to small and you can get issues when you try to compile PHP from source for instance. Basically for optimisation, caching etc, it should have as much RAM as possible. We usually goes with 2GB and above. But 1GB is minimum you should aim for.

SSD - if it has SSD, that's great. We switched all our servers from HDD to SSD. Machines are much faster and more performant. Downside is that usually they are bit more expensive and have smaller disk sizes. If you need lot of disk space you should go with SSD + HDD.

Transfer - it is really important factor. If you will serve images from your server or you expect lot of traffic and you won't use CDN, you should go with 1-2TB per month. It really depends on the website and traffic, so it's hard to say how much transfer you will really need.

Additional IP addresses - if you plan to host multiple websites on single server make sure that it allows you to add additional IP address. If you want to go with SSL, and I'm sure you will want to do that, 1 IP address is not enough. You can't have two SSL websites on single IP address.

Your server does not have to be in Cloud, unless you want to get easier access to automatic scalability etc. We are using two providers mostly. For smaller apps/websites, we are using DigitalOcean. Simple pricing, nice servers, easy to use. Most of our servers are 10$ or 20$ per month. We don't go higher as it becomes more costly.

However if we need more horsepower, more RAM, CPU cores we are looking for something more performant. We are using dedicated servers for that. We tried multiple solutions but our favourite so far is Hetzner. They have really nice value for the money. For instance for around 50$ you can get 4 cores, 32GB rams and 30TB of traffic. Uptime is pretty high and their support is awesome. Highly recommended:)

How about pure cloud solutions?

You can of course go 100% with AWS, but as I mentioned above, it will cost you significant amount of money. It will have it's benefits, but I feel that AWS is dedicated to large companies and websites. I especially don't like their pricing as it's hard to predict how much you will pay for given configuration.

We however use AWS for two purposes.

Backup - it's important factor. Most of users that runs their own servers, usually forget about making backups. Guys, if you don't do backups, start today. Hard drives can break, you or someone else can delete something etc. Backup are super important thing! We are using S3/Glacier from AWS for this purpose. Once per day or every couple of hours we are making full backup of DBs/Images/Important data to AWS. It's really easy to setup and to use. After an hour or so, you should get your backups up and running. Glacier is relatively cheap and Amazon is taking care of persistence of our data.

CDN - If MaxCDN or CloudFront is not enough, we go with CloudFlare. IMHO they offer enormous number of features and configuration gives us much more power.

Should I use CDN?

Speaking about CDN. Should you use one? The answer is yes. It will give your website significant boost if your users are connecting from different countries. Hetzner has their servers in Germany, but some of our websites are worldwide oriented. CDN is a must here.

You can have CDN for free by using CloudFlare. They don't offer much options but it's for free:) If you have a blog with lot of images, it will also takes some of the transfer for you from the server. Images will be served from CDN instead of your server.

If free is not enough, you can use paid plan from CloudFlare or try MaxCDN.

If you need detailed control, we suggest to go with Amazon and their CloudFront:)

Summary

So it's all come down to how much time and money do you want to spend here. If you don't plan to run your own servers for your app, you should go with Heroku. If you want to play around with servers and want to have bigger control, go with DigitalOcean/Dedicated Server + S3/Backup server + CDN. It's the best value for money. If you have lot of money and you want best scalability and performance, go with AWS and all the features it offers;)

If you will go with DigitalOcean or custom server, you should learn about Ansible. It will save you lot of time when it comes to configuration of the server. Read the tutorial about Ansible.

If you want to learn how to configure your own server, you should read our series about setting up LAMP on steroids.

Wordpress won't send emails

WordPress won’t send emails

It's been long time since I wrote something here. But today I decided to wrote the story of my problem with WordPress. In short words - WordPress won't send email. The problem was raised by the clients, they didn't receive emails from WooCommerce with downloadable item. It was huge problem, as payment was processed successfully, but they didn't receive email with PDF they bought.

Research about not working emails in WordPress

I read tons of threads, articles about problems with WordPress emails. Lot of solutions but none of them actually fixed the problem. It pissed me off, because something like that should work without any problems!

Solving the problem with WordPress emails.

I checked few things:

First of all I wasn't sure if it's a problem with WordPress or with WooCommerce. I'm using PayPal only so i turned on debugging in WooCommerce PayPal settings. I tested the transaction, no email sent. I checked the log, and transaction was completed, but no errors on sending email or anything like that.
Error log from apache was empty so it wasn't pure PHP problem or anything like that.
WordPress use default PHP mail() function for sending emails. In hundreds of threads I checked they suggesting using SMTP protocol instead of using mail function. I installed plugin called Check Email. It's simple plugin that checks if WordPress is sending email correctly. I used standard headers for that, typed the email. Check Email told me that email was sent successfully, but it doesn't mean that email will be delivered. I checked my gmail account and no email at all ;/

So I thought, OK, I will switch to SMTP. I installed plugin called WP-Mail-SMTP. All i need was email account where from I will be able to send emails. So I logged in to my server admin panel (DirectAdmin in my case) and created some dummy email. I received all required information for WP-Mail-SMTP plugin like host and port. I filled all require settings field in plugin's settings. Plugin has also great feature where you can test the email. Everything was great, email should be delivered. I checked my gmail account. Still nothing.

Right direction

That was pretty weird for me. It should have work like a charm! So I decided to log in to fresh created email address and try to send email from there. My server provider has Roundcube system as email system. I created new email and it wasn't delivered. But! I received response email with title: Mail delivery failed: returning message to sender. Email says:

This message was created automatically by mail delivery software.

A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:

*****@gmail.com
SMTP error from remote mail server after end of data:
host aspmx.l.google.com [2a00:1450:4013:c01::1a]:
550-5.7.1 [2a01:4f8:101:324d::2 12] Our system has detected that this
550-5.7.1 message is likely unsolicited mail. To reduce the amount of spam sent
550-5.7.1 to Gmail, this message has been blocked. Please visit
550-5.7.1 http://support.google.com/mail/bin/answer.py?hl=en&answer=188131 for
550 5.7.1 more information. i49si3865415eem.12 - gsmtp

I checked the link in the email. Title of this page is Why has Gmail blocked my messages?

First thing that comes to my mind was that I'm on some kind of blacklist. Maybe I'm a spammer? I used http://mxtoolbox.com/ - great tool that checks if you're not blacklisted. My domain was OK, not blacklisted at all.

What comes to my mind, for test i was using @gmail.com email all the time. I tried to send email to other domain and... email was delivered! I read all that I could and it seems that gmail, yahoo, and few other bigger email providers have algorithms that sometimes block domain, server etc. I wasn't able to find complete solution for this problem. Also, i didn't want to contact Google Customer Center or anything like that. Also i was wondering why I've been blocked by Google?

Fixing Google issue

First of all, i had free domain that I got when I bought the server. I created new account to check if server or domain is blocked. I had the same problem with sending emails from this domain so it was obvious to me, that there's something wrong with the server.

Solution 1 - SPF

SPF is Sender Policy Framework that secure SMTP servers from email spam by email spoofing detection. First of all, I need to know what You must add and where. It should be somewhere in Your server admin panel where You can manage DNS settings. If You can't manage the DNS option You will have to ask Your hosting company to add SPF information to Your DNS records.

It's TXT record with this signature:

v=spf1 [server info here] ~all

Where you have to replace [server info here] with

if You have domain server for your mail server where emailserver.com is domain of Your server

include:emailserver.com

Or server IP address where 111.222.333.444 is mail server IP

ip4:111.222.333.444

Example:

v=spf1 ip4:180.4.140.130 ~all

Important note is that You must use "From" address, that belongs to SPF enabled domain. If You won't provide this information SPF won't work.

I added the record to my DNS panel. I read in 2 or 3 threads that it helped in WordPress not sending email case. But it didn't helped in my case unfortunately. Maybe it didn't worked but I had anti spoofing protection to non-gmail emails 😀

Solution 2 - DKIM

After some further research I finally found working solution DKIM - DomainKeys Identified Mail. It's a way of associating Your domain name with email message.

Unfortunately for the reader it requires integration with server. Simple DirectAdmin or other panel might be not enough in that case. The simplest way is to contact Your hosting provider and require to setup DKIM for Your domain(s).

If You have access to Your server you can do it by yourself. Here is great tool for generating DKIM keys: http://dkimcore.org/ Installation process is different for every server and it depends of the software and OS you're using. I bet that you can find tutorial for Your OS'x using Google Search. For instance here is the tutorial for Postfix and Debian:

https://www.digitalocean.com/community/articles/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy

Hope that one of this option will help You solve Your WordPress email sending problem. If You have any other solution that might help solve this issue please post it in comments below:)

 

 

Instagram Widgets Overview

Instagram Widgets Overview

Recently I was looking for Instagram widget for some of our sites. We wanted to display images grabbed from Instagram by hashtag and from particular account. But which one to choose? Instagram doesn't provide any widget like Facebook or Pinterest. But from the other side Instagram has very powerful API that can extract images from their database. But why bother to write something like that when You have few quiet nice plugins? Let's do short overview.

SnapWidget | Instagram Widget

http://snapwidget.com/

Personally I used it a few times. It has the basic functionality which most of the widgets have. You can extract images from Instagram by username and hashtag. They have 5 basic types of displaying images. As a grid, slideshow, map, board and scrolling slider. Each of them are customizable in some way.

Widget, as all of them, come as an iframe that You have to embed on Your website anywhere You want. "Installation" is super easy if You know HTML a little bit. But non-geek people that are using ready WordPress installation for instance could have a problems in installation.

Widget is free for all users, but there's also non-free version, with some additional bonuses. But for most of users features that comes with free version will be enough.

Instagram Widget | Intagme.com

http://www.intagme.com/

Actually it's a copy of SnapWidget, but with little less options. You can generate widget from Instagram username or hashtag. It generate an iframe. It's completely free, doesn't have any paid version.

Don't know why, but few times we get nginx errors instead of our pictures. That's the only one issue that I found with Intagme. Problem was solved quiet fast and we were able to see our pictures again. Hopefully that won't happen again:)

Instagram Widget and TOOLS | Webstagram

http://web.stagram.com/tools/

Webstagram is more advanced than other websites. I mean, they have much more tools, than simple gallery. They also have follow us button and so on. Number of options in gallery is somewhere between Intagme and SnapWidget. It generate the iframe as all widgets that You can easily post into Your website. And it's free:)

In general, gallery widget is cool add-on to Webstagram website, which is quiet integrated with Instagram.

 Slidagram | Free Instagram Slideshow Widget

http://www.slidagram.com

Very nice website, with exactly the same features as previous widgets. It's free, comes as an iframe, so it can be putted almost everywhere. Not so intuitive interface thought, but still, it offers the same functions as previous one.

Instansive | Responsive Instagram Widget for Your website or blog

http://instansive.com/

Last, but not least - Instansive. Personally I think that it's the best Instagram widget available. I mean, it doesn't have that much options. Let's say that even less than Instagme. You can generate widget from username or from hashtag, like on previous one. The only type is grid, but for our purposes it was enough:)

The biggest advantage of this plugin is that it is RESPONSIVE. Previous widgets unfortunately are not responsive. There are of course number of hacks where You can hide and show certain iframe, but i think it's not the best idea. One missing thing for me was changing the number of pictures when I reach certain break-point, but I can live with that.

I wrote an email to creator of Instansive, with questions about the features and future development. Response came quiet fast and was more than satisfying. I can't tell You much about the upcoming features, but I was allowed to inform here that new types like scrolling widgets, better mobile support, multiple styling options, break point manager (may be quiet interesting thing!), Instansive as WordPress and Drupal plugins and many more.

I think it worth to check this plugin. It has also quiet good support. Questions are answered pretty fast via email.

 

Which one Instagram Widget  should I choose?

For me choice was simple. If I need slideshow or more customization options I suggest use SnapWidget. But if You don't need multiple functions and Grid type is good enough for You + You have responsive website, Instansive is obvious choice as Your Instagram Widget.

postMessage in JavaScript

postMessage in JavaScript

The big problem with iframes is communication between the iframe and it's parent. When the origin of an iframe is the same as parent there's no problem. But when the domains are different it was impossible to change anything in iframe from parent for instance. postMessage solve this problem almost completely.

Two ways communication with postMessage

The cool part is that postMessage works almost on every browser including IE8. Let's start playing around with postMessage then.

Sending data with postMessage

Let us take a look on the snippet below

var iframe = document.getElementById('iframe').contentWindow;
iframe.postMessage('Hello iframe!', 'http://iframe.domain.com');

Yes, that's it:) In first line we are getting contentWindow of iframe with id="iframe". Let's assume that domain of page inside the iframe is http://iframe.domain.com

In second line we will send the message to this iframe via postMessage function. It takes 2 parameters. First one is data that we want to send to iframe. Basically it can be any kind of object, json, etc. but the safest way is to use String type. It is supported by all major browsers.

Second parameter is target domain. It should be the iframe URL. You can also put * to target any domain. But from security reasons and targeting only particular iframe with given domain I suggest to put the URL address:)

Receiving data with postMessage

Receiving data will take little more than 2 lines, but is as easy as sending. Take a look on example below:

var messageListener = function(event){
    //Optional check
    if(event.origin !== 'http://domain.com'){
        return;
    }

    //Do whatever You want to do with recieved data
    console.log(event.data);

    //Respond
    event.source.postMessage('Message recieved, thanks!', event.origin);
}

if(window.addEventListener){
    addEventListener('message', messageListener, false);
}else{
    attachEvent('onmessage', messageListener);
}

First of all we should write short function that will handle our message. It should take parameter that will have received message.

With event will come 3 basic properties that are important to postMessage

  • origin - contain domain from where message was posted
  • data - posted message
  • source - reference to sender window

First of all we can check if message should be accepted. It's optional check. Usually I don't care where from message was posted. But if we want to check, origin will help us.

In event.data we will have our posted data. Now world is Yours and You can do whatever You want to do with that:)

Quiet often we want to respond to the message, for instance send confirmation message or some status. We will use event.source.postMessage() function. As target domain pass event.origin, to send request to sender window.

But do not forget that You have to write another receiving function in parent window, that will handle onMessage request!

Last part is to bind our function using eventListener, or in older browser using attachEvent function.

GIT Deployment Keys

GIT Deployment Keys on Windows

Hello everybody!
Today I'd like to show You how to setup deployment keys on Windows OS. It's pretty helpful and time saving thing. If You are tired of passing username and password each time, it'll be simpler to use deployment key. After git push, your won't have to pass username and password.

OK, so how to start with deployment keys?

I'm using both GitHub and Bitbucket. They have possibilities to use deployment keys. I'm not entirely sure how about the rest of services. You will have to click through the settings to check if there's any Deployment key option. As I assume You already have the account. There's no need to read this article further if You don't have such account:p

Second thing that You have to have is GIT. Personally I use msysgit. But deployment keys trick will work on any other GIT that You are using.

Third, the most important thing is Your SSH key. Usually I'm using PuTTY Key Generator (puttygen.exe) to create public and private key pair. But You can use any software like OpenSSH. If You don't know how to generate private and public key, You can learn how to do this here. Or just typing in google something like "windows generate ssh key". There are plenty of good tutorials for that, depends on which software You are using for generating ssh key. While You are using PuTTY Keygen please choose from menu Conversion -> Export OpenSSH key. It will save Your ssh key in OpenSSH format.

When You are saving Your private and public key, it's nice to stick to Linux naming convection. So name Your keys like that:

  • private key -> id_rsa
  • public key -> id_rsa.pub

It's not necessary of course, but it's more readable to other users.

What to do with public ssh key?

When You have your keys generated which will become Your deployment keys, please login to GitHub or Bitbucket. In Your account settings You will find SSH Key options.

  • In Bitbucket You can find this section by visiting Manage Profile and SSH key.
  • In GitHub it's on Account Settings and SSH Key

In both cases please press Add SSH key  button in order to add new one. Label it as You wish and paste SSH public key into Key text area.

Check Repository config

When You create new repo, it's not a problem as long as You copy SSH not HTTPS URL for Your repo.

If You have existing repository, You will have to change it's config file if You want Your deployment keys to be working correctly. Simplest way is just to edit it in text editor.

Please open .git/config file. On Windows .git directory is hidden by default. Modify this file like this:

[remote "origin"]
    url = https://github.com/username/your_project.git //Remove this line
    url = git@github.com:username/your_project.git //Add this line

You can also do it from console by typing this command:

git remote set-url origin git@github.com:username/your_project.git

If You are not sure what Your repository ssh URL should look like, please login to Bitbucket/GitHub, go to Your repository and under clone choose SSH instead of HTTPS. The URL for clone will be the URL that You have to provide in set-url or paste it after url = in .git/config file.

Where to put my ssh keys?

That's very good question actually. When I wanted to setup deployment keys at the first time I didn't really know where to put them. In Linux OS we have .ssh directory in our home directory. So You just have to copy it there and it will work.

On Windows OS there is also ~ directory. Just type ls ~ in You command line and it will take You to Your home directory. Usually it'll be C:\User\USERNAME where USERNAME is Your Windows username. You can create .ssh directory there and it will behave like on Linux OS.

If this trick doesn't work for You, please try to create .ssh folder and copy your keys to msysgit installation folder.

Is it working?

Let's test our setup with deployment keys. Try for instance git pull. After first connection You will be asked if You want to add Your key permanently to know_hosts file. Type yes. You will have to type your passphrase to key if You set one. After that You can use deployment keys and never be notified that You have to type username or password.

Still not working? Please describe Your setup and errors in comments below. I'll try to solve Your problem:)

matchMedia in JavaScript

How to use matchMediaLet's dig in into JavaScript and matchMedia usages. For those who doesn't know what matchMedia is, let me explain. You probably know what Media Queries in CSS are. You can match the max-width for instance to check if You are on mobile device etc. But sometimes CSS is not enough and You have to execute additional code in JavaScript when particular break point in Media Query has been reached. Here matchMedia comes with help:D

Before matchMedia

Before I knew about matchMedia I used onResize event a lot. Every time I checked the width of the screen and for instance if it was lower than 400 pixels I executed the code. But there were two main problems. Getting width of the viewport was usually problematic when I used different browsers. Second problem was that viewport width wasn't always coincide with particular Media Query. For instance when I tried to check if I have 480 pixels media query was executed and CSS rules was changed, but JS code wasn't executed. It drives me mad...

After that I learned how to use matchMedia and it solves my problems (almost)

How to use matchMedia

Usage is really simple. Let's assume that we wan't to check this in JavaScript:

@media all and (max-width: 480px){
 /* Some CSS here... */
}

We will try to target all media that viewport is less or equal to 480 pixels. OK, now the fun part in JS:

var mql = window.matchMedia('all and (max-width: 480px)');
if (mql.matches) {
    //Yes, media query matches, we are 480px or less
} else {
    //No match here, sorry...
}

We create matchMedia by window.matchMedia('here should be your rule');  Basically it's copy+paste from CSS @media rule.

Now we check if it match the CSS by mql.matches If it match we are executing the code or not. And basically... that's it! Now You know how to use matchMedia, really simple, isn't it?

matchMedia and resize event using addListener

OK, but how can we handle dynamic screen resizing? How to wait for changes? For instance I want to execute some action every time screen will reach 480px. For instance let's load mobile ads when we are under 480 pixels and load normal ads when we are above 480px. I will use previous code with some extra stuff:

var handleMatchMedia = function (mediaQuery) {
        if (mediaQuery.matches) {
            //load mobile ads
        } else {
            //load desktop ads
        }
    },
    mql = window.matchMedia('all and (max-width: 480px)');

handleMatchMedia(mql); //Execute on load
mql.addListener(handleMatchMedia); //Execute each time media query will be reached

First of all we have to create function that will handle the matchMedia (handleMatchMedia). After we define it we have to execute the function for the first time. We need to check on page load if we are already in 480px media query or not. Line below we have to add listener to matchMedia. In parameter we have to pass the function that will be executed when viewport will be in media rule.

You have to know that this code won't be executed on every screen resize. Function will be executed ONLY when viewport size will be 480px.

Browser support, polyfills

Generally what is really big plus it that it's widely supported: http://caniuse.com/matchmedia

Problem is on Internet Explorer of course is on IE9 and below. But there is really simple solution for that - polyfills. Here is one of the most popular I think:

https://github.com/paulirish/matchMedia.js/

I remember having problems on IE7 and IE8 with this, but there is nice extension for this polyfill here:

https://github.com/benschwarz/matchMedia.js/tree/IE7-8

 

MySQL insert or update using ON DUPLICATE KEY UPDATE

MySQL ON DUPLICATE KEYMySQL insert or update - one of the most common problems when it comes to database. We want to check if the record exists in the database, if not we want to update it. Let's take statistics example. We would like to insert IP Address if it's not in database or update view's count if it's already in there. Simple? Sure! We can first make SELECT query for the given record. If it's in database we update the record, if not we insert new one. Simple, right? But we can do it with single query using ON DUPLICATE KEY UPDATE

ON DUPLICATE KEY UPDATE - introduction

This is really simple and easy in use. Let's take a look on some really simple example. Let's assume that we want to collect number of views for the article in our website.

It will be as simple as possible, I just want to show You how to use ON DUPLICATE KEY UPDATE:)

CREATE TABLE `stats` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `article_id` int(11) NOT NULL,
  `views_count` int(11) NOT NULL DEFAULT '1',
  `created` date NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

We create simple table with 4 columns:

  • id - auto-incremented unique ID number
  • article_id - ID of our article
  • views_count - number of views of the article
  • created - when stats info was created. To show You more advanced usage of ON DUPLICATE KEY UPDATE lets save only the date without time.

So when we load the page we want to insert row into table if it's not exists. Otherwise we want to increase views_count field by 1. As I wrote before, we can do two queries. SELECT and INSERT or UPDATE. But let's use ON DUPLICATE KEY UPDATE.

First of all we have to have UNIQUE key if we want to use ON DUPLICATE KEY UPDATE. It's a must, we have to have some key that we want to perform check on. So let's think, which field we want to be unique? It's obviously article_id.

Let's add the key then by executing this query:

ALTER TABLE  `stats` ADD UNIQUE uk_article_id(
`article_id`
);

After that query we will have UNIQUE key named uk_article_id.  MySQL will generate name of the key by itself, but good practice is to name Your key. It will be simple to remove it for instance.

Alright, we have our unique key. So let's create really simple query that will insert the data to database or update the existing one.

INSERT INTO stats (article_id, created) VALUES 
	(12, CURRENT_DATE())
ON DUPLICATE KEY UPDATE
	views_count = views_count + 1

If we execute such query for the first time we will have single record with our article_id = 12, views_count = 1 (1 is default value, if not given), and current date.

If we execute this query several times we will still have single record in database but views_count value will be increased. Really simple, isn't it?

Multiple keys in ON DUPLICATE KEY UPDATE

Let's upgrade our concept a little bit. Let's say that we want to have daily statistics for each article. We can't use our example as there is only creation date of the first insert. How to solve this situation? We have to have separate rows for each day.

First of all we have to delete our previous key as it won't be needed anymore. If we named our index we can simply execute this query to remove the unique key:

DROP INDEX uk_article_id ON stats

If we didn't name our key, we don't know how to delete it. Fastest option is to list all keys in our table, like that:

SHOW INDEX FROM stats

This query will list all keys in our table. In column Key_name there will be the name of the key we want to delete.

OK, we are ready to add new key to the table with article_id and created columns. To add UNIQUE key for two or more columns we have to execute such query:

ALTER TABLE  `stats` ADD UNIQUE uk_article_id(
`article_id`, `created`
);

Now, if we execute our insert or update query, we will see that we can add multiple article_id rows with the same value, but date in created field must be unique. We won't have two exactly same rows with article_id and created date.  For testing purposes You can change CURRENT_DATE() function to the particular date, for instance "2012-12-12" to see how it really works.

 Conditional ON DUPLICATE KEY UPDATE with IF

Sometimes there might be need to make additional IF on update process. For instance we want to update our record only if another passed column has different value or something. Let's take a look at this example:

INSERT INTO stats (article_id, created) VALUES 
	(12, CURRENT_DATE())
ON DUPLICATE KEY UPDATE
	views_count = IF(VALUES(article_id) = 12, views_count + 2, views_count + 1) /*,
	additional_field = additional_field + 1,
	next_field = IF(article_id = 1, 1, 0)

Let's say that we want to "cheat" a little bit and increase views_count by two on article_id = 12. We have to add IF statement. It has three parts, condition, value if true, value if false.

In condition we use VALUES() function, which returns given value for the field. Which mean that VALUES(article_id) will return 12, because we passed this value in INSERT statement above. So this condition will be true and views_count will be increased by 2. We can pass multiple IF statements both with update multiple values. Code in commented section have some simple examples.

Keep in mind, that on first insert, when there's no record in the table, insert will be performed. It means that all code after ON DUPLICATE KEY UPDATE won't be executed. For instance in our example when we don't have such values in database, after this query we will have row with article_id = 12 and views_count = 1 (not 2).

Batch insert with ON DUPLICATE KEY

There is also option to make batch insert to database using ON DUPLICATE KEY UPDATE. It will execute update for each given row if there is duplication. Here is some simple example:

INSERT INTO stats (article_id, created) VALUES 
	(13, CURRENT_DATE()),
	(14, CURRENT_DATE()),
	(15, CURRENT_DATE())
ON DUPLICATE KEY UPDATE
	views_count = views_count + 1

 

If You want read a little bit more about ON DUPLICATE KEY and rest of the stuff I wrote about here are some external links to MySQL manual:

  1. http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
  2. http://dev.mysql.com/doc/refman/5.0/en/drop-index.html
  3. http://dev.mysql.com/doc/refman/5.0/en/show-index.html

iPhone and iPad CSS hacks

iOS devicesHello guys

Today it'll be short post (but hopefully I will add here new hacks later on) about CSS on iPhone and iPad. It should work as well on any mobile Web-kit based browser.

When it comes to styling webiste usually I'm checking it in my desktop browser. Everything seems to works fine but when I run website on my iPhone or iPad, strange things happens. Here are some short fixes for problems I encountered.

Preserver font sizing on orientation change in iPhone and iPad

html {
    -webkit-text-size-adjust: 100%;
}

The problem is that when You load the website on iPhone fonts looks normal. But when You rotate the screen and change orientation fonts become much more bigger than normal. It shouldn't suppose to happen. So here is quick fix for this problem:)

There is also second version of this solution. To use none instead of 100%. But when You use none it will disable zoom behavior in default browsers.

Remove input shadows and rounded corners on iOS devices

input {
  -webkit-appearance: none;
  border-radius: 0;
}

Second problem is default styling provided by Web-kit browser on iPhone and iPad. All inputs have shadow and rounded corners. First rule turn off input appearance and it will remove shadows in our inputs.

Setting border radius to 0 will remove rounded corners in our inputs.

How to open WordPress admin panel in iframe?

How to open wp-admin in iframe?Hello everybody,

You want to put WordPress in iframe? Sure, no problem. Now, are You trying to log in to wp-admin from iframe? Not possible? Here is the simple solution how to fix opening wp-admin in iframe.

How to open wp-admin in iframe?

Open this file in Your editor:

/YOUR_WORDPRESS_INSTALLATION/wp-includes/default-filters.php

Find and comment out this two lines:

add_action('login_init', 'send_frame_options_header', 10, 0);
add_action('admin_init', 'send_frame_options_header', 10, 0);

 

Background story of wp-admin in iframe problem

What problems we encountered? We had to create solution, that can manage multiple WordPress instances from one admin panel. The problem was, that all websites was on different servers, separate databases etc. So mutlisite is not an option here.

I did small research and found some good wordpress plugins that helps manage multiple wordpress instances:

All of them are really great solutions if You need quick and ready solution.

Both WP-Remote and ManageWP are based on admin panel that creators of these services provides. So You don't have to install anything on Your server. Just create an account on one of them, add Your websites and that's it. Really simple, but unfortunately due to some restrictions in the company I work it was impossible to use one of these solutions. We wanted to be able to change the logo, restyle the admin panels etc. And if we will need any additional functionality that these two solutions provides we will be screwed.

Third solution - InfiniteWP seemed to be best option. You can install it on Your server, you have access to source code, You are able to modify almost anything. I installed it on my localhost and have already some problems.

InifniteWP works like this: You install small plugin on the WordPress website You want to connect with InfiniteWP. It provides You connection data, some secret key etc. When I was trying to add one of the websites I was waiting and waiting and then BUM! Connection was reset. There was nothing in log files, I didn't get any errors and anything. So when I run it with error_reporting(E_ALL) - OMG. Hundreds of warnings etc. After two days of debugging finally I was able to add websites to the InfiniteWP. It works really great on local machine. Clients was satisfied when I showed them the solution via conference room and screen sharing.

More problems started when we putted it on our test server. First of all it worked sooooo slow. After adding website indicator was spinning like forever. All requests took about 5-20s to finish. I fought with that for another 2 days and there was nothing I could really do about it. Googling, reinstalling etc. Nothing!

My approach of dealing with wp-admin in iframe

When I was showing our clients InfiniteWP on my local machine they was quite happy, most of because I was able to run multiple websites without logging in to each website separately. They was able to switch between the websites. InfiniteWP is working kind of a windows with the taskbar where You can switch between applications.

So I thought, we not to create some really simple solution, when I will open WordPress in iframe? Simple switching on JavaScript between iframes. They was quite happy about this, as writing this solution took only 1 day. Fast and simple. The only problem was how to enable opening wordpress admin panel in iframe? But you know the solution already, don't you?:)

MySQL query log – how to log all queries?

MySQL query log - how to enable and read the log file?Hi guys!

Today I would like to tell you a bit more about MySQL query logging. It's very useful to preview all queries that goes to your database. Sometimes you don't have to access to direct query that is generated by ORM, but you have to check what's going on? Not a problem. Enable logging in your MySQL service and get all queries.

Problem with MySQL query logging

When using Drupal I can not previewed exact query that goes to database. I checked documentation for any useful function that can print full SQL query but I didn't find anything like that. So after further investigation and checking the code I get the PDO method. So yes, now I can print SQL query but without parameters... You can get queries like:

SELECT * FROM table_name WHERE name LIKE :name

or very similar. Unfortunately I needed full query with binded parameters. Sure, I could write some short function that will bind all parameters for me, it would be easy. But sometimes there goes very large query with hell of a lot of parameters including arrays etc. I needed something more than that.

I looked for specialized software etc but hey! Why not use the database build-in logging mechanism? It can catch all the database queries that are executed to your database. It was exactly what I needed.

How to turn on MySQL query log

OK, case is very simple, basically there are 3 ways of turning on the MySQL query log in your installation.

Method 1

You can turn on log on MySQL start/restart  via command:

mysqld --general_log=1 --general_log_file=my_logs.txt

First option will turn on query log, second is path to the file where log will be saved.

Depend on the version of MySQL you're using: You should use --log parameter. More informations here: http://dev.mysql.com/doc/refman/5.1/en/query-log.html

Method 2

Method 2 is very similar to method 1 above. It's hard to remember that every time you're run MySQL you should pass logging parameters if You want to turn on MySQL query log. It's easier if you put these settings into MySQL configuration file.

Open Your configuration file and append these lines in [mysqld] section:

general_log=1
general_log_file=my_logs.txt

Have in mind version of your mysql installation. Check method 1 with --log parameter. After saving changes in mysql configuration file restart MySQL service to enable logging mechanism.

*Method 3

My favorite method:) If you don't want to restart MySQL server or you want to turn logging only for single page refresh than turn off logging it's your method.

Execute queries below:

SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';

You will find all logs in mysql.general_log table. It's pretty useful because you can perform select operation on this table and you don't have to bother searching in text file. For me it's best method for good MySQL query log:)

If you want to log queries into file except of database table execute these queries:

SET GLOBAL log_output = 'FILE';
SET GLOBAL general_log_file = 'my_logs.txt';
SET GLOBAL general_log = 'ON';

You can execute these queries in runtime! There's no need to restart your MySQL service.

You can read more about setting global configuration options here:

http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_general_log

Viewing MySQL query log

Log file is very easy to read. It's text file so you can open it in any editor you prefer. Open your log file, you will find there 4 columns:

  • Time - date time of query execution in yymmdd hh:mm:ss format.
  • Id - Thread Id of the connected client
  • Command -  Command type, usually Query
  • Argument - Query body executed on MySQL body

Important info

OK, so now you have the list of the queries that are executed on database. It's great to check the full query executed on database. It's really helpful especially when You don't have direct access to generated queries for example like in Drupal.

But don't forget to turn off your logging. When You have many queries executed on your database it will make query log very big and you can run out of space on your disk. Second thing is lot of write operation when logging is turned off. So it's nice to turn logging on only for debug purposes and turn off logging on production environments.

Our services: