Mostrando entradas con la etiqueta php. Mostrar todas las entradas
Mostrando entradas con la etiqueta php. Mostrar todas las entradas

viernes, 28 de mayo de 2010

wp-e-commerce upload adding images to CSV upload

We've covered uploading multiple categories in wp-e-commerce, but what about images?

It stands to reason that if you are uploading a bunch of products, you will want images to accompany them. This takes a little more work than adding multiple categories, but is significantly easier than adding them one-by-one.

1. Preparing the Images
If you are happy doing bulk resizing/cropping in whichever graphics package you use, then do it! Process your product images so that you have a thumbnail that matches the size defined in your wp-e-commerce installation (96px X 96px is the current default).

Next process your source images again so that you have a large image that is either a manageable size, or sized to your wp-e-commerce product image size settings (128px X 128px is the current default). Once you have thumbnails and full-size images, upload the thumbnails to "wp-content/uploads/wpsc/product_images/thumbnails/" and the full-size to "wp-content/uploads/wpsc/product_images/". You can now move onto step 2 "Importing".

If you aren't happy batch-processing images you can create a directory called "'wp-content/uploads/wpsc/product_images/temp" and upload all your product images there. Please ensure that the images are at a manageable size (i.e. less than 1000px wide or high).

Next download and save a copy of the "imgprocess.php" script we cobbled together (remove the XXX from the extension) - n.b. this script is largely based on a great function here

Adjust the thumbnail size variables ($thumbwidth and $thumbheight) on lines 3-4 to correspond with the thumbnail sizes specified in wp-e-commerce (default is 96px X 96px). If you want your large images processed as well then add the relevant dimensions to the $largewidth and $largeheight variables on lines 6 and 7. Alternatively, leave them at 0 if you don't want to resize your large images. Please note that this is a basic script so it only crops images to the exact sizes specified. If you want your large images to be scaled, you will have to add that functionality yourself.

Once you have made your adjustments, upload the script to the root of your WordPress installation (in most cases yoursite.com/imgprocess.php). Please note that this script has not been extensively tested, and you run it very much at your own risk. We highly recommend running it in a test environment first and take no responsibility for anything (from server failure to hives or plagues of locusts) that occurs from the moment you run it!!

If you chose to continue, run the script by entering the location into your browser (in most cases yoursite.com/imgprocess.php). The script will take a while to execute, but all being well you will see a big ugly message saying "Images processed". Your thumbnails directory should now be populated with the thumbnails you created.

If you chose not to resize the large images then simply copy the images from "wp-content/uploads/wpsc/product_images/temp" to "wp-content/uploads/wpsc/product_images". Otherwise, your resized large images should be in wp-content/uploads/wpsc/product_images/'.

Next delete "wp-content/uploads/wpsc/product_images/temp" and delete imgprocess.php.

2. Importing
Open wp-e-commerce/wpsc-admin/includes/settings-pages/import.php
locate the option list:

Product Name
Description
...etc


and add the following option value:

Image


Next locate the line

$existing_name = get_product_meta($id, 'url_name');


and add the following above it so it reads:

$image_query = "INSERT INTO `".WPSC_TABLE_PRODUCT_IMAGES."` (product_id,image ) VALUES ('$id','".$cvs_data2."')";
$wpdb query($image_query);
$imageid = $wpdb get_var("SELECT LAST_INSERT_ID() as id FROM `".WPSC_TABLE_PRODUCT_IMAGES."`");
//now add image id to product
$image_query2 = "UPDATE `".WPSC_TABLE_PRODUCT_LIST."` SET image = ".$imageid." WHERE id=".$id;
$wpdb query($image_query2);
$existing_name = get_product_meta($id, 'url_name');


Now add a column to your product list csv that you wish to upload and add the name of each image uploaded to the relevant image
e.g.
SKU, Name, Price, Image
001, Shoe, 100, shoe.jpg
002, Hat, 20, hat.jpg

Upload the csv as normal remembering to assign 'Image' to the relevant column, and your products should now be loaded complete with images.

