Magento – The missing view type!

Magento has four options when it comes to display products on your e-commerce website:

  1. Not Visible Individually
  2. Catalog
  3. Search
  4. Catalog, Search

Now, normally that about covers most use cases. But if you have configurable products it is somewhat more common place to set the children to Not Visible Individually.

This is great and all, but what if you are using Google Shopping real-time attribute/schema scraping which requires the Child to be visible individually to read those tags (and can be handy for direct to a page when SKU searching on the front end), and you don’t want the children to show in either your category or search grid pages?

This is where an additional catalog visibility type comes in useful, and it is actually very straight forward to achieve!

First setup a basic Magento module/plugin, which I won’t bore you with the complete details of, but we are binding to a model of the Mage Catalog Module under a rewrite!

Set up your

local/Company/Catalog/etc/config.xml

as follows:

<?xml version="1.0"?>
<config>
    <modules>
        <Company_Catalog>
            <version>0.0.1</version>
        </Company_Catalog>
    </modules>
    <global>
        <models>
            <catalog>
                <rewrite>
                    <product_visibility>Company_Catalog_Model_Product_Visibility</product_visibility>
               </rewrite>
            </catalog>
        </models>
    </global>
</config>

Fairly straight forward here, setup a basic module and override Mage/Catalog/Product/Visibility.

Next setup the Model

local/Company/Catalog/Model/Product/Visibility.php
class Company_Catalog_Model_Product_Visibility extends Mage_Catalog_Model_Product_Visibility {
    const VISIBILITY_PAGE = 5;
    
    public function getVisibleInSiteIds()
    {
        return array(self::VISIBILITY_IN_SEARCH, self::VISIBILITY_IN_CATALOG, self::VISIBILITY_BOTH, self::VISIBILITY_PAGE);
    }
    
    static public function getOptionArray()
    {
        return array(
            self::VISIBILITY_NOT_VISIBLE=> Mage::helper('catalog')->__('Not Visible Individually'),
            self::VISIBILITY_IN_CATALOG => Mage::helper('catalog')->__('Catalog'),
            self::VISIBILITY_IN_SEARCH  => Mage::helper('catalog')->__('Search'),
            self::VISIBILITY_BOTH       => Mage::helper('catalog')->__('Catalog, Search'),
            self::VISIBILITY_PAGE       => Mage::helper('catalog')->__('Own Page Only')
        );
    }
    
    /**
     * Retrieve all options
     *
     * @return array
     */
    static public function getAllOption()
    {
        $options = self::getOptionArray();
        array_unshift($options, array('value'=>'', 'label'=>''));
        return $options;
    }
    
    /**
     * Retireve all options
     *
     * @return array
     */
    static public function getAllOptions()
    {
        $res = array();
        $res[] = array('value'=>'', 'label'=> Mage::helper('catalog')->__('-- Please Select --'));
        foreach (self::getOptionArray() as $index => $value) {
            $res[] = array(
               'value' => $index,
               'label' => $value
            );
        }
        return $res;
    }
    
    /**
     * Retrieve option text
     *
     * @param int $optionId
     * @return string
     */
    static public function getOptionText($optionId)
    {
        $options = self::getOptionArray();
        return isset($options[$optionId]) ? $options[$optionId] : null;
    }
}

First of all we add a new Constant, logically named

VISIBILITY_PAGE

and we give it the next free “id” of 5. (Check core/Mage/Catalog/Model/Product/Visibility.php for the base list).

Next the important function

getVisibleInSiteIds

tells Magento which Products to allow to be shown individually, so we just add our constant to the array here.

All the other functions deal with rendering the new Visibility type in the admin interface for editing products (as otherwise the parent functions are used and they can’t “see” the new visibility type).

As per usual when you add/edit a new module make sure to clear the cache accordingly!

That is it all done, short and sweet!

A Week of Commuting

So today ends my first week of my Manchester based job at Fred Aldous. Currently this means I’ve been commuting to and from Manchester every day.

Currently my journey goes

  • My House
  • Burley Park
  • Leeds train station
  • Manchester Piccadilly
  • Starbucks
  • Short walk

And of course the reverse!

So far it’s been difficult to get a seat but I don’t mind standing since it is some form of exercise 😛

Anyway, what really annoys me is when a train arrives at a station and people gravitate towards the doors.

