Alex Ivaylov – a web developer http://www.alex.bg Alex BG Web Developer Blog Sun, 26 Nov 2017 17:09:04 +0000 en-US hourly 1 https://wordpress.org/?v=4.8.3 AWS http://www.alex.bg/2017/11/aws/ Sun, 26 Nov 2017 17:05:43 +0000 http://www.alex.bg/?p=939 So here we are.. this website is now hosted on AWS. It used to be hosted on a VPS before but now I need that VPS for another (much more complex) web system. This website is now nearly 9 years old but I don’t have time to re-do it so for now it will stay as it is.

That system which I am building at the moment has functionality ranging from automatic management of advanced Linux configuration settings, cron jobs and is also tapping into various APIs using different protocols. All of which has to be mobile friendly. I love PHP because it supports nearly all of those.

]]>
Installing imagick on Windows http://www.alex.bg/2017/08/installing-imagick-on-windows/ Wed, 30 Aug 2017 19:24:42 +0000 http://www.alex.bg/?p=885 A few years ago i wrote a post moaning about how difficult it is to install imagick on Centos. Well i have to say that was a breeze compared to installing it on Windows..

As we know it is a PECL extension. On the page we see this “This extension requires ImageMagick version 6.5.3-10+ and PHP 5.4.0+.”.

But what they are not saying there is that you should not use the official windows binaries that you get from imagemagick.org. In fact they are saying the opposite.


When I installed the official binaries together with the PECL extension I got low level crashes of php-cgi.exe. There wasn’t much information on to why.

After that I noticed that on the bottom of the download page of imagemagick that they require Visual C++ 2013 while the php PECL extension and PHP itself require Visual C++ 2015 (VC14). So that explained the crashes.

Just as I was thinking about compiling it myself – I found this great article. The guy has went through the same pain as me.

In that article there is a link to PECL dependencies folder. The link is http://windows.php.net/downloads/PECL/deps# in there there is a different build of the imagick runtime. So I downloaded that and uninstalled the official imagick binaries.

I then added the environmental variables as explained in that article and boom – it started working.

]]>
Show IIS PHP server2server connections in Fiddler http://www.alex.bg/2017/04/show-iis-php-server2server-connections-in-fiddler/ Mon, 24 Apr 2017 19:56:02 +0000 http://www.alex.bg/?p=872 So I am running PHP on Microsoft IIS web server. I have to open some sort of a socket to a remote host. I would like to inspect that socket because I would like to see the data being exchanged between PHP and the remote web service. In our case you could call this a server to server connection. But remember that as far as the remote web service is concerned PHP is acting as a client. Fiddler is an irreplaceable tool. I have been using it for years and I really can’t imagine my life without it.

Fiddler itself is a web debugging proxy. When it is started, it creates a proxy service (by default on port 8888). It also configures Windows and the browsers to automatically route the traffic through that proxy but only for the current user. After that you see a list of all http(s) requests that have went through the proxy and you can click on one to view all its of its parameters. As a bonus it can render XML, JSON or HTML. This is priceless.

However, if you are on a Windows Server box with PHP running on IIS. It is highly likely that IIS is running under a different user so server2server connections will not show in fiddler. Do not try to configure the IIS settings via the IIS console or web.config as that will not work as those are specific for .NET apps and do not affect PHP. Remember PHP is running in FastCGI mode.

What we need to do is we need to tell PHP to use the proxy server. I was surprised that there are no Proxy settings in php.ini. The recommended way to do this is using the stream_context_set_default() function.

$stream_default_opts = array(
'http'=>array(
'proxy'=>"tcp://127.0.0.1:8888",
'request_fulluri' => true,
)
);

stream_context_set_default($stream_default_opts);

As with most of the other PHP environment setters – this needs to be at the start of the PHP file. If you would like this to be global server setting, you can save the above snippet in a .php file on your server and then you could specify it to be prepended (i.e put in the start) of every other PHP file automatically in php.ini like this:

auto_prepend_file = "/path/to/proxySetter.php"