miércoles, 19 de mayo de 2010

wp-e-commerce upload adding multiple categories to CSV upload

How to bulk upload to more than one category with the excellent Wp-e-commerce plugin.

In our case, we needed to assign each product to a category and a brand (e.g. Category: Jeans, Brand: Levis). To do this, we removed the bulk 'add to category' dropdown from the bottom of the import page and added a category and brand option to the dropdowns that are used to assign columns in the uploaded .csv file. Here's how...

Open wp-e-commerce/wpsc-admin/includes/settings-pages/import.php

As we are going to assign each item to its own category and brand, the category dropdown at the bottom of the upload page is no longer relevant. So, we remove lines 77 - 85:

Please select a category you would like to place all products from this CSV into:

'.$category.'';

}




Next we add the category and brand options to the dropdown list of assignable fields.
lines 61 - 69 show:

Product Name
Description
Additional Description
Price
SKU
Weight
Weight Unit
Stock Quantity
Stock Quantity Limit


We are going to add to these so we now have:

Product Name
Description
Additional Description
Price
SKU
Weight
Weight Unit
Stock Quantity
Stock Quantity Limit
Category
Brand


now we change (what is now) line 122 - 123 to read:

$category_query = "INSERT INTO `".WPSC_TABLE_ITEM_CATEGORY_ASSOC."` VALUES ('','$id','".$cvs_data2."')";
$wpdb query($category_query);


and add the following two lines underneath:

$brand_query = "INSERT INTO `".WPSC_TABLE_ITEM_CATEGORY_ASSOC."` VALUES ('','$id','".$cvs_data2."')";
$wpdb query($brand_query);


This is simply adding the category and brand id to the WPSC_TABLE_ITEM_CATEGORY_ASSOC table.

Remember to add the Category IDs to your csv file and NOT the category name. Alternatively you could extend this tutorial by looking up the Category ID using the Category Name and inserting that.

viernes, 29 de enero de 2010

Changing the Wordpress Language

The Wordpress backend deals with 'Posts' and 'Pages'. For some clients this is too vague, and tweaks are needed.

As an example a site i've been working on recently needed the word 'Post' to be replaced with 'Product'. To do this, we need to create our own custom language file. Unfortunately creating a language file is a pretty complex process as compared to how simple other Wordpress processes can be. It is also not as well documented as other facets of Wordpress. So watch closely!

To begin with you will need a copy of the official WordPress POT file.

Next get yourself a translation tool. We opted for poEdit, which was quick and easy to download and install.