They do it in such a way so that it makes it difficult for people to get off. Which aside from being a pain in the arse do them, the moment there is a gap people start piling on, and of course at peak times there is always a person or two stuck in the aisle trying to get off whilst people are piling on the train.

Inevitably this causes delays as the piling on lot have to stop and clear a route for those getting off to get off.

/Begin Rant/
Why can’t people just take a step or to back and not be in such a rush! If you let people get off and just give everyone some space. I’m sure it will be better for everyone involved and potentially help keep the trains on time at these peak times!
/End Rant/

Anyway my first week hasn’t been to bad. But more on my new job in another post. Currently standing on a train! Trying to publish this blog post in the little windows of coverage I get! And we appear to be following a slow moving train!

My CV and some other Updates

Just a quick post to say hello.

I’ve updated my CV and tidied it up a little.
So any feedback on it would be useful! (Drop Me a Line rather than a Comment please)
Link in the SideBar on the right!

I should really write on my blog some more, but not a lot to write about of late.
JetPack Extras is doing OK, but JetPack core decided to implement the main feature I added, that being Pinterest but, Extras has evolved, it still of course has the ability to control button placement and has the extra Twitter Via/Related options, and the ability to share the WP.me shortened URL, makes a nice Twitter Card, embedding a short Preview of the Post with the Tweet, (check this Meta Tweet for an example) works with any wp.me url you share on Twitter by the way!

Most useful, mainly updated to keep up with JetPack core and use the new shiny hooks they have.
You can check it out on extend. Feedback/request are always Welcome!

Made a couple of tweaks and updates to the Blog in the background, added a better 404 page and updated the .htaccess rules, I have all subdomains pointing to the here, (unless their is a separate to show), so its a good idea to redirect non sites to here, rather than duplicating the content.
Also tweaked the Root .htaccess to have a Error Document (404) since it was just standard Apache Error, bit nasty, but now better, LOLCATS TO THE RESCUE! 😀

Heres a extract of the rules, if you find it useful/handy:

RewriteEngine on

RewriteCond %{HTTP_HOST} !^barrycarlyon.co.uk  
RewriteRule ^(.*)$ http://barrycarlyon.co.uk/%{REQUEST_URI} [R=301,L]
ErrorDocument 404 http://barrycarlyon.co.uk/wordpress/404-2/
ErrorDocument 403 http://barrycarlyon.co.uk/wordpress/404-2/

Next thing to do, is probably update and replace the MineCraft Server Site probably using Twitter Bootstrap as a new basis. It’s now a whitelisted server for Armchair Heroes or on Facebook, but of late I’ve been getting my MineCraft fix playing over at PhantomCraft, like a lot of open Servers I tend to get robbed/cleaned out and griefed a lot, but then again I am a little close to spawn. It’s a fun server to play on and the regulars are quite nice.

Hopefully moving further away when I get a chance to play some more, thinks are pretty busy at the moment between Magento fun at Day Job and Freshers Fun at the Union.

