Web Page Templates Icons, Clipart, Logos

Hot Topics

Aug 03, 2009 07:18 PM

Browser Screen Size

800×600 has been the standard browser screen size for years; however, only 8% of the population still use this resolution. 1024×768 and larger now represent over 90% of the Internet. With this in mind, it’s time to start developing websites with 1024×768 in mind. However, that doesn’t mean that a person actually has this much room to view their pages, and many people with better resolutions don’t have their browser maximized.

With a couple of standard browser plugins installed, here is what I found for the two current browsers, IE7 & FF2.

1024×768
Internet Explorer Version 7 - 1003×517 usable space.
Firefox Version 2.0.0.6 - 999×546 usable space.

1280×1024
Internet Explorer 7 - 1259×773
Firefox 2.0.0.6 - 1263×810

Therefore, above the fold browser space for the majority of today’s browsers is 999×517.

darren

browsers | screen size


Aug 03, 2009 07:15 PM

X-Cart modification: adding a 2nd image upload field

X-Cart is an e-commerce package that is written in PHP with the use of Smarty tags for its template system. For about $200, it includes a lot of functionality out of the box, and you can buy prebuilt skins for another $60 or so. For those interested in SEO, there is a module called CDSEO that you can purchase by a third party that’ll change the URLs from including GET request variables to a folder style SEO friendly format for another $150 or so. After the add ons, you can have a cart up and running for about $400.

The smarty system leaves a lot to be desired, so beware that it’s going to take longer than you’d normally think if you want to skin the site yourself, especially the first time you work with X-cart. One of the biggest challenges is knowing which template to modify. X-cart helps with this by providing a “webmaster mode”, which changes the status bar to reflect the folder and template structure of a particular section of the page. It’s quite handy because many of the template files are in strange places, and there are a ton of different template files.

X-Cart also loads pages slower than you would expect from a PHP site, which might be because of Smarty templates, but I’m not certain of that.

Note: this article is referring to version 4.0. 4.1 is out now, but I’ve heard that the newer versions are somewhat unstable until they’ve been out there for a while. 4.1 hasn’t been around long enough for me to use in a production environment yet. These instructions will
likely help with 4.1 as well. Of course, you’ll need to modify them to fit the newer codebase.

One issue I’ve come across is the need to put a small thumbnail image for each product listed on the shopping cart checkout pages. Below is how I modified the code to allow a 2nd picture to be uploaded in X-Cart’s admin area. I use one upload for a 250 pixel wide picture on the product detail page, and a 70 pixel wide image on the cart checkout page.

This article is assuming that you know PHP pretty well and can either grasp the Smarty concepts easily or have a familiarity with them. If you need further explanation about Smarty, please comment and I’ll write more about that in another post.

——-

Modifying X-cart to allow 2 picture upload fields

First, back up your x-cart files and database in case something goes wrong.

Then, modify the following files:

In include/product_modify.php:

Add this code directly below the ‘if’ block with the comment “Check if image selected is not expired”:
If that comment can’t be found, look for the same block of code except that it’s looking for an imtype of “T” instead of “S”.
The two “if” blocks could probably be combined into 1, if you’d like. Please note that as is, you can only upload one image at a time.
If you want to be able to upload both at once, you’ll need to modify the code beyond the example to handle that.


//Cart Image
if ($file_upload_data["imtype"] == "S") {

if ($file_upload_data["counter"] == 1) {
$file_upload_data["counter"]++;

$smarty->assign("file_upload_data", $file_upload_data);
}
else {
if ($file_upload_data["source"] == "L")
@unlink($file_upload_data["file_path"]);
x_session_unregister("file_upload_data");
}
}

Also in include/product_modify.php, change the # Prepare for thumbnail updating (around line 278) to this:

# Prepare for thumbnail updating
$image_posted = func_check_image_posted($file_upload_data, "T");
$cartimage_posted = func_check_image_posted($file_upload_data, "S");

$store_in = ($config["Images"]["thumbnails_location"] == "FS"?"FS":"DB");
$cartstore_in = ($config["Images"]["cartimages_location"] == "FS"?"FS":"DB");

And add this code block directly after the $image_posted “if” block:

if ($cartimage_posted) {

$cartimage_data = func_get_image_content($file_upload_data, $productid);
$row_exists = func_query_first("select * from $sql_tbl[thumbnails] where productid = '$productid'");
if ($row_exists['productid'] == "") {
db_query("INSERT INTO $sql_tbl[thumbnails] (productid, ".($cartstore_in == "FS"?"cartimage_path":"cartimage").", cartimage_type) VALUES ('$productid', '$cartimage_data[image]', '$cartimage_data[image_type]')");
} else {
db_query("UPDATE $sql_tbl[thumbnails] SET ".($cartstore_in == "FS"?"cartimage_path":"cartimage")." = '$cartimage_data[image]', cartimage_type = '$cartimage_data[image_type]' WHERE productid = '$productid'");
}
}

On skin1/main/product_details.tpl, add this text below the normal thumbnail table row:


<!-- Cart Image -->
<TR>
{if $productids ne ''}<TD width="15" class="TableSubHead"> </TD>{/if}
<TD colspan="2">{include file="main/subheader.tpl" title="Small Cart Image"}</TD>
</TR>

<TR>
{if $productids ne ''}<TD width="15" class="TableSubHead"><INPUT type="checkbox" value="Y" name="fields[thumbnail]"></TD>{/if}
<TD class="ProductDetails" valign="top"><FONT class="FormButton">Small Image</FONT><BR>(recommended size 50x50 or smaller)</TD>
<TD class="ProductDetails">
{include file="product_cartthumbnail.tpl" productid=$product.productid product=$product.product}
<BR>
<TABLE border="0" cellpadding="0" cellspacing="0" width="100%">
<TR>
<TD>
<INPUT type="button" value="{$lng.lbl_change_image}" onclick='javascript: if (confirm("{$lng.txt_change_image_text|strip_tags}")){ldelim}popup_image_selection("S", "{$product.productid}", "{$query_string}");{rdelim}'>
  
<!--
<INPUT type="button" value="{$lng.lbl_delete_image}" onclick='javascript: if (confirm("{$lng.txt_change_image_text|strip_tags}")){ldelim}self.location="product_modify.php?mode=delete_thumbnail&productid={$product.productid}"{rdelim}'>
-->
</TD>
<TR>
{if $file_upload_data.file_path}
<TR>
<TD>
<BR><BR>
{$lng.txt_save_thumbnail_note}
</TD>
</TR>
<!-- End Cart Image -->
 

In include/image_selection.php, add this case in the $imtype switch:

case "S":
$config_data["location"] = $config["Images"]["cartimages_location"];
$config_data["path"] = $config["Images"]["cartimages_path"];
$config_data["path_only"] = $config["Images"]["cartimages_path_only"];
break;

Save image.php as cartimage.php, then change the code portion to the following (leave the x-cart license comment stuff alone):
Also note that I’ve included <?php even though it shows up above the comments. Of course, you only need this in one spot.

<?php
require "./top.inc.php";
require "./config.php";

if (empty($productid)) $productid = "";

$image_out = ""; $image_type = ""; $image_path = "";

if (!empty($tmp)) {

x_session_register("file_upload_data");

if (!empty($file_upload_data["file_path"]) && $file_upload_data["id"]==$productid && $file_upload_data["imtype"]=="S") {
$image_out = func_file_get($file_upload_data["file_path"], true);
}

}

if (empty($image_out)) {

if(!empty($variantid))
$result = db_query("SELECT cartimage as image, cartimage_path as image_path, cartimage_type as image_type FROM $sql_tbl[thumbnails] WHERE productid='$productid' AND variantid = '$variantid'");
if(empty($result))
$result = db_query("SELECT cartimage as image, cartimage_path as image_path, cartimage_type as image_type FROM $sql_tbl[thumbnails] WHERE productid='$productid' AND variantid = ''");

if (db_num_rows($result)) {
list($image, $image_path, $image_type) = db_fetch_row($result);

if ($image == "") {
header("Content-type: image/gif");
func_readfile($default_image, true);
exit;
}
} else {
header("Content-type: image/gif");
func_readfile($default_image, true);
//echo "Image: " . $image_type;
exit;
}

db_free_result($result);

if ($config["Images"]["thumbnails_location"] == "DB") {
if (!empty($image))
$image_out = $image;
else
$no_image_db = true;
}

if ($config["Images"]["thumbnails_location"] == "FS" || !empty($no_image_db)) {
if (!empty($image_path)) {
header("Content-type: $image_type");
func_readfile($image_path, true);
exit;
}
}

}

