Showing posts with label Coding Practices. Show all posts
Showing posts with label Coding Practices. Show all posts

Wednesday, September 10, 2008

CakePHP Model::findAllThreaded Frustrations

Been working on a shopping cart system at work, and we were having some weird issues with the category hierarchy manager we had built. For some reason (randomly it seemed at first) we would add a category and then shuffle its parent category and suddenly it would disappear from the threaded list. After about an hour of trying to debug the code for findAllThreaded (show below) I finally found the culprit in our case.


function __doThread($data, $root, $index = 0) {
$out = array();
$sizeOf = sizeof($data);

for ($ii = $index; $ii < $sizeOf; $ii++) {
if (($data[$ii][$this->alias]['parent_id'] == $root) || (($root === null) && ($data[$ii][$this->alias]['parent_id'] == '0'))) {
$tmp = $data[$ii];

if (isset($data[$ii][$this->alias][$this->primaryKey])) {
$tmp['children'] = $this->__doThread($data, $data[$ii][$this->alias][$this->primaryKey], 0);//$ii);
} else {
$tmp['children'] = null;
}

$out[] = $tmp;
}
}

return $out;
}


Basically, the way the function is structured if a child comes before a parent in the findAll results that findAllThreaded uses then it won't find it because it only looks after the parent for any children results, which forces you to do one of two things:

1. In our case, I edited the line $tmp['children'] = $this->__doThread(... to pass '0' for the $index parameter instead of $ii. This forces the function to go through all results each time. In our case we are only using findAllThreaded in the admin area of our cart, so we felt any hit in performance wasn't too serious. In your case, it might be.

2. Ensure the order you are using for the findAll results pulls results that are already structured somewhat hierarchal. You could have an order field that you sort by, but it needs to be somewhat static so that it can't be easily changed and mess up your list again (hence using something like the built in modified date field in CakePHP could cause some issues).

Hope this helps you bakers out there. If you have a better idea on how to ensure findAllThreaded works properly, drop a line in the comments.

EDIT: Actually, you can simplify all this by just ordering you results by the parent_id. So far that seems to work great without having to edit any of the cake core code. Plus it won't eat up as many resources as having to loop through all the results every time.

Saturday, August 23, 2008

Two Coding Styles Face Off

I notice that anytime I'm programming a new (CakePHP) site I'm often fighting internally about my coding practices.

In the blue corner is quick and serviceable. Quick and serviceable has come in winning many fights. His speed makes him difficult to corner, and he can be very adept at completing many things quickly. Unfortunately, this also leads to more problems as situations arise that were not considered originally making him more vulnerable.

In the red corner is longer and more thorough. He often takes a while to get going initially, leading to losses in shorter bouts. However, when entering the later rounds, he becomes a more serious opponent, and his record becomes even more impressive in closing out projects, I mean fighters, effectively.

We've been working on a new shopping cart site lately, and I have an add to cart script that checks the current product being added (along with any product attributes that may differentiate it) against the current shopping cart to see whether to add it as a new product or to an existing one.

My original inclination was to check by pulling all attribute groups for a product. Since they are associated with only that product I could easily assume that those attributes were also in the product in the cart. A simple loop through and comparison with the attributes in the cart should do the trick.

However, what if someone administering the site changed an attribute after someone added something to their cart, but before they want back and decided to buy some more. While that may not happen very often, it's just that type of thing that causes headaches and late night calls from clients wondering why a customer is angry with an issue with the website.

So instead of making that assumption, I loop through all the product attribute groups. Then, I check specifically if each product attribute group has actually been submitted by the customer (which originally I was going to just assume actually took place), and then check to make sure that the actual attribute values correspond before adding to a previous cart item or making a new cart entry.

What practices give you fits? Let me know in the comments.