I'm assigning this as critical because there are too many unpatched category_menu problems, and apparently too few people who understand how we might fix them. I think the majority of problems involving category_menu.module's update problems come from this fucntion in category_menu.module.
I'm trying my best to understand the code, but my mind can't seem to grasp enough of it at a time to see what's going wrong. Anyone have any insight? Jaza's busy on summer of code and won't be able to take care of this issues, so we probably should begin to work this out ourselves. Does someone have a "rough" idea of what the rational is behind the checks in the menu_update functions?
/**
* Provides the control logic to determine the necessary action upon updating.
*
* @param $node
* The node being updated.
*/
function category_menu_entity_updated(&$node) {
// This boolean indicates whether or not the menu item settings for the
// given node allow a menu item to be inserted / updated for it.
$do_insert = FALSE;
$menu_settings = NULL;
if (category_is_cat_or_cont($node->nid)) {
$is_cat = !empty($node->cnid);
if (!$is_cat) {
category_menu_cont_update($node);
$menu_settings = category_menu_cont_load($node->nid, TRUE);
if ($menu_settings->item_for_cats && !$node->hidden_cont) {
$do_insert = TRUE;
}
}
else {
$menu_settings = category_menu_cont_load($node->cnid);
if ($menu_settings->item_for_cats) {
$do_insert = TRUE;
}
}
if ($do_insert) {
$node->menu_settings = $menu_settings->item_for_cats;
if (empty($node->parents)) {
// Update case 1(a): category / container with 0 parents
category_menu_save_item($node);
}
elseif (is_array($node->parents)) {
$parent = $node->parents[0];
$item_found = FALSE;
$reached_root = FALSE;
do {
$item = category_menu_get_mapping($parent, TRUE);
if ($item) {
$item_found = TRUE;
}
else {
$parents = category_get_parents($parent, 'cid', TRUE, TRUE);
if (!empty($parents)) {
$parent = reset($parents);
$parent = $parent->cid;
}
else {
$reached_root = TRUE;
}
}
} while (!($item_found || $reached_root));
// Update cases 1(b) and 2: category / container with >= 1 parent
category_menu_save_item($node, $parent);
}
$assigned_nodes = category_select_nodes(array($node->nid));
while ($assigned_node = db_fetch_object($assigned_nodes)) {
$categories = category_node_get_categories($assigned_node->nid);
if (!empty($categories)) {
// Update special case (variation on cases 3 and 4): category with
// assigned nodes that are assigned to >= 1 category
$first_category = reset($categories);
$menu_settings = category_menu_cont_load($first_category->cnid, TRUE);
$assigned_node->menu_settings = $menu_settings->item_for_nodes;
category_menu_save_item($assigned_node, $first_category->cid);
}
}
$category_multiple_parents = ($node->cnid && $node->hierarchy == 2);
$container_multiple_parents = (!$node->cnid && variable_get('category_distant_containers', 1) == 2);
if ($category_multiple_parents || $container_multiple_parents) {
// Update special case: category / container where children have >1 parent
$children = category_get_children($node->nid);
foreach ($children as $child) {
$node_item = node_load($child->cid);
if (is_array($node_item->parents) && !empty($node_item->parents)) {
category_menu_save_item($node_item, $node_item->parents[0]);
}
}
}
}
}
else {
$categories = category_node_get_categories($node->nid, 'cid', TRUE);
$clear_menu_item = FALSE;
if (!empty($categories)) {
do {
// Update cases 3 and 4: node tagged with >= 1 category from >= 1
// container
$first_category = reset($categories);
$menu_settings = category_menu_cont_load($first_category->cnid);
if ($menu_settings->item_for_nodes) {
$do_insert = TRUE;
$node->menu_settings = $menu_settings->item_for_nodes;
category_menu_save_item($node, $first_category->cid);
}
array_shift($categories);
} while (!$do_insert && (count($categories) > 0));
if (!$do_insert) {
$clear_menu_item = TRUE;
}
}
else {
$clear_menu_item = TRUE;
}
if ($clear_menu_item) {
// Update special case: node tagged with no categories
$mid = category_menu_get_mapping($node->nid);
if ($mid) {
category_menu_delete_item($node);
}
}
}
}
Comments
Comment #1
canen commentedSubscribing
Comment #2
bdragon commentedDo my category_get_parents() fixes do anything for you?
http://drupal.org/node/76921
Specifically the patch attached to #6.
Comment #3
canen commentedNever knew about this patch.
Anyway, I applied the patch but nothing changed. I think I read in one of the many posts about this bug that the bug may be in the menu system. I cannot confirm this.
If I have some time in the coming days I'll have a look at the above function.
Comment #4
JonathanDStopchick commentedCould you please explain your issue a little more in depth, I've been working onthe module and I may be able to help with a little more information about what your trying to acheive.
Comment #5
bdragon commentedDoes patch #1 at
http://drupal.org/node/84424
help any?
Comment #6
JirkaRybka commentedThis issue is obsolete now, over 2 years silent, and about 4.7.x (now unsupported). Closing.