To make things more complicated, this method does not apply to all connections. If this doesn’t work – you will need to research how to set proxy for whatever objects you are using. In my case where I am using the SoapClient class, I have to explicitly specify the proxy host and port:

$wsdl = 'https://example.com/path/myWebService.wsdl';
$options=array(
'trace' => 1,
'exceptions' => 1,

'proxy_host'=>'127.0.0.1',
'proxy_port'=>'8888',

);

try
{
$client = new SoapClient($wsdl, $options);
}
catch (Exception $e)
{
echo 'The web service call failed with error "';
echo $e->getMessage();
echo '"';
exit();

}

If all of these fail (or you are too lazy) you could try a program called Proxifier but I can’t guarantee it will work.

Hope this will help someone out there 🙂

]]>
Copy Mac OS X installation from physical to virtual machine http://www.alex.bg/2016/04/copy-mac-os-x-installation-from-physical-to-virtual-machine/ Sun, 10 Apr 2016 14:11:07 +0000 http://www.alex.bg/?p=861 I am writing this guide because I couldn’t find a working solution to the problem where you might want to clone a complete installation of Mac OS X on a physical hardware Mac to a Parallels virtual machine. In order to do that you would need to take full DMG image of the whole hard drive. Most solutions out there suggest that Parallels should automatically prompt you to conver the DMG file to its .HDD format when you add it to the VM, so you should try that first. However, that method did not work for me.

Before trying this method, you should also try to take a complete Time Machine backup and then try to restore it on to the VM. If time machine backup / restore method doesn’t work, follow this guide. Unfortunately it didn’t work for me either. Before trying this method you would need an external hard drive that is bigger in size than the disk space you have used. This guide was written assuming that you will be taking the installation of an old Mac and putting it inside a VM on your new mac. However, it should also work if you want to reinstall OS X on the same box (but I haven’t tested it this way).

1) Plug the external hard drive into the old mac
2) Turn on the old Mac while pressing multiple times Cmd + R during start up, in order to enter the start up recovery options
3) Choose Disk Utility
2) Take an image of the whole hard drive and save it as a .DMG file on the external hard drive
3) Once you have your DMG on the external hard drive, unplug the hard drive, restart the old mac and plug in the hard drive into your new mac.
4) Copy the DMG file into a folder somewhere on to your new mac (For example in “Documents”)
5) Mount it (by double clicking the copied DMG file). Let the system verify if it can open the image before it mounts it (dont skip verification – it might take some time depending on the size of your drive)
6) Optimal: Browse the files to make sure you are happy all your files are there
7) Unmount it
5) On your old mac: open parallels (If both your old mac and new mac have the exact same version of Mac OS X, you should use your new mac instead)
6) Create a new VM installing Mac OS from the recovery partition
7) You should now have a virtual machine which has a clean, working version of Mac OS that is exactly the same as the OS X version on your old mac.
8) If you used your old mac, copy the VM to your new mac (Documents/Parallels). On the new mac choose “add existing VM” and add the clean Mac OS from the old mac
10) Open the settings of the VM
12) Click the Add (“+”) sign and choose hard drive.
13) Create a new blank hard drive which is bigger in size than the disk space used in the the DMG file and make sure it is expandable (dont worry if your old hard drive is bigger than your new one – just make sure you have enough space to cover the used disk space)
14) Turn on the VM and go into the clean Mac OS installation
14) Open the Disk Utility app
17) Click File, Open Disk Image
18) Go to the Parallels shared folders
19) Find your copied DMG file and open it
20) You should now have your old hard drive mounted into your clean installation VM
21) Unfortunately, doing a recovery to the empty disk from the disk utility did not work for me here. For that reason I went out and looked for a 3rd party solution. I used Carbon Disk Cloner. You can get a free trial from their official website bombich.com
22) Install Carbon Disk Cloner inside your VM and open it. Choose the source to be your mounted disk image and destination to be you blank hard drive
23) Click “Clone”
24) Once the clone completes, turn off your VM
25) Go into the VM settings and delete the clean installation hard drive without moving files to trash (by clicking the “-” sign). Make sure you leave only what was the blank HDD
26) Boot up the machine – you should now have your old installation working
27) Install parallels tools (from the Parallels Action menu on the top)
28) Optimal: If you are happy that everything is working you should backup up your VM (you can delete the copy you made in step 8)
29) Optimal: After you have backed up your VM you can delete the clean install OS hard drive to free up disk space (go to Documents/Parallels/ and right click on the VM, select “Show Package contents”)
30) Optimal: Delete the DMG file to free up space

]]>
dynamically manipulate a jQuery Mobile Control Group http://www.alex.bg/2015/05/jquery-mobile-control-group-populate-and-change-dynamically/ Mon, 18 May 2015 18:26:28 +0000 http://www.alex.bg/?p=821 I could not find a working answer to the question How to dynamically populate a control group in jQuery Mobile and programatically change its selected value in the search engines, so I though I would write this quick article.