if (!empty($image_out)) {
header("Content-type: $image_type");
echo $image_out;
} else {
header("Content-type: image/gif");
func_readfile($default_image, true);
}
?>

Create a new file called skin1/product_cartthumbnail.tpl, and put this code in it:


{* $Id: product_cartthumbnail.tpl,v 1.14 2007/09/14 09:53:29 max Exp $ *}
{if $config.Appearance.show_thumbnails eq "Y"}
<IMG id="{$id}" src="{if $tmbn_url}{$tmbn_url}{else}{if $full_url}{$http_location}{else}{$xcart_web_dir}{/if}/cartimage.php?productid={$productid}{if $file_upload_data.file_path}&tmp=y{/if}{/if}" alt="{$product|escape}" border="0">
{/if}

In include/func.php, in the func_get_image_content function, add this to the $file_upload_data[”imtype”] switch:

case "S":
$config_data["location"] = $config["Images"]["cartimages_location"];
break;

In the database:

Modify xcart_thumbnails (assuming you used the prefix “xcart” when installing it, otherwise modify the table with the appropriate prefix)
to include the following fields:

cartimage mediumblob allow nulls
cartimage_path varchar(255) allow nulls
cartimage_type varchar(64) allow nulls

In xcart_config, add the following rows (modify the table name if you used a different prefix other than xcart):

INSERT INTO xcart_config (name, comment, value, category, orderby, type, defvalue)
values ('cartimages_location', 'location of small cart images', 'DB', 'Images', '130', 'text', 'DB')

INSERT INTO xcart_config (name, comment, value, category, orderby, type, defvalue)
values ('cartimages_path', 'FS junk - not needed', '', 'Images', '140', 'text', '')

INSERT INTO xcart_config (name, comment, value, category, orderby, type, defvalue)
values ('cartimages_path_only', 'FS junk - not needed', 'N', 'Images', '150', 'checkbox', 'N')

After that, test it and see if everything works. If not, you’ll need to troubleshoot the code to see where you missed something.

Good Luck,
Brian

darren

xcart | php | cdseo


Aug 03, 2009 07:13 PM

PHP script to repair all MySQL databases and tables on a server

The repair table command in MySQL is useful to repair database indicies when they become corrupt. A prime example of when an index can become corrupt is when the power is shut off unexpectedly to a server. If the power is shut off after a row has been inserted into the table, but before its index has been updated, the table will become corrupt and unusable.

Unfortunately, there isn’t a “repair all tables” option that I know of. Instead, you can use this simple PHP script to do the trick for you. It simply calls “show databases” to loop through a list of your databases, and then “show tables” so that it knows which tables exist for the repair command. Depending on how many databases you have and the size of their tables, this can take several minutes to run.


<?
### Enter your username and password into the connection string: ###
$dbLink = mysql_connect("localhost", "username", "password") or die("Unable to connect to the database.");

$sql = "show databases";
$query = mysql_query($sql) or die("error fetching database names");

while ($rs=mysql_fetch_array($query)) {

//echo "Database: " . $rs['Database'] . "\n";

mysql_select_db($rs['Database'],$dbLink) or die("Unable to select database: " . $rs['Database']);

$sql = "show tables";
$query2 = mysql_query($sql) or die("error fetching table names");

while ($rs2=mysql_fetch_array($query2)) {
$key = "Tables_in_" . $rs['Database'];
//echo "Table: " . $rs2[$key] . "\n";

$sql = "repair table " . $rs2[$key];
$query3 = mysql_query($sql) or die("Error repairing a table - $sql");
$rs3 = mysql_fetch_array($query3);
echo $rs3['Table'] . " | " . $rs3['Op'] . " | " . $rs3['Msg_type'] . " | " . $rs3['Msg_text'] . "\n";

}

}

