Wednesday, May 13, 2009

.htaccess Hacking in Joomla

I have a good number of Joomla websites that are hacked by hackers.

Generally, the website ends up been slower in performance. However, there are times where the websites are total defaced.

Most common hacking attempts can be easily reversed by going to index.php (either in the default root directory or the template directory) and simply delete the hacking codes. That's the most common remedy.

Another one is the .htaccess hacking. The hacker inserts .htaccess file into your directories and using mod_rewrite, it redirects your web pages (including images, javascript files, etc) to their destinated website. This either causes slow performance or website to hang.

The remedy to the above hacking is to find and locate every .htaccess file in your website and delete them away. Each directory only have at most 1 .htaccess so you would probably have to move around most of your directories to locate them. The .htaccess file will most probably be placed in common directories such as /images, /templates, etc.

After you have solved and resumed your Joomla website, you will need to update your Joomla version to the latest one. You should change your password for FTP and your hosting account access too.

Wednesday, February 27, 2008

Virtuemart Image Update Problem

There seems to be a problem with the product images of Virtuemart 1.0.13a. When you try to upload or update the image of a product, the image does not appear or it will have an unlink problem. This "Virtuemart product image is not showing" problem is quite elusive and appears in some servers only.

Since I had the same problem with one of my client's website, I had to solved it. So here's my solution that works for me:

Go to /administrator/components/com_virtuemart/classes/ps_main.php.

Add this line of code directly after line 269.
chmod( $exec['param2'], 0644 );
Yup! That's it. The problem is due to the permission setting of the uploaded files.
Hope this helps!

Thursday, December 6, 2007

Importing Unicode Data into MySQL

Phew! I have finally solved a big unicode problem for importing chinese characters into MySQL. The problem is like this: My client has a huge Access database containing English and Chinese data which I need to migrate into MySQL.

In the past, I used MySQL Migration Toolkit to import from Access into MySQL. However, this time, it doesn't work because the toolkit turns all the Chinese characters into ???. Yup, exactly that! Question marks.

So I tried to export the Access table into CSV. I opened it with Wordpad and it looks great. So after playing around with the CSV to turn it into SQL statements, I am ready to use command line import style to import the data in. The idea is to go to MySQL command prompt and type:
mysql -u root -p database_name < data.csv

This ought to do the job... but it doesn't. It has some very very funny MySQL Syntax error which is like some funny characters. I find it extremely funny so I opened up the file using MySQL Query Analyser instead. What I discovered is that the data is suddenly shortened significantly to just 3 funny characters. My best guess is that wordpad actually compresses the data when you saved it.

Never mind! Chill! I rework the data in MySQL Query Analyser and save it properly. It is neat to know that MySQL Query Analyser will save your sql file in proper UTF encoding. With the proper UTF file, I tried the command line import again.

There shouldn't be any more problem... but there is. Now MySQL told me "Error 2006: SQL Server has gone away". What? Gone away? For a smoking break? OMG! After some searching on the net, I realize that the problem could be with the MySQL server setting to automatically close a connection when there is a large transfer. So I fired up MySQL Administrator GUI, go to "Startup Variables", under "Advanced Networking" tab, I checked and set "Max Packet Size" and "Max Buffer Length" to 5M each.

Back to the command line import, YUP it works! FINALLY! I am writing this out to throw it in the net hoping that it will just help some poor soul who is searching for such a solution.

Wednesday, December 5, 2007

Joomla Access Control

One of the greatest shortcoming of Joomla is that it does not have an editable access control feature. That means you can't really create new access groups nor can you change what each group can access.

The only to edit Joomla's access groups is to programmically hack it. In this posting, I will outline how to edit the access permissions of the existing backend access groups in Joomla.

All the access roles are defined in /includes/gacl.class.php and in the function gacl (line 97 of the file). You will see many statements like this:
$this->_mos_add_acl( 'action', 'edit', 'users', 'manager', 'content', 'all' );
To add an access rule, simply monkey see monkey do:
$this->_mos_add_acl( {Action}, {Action Value}, 'users', {Access Group}, {The Component Name}, {The Access} );
Not much point in explaining the variables in this statement which you will see why in the next step. We have defined the rule but that is not enough. The component/program has to honor it. Hence, in the component which is to impose this rule, you will need to add something like this:

global $acl, $my;

if (!($acl->acl_check( 'action', 'edit', 'users', $my->usertype, 'content', 'all' ))) {
mosRedirect( 'index2.php', _NOT_AUTH );
}
You just do a checking and if it is not true, redirect to a "Not Authorized" web page. You may notice that the number of arguments in the function acl_check is the same as the function _mos_add_acl. Yup! The thing is this: the function acl_check simply checks if you have added a rule through _mos_add_acl that has the exact arguments and values as the acl_check function! So if the acl_check is called with the same arguments as the _mos_add_acl, then it will return true. ACL is quite simple in Joomla right? =)