Now, lets say your HTML looks like this:


<fieldset data-role="controlgroup" data-type="horizontal" id="myContrGrp">
<input name="favFruit" id="favFruit-f1" value="apples" type="radio" />
<label for="favFruit-f1">Apples</label>
<input name="favFruit" id="favFruit-f2" value="bananas" type="radio" />
<label for="favFruit-f2">Bananas</label>
<input name="favFruit" id="favFruit-f3" value="strawberries" type="radio" />
<label for="favFruit-f3">Strawberries</label>
</fieldset>

The first thing I am gonna do with this is I am going to bring in a relation between the VALUE and the ID of the inputs. So something like this is better:


<fieldset data-role="controlgroup" data-type="horizontal" id="myContrGrp">
<input name="favFruit" id="favFruit-apples" value="apples" type="radio" />
<label for="favFruit-apples">Apples</label>
<input name="favFruit" id="favFruit-bananas" value="bananas" type="radio" />
<label for="favFruit-bananas">Bananas</label>
<input name="favFruit" id="favFruit-strawberries" value="strawberries" type="radio" />
<label for="favFruit-strawberries">Strawberries</label>
</fieldset>

Now that there is a link between the ID and the VALUE attributes, we can do something like this:

 


//the value we want to set the control Group to
var favFrt = 'strawberries';
var favFrtSelector = '#favFruit-' + favFrt;
//add the checked="checked" attribute to the appropriate INPUT
$(favFrtSelector).attr('checked', 'checked');
//refresh the control group
$("#myContrGrp").enhanceWithin().controlgroup("refresh");

 

The above concludes how to change the selected option of control group that already exists and has all its HTML pre-set.
If you need to dynamically populate a jQuery mobile group before you change it, follow these steps.

Create an empty fieldset:


<fieldset data-role="controlgroup" data-type="horizontal" id="myContrGrp"></fieldset>

And use something like the following:


//create an array with all your options:
var cgOpts = ['apples', 'bananas', 'strawberries'];
//create your innerHTML container var:
var innerHTML = '';
//iterate through your array:
for (var i=0;i<cgOpts.length;i++)
{
//current fruit is cgOpts[i]
innerHTML += '<input name="favFruit" id="favFruit-'+ cgOpts[i] + '" value="'+ cgOpts[i] + '" type="radio" /><label for="favFruit-'+ cgOpts[i] +'">'+ cgOpts[i] + '</label>';
}
//now that you have your innerHTML - append it to the jQuery Mobile control group like this:
$("#myContrGrp").controlgroup("container").append(innerHTML);
//and refresh the jQuery Mobile control group like this:
$("#myContrGrp").enhanceWithin().controlgroup("refresh");

 

Also, I couldn’t find out how to disable a jQuery mobile control group programatically. The native plugin has a “disable” method as well as a disable option but unfortunately they both don’t work.

What I found did work was adding the disabled=”disabled” attribute to the inputs:


$("#myContrGrp input").attr('disabled', 'disabled');

Remember to refresh after this.