You are ready to start translating!
Open Poedit and use the File/open dialog to open your Wordpress POT file (ensure you change 'files of type' from GNU Gettext catalogs (*.po) to 'all files (*.*) )

Firstly, most importantly, and not well documented:

Go to Catalog/Settings
In the 'Project Info' tab:
change the language team to something new (e.g. Haycroft Media)
change the 'Plural Forms' value to nplurals=2; plural=(n != 1)
(if you are translating to a different language check this: list of Gettext plural forms for the correct setting
Click Ok

Now go to File/preferences and click on the 'Editor' tab.
Ensure that the 'Automatically compile .mo file on save' box is ticked
Click OK

Now File/save as to save
For this example I am saving the file as custom_lang
after saving you should see: custom_lang.mo and custom_lang.po saved in the location you chose.

Now at last we can begin!

Click Edit/find and enter the term you wish to translate (in my case it was 'Post')
tweak the search settings according to what you need and search

The first result I get for my 'Post' example is "Error: you are replying to a comment on a draft post."
Copy and paste this into the translation box and then amend the word post so you get:
Error: you are replying to a comment on a draft product.
Repeat this process until you have finished.

Save again

Now open your wp-config file and amend:
define ('WPLANG', '');
so that it reads:
define ('WPLANG', 'custom_lang');
(or whatever you saved your language file as)

Now create a directory called 'languages' in your wp-content directory
Upload the custom_lang.mo (or wahtever you saved it as) file to the languages folder you just created

Your backend should now display your amended language!

martes, 12 de enero de 2010

TwitterTools - open links in external window

Our site makes use of the Twitter Tools plugin, but with some minor tweaks

The only links that Twitter Tools displays with our set-up are the bit.ly links, the link to the specific tweet (e.g. "1 hr ago") and the "More Updates..." link. All of these links will open their target in the same window, but we wanted them to open an external window so the user remains on the site.

To do this, you need to locate the plugin's main coding. This is currently at:
wp-content/plugins/twitter-tools/twitter-tools.php

Now make the folllowing changes:

"More Updates Link": Change Line 812:

$output .= ' twitter_username).' '.__('More updates...', 'twitter-tools').''."\n";

To:

$output .= ' twitter_username).'" target="_blank '.__('More updates...', 'twitter-tools').''."\n";


"Time Display Link": Change Line 879:

$output .= ' '.aktt_status_url($aktt twitter_username, $tweet tw_id).'" class="aktt_tweet_time '.$time_display.'';

To:

$output .= ' '.aktt_status_url($aktt twitter_username, $tweet tw_id).'" class="aktt_tweet_time" target="_blank '.$time_display.'';


"Bit.ly links": Change Line: 881:

return $output;

To:

$output = str_replace('rel="nofollow ', 'target="_blank" rel="nofollow ', $output);
return $output;

Custom Write Panels

One of the great assets Wordpress possesses is the ability to easily customise the backend.

For example, a client needs a website for a real estate agent. The client will be posting information on the various properties available and displaying standard information on each property:

Title
Short Description
Long Description
Price
Thumbnail image
Large images
Bedrooms
Bathrooms
Generic Description (selected from a list of pre-defined descriptions)


Obviously the title and description fields can be covered using the standard Wordpress Title and Content fields. Thanks to the fantastic additions to Wordpress 2.9, Post Thumbnail images are now easy to use and reference, and the Gallery Shortcode has been in effect for a while now.

This just leaves the custom fields. There are plugins you can use, but we are control freaks and like to do thinks ourselves. So, as a starting point, we use this fantastic tutorial on Wefunction, but with a few extras.

First of all we create an array for our fields:

$track_meta_boxes =
array(
"price" => array(
"name" => "price",
"type" => "input",
"std" => "",
"title" => "Price",
"options" => "",
"description" => "Enter Property Price"),
"bedrooms" => array(
"name" => "bedrooms",
"type" => "input",
"std" => "",
"title" => "Bedrooms",
"options" => "",
"description" => "No. of bedrooms"),
"bathrooms" => array(
"name" => "bathrooms",
"type" => "input",
"std" => "",
"title" => "Bathrooms",
"options" => '',
"description" => "No. of bathrooms"),
"desc" => array(
"name" => "desc",
"type" => "select",
"std" => "",
"title" => "Description",
"options" => $desc,
"description" => "Description")

);


Notice that we have added a field called "type" to our array. This defines whether we are displaying and input box or a select box. We also add an array called $desc to the 'options' field. This could be defined as follows:

$desc = "Great for the first time buyer";
$desc = "Roomy and spacious";
$desc = "No room to swing a cat";


Now we just make a small amendment to the code to test whether we are displaying a select or input field:

if ( $meta_box == 'select' ) {
echo '';
} else {
echo '';
}


Note that this code just deals with displaying the panel. You can ascertain the necessary coding to display saved values (front and backend) from the wefunction tutorial. You will probably also want to test each of your option values against the saved value and flag it as selected if it is indeed the saved value.

We would also advise using the standard Wordpress markup when it comes to displaying the panels (something that they don't do in the wefunction tutorial). This is just for aesthetics, and it saves space.

Writing Wordpress Plugins

We're branching out this year, as well as Wordpress themes, we are now building custom plugins as well.

Although we've built a few plugins for customers sites, up until this point we haven't released anything into the Wordpress community, but all this is set to change with our first plugin.

Meantime, if you want to write Wordpress plugins, here's where you should start:

Creating Options Pages : Nearly all plugins will have some options. This page is also highly valuable if you want to add options to your themes.

Add a Widget : Your plugin may display data in a sidebar widget. Here's how!

Interact with the Database : Add your own tables to the Wordpress Database, or add/update/retrieve data that's already there.

martes, 1 de diciembre de 2009

Convert Text into PNG Image using PHP

We are currently working on a Wordpress MU theme that requires logos to be generated on the fly.

Fortunately the logos will just make use of a simple script font, but we still need some means of auto-generating them. We started with a great tutorial at Vision Master Designs and tweaked it slightly to fit in with Wordpress and the specification of the client.

Firstly, and fortunately, the name of each of the WPMU blogs would be the name required in the logo. This meant that we could pass "bloginfo('name')" in the text variable:


" />


Secondly, all the site names would be two words and these needed to be spread over two lines. This required a small addition to the code that simply replaces the whitespace between the two words with a PHP_EOL (end of line) call.


if (isset($_GET)):
$helloworld = $_GET;
$helloworld = str_replace(' ', PHP_EOL.' ', $helloworld);
else :
$helloworld = "Lifetime
Experiences";
endif;


With those two additions, we now have a theme that automatically generates logos on the fly. Perfect for a client who needs to be able to publish sites quickly and easily.

Exclude categories from Wordpress RSS

The Haycroft Media website uses a category for the flashy portfolio on the home page, which we want to hide from the Wordpress RSS feed

There are various options for doing this all detailed in a nice simple tutorial at Web-Kreation.com. We opted for option 2: Exclude categories in your template’s functions.php file, which simply involved the addition of a few lines of code to the functions.php file (just change the category id to that of the one you wish to omit):


function myFeedExcluder($query) {
if ($query is_feed) {
$query set('cat','-12');
}
return $query;
}
add_filter('pre_get_posts','myFeedExcluder');

Strip wp_head in Wordpress

The wp_head() call in the header of most themes is an invitation for Wordpress to start inserting code into your nice tidy head.

However, we are of the opinon that if you don't need it, get rid of it. If you view the source of this site, you will see that we have removed the rsd link, the wml manifest link and the generator link. We're not using them, so we don't need them.

In addition, many Wordpress security blogs recommend removing the generator tag as it reveals the version of Wordpress you are using. So, say the good people at Wordpress discover a major security flaw in version 2.6 and you haven't upgraded to 2.7 yet, anyone with a knowledge of the flaw knows that your site is vulnerable.

So, how do we remove these pesky tags? Simply add the following to your themes functions.php file:


function striphead() {
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wlwmanifest_link');
add_filter('the_generator', 'no_generator');
}
function no_generator() {
return '';
}
add_action('init', 'striphead');

martes, 17 de noviembre de 2009

Displaying user data in your Wordpress theme

The last time I needed to display user data was for the Press Stick website. For their site, they wanted the user to be greeted with a personalised message on logging in.

The message for the Press Stick site was:
"hi from . welcome back to the press-stick sourcing portal. we look forward to showing you the new and exciting products available to you."

For the purpose's of this site, we tweaked the standard Wordpress user data so that the user's magazine name would be stored in the 'Nickname' field. To return the message above, we simply insert the following:

user_firstname.' '.$current_user user_lastname;
$magazine = $current_user nickname;

echo '';

List all blogs in a Wordpress MU installation

The African Travel Experts site has two dropdown lists of all the blogs on their WPMU installation sorted into two different categories. Here's how.

The way the site is set up is to have the African Travel Experts site as the main 'umbrella site' with sub-sites for each African country, which act as parent sites to sub-sites relating to the country. For example:

Master site: African Travel Experts
Country sub-site: South Africa
Child-site: Cape Town

Seeing as the standard WPMU installation doesn't provide for classifying blogs/sites in this way, a plugin and a bit of lateral thinking was required. I opted for the Blog Types plugin, which allows you to define your own categories for a blog. Once installed, I defined my categories in the config as follows:


// Blog types
// name and nicename are required

$blog_types = 'South Africa';
$blog_types = 'south_africa';
$blog_types = '';
$blog_types = 'no';

$blog_types = 'Botswana';
$blog_types = 'botswana';
$blog_types = '';
$blog_types = 'no';

//.... etc until all countries are defined

$blog_subtypes = 'Cape Town';
$blog_subtypes = 'cape_town';
$blog_subtypes = 'south_africa';
$blog_subtypes = '';

$blog_subtypes = 'Eastern Cape';
$blog_subtypes = 'eastern_cape';
$blog_subtypes = 'south_africa';
$blog_subtypes = '';

//.... etc until all areas are defined

// Allow users to select one or multiple blog types
// Note: If you allow users to select multiple blog types, they cannot select a subtype
$blog_types_selection = 'single'; //Options: 'single' or 'multiple'

// Allow users to select one or multiple blog subtypes
$blog_subtypes_selection = 'single'; //Options: 'single' or 'multiple'

// Branding singular
$blog_types_branding_singular = __('Country');
$blog_subtypes_branding_singular = __('Area');

// Branding plural
$blog_types_branding_plural = __('Countries');
$blog_subtypes_branding_plural = __('Areas');

// Display admin panel blog types page
$blog_types_display_admin_page = 'yes'; //Options: 'yes' or 'no'

// Display signup form blog types selection
$blog_types_display_signup_form = 'yes'; //Options: 'yes' or 'no'

// Enable subtypes
$blog_types_enable_subtypes = 'yes'; //Options: 'yes' or 'no'

Watermark images

Quivertree publications are an image library website and like most image library websites, they wanted their images watermarked

There are a lot of scripts floating about for adding watermarks to image as they are served up to the end user, but a lot of these made it too easy for the end user to ascertain the location of the original, 'un-watermarked' image, and as there was already a backend process involved in loading the images and their meta-data, it made sense to write code that generated the final watermarked image in advance. I used this fantastic tutorial on Watermarking Images on the Fly in PHP as a starting point and came up with this:


$dir = dirList ('temp_images');//function that returns a list of all images in the temp_images directory - these images were already uploaded to this location by the site admin
if($dir)://if there are images in the temp_images directory, then away we go!
foreach($dir as $key => $value): //for each image $key = image number, $value = the image name (e.g myImage.jpg)
$imgsrc = 'temp_images/'.$value; //source image without watermark
$imgout = 'temp_watermark/'.$value; //where to save the image with the watermark
watermark_img($imgsrc,$imgout);//this function is below
endforeach;
else:
echo 'You need to upload some images first';
endif;


Here is the watermark_img function:


function watermark_img($imgsrc,$saveas) {
$watermark = imagecreatefrompng('images/watermark.png'); //location of my watermark
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
$image = imagecreatetruecolor($watermark_width, $watermark_height);
$image = imagecreatefromjpeg($imgsrc);
$size = getimagesize($imgsrc);
$mainimg_w_pos = $size / 2; //get half of the main image
$watermark_w_pos = $watermark_width / 2; //get half of the watermark
$dest_x = $mainimg_w_pos - $watermark_w_pos; //watermark sits at half of width minus half its own width
$mainimg_h_pos = $size / 2; //get half of the main image
$watermark_h_pos = $watermark_height / 2; //get half of the watermark
$dest_y = $mainimg_h_pos - $watermark_h_pos; //watermark sits at half of width minus half its own width
_ckdir($saveas);//function to test that save as location is available
imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);
imagejpeg($image,$saveas,100);
}

lunes, 16 de noviembre de 2009

Auto-generating Community Builder profiles

For the AIRCO website, user profiles had to be auto-generated on admin approval, and a mail generated to the user.

The site was already running on a Joomla installation making use of the Community Builder suite, but some extra tweaking was needed to hook the site up to the member application backend.

The Process:
Potential member completes application form
Admin approves form
Profile is auto-generated and details are mailed to the member as follows:

1. Convert the member's name to a valid username (the member can always edit this if it isn't what they want)

$username = ereg_replace("", "", $name ); //convert to alphanumeric
$username = trim($username); // remove any unnecessary whitespace
$username = substr($username, 0, 24); //ensure the length of the username doesn't exceed 24 characters


2. Ensure that the email address used is unique (this is tested on initial registration, but we re-test to be safe)

$query = "SELECT * FROM jos_users WHERE email = '$email'";
$result = mysql_query($query) or die(mysql_error());
$check = mysql_num_rows($result);
if($check 0):
//flag as duplicate and exit
endif;


3. Check for duplicate username, and if one exists add a number on the end, retest and increment number until we get a unique value:

$n = 0;
$username_flag = '';
while($username_flag != 'set'):
$query = "SELECT * FROM jos_users WHERE username = '$username'";
$result = mysql_query($query) or die(mysql_error());
$check = mysql_num_rows($result);
$n++;
if($check 0):
$username = $username.$n;
else:
$username_flag = 'set';
endif;
endwhile;


4. Everything ok? Then we add the data:
a. Add
jos_users - name, username, email, password (remember to encrypt this with md5), usertype, gid, registerDate, params
jos_core_acl_aro - section_value = users, value = id of the record you inserted into jos_users, name = name of the member (as entered into jos_users)
jos_core_acl_groups_aro_map - group_id = id of the group your member belongs to, in my case 19 - Author, aro_id = id of the record you inserted into jos_core_acl_aro
jos_comprofiler id & user_id = id of the record you inserted into jos_users, then any other values captured for custom fields.

5. Finally email the member:

$to = $email;//captured from application form
$subject = "Your profile";
$body = "Dear ".$name."\n";
$body .= "You are now a full Member.\n\n";
$body .= "MEMBER'S AREA LOG-IN DETAILS\n";
$body .= "Username: ".$username."\n";
$body .= "Password: ".$password."\n\n";
$from = "FROM: ".$SENDERS_EMAIL_HERE;
mail($to, $subject, $body, $from);

jueves, 12 de noviembre de 2009

Dynamic mp3 player

For the Elastic Artists website, a dynamic MP3 player was required that could be controlled and loaded from the backend.

I decided to go with a Flash based player and found a great tutorial for creating a flash MP3 player using XML. In order for the player layout to match the design called for by the client, a few tweaks were needed:

Original code:

_root._x = 5;
_root._y = 40 + (i*15);
_root.but_txt.text = songname;
if (i >= 3){
_root._x = 160
_root._y = -5 + (i*15);
}


My code:

_root._x = 0;
_root._y = 55+(i*30);
_root.but_txt.text.html = true;
_root.but_txt.htmlText = "Artist: "+songband+""+newline+"Track: "+songname;

The original produces two columns of 3 tracks side by side and just displays the song name. The amended code produces one list of tracks with font-color black (other font info was applied through flash) in the format:
Artist: artistname
Track: trackname
The amount of tracks returned will always be nine. This is controlled by the backend of the website.

Other than all the various original design elements, the only other change called for was for a playlist generated from a database table. While the tutorial makes use of a user-generated XML file, I used a php file that generates XML:


header("Content-type: text/xml");
$xml_output = '$xml_output .= '';
//connect and run query to return values for track title, artist and link to mp3 file
$title = $row;
$url = $row;
$artistName = $row;
$xml_output .= '';
$xml_output .= '
';
echo $xml_output;

The client can then control the contents of the playlist via the site backend.

lunes, 7 de enero de 2008

PHP: 10 things you may not know

10 things you (probably) didn’t know about PHP.

Great post on Rightbrainnetworks.com. Of particular interest is the reference to the Ternary Operator. Put simply if you are using an "IF" loop, and only testing two conditions, instead of using:

"if (condition1 == "set")
{
$variable = 1
}
else
{
$variable = 2
}

you can use:

$variable = (condition1 == "set") ? 1 : 2;