With that, you should now understand that the arguments for _mos_add_acl is not very important but more for readability. Just good programming practice, it is always good to give meaningful names.

Wednesday, October 31, 2007

Google PR and Joomla SEO

Google has recently updated their PR status to all the websites. As usual, when such as thing happens, there are some websites who got penalized (PR dropped) and some websites who got the prize (PR increases, YAHOO!)

What's PR? PR stands for Page Rank and it is the heart of Google search engine. Basically, when you search for something through a search engine, the search engine simply looks at the content of the website and determine the relevancy of the website to your search and serves it to you. This method allows webmaster to easily tamper with the search engine's ranking as the content is controlled by them.

Hence, Google's ingenious way to counter this is to allow the web to vote for the website. Every time a website receives a link from another website, Google will take that as a vote and calculates that in their ranking of the website. The number of votes that a website has is recorded by Google and Google will assign a rank to the website known as Page Rank. Page Rank is upon a scale of 10 so the higher your page rank, the better Google thinks your website is and the higher the chance of your website appearing in the Google search results.

Of course, that is a grossly oversimplification of the real methodology of assigning a page rank to a website but that is the core idea. That's why you have SEO experts who always talk about getting backlinks backlinks and backlinks for your website!

Just for the record, my company website http://www.futureworkz.com is PR5 and this blog that you are reading is PR4. Not bad for a one-month-old blog! However, my own personal blog http://stevenyap.blogspot.com is still PR zero.

So you might be asking: What is a good PR value for my website? For a starter, achieving PR4 is a good status. That would be a good boost to your search engine ranking for the keywords that you are targeting. However, one should not be overly obsessed with PR. We must always remember that at the end of the day, what really matters for SEO is conversion of web visitors to real customers. PR plays a part but ultimately it is the right ranking in the right market that matters.

Finally, the reason that this blog is able to get PR4 in such a short time is that my company website has a link on the homepage to this blog. This is a PR5 link to this blog and that is a big vote for this website. Hence, in such a short time, this blog is able to get PR4. However, for my personal Steven Yap blog, I have not done anything for it and probably no ones in the world knows about it until I have said something about it or someone searches for it explicitly. That's why it is PR zero. (but now that a PR4 blog is linking to it, there should be at least a PR1 for my blog)

Thursday, October 25, 2007

PHP Setting Configuration Through .htaccess

Many components in Joomla give you exciting functionalities to your website. Most components can be configured properly through the Joomla backend and you are set to use it. However, there are situations (quite often!) that demands configuration at the server level. There situations are generally solved by configuring the PHP setting.

To configure it properly, there are 2 things you have to know:
1) Unless you are the administrator of the server, you cannot directly edit the php.ini file which contains the PHP settings. The way to configure it is to do it throught the .htaccess method. At the root of your web directory (ie. /public_html or /httpdocs or /var/www/html or whatever), there is a file named .htaccess which Apache uses for configuring setting for your website to run. Yes, I said Apache... if you are using IIS, then my post is not going to help you. We will add changes to this file to configure the PHP settings.

2) Know what to change. You can't have a solution without knowing what's the problem, right? Common sense 101. Anyway, that's why I have prepared a list for you to check out if you experienced some of the common problems that most other people will encounter. Here it is:

Problem: Blank screen when Joomla loads up

Analysis: This is a huge one. There are hundreds of reasons why it is blank... database failed, website down, domain not pointing correctly, your internet connection is down, PHP coding errors, blah blah blah... However, Joomla will generally at least throw a notice/warning/error to you if it is loaded to your browser and some server PHP setting is set to NOT display any error messages. Hence, you can try this solution.

Solution: Add "php_flag display_errors on" to your .htaccess file. It will make the server throw error messages on the screen if there is an error with the codes.


Problem: Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 1200 bytes) in /public_html/components/whatever/phpthumb.functions.php on line 334

Analysis: This is a php error message. Note the particular file and line number. This message tells you that the code in the script needs more memory to run. Now, generally well-written scripts do not need extra memories to run. Note the word generally. There are cases where more memory is really needed such as loading and processing a huge file or database. My advice will be to google the problem to see if it is a configuration problem or something like before you use my solution below to increase your PHP memory allocation to the script.

Solution: Give more memory for your script to run. Add "php_value memory_limit 10M" to your .htaccess file. Change 10M to your desired amount. Care!


Problem: Uploading a large file causes problem

Analysis: This is from my own experience. For example, I am using the forum component Fireboard for one of my client's website and we need to let users upload a 5MB music files to the forum. 1MB music file is ok but > 3MB is a big problem. After some time trying to find the solution, I realized that file upload is limited by PHP setting. Hence, you would need to increase the file upload if you want users to upload a bigger size file.