So there you have it. Feel free to copy/paste whatever you like.
Note this was done with jQuery Mobile version 1.4. It might change in future versions.

]]>
Enabling PHP in a single directory http://www.alex.bg/2015/03/enabling-php-in-a-single-directory/ Tue, 10 Mar 2015 18:05:44 +0000 http://www.alex.bg/?p=808 I am writing this because I couldn’t find any information on how to enable PHP for a single directory.

Let’s say we have a website example.com, whose documentRoot is in /var/www/vhosts/example.com. I want PHP disabled for the entire website apart from the directory /myApp.

Let’s say the configuration of the vhost is something like this:


<VirtualHost *:80>
ServerAdmin me@example.com
ServerName example.com

DocumentRoot /var/www/vhosts/example.com

<Directory /var/www/vhost/example.com>
Options -Indexes
AllowOverride All
Order allow,deny
allow from all

#disable PHP:
php_admin_value engine Off
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined

As you can see we have turned off PHP globally for the whole website.

One thing I found by trail and error is that if you change engine Off to engine On in the above example, PHP will still not work.

That is the case in the current Ubuntu (Debian) Apache 2 with mod_php 5. I dont know if this is a feature or a bug.

If you want to switch on the PHP engine, try 1 instead of On.

This works:

php_admin_value engine 1

So now we need to figure out how to override the flag just for the /myApp directory.

Overriding with <Directory> does not work. What I found is that overriding with <Location> does work. That’s probably because <Location> is called last (after <Directory> and .htaccess).

So here is how to override the PHP engine flag directive for one single directory:


<VirtualHost *:80>
ServerAdmin me@example.com
ServerName example.com

DocumentRoot /var/www/vhosts/example.com

<Directory /var/www/vhost/example.com>
Options -Indexes
AllowOverride None
Order allow,deny
allow from all

#disable PHP:
php_admin_value engine Off
</Directory>
<Location /myApp>
php_admin_value engine 1
</Location>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined

I haven’t tried it with .htaccess because I don’t use it any more.

]]>
Upgrading PHP? http://www.alex.bg/2014/01/upgrading-php/ Mon, 27 Jan 2014 21:17:56 +0000 http://www.alex.bg/?p=794 If you think that by upgrading to the latest version of PHP you will be more secure than before you might be wrong. Some security features such as magic quotes GPC and safe mode have been removed as of 5.4.

In HTTP all of the communication coming into a web app from the outside world happens via one of the 3 channels (Get, Post and Cookie). The magic quotes GPC feature automatically escapes the input.

In the newer versions of PHP it has been removed and now it is up to the developer to escape the user input accordingly. Problem is that newbie developers might not know that they have to do that. Other problem is with old legacy code which makes use of magic quotes. Businesses simply can not afford to re-code web applications according to the new standards. Other problem is that the resources available those learning PHP in many cases are out of date and contain code snippets and examples which are potentially vulnerable. That is why it is very important that only seasoned developers who code php the right way are hired for business critical web applications. Of course that will not be the low-tariff developers who cant even speak English.

The other removed feature “Safe Mode” was a handy setting which lets sys admins disable potentially dangerous PHP functionality used by exploits and rootkits (such as the functions which let php run custom code on the system shell (system(), shell_exec(), “, etc). Safe mode also prevents PHP from writing files to the file system. I would actually recommend that safe mode is kept on by default and only disabled if really needed.

The good news is that even though 5.3 is end of life – it still receives critical security updates. So for now you can secretly continue to run 5.3 on your server (which is recommended if you provide shared web hosting and you don’t need the new features). However, we don’t know how long that will continue to be the case. Also remember that there’s the option of running multiple versions of PHP on the same server (as FastCGI) if you are dying for traits or the new password hashing.

]]>
Kitchens Website http://www.alex.bg/2013/11/kitchens-website/ Sat, 23 Nov 2013 20:17:05 +0000 http://www.alex.bg/?p=785 I’ve just finished working on this website for my uncle in Bulgaria who has a kitchens company. Check it out:

http://kitchens.bg/en/

]]>
Copying a LAMP web application http://www.alex.bg/2013/06/copying-a-lamp-web-application/ Wed, 12 Jun 2013 23:29:47 +0000 http://www.alex.bg/?p=769 One of the most common things a web professional does is copying a website from one web server to another. Whatever the reason – deploying, debugging, upgrading – it doesn’t matter. A few years ago when I started working with the web – I was using FTP. The more I was digging into the Linux Command Line the less I was using things like FTP until the point I completely stopped using it. You will see how quicker it is doing a copying via SSH compared to downloading all files via FTP and then uploading them again. The 5 main steps you need to take when copying a website are described below:

1. Prepare the new server

If you are using a control panel such as CPanel, Plesk, Kloxo, etc – it is most likely that your environment is automatically prepared when you create the website from the control panel interface because it uses pre-defined templates to create all websites so you don’t need to do any of the preparation here.

Before you can copy a website from server A to server B – you need to ensure that server B is ready. That means that the virtual host is configured properly in Apache, you have a document root folder for the website and Apache is serving it correctly. An easy way to test this is to edit the hosts file on your system and make it point to the IP address of server B. Search google on how to do that. To ensure that Apache is serving the right document root – you could create a test.html file and then try to request it from your browser http://example.com/test.html

Also make sure that server B is matching the system requirements of the web application. Popular CMSes such as WordPress, Joomla, etc have their system requirements on their websites.

Some web systems might require specific Apache options to be set in a specific way and/or specific modules to be enabled – for example if the system uses mod_rewrite – you will need to enable it and if the system also uses .htaccess to specify the rewriting rules – you will need to set the vhost config to have the directory’s AllowOverride to either ‘options’ or ‘all’ (but not ‘none’).

On the PHP side of things – you need to make sure that all the required PHP extensions are installed (that should be specified in the system requirements document).

2. Copy files

Once you are happy that the environment on server B is ready for the website to be copied you can continue.

2.1 The first step before you start copying the website is to suspend it. So if the CMS or the Shopping Cart has an option to close the site – you need to do it now. The reason for that is because you don’t want orders placed (or users registered) on your website between the times DNS has switched to the new server to be lost.
2.2. First you need to change the current directory the directory of your website:

cd /var/www/vhosts/alex.bg/httpdocs/

2.3.Then you need to use the tar utility to create the archive:


tar cfz mywebsite.tar.gz .

When you type the command – it might take some time to create the archive – so be patient.
Once the command has finished – you should see the root@serverA… place to type again.
Make sure that no errors are displayed.
2.4. Open a new SSH window to server B.
2.6. cd to the directory of where the new website will be hosted:

cd /var/www/vhosts/alex.bg/httpdocs/

If you have any files which are not needed by the website in there (like a test.html file) – delete them(using “rm ” command).
2.7. Download the archive from Server A:

wget http://example.com/mywebsite.tar.gz

You should see a file download.
Again – wait for it to finish and make sure no errors are displayed.
2.8. Once the download is complete – extract the files:

tar xf mywebsite.tar.gz

2.9. Once the extract is complete – delete the archive(do this on both servers A and B):

rm mywebsite.tar.gz

Congrats – you have copied all the files from your old server to the new one.