Then I really should get the Portfolio page on the Blog fixed up to showcase what I’ve done before, since I am a Freelance Web Developer (you got any work going or want a quote for? (Drop me a line)

So a couple more weeks and we’ll be back to the usual grind.
Hopefully I will have more to write about soon!

Facebook Credits, the Order ID, and dealing with large integers in 32 bit PHP

So, currently at work I’ve been rewriting all our Payment Gateways for Your Members. Making them more better Class based an abstracting out the common functions to a base class, to save memory footprint and code etc.

And came across a problem when rewriting the Facebook Credits handler.

The order ID that gets passed around, as well as the Application ID is too long for a 32 Bit PHP installation to handle when treating it as an Integer.

So a number like “239724439419867” was ending up as “1.7592246582797E+14” when stored/processed, or converted to a string.
Now the obvious way to process this is to convert it to a string another way, which is somewhat difficult since before you even start it is in a format that you can’t handle.

The saving grace here is the fact that data is passed to you as a JSON packet (aside from the fact the Order ID is in the $_POST variable and thus a string, so I could of used it from there).

This led to me to look at the JSON packet, which starts as a string but when decoded the large integers are still a larger integer than can be processed (whether you json_decode to a Array or to an Object, the problem persists). So I thought about how to process the raw JSON packet and make sure the order ID, and other large integers are treated as strings.

If you look at a Raw JSON packet you can easily spot whats a string, integer, object or array.

Take this example Facebook Credits JSON Packet, (wrapped for readability):

{"order_id":239724439419867,"buyer":197803678,"app":148748711865470,
"receiver":197803678,"amount":5,"update_time":1320075413,
"time_placed":1320075408,"data":"","items":[{"item_id":"<item_id>","title":"Post",
"description":"A New Purchasable Post",
"image_url":"<some url>","product_url":"<some other url>",
"price":5,"data":"<data>"}],"status":"<status>"}
  • order_id is an integer as it has no ” around it
  • status is a string as its surrounded by “
  • Items is an array as its surrounded by [, in this case containing a single object, entries/items are comma separated.

So after thinking about this I decided the best way to sort this out was to convert the integers in the raw JSON packet to strings before decoding.

In pseudo code.

Lop off the { and } from the start and end
Explode around ,
array walk each item
split on :
check if there are no " in the second bit
if none wrap in "
glue back together

Something alone the lines of:

function largeint($rawjson) {
  $rawjson = substr($rawjson, 1, -1);
  $rawjson = explode(',' , $rawjson);
  array_walk($rawjson, 'strfun');
  $rawjson = implode(',', $rawjson);
  $rawjson = '{', . $rawjson . '}';
  $json = json_decode($rawjson);
  return $json;
}

function strfun(&$entry, $key) {
  $data = explode(':', $entry);
  if (FALSE === strpos($data[1], '"')) {
    $data[1] = '"' . $data[1] . '"';
    $entry = implode(':', $data);
  }
}

I’m not sure in terms of memory footprint if its cheaper to do a substr of $data[1] and check if its a ” or not.
I suppose it could test the string length of the detected integer to see if its invalid/unable to process, but then you would be performing a string function on an integer and again the problem would arise.

But as a block of code is does the job, its obviously not ideal for all situations, since in this case I want the integer as a string, I’m not using it for math, but if I did, we probably need to do some bizarre unpack-ing or something.

Any opinions or improvements give us a comment below 😀

Thoughts on working on a different computer when your normal one is not available

So currently my Mac Book Pro is in with Clockwork Leeds getting its Hard Drive replaced as it failed/has failed/is failing.

So currently at work, I am sans my normal Development machine and find myself on the Mac Mini server that sits and does our File Server and System Monitoring.

Its quite odd having to get used to a system that for starts is the Server build of Mac OSX as well as having none of my personal preferences.
Its bringing to light how slightly useless some of the things I have setup on my Personal machine are that I thought were useful.

For example, I’m stuck with a single screen, so no dual screen lovely-ness. So I’m very restricted to the screen real estate I have available.
So not having new Terminal Windows opening to fill half the screen like on my mac is quite useful. Whereas before having the secondary screen with two terminal windows full height, half width was the norm, as well as using a little app I’ve forgotten the name of which allows me to press ctrl + ~ to get a window appear from the top, is a bit of a pain, but resolved now with having three default sized terminals and chrome open.

So far its seemed to work just about fine like that.

I also find myself using Spaces/Expose a lot less, I’m doing a lot less jumping between spaces all the time. But I also don’t have the “App only opens in space x” setup so I get a lot less forced jumping.

Finally tho I miss my music collection, so I’ve switched to plugging my headphones into my iPad and listening to Spotify. Tho I could just plug in my external drive thats in the office and have most of my older music on hand….

I’m also on a different desk which is nice.
I’m not by the door and have the window behind me and I’m in the corner.
I quite like it over here. Seems a bit more separated from everyone else. Which is a good thing and a bad thing in its own right.

I love working with the team, *can’t think of right words to express feelings will just skip to post summary*.

Summary

My Mac is in the repair shop getting fixed.
The hard drive was failing and is pending spare parts from Apple.
Clockwork are amazing for Apple Repairs.
I’m in a corner at work
I have no home machine to really play or work on. (I made my home windoze laptop blue screen just by looking at it….)

I watched last nights Torchwood on my iPad using the BBC iPlayer Application and it worked perfectly.

Finally my local dev environment is shafted as that was my Mac Book Pro. Luckily everything is in offsite repo’s and I have a Server in a Server Room down the corridor to talk to 😀

-End-