Solution: Add "php_value upload_max_filesize 7M" and "php_value post_max_size 7M" to your .htaccess file. Put the 2 codes in separate lines (ie. don't put them in a single sentence/line). You can change 7M to your desired size.

An explanation here for the 2 codes: upload_max_filesize determine the maximum size of the file that can be uploaded to your server. post_max_size is the maximum size that your server can receive from a form post request. Hence, post_max_size is the sum of all post variables plus the file which means strictly speaking post_max_size should be larger than upload_max_filesize. However, most other post variables are small in size and we do not expect the uploaded file to be larger than 5MB (the limit is set in the Fireboard forum), we just leave the 2 values the same. If you don't understand what I am talking about, just use the code.


Once you are done adding the extra codes to .htaccess, upload them to your web directory and check it out. If it works, I am happy for you. =) There are various other PHP settings that you can use for the .htaccess and here's a short list of the common ones that I use for my Joomla websites:

php_flag register_globals off (Solves the Joomla backend error warning)
php_flag magic_quotes_gpc on (Solves the Joomla backend error warning)
php_value session.save_path '/tmp/' (Solves session problems - sometimes)

Wednesday, October 24, 2007

Zoom 2.5.1 RC 4 Lightbox Popup Error in IE7

One of the best media gallery component for Joomla! is the Zoom Media Gallery. Their website is at http://www.zoomfactory.org/

One of my client website needs to implement a gallery function on the website and of course, I choose the best for my client - Zoom Gallery. The current version is 2.5.1 RC4 as of the time of this writing. Zoom has a great display animation using Lightbox Javascript and the best way for you to see it is to go here: http://www.theartofmusic.com.sg/component/option,com_zoom/Itemid,97/catid,2/

Nice animation? However, out of RC4 Zoom installation, that effect does not work well for IE6 and IE7. In fact, it does not work at all... =_(

Luckily, I am paid to make it work and hence here's the hack that will make it work:
File: /components/com_zoom/lib/js/lightbox.js
Line NumberOriginal CodeReplaced With
254objPrevLink.setAttribute('href', '#');objPrevLink.setAttribute('href', location.href + '#');
259objNextLink.setAttribute('href', '#');objNextLink.setAttribute('href', location.href + '#');
303objBottomNavCloseLink.setAttribute('href', '#');objBottomNavCloseLink.setAttribute('href', location.href + '#');
182 if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){ if (anchor.getAttribute('rev') && (relAttribute.toLowerCase().match('lightbox'))){
334imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title'))); imageArray.push(new Array(imageLink.getAttribute('rev'), imageLink.getAttribute('title')));
341if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){if (anchor.getAttribute('rev') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){
342imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));imageArray.push(new Array(anchor.getAttribute('rev'), anchor.getAttribute('title')));
346while(imageArray[imageNum][0] != imageLink.getAttribute('href')) { imageNum++;}while(imageArray[imageNum][0] != imageLink.getAttribute('rev')) { imageNum++;}

File: /components/com_zoom/lib/template/template.gallery.php
Line NumberOriginal CodeReplaced With
395 $link .= " href=\"".$zoom->hotlinkImage
($zoom->_gallery->_id, '0', $ided, null)."\"";
$link .= " href=\"javascript: void(0);\"";
$link .= " rev=\"".$zoom->hotlinkImage
($zoom->_gallery->_id, '0', $ided, null)."\"";

Yup! That's about all the hacking. There are actually 2 cross-browser problems in the code that prevent the lightbox effect from working in IE7:
  1. <a href="#"> does not work well in IE. If your current URL is at http://www.yourwebsite.com/somedirectory/somemoredirectory/page.html and when you click on the link above, it will cause you to go to http://www.youwebsite.com/# even though BY RIGHT it should be http://www.yourwebsite.com/somedirectory/somemoredirectory/page.html#. Hence, we have to change all href="#" in the <a> tag to href="javascript: void(0);" or href="{current URL}#", the latter {current URL} being created dynamically by Javascript.
  2. Image's link is done by <a> with its href set to the image's src. What this means is that the image is linked to its exact file location on the web. This <a> link is used to trigger the lightbox effect. The <a> is actually something like this: <a href="{image file url}" onclick="{trigger lightbox effect}">.

    This causes problem in IE because for some unknown reasons, when you click on the link, IE will immediately go to the link's location, bypassing in the onclick event and hence, did not launch the lightbox effect. What you see is being directed to another web page.

    Therefore, we have to change all the href="javascript: void(0);" and set another attribute (in this case, I used the rev attribute) for the lightbox script to use for referencing the image URL.

Anyway, I hope the great guys at Zoom will be able to stablise the code at Zoom more. I have a couple of gitches too in the component. However, all in all, this is definitely a WONDERFUL gallery component and I really appreciate the efforts that all the current and past developers have put in.

Anyone reading this post and is still not able to make the lightbox work in your website, I am sure you will email me but please add more details for the error. Don't like just "My lightbox still doesn't work even though I follow your instructions. Please help." and expect me to auto-magically guess where-the-hell-is-wrong-with-your-setup. Really appreciate. =)