3. Copy database
3.1 The database information is stored into a configuration php file. In most cases it is something like config.php, configuration.php(in Joomla), wp-config.php (in wordpress), etc.
3.2. FTP into your new server and find the config file in there (or use “ls” to view the files).
3.3. After that open the configuration file and look for Database Name, Database User and Database Password variables (constants in WordPress).
3.4 On server A – login to your database manager (phpmyadmin) via the control panel or via the PMA url if you have installed it yourself (using the username/password from above step).
3.5 On the top left click on “Databases”, then click the database name.
3.6. Click “Export” on the top
3.7. Leave it as “quick” and click the “export” button
3.8. A .sql file should download – save the file to your computer
3.9. Logout of phpMyAdmin on Server A and login to phpMyAdmin on server B (preferably using a root account)
3.10. Again, click on “databases” on the top left
3.11. In the “Create new database” section enter the name of the database exactly as the way you had it in 3.3.
3.12. After your database has been created – click on it’s name
3.13. Click import
3.14. Click “browse” and find the .sql file you just downloaded from the other server
3.15. Click the “Import” button and wait for the file to import. Your browser might look like frozen but wait for it (it might take hours depending on your network speed and size of the .sql file).
After it completes – you should see a list of all the tables in the database on the left.
Again – make sure no errors are displayed.
3.16. After the import is complete – create a new user for this database
3.17. Click “users” (or “Privileges” in the old phpMyAdmin) on the top of the screen
3.18. Click add new
3.19. Now you could either specify the old user/password you have from step 3.3. or enter a completely different user/password combination. Make sure that host is set as “localhost” and you have not assigned any global server rights to the user. I would recommend using a new user/pass combination because it is always good to change credentials.
3.20. If you created a new user/password – update the config file with them, save it and then upload it to the server B. If you used the old user/pass – skip this step.
3.21 Go into the “users” section of the database again and go into the “edit user” screen for the user you just created.
3.22 From the drop down with database names find the one you just created and submit the form
3.23. Assign only the privileges needed for the web system to work (if you are no sure – you could have a look at Server A to see what privileges the user has to the database there).

4. Test

At this stage your old website should be working on your new server.

Make sure the hosts file is pointing to the new server and load the website. If you closed the web system – open it again. Do not open the website on Server A – only the one on server B.

Test everything – if you see any errors – search Google.

5. Change DNS
Once you are happy that your website works on the new server as intended – change the DNS of the domain name. Look for A records. Where you see the IP address of Server A, change it to the IP of Server B (note this might effect services different than web such as Email, so make sure those are set up on the new server properly too).

After DNS switches your visitors should be served by the new server. If you are intending to close your old server’s hosting account make sure you cancel it properly (using the system of the host provider) because some hosts do auto-renew and charge your card without any notice (bad practice in my opinion).

]]>
June 2013 already? http://www.alex.bg/2013/06/june-already/ Wed, 12 Jun 2013 21:58:57 +0000 http://www.alex.bg/?p=754 Is it June already? Time flies when you are having fun! haha… Last time I wrote here was in January, so I guess the plan to start writing here more often failed. The truth is that I have been busy with soo many different things.

On the personal side of things – it’s all the same (partying, travelling, socialising, living life to the full and enjoying the small things). I must admit – the weather in Scotland has been lovely for the last few weeks. I think that Europe and Scotland exchanged – while EU gets all the rain – we got the sunshine in Scotland 🙂

On the technology side of things I have been digging deep into the mobile side of the web (building HTML5/CSS3/jQueryMobile web apps in Cordova) as well as trying to build the perfect MVC PHP framework to use for my own projects (I might release it under the GNU/GPL one day).

So far I have a very good database class which has enough functionality in its methods to almost replace writing SQL queries. The DB class uses the PHP PDO interface and it is meant to be the parent of the model class of the MVC framework I am building. That means that the model will be inheriting (extending) the DB class which will give standard $this->blah access to its methods. For example to get the result of this query

$query = 'SELECT `name`, `surname` FROM `people` WHERE `id`=\'' . $id . '\';';

as an array you would just do this in my class:


$peopleArray = $this->listFiltered($fields=array('name','surname'), $dbTable='people', filterData=array(array('field'=>'id','value'=$id, type='equals')));

So with one line you get the result you need without having to go through the standard PDO procedures (instance class, separate dynamic data, run query, etc). Similar methods are available for all the standard SQL statements (SELECT/UPDATE/DELETE). As you saw above it also supports complex operations such as specifying WHERE clauses(with all the operators), LIMIT parameters and JOIN instructions. I also have a few other classes like the user management/authentication class, methods for simple front-end database table records management (something like phpMyAdmin but simplified) + a few other classes.

There are hundreds of PHP frameworks that offer similar functionality but the truth is that they are all too limited for what I need. The technology and data I work with is spread from a lot of different programs on different platforms and different devices which have their own APIs and data formats with their own constrains and requirements (that’s the simplest way to put it without going into technical details). That’s why I am thinking that my framework is something unique.

]]>