echo "Finished!\n";

?>
 

darren

mysql | database | tables | server


Aug 03, 2009 07:12 PM

Permission problems between Plesk and Apache resulting in 403 forbidden errors

After setting up a new site in Plesk and restarting Apache, the site would only display 403 Forbidden errors. The same error occured whether we went to the exclusive IP address or the domain name so we knew that it wasn’t a DNS problem. We checked the logs and it showed that Apache was unable to read the .htaccess file. We changed the permissions on this file, which didn’t do any good.

It turned out that when Plesk set up the domain, it gave the httpdocs directory the wrong permissions. Instead of the permissions that it assigned it, we changed it to 755 or rwxr-xr-x and everything works now.

If you get permission errors in the future, be sure to check the directory the file belongs in as well.

darren

permissions | plesk | apache | errors


Aug 03, 2009 07:10 PM

Securing a Linux server with Iptables

You can save and restore your iptable rules by using the iptables-save and iptables-restore commands. An example of an iptables-save file is below, and as you see it allows access to http (port 80), https (port 443), smtp and pop3 (ports 110 and 25), ftp (port 21), dns (port 53), mysql (port 3306), ssh (port 22), plesk (port 8443), and a few others. It also allows traffic through ports 51000 through 51010. This is because ProFTPd is configured to forward established connections to these ports; Otherwise, it’ll use any high port and you won’t be able to lock anything down.

# Generated by iptables-save v1.2.7a on Fri Oct 15 18:04:43 2004
*filter
:INPUT ACCEPT [6496247:1563147047]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [10757411:8360947636]
:RH-Lokkit-0-50-INPUT - [0:0]
-A INPUT -j RH-Lokkit-0-50-INPUT
-A FORWARD -j RH-Lokkit-0-50-INPUT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 443 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –sport 443 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 8443 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 110 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p udp -m udp –dport 110 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 25 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p udp -m udp –dport 25 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 21 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p udp -m udp –dport 21 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 20 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p udp -m udp –dport 20 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 3306 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p udp -m udp –dport 3306 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 53 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p udp -m udp –dport 53 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p udp -m udp –sport 53 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51000 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51001 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51002 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51003 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51004 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51005 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51006 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51007 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51008 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51009 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 51010 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 22 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –dport 80 –tcp-flags SYN,RST,ACK SYN -j ACCEPT
-A RH-Lokkit-0-50-INPUT -i lo -j ACCEPT
-A RH-Lokkit-0-50-INPUT -s 217.160.242.226 -p udp -m udp –dport 53 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -s 217.160.242.226 -p udp -m udp –sport 53 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -s 217.160.243.251 -p udp -m udp –sport 53 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -s 195.20.224.99 -p udp -m udp –sport 53 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -s 195.20.224.234 -p udp -m udp –sport 53 -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp –tcp-flags SYN,RST,ACK SYN -j REJECT –reject-with icmp-port-unreachable
-A RH-Lokkit-0-50-INPUT -p udp -m udp -j REJECT –reject-with icmp-port-unreachable
COMMIT
# Completed on Fri Oct 15 18:04:43 2004

Here is an example of a cronjob that restores the Iptables rules. I added the cronjob to ensure that IPtables was always loaded with the correct rules. This was on a dev box and we were messing with a lot of ports at the time so we wanted to make sure that it was reset periodically. It also helps for when the box was rebooted to make sure the rules were loaded. Of course, a better way to do that would be to modify the startup scripts. Also, you can put the firewall.txt file where ever you want. It doesn’t need to be in root’s home directory.

### Restore Iptables Rules
5 7,14,21 * * * /sbin/iptables-restore -c < /root/firewall.txt

And finally, to set up the ftp server to only use the specified ports, configure /etc/proftpd.conf and add this line:

PassivePorts 51000 51010

The actual ports could be any unused high port, so keep that in mind. It can also be more than 10 ports (which essentially would allow 10 concurrent connections). Whatever you do, you’ll need to make sure the iptable rules allow the ports you’re expecting FTP to transfer data on.

darren

linux | security | iptables


Displaying posts 1 - 5 of 25 in total

 


 

Visit www.Vauntium.com for more information.

 

 

Resource Links