Archive for the ‘eCommerce’ Category

How to bring in Related Product Data into View.phtml with Downloadable Sample Links

Monday, July 26th, 2010

Morning Guys and Girls,

Today we will learn how to bring in related product data into the View.phtml or product colum or middle column.

To see a demo of this have a look at this page:

3AM Psytrance Timecode Records – Multistate – Collaborating with machines

Ready? Let’s do it!


<?php foreach ($_product->getRelatedProducts() as $related_product) {
 if (sizeof($_product->getRelatedProducts())>0):
 ?>
 <?php

$ids[] = $related_product->getId();

echo $relatedproduct->getName(); ?>

That will get you related products. However, I actually extended it quite a bit more, in the sense that my related products are downloadable products, and I needed to get the sample link from these products. The complete code that I used therefor looks like this:


<?php $i = 1; ?>
 <?php foreach ($_product->getRelatedProducts() as $related_product) {
 if (sizeof($_product->getRelatedProducts())>0):
 ?>
 <?php
 $ids[] = $related_product->getId();

 //Download product samples code :)  Ninja Go!!
 $_myprodsamples = Mage::getModel('downloadable/sample');
 $_mySampleCollection = $_myprodsamples->getCollection()->addProductToFilter($related_product->getId());

 $relatedproduct = Mage::getModel('catalog/product');
 $relatedproduct->load($related_product->getId());

 if (sizeof($_mySampleCollection)>0):
 ?>

 <?php
 foreach ($_mySampleCollection as $_sample) {
 //$_samplelink = $this->getUrl('downloadable/download/sample/sample_id/'.$_sample->getId());
 $_samplelink = Mage::getModel('downloadable/sample')->load($_sample->getId())->getUrl();
 ?>
 <span><?php echo $i++; ?><?php echo $this->__('. ') ?><a href="javascript:void(0)" onclick="player1.sendEvent('STOP'); player1.sendEvent('LOAD', {'image':'<?php echo $_product->getImageUrl(); ?>', 'file':'<?php echo $_samplelink ?>', 'provider':'sound', 'buffer':0, 'autostart':true});" title="Click to play <?php echo $relatedproduct->getName(); ?>"><?php echo $relatedproduct->getName(); ?></a></span>
 <?php } ?>
 <?php /*endforeach;*/ ?>

 <?php endif; ?>

 <?php //Mage::Helper('debug')->log($_sample) ?>
 <?php endif; ?>
 <?php } ?>
 <?php /*endforeach;*/ ?>

Beer time!
There you have it, if you don’t come right, use the contact form to contact me, and I will set this up for you.

Have a wonderful day!

Winston

Magento Cape Town

Monday, July 19th, 2010

We work with Magento all day long, and know this system very well now.
At BUYX Online, we will be able to support, host, and develop your on-line store. We have also made Magento Partners throughout the world and can recommend someone in Europe, America, and India.

Should you have a Magento related query, contact us here.

HOWTO Compile JW Player from Longtail on Windows

Saturday, July 17th, 2010

Okay today we will learn howto compile Actionscript, and JW Player on Windows Vista.

Normally I only work on Linux but since I have never done this I took the dummy way out. Sue me :P

Okay We will need this software:

* Flex SDK 3.3: http://opensource.adobe.com/wiki/display/flexsdk/Downloads
* Ant 1.7.0: http://ant.apache.org/bindownload.cgi
* FlexUnit 4: http://opensource.adobe.com/wiki/display/flexunit/FlexUnit (for testing the player)

Make sure you get Flex version 3.3!! This is so Important otherwise you’ll get strange errors.

Okay I put Flex in this directory:

C:\Program Files\Adobe Flex Builder 3\sdks\3.3.0\

Inside this directory is the following contents:

ant
asdoc
bin
build.properties
build.xml
frameworks
lib
license-mpl.htm
readme-open.htm
samples
templates

That’s Flex done.
Now for Ant

I downloaded ant and put it in the directory

C:\ant

There is no install, just copy the files. Inside the directory is the following contents:

bin
docs
etc
fetch.xml
get-m2.xml
INSTALL
KEYS
lib
LICENSE
NOTICE
README
WHATSNEW

That’s Ant done.

Now for JAVA SDK. I downloaded this file:
jdk-6u21-windows-i586.exe and installed it. I chose the location:

C:\jdk_6

That’s JAVA SDK done.

Now grab your version of the JW Player source, and copy it to your C drive. My source is in this directory.

C:\trunk\fl5\

Inside this directory is the following contents:

assets
bin-release
build
doc
libs   ###NOTE### THIS DIRECTORY I COPIED FROM THE FLEX DIRECTORY
C:\Program Files\Adobe Flex Builder 3\sdks\3.3.0\frameworks
player.swf
player.xml
README.txt
src
test
yt.as
yt.fla
yt.swf

That’s our source Done!
Now before we compile to open up our command line and give the following commands. You have to do this everytime you restart Windows and before you want to compile.

set ANT_HOME=c:\ant
set JAVA_HOME=c:\jdk_6
set PATH=%PATH%;%ANT_HOME%\bin

Now for the goodstuff or the bad stuff, to compile the source code in the command line, navigate to

C:\ant\bin and give this command
ant -buildfile C:\trunk\fl5\build\build.xml

And that’s it! Good luck! Let’s go have a beer :P

Winston

JW Player 5.2 Autostart BUG: Ticket #928

Saturday, July 17th, 2010

Hi there,

My awesome twin brother and I recently re-launched our super-cool-oh-my-gosh-this-rocks website www.3am.co.za

With the relaunch we changed frameworks and our old Flash media player no longer could do the job.
I looked into using the awesome Flowplayer but was suggested by my good friend Bruno
(balexandre #magento) to use JW player from Longtail.

I built the flash JW Player into my Magento website and started plugging in my samples.
The JW Player is quite cool, and it took me a couple of days to get to grips with the framework and how it functions. When all was setup I noticed that my Autostart function doesn’t work. This was bad because of the following.

- When a user click on a song to play, it would start the autoplay, and downloading the song, but no sound would come through
- The user then had to click Pause and then Play for the song to start playing.

So 3 clicks made a play.

I then decided to look into it and came across this BUG post.

The fix there was stated by Pablo as

This issue can probably be tracked down to the following line: trunk/fl5/src/com/longtailvideo/jwplayer/media/SoundMediaProvider.as#L150

Replace

if (_sound.isBuffering == true && _sound.bytesTotal > _sound.bytesLoaded) {

with

if (_sound.isBuffering == true && _sound.bytesTotal > _sound.bytesLoaded > 0) {

So I decided to give it a try, nevermind the fact that I have never in my life compiled Actionscript. But hey..more on that later. See my blog Post on How to Compile Actionscript and JW Player 5.2

This change did not make a huge difference so I went back into the code this morning and came up with this:
In the file:
/trac/browser/trunk/fl5/src/com/longtailvideo/jwplayer/media/SoundMediaProvider.as#L150″>trunk/fl5/src/com/longtailvideo/jwplayer/media/SoundMediaProvider.as

I changed this protected function positionHandler(progressEvent:ProgressEvent=null):void function

For sake of clarity I’m just going to paste the whole file. Look for my changes around Line 141, Line 144, Line 155 and Line 157. Let me just tell you now, that I have NEVER in my whole entire life written even one line of ActionScript. This code is not the prettiest, but as you can see on this page it does work :)

/**
 * Wrapper for playback of mp3 sounds.
 **/
package com.longtailvideo.jwplayer.media {
 import com.jeroenwijering.events.*;
 import com.longtailvideo.jwplayer.events.MediaEvent;
 import com.longtailvideo.jwplayer.model.PlayerConfig;
 import com.longtailvideo.jwplayer.model.PlaylistItem;
 import com.longtailvideo.jwplayer.player.PlayerState;

 import flash.events.*;
 import flash.media.*;
 import flash.net.URLRequest;
 import flash.utils.*;

 public class SoundMediaProvider extends MediaProvider {
 /** _sound object to be instantiated. **/
 private var _sound:Sound;
 /** Sound control object. **/
 private var _transformer:SoundTransform;
 /** Sound _channel object. **/
 private var _channel:SoundChannel;
 /** Sound _context object. **/
 private var _context:SoundLoaderContext;
 /** ID for the position interval. **/
 protected var _positionInterval:Number;
 /** Whether the buffer has filled **/
 private var _bufferFull:Boolean;
 /** Whether the enitre video has been buffered **/
 private var _bufferingComplete:Boolean;
 /** User-defined item duration **/
 private var _userDuration:Number = -1;

 /** Constructor; sets up the connection and display. **/
 public function SoundMediaProvider() {
 super('_sound');

 }

 public override function initializeMediaProvider(cfg:PlayerConfig):void {
 super.initializeMediaProvider(cfg);
 _transformer = new SoundTransform();
 _context = new SoundLoaderContext(config.bufferlength * 1000, true);
 }

 /** Sound completed; send event. **/
 private function completeHandler(evt:Event):void {
 complete();
 }

 /** Catch errors. **/
 private function errorHandler(evt:ErrorEvent):void {
 stop();
 error(evt.text);
 }

 /** Forward ID3 data from the _sound. **/
 private function id3Handler(evt:Event):void {
 try {
 var id3:ID3Info = _sound.id3;
 var obj:Object = {type: 'id3', album: id3.album,
 artist: id3.artist, comment: id3.comment,
 genre: id3.genre, name: id3.songName, track: id3.track,
 year: id3.year}
 sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata:obj});
 } catch (err:Error) {
 }
 }

 /** Load the _sound. **/
 override public function load(itm:PlaylistItem):void {
 _position = 0;
 _bufferFull = false;
 _bufferingComplete = false;
 _userDuration = itm.duration > 0 ? itm.duration : -1;
 if (!_item || _item.file != itm.file) {
 _item = itm;
 _sound = new Sound();
 _sound.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
 _sound.addEventListener(Event.ID3, id3Handler);
 _sound.addEventListener(ProgressEvent.PROGRESS, positionHandler);
 _sound.load(new URLRequest(encodeURI(_item.file)), _context);
 }
 if (!_positionInterval) {
 _positionInterval = setInterval(positionHandler, 100);
 }

 sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_LOADED);
 setState(PlayerState.BUFFERING);
 sendBufferEvent(0);
 streamVolume(config.mute ? 0 : config.volume);
 }

 /** Pause the _sound. **/
 override public function pause():void {
 if (_positionInterval){
 clearInterval(_positionInterval);
 _positionInterval = undefined;
 }
 if (_channel) {
 _channel.stop();
 }
 super.pause();
 }

 /** Play the _sound. **/
 override public function play():void {
 if (position == 0 && _item.start > 0) {
 seek(item.start);
 return;
 }
 if (!_positionInterval) {
 _positionInterval = setInterval(positionHandler, 100);
 }
 if (_channel){
 _channel.stop();
 _channel = null;
 }
 _channel = _sound.play(_position * 1000, 0, _transformer);
 _channel.addEventListener(Event.SOUND_COMPLETE, completeHandler);
 super.play();
 }

 /** Interval for the _position progress **/
 protected function positionHandler(progressEvent:ProgressEvent=null):void {
 var bufferPercent:Number;

 if (_sound.bytesTotal > 0 && _sound.bytesLoaded / _sound.bytesTotal > 0.1 && (_item.duration <= 0 || _userDuration < 0)) {
 _item.duration = _sound.length / 1000 / _sound.bytesLoaded * _sound.bytesTotal;
 }

 if (_channel && _sound && _sound.bytesTotal > 0) {
 _position = Math.round(_channel.position / 100) / 10;
 bufferPercent = Math.floor(_sound.bytesLoaded / _sound.bytesTotal * 100);
 } else if (!_channel && progressEvent && progressEvent.bytesTotal > 0) {
 bufferPercent = Math.floor(progressEvent.bytesLoaded / progressEvent.bytesTotal * 100);
 } else {
 bufferPercent = 0;
 }

 //if (_sound.isBuffering == true && _sound.bytesTotal > _sound.bytesLoaded) {
 if (_sound.isBuffering == true && _sound.bytesTotal > _sound.bytesLoaded > 0) {
 if (state != PlayerState.BUFFERING) {
 //_bufferFull = false;
 _bufferFull = true;
 if (_channel) {
 _channel.stop();
 play();
 }
 if (!progressEvent) {
 setState(PlayerState.BUFFERING);
 }
 }
 } else if (state == PlayerState.BUFFERING && _sound.bytesLoaded > 0 && !_bufferFull) {
 //_bufferFull = true;
 _bufferFull = false;
 //sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL);
 play();
 }

 if (!isNaN(bufferPercent) && !_bufferingComplete){
 if (bufferPercent == 100 && _bufferingComplete == false) {
 _bufferingComplete = true;
 }
 sendBufferEvent(bufferPercent, 0, {loaded:_sound.bytesLoaded, total:_sound.bytesTotal});
 }

 if (state != PlayerState.PLAYING) {
 return;
 }

 if (_position < _item.duration) {
 sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: _position, duration: _item.duration});
 } else if (_item.duration > 0) {
 complete();
 }
 }

 /** Seek in the _sound. **/
 override public function seek(pos:Number):void {
 if (_sound && _sound.bytesTotal > 0 && (pos < (_sound.bytesLoaded / _sound.bytesTotal) * item.duration) || item.start) {
 clearInterval(_positionInterval);
 _positionInterval = undefined;
 if (_channel) {
 _channel.stop();
 }
 _position = pos;
 play();
 }
 }

 /** Destroy the _sound. **/
 override public function stop():void {
 clearInterval(_positionInterval);
 _positionInterval = undefined;
 super.stop();
 if (_channel) {
 _channel.stop();
 _channel = null;
 }
 try {
 _sound.close();
 } catch (err:Error) {
 }
 }

 /** Set the volume level. **/
 override public function setVolume(vol:Number):void {
 streamVolume(vol);
 super.setVolume(vol);
 }

 /** Set the stream's volume, without sending a volume event **/
 protected function streamVolume(level:Number):void {
 _transformer.volume = level / 100;
 if (_channel) {
 _channel.soundTransform = _transformer;
 }
 }
 }
}

Okay, so now we have that covered. I’ll submit my changes to the Longtail forums and then maybe a pro can make some changes – and then we have opensource going – and then we can all go and drink some beer at the Pub *YAY!*

I hope this helps you in any way,

Winston

Magento Contact Us – Unable to submit your request. Please, try again later error

Saturday, May 8th, 2010

I had an issue with Magento CE Version 1.4.0.1 where an email would not be sent when a visitor used the contact us page, I found the fix using Google, on ScreencastWorld

In WEBROOT/app/design/frontend/base/default/template/contacts/form.phtml
Look for

<div class="buttons-set">

It should look like this, the important part is the input file name=”hideit”

<div class="buttons-set">
        <p class="required"><?php echo Mage::helper('contacts')->__('* Required Fields') ?></p>
        <input type="text" name="hideit" id="hideit" value="" style="display:none !important;" />
        <button type="submit" title="<?php echo Mage::helper('contacts')->__('Submit') ?>" class="button"><span><span><?php echo Mage::helper('contacts')->__('Submit') ?></span></span></button>
</div>

Good luck !