| 1 |
<?php |
<?php |
| 2 |
// $Id: category.module,v 1.160 2009/05/31 09:34:27 jaza Exp $ |
// $Id: category.module,v 1.161 2009/05/31 10:06:26 jaza Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* @file |
* @file |
| 37 |
} |
} |
| 38 |
|
|
| 39 |
/** |
/** |
| 40 |
|
* Implementation of hook_flush_caches() |
| 41 |
|
*/ |
| 42 |
|
function category_flush_caches() { |
| 43 |
|
return array('cache_category'); |
| 44 |
|
} |
| 45 |
|
|
| 46 |
|
/** |
| 47 |
* Implementation of hook_link(). |
* Implementation of hook_link(). |
| 48 |
* |
* |
| 49 |
* This hook is extended with $type = 'categories' to allow themes to |
* This hook is extended with $type = 'categories' to allow themes to |
| 383 |
$node = $form['#node']; |
$node = $form['#node']; |
| 384 |
|
|
| 385 |
if (isset($node->category)) { |
if (isset($node->category)) { |
| 386 |
|
$form['#submit'][] = 'category_node_form_submit'; |
| 387 |
_category_add_form_elements($form, $node); |
_category_add_form_elements($form, $node); |
| 388 |
$form['category']['hierarchy']['pick-container'] = array( |
$form['category']['hierarchy']['pick-container'] = array( |
| 389 |
'#type' => 'submit', |
'#type' => 'submit', |
| 570 |
} |
} |
| 571 |
|
|
| 572 |
/** |
/** |
| 573 |
|
* Additional form submit handler for category/container node forms. |
| 574 |
|
* |
| 575 |
|
* Flattens and processes the $form_state['values']['category'] array |
| 576 |
|
* on both submits and previews. This is needed because |
| 577 |
|
* the 'category' fieldset on the node form has to be 'tree = TRUE', but |
| 578 |
|
* we don't want to deal with the fieldset hierarchy all the time. |
| 579 |
|
*/ |
| 580 |
|
function category_node_form_submit($form, &$form_state) { |
| 581 |
|
$fieldsets = array( |
| 582 |
|
'hierarchy' => TRUE, |
| 583 |
|
'advanced' => TRUE, |
| 584 |
|
'identification' => TRUE, |
| 585 |
|
'content_types' => TRUE, |
| 586 |
|
'tagging' => TRUE, |
| 587 |
|
'distant' => TRUE, |
| 588 |
|
); |
| 589 |
|
foreach ($form_state['values']['category'] as $key => $value) { |
| 590 |
|
if (isset($fieldsets[$key]) && is_array($value)) { |
| 591 |
|
$form_state['values']['category'] += $value; |
| 592 |
|
unset($form_state['values']['category'][$key]); |
| 593 |
|
} |
| 594 |
|
} |
| 595 |
|
|
| 596 |
|
if (!empty($form_state['values']['category']['cid']) && $form_state['values']['category']['cid'] == 'new') { |
| 597 |
|
unset($form_state['values']['category']['cid']); |
| 598 |
|
} |
| 599 |
|
|
| 600 |
|
// Load the new parent for distant-parent category selection. |
| 601 |
|
if (!empty($form_state['values']['op'])) { |
| 602 |
|
$containers = category_get_containers($node->type); |
| 603 |
|
$is_valid_submission = FALSE; |
| 604 |
|
foreach ($containers as $container) { |
| 605 |
|
if ($form_state['values']['op'] == t('Update children of @parent', array('@parent' => $container->title))) { |
| 606 |
|
$is_valid_submission = TRUE; |
| 607 |
|
} |
| 608 |
|
} |
| 609 |
|
|
| 610 |
|
if ($is_valid_submission) { |
| 611 |
|
foreach ($containers as $container) { |
| 612 |
|
if (!empty($form_state['values']['categories'][$container->cid])) { |
| 613 |
|
$post_categories = $form_state['values']['categories'][$container->cid]; |
| 614 |
|
if (!is_array($post_categories)) { |
| 615 |
|
if (is_numeric($post_categories)) { |
| 616 |
|
$post_categories = (int) $post_categories; |
| 617 |
|
$node->categories[$post_categories] = category_get_category($post_categories); |
| 618 |
|
} |
| 619 |
|
} |
| 620 |
|
else { |
| 621 |
|
foreach ($post_categories as $post_category) { |
| 622 |
|
if (is_numeric($post_category)) { |
| 623 |
|
$post_category = (int) $post_category; |
| 624 |
|
$node->categories[$post_category] = category_get_category($post_category); |
| 625 |
|
} |
| 626 |
|
} |
| 627 |
|
} |
| 628 |
|
} |
| 629 |
|
} |
| 630 |
|
} |
| 631 |
|
} |
| 632 |
|
} |
| 633 |
|
|
| 634 |
|
/** |
| 635 |
* Generate a form element for selecting categories from a container. |
* Generate a form element for selecting categories from a container. |
| 636 |
*/ |
*/ |
| 637 |
function category_form($cnid, $value = 0, $help = NULL, $name = 'category', |
function category_form($cnid, $value = 0, $help = NULL, $name = 'category', |
| 823 |
*/ |
*/ |
| 824 |
function category_node_delete($node) { |
function category_node_delete($node) { |
| 825 |
db_query('DELETE FROM {category_node} WHERE nid = %d', $node->nid); |
db_query('DELETE FROM {category_node} WHERE nid = %d', $node->nid); |
| 826 |
|
category_cache_op('flush', $node->nid); |
| 827 |
} |
} |
| 828 |
|
|
| 829 |
/** |
/** |
| 831 |
*/ |
*/ |
| 832 |
function category_node_delete_revision($node) { |
function category_node_delete_revision($node) { |
| 833 |
db_query('DELETE FROM {category_node} WHERE vid = %d', $node->vid); |
db_query('DELETE FROM {category_node} WHERE vid = %d', $node->vid); |
| 834 |
|
category_cache_op('flush', $node->nid); |
| 835 |
} |
} |
| 836 |
|
|
| 837 |
/** |
/** |
| 898 |
case 'prepare': |
case 'prepare': |
| 899 |
$behavior = variable_get('category_behavior_'. $node->type, 0); |
$behavior = variable_get('category_behavior_'. $node->type, 0); |
| 900 |
if (!empty($behavior)) { |
if (!empty($behavior)) { |
|
$container_nid = $_POST['category']['hierarchy']['container']; |
|
|
|
|
| 901 |
// Prepare defaults for the add/edit form. |
// Prepare defaults for the add/edit form. |
| 902 |
if (empty($node->category)) { |
if (empty($node->category)) { |
| 903 |
$node->category = array(); |
$node->category = array(); |
|
if (!empty($container_nid) && is_numeric($container_nid)) { |
|
|
$node->category['container'] = $container_nid; |
|
|
} |
|
| 904 |
if (empty($node->nid) && isset($_GET['parent']) && |
if (empty($node->nid) && isset($_GET['parent']) && |
| 905 |
is_numeric($_GET['parent'])) { |
is_numeric($_GET['parent'])) { |
| 906 |
// Handle "Add child page" links: |
// Handle "Add child page" links: |
| 927 |
$node->category += _category_defaults(!empty($node->nid) ? $node->nid : 'new'); |
$node->category += _category_defaults(!empty($node->nid) ? $node->nid : 'new'); |
| 928 |
} |
} |
| 929 |
else { |
else { |
|
_category_flatten_values($node); |
|
|
if (!empty($container_nid) && is_numeric($container_nid)) { |
|
|
$node->category['container'] = $container_nid; |
|
|
} |
|
| 930 |
$node->category['container'] = empty($node->category['container']) ? $node->category['cnid'] : $node->category['container']; |
$node->category['container'] = empty($node->category['container']) ? $node->category['cnid'] : $node->category['container']; |
| 931 |
if (empty($node->category['container']) && !empty($node->category['parents']) && $behavior == 'container') { |
if (empty($node->category['container']) && !empty($node->category['parents']) && $behavior == 'container') { |
| 932 |
reset($node->category['parents']); |
reset($node->category['parents']); |
| 942 |
$node->category['parent_depth_limit'] = (MENU_MAX_DEPTH - 1); |
$node->category['parent_depth_limit'] = (MENU_MAX_DEPTH - 1); |
| 943 |
} |
} |
| 944 |
$node->category['behavior'] = $behavior; |
$node->category['behavior'] = $behavior; |
|
if (empty($node->category['parents'])) { |
|
|
$node->category['parents'] = array(); |
|
|
} |
|
|
$node->category['parents'] = array_keys($node->category['parents']); |
|
|
} |
|
|
|
|
|
// Load the new parent for distant-parent category selection. |
|
|
if (!empty($_POST['op'])) { |
|
|
$containers = category_get_containers($node->type); |
|
|
$is_valid_submission = FALSE; |
|
|
foreach ($containers as $container) { |
|
|
if ($_POST['op'] == t('Update children of @parent', array('@parent' => $container->title))) { |
|
|
$is_valid_submission = TRUE; |
|
|
} |
|
|
} |
|
|
|
|
|
if ($is_valid_submission) { |
|
|
foreach ($containers as $container) { |
|
|
if (!empty($_POST['categories'][$container->cid])) { |
|
|
$post_categories = $_POST['categories'][$container->cid]; |
|
|
if (!is_array($post_categories)) { |
|
|
if (is_numeric($post_categories)) { |
|
|
$post_categories = (int) $post_categories; |
|
|
$node->categories[$post_categories] = category_get_category($post_categories); |
|
|
} |
|
|
} |
|
|
else { |
|
|
foreach ($post_categories as $post_category) { |
|
|
if (is_numeric($post_category)) { |
|
|
$post_category = (int) $post_category; |
|
|
$node->categories[$post_category] = category_get_category($post_category); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
| 945 |
} |
} |
| 946 |
break; |
break; |
| 947 |
|
|
| 949 |
case 'update': |
case 'update': |
| 950 |
$behavior = variable_get('category_behavior_'. $node->type, 0); |
$behavior = variable_get('category_behavior_'. $node->type, 0); |
| 951 |
if (!empty($behavior)) { |
if (!empty($behavior)) { |
|
_category_flatten_values($node); |
|
| 952 |
if ($behavior == 'category') { |
if ($behavior == 'category') { |
| 953 |
category_save_category($node); |
category_save_category($node); |
| 954 |
} |
} |
| 1091 |
} |
} |
| 1092 |
} |
} |
| 1093 |
|
|
| 1094 |
|
category_cache_op('flush', 'all'); |
| 1095 |
return $status; |
return $status; |
| 1096 |
} |
} |
| 1097 |
|
|
| 1121 |
} |
} |
| 1122 |
} |
} |
| 1123 |
|
|
| 1124 |
|
category_cache_op('flush', 'all'); |
| 1125 |
return SAVED_DELETED; |
return SAVED_DELETED; |
| 1126 |
} |
} |
| 1127 |
|
|
| 1237 |
} |
} |
| 1238 |
} |
} |
| 1239 |
|
|
| 1240 |
|
category_cache_op('flush', 'all'); |
| 1241 |
return $status; |
return $status; |
| 1242 |
} |
} |
| 1243 |
|
|
| 1256 |
db_query('DELETE FROM {category_synonym} WHERE cid = %d', $cid); |
db_query('DELETE FROM {category_synonym} WHERE cid = %d', $cid); |
| 1257 |
db_query('DELETE FROM {category_node} WHERE cid = %d', $cid); |
db_query('DELETE FROM {category_node} WHERE cid = %d', $cid); |
| 1258 |
|
|
| 1259 |
|
category_cache_op('flush', 'all'); |
| 1260 |
return SAVED_DELETED; |
return SAVED_DELETED; |
| 1261 |
} |
} |
| 1262 |
|
|
| 1374 |
// Need this for AJAX. |
// Need this for AJAX. |
| 1375 |
$form['#cache'] = TRUE; |
$form['#cache'] = TRUE; |
| 1376 |
drupal_add_js("if (Drupal.jsEnabled) { $(document).ready(function() { $('#edit-category-hierarchy-pick-container').css('display', 'none'); }); }", 'inline'); |
drupal_add_js("if (Drupal.jsEnabled) { $(document).ready(function() { $('#edit-category-hierarchy-pick-container').css('display', 'none'); }); }", 'inline'); |
| 1377 |
$is_container = ($node->category['behavior'] == 'container'); |
$node->category['behavior'] = variable_get('category_behavior_'. $node->type, 0); |
| 1378 |
|
$is_container = ($node->category['behavior'] === 'container'); |
| 1379 |
|
|
| 1380 |
|
if (empty($node->category['parents'])) { |
| 1381 |
|
$node->category['parents'] = array(); |
| 1382 |
|
} |
| 1383 |
|
$node->category['parents'] = array_keys($node->category['parents']); |
| 1384 |
|
|
| 1385 |
$form['category'] = array( |
$form['category'] = array( |
| 1386 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 1391 |
'#tree' => TRUE, |
'#tree' => TRUE, |
| 1392 |
'#attributes' => array('class' => 'category-form'), |
'#attributes' => array('class' => 'category-form'), |
| 1393 |
); |
); |
| 1394 |
foreach (array('cid', 'original_container', 'parent_depth_limit') as $key) { |
foreach (array('cid', 'original_container', 'parent_depth_limit', 'behavior') as $key) { |
| 1395 |
$form['category'][$key] = array( |
$form['category'][$key] = array( |
| 1396 |
'#type' => 'value', |
'#type' => 'value', |
| 1397 |
'#value' => $node->category[$key], |
'#value' => $node->category[$key], |
| 1638 |
$container->parents = _category_flatten_parents(category_get_parents($container->cid)); |
$container->parents = _category_flatten_parents(category_get_parents($container->cid)); |
| 1639 |
|
|
| 1640 |
if (!$container->tags) { |
if (!$container->tags) { |
| 1641 |
if (empty($form_state['values']['category']['hierarchy']['parents']) || !is_array($form_state['values']['category']['hierarchy']['parents'])) { |
if (empty($form_state['values']['category']['parents']) || !is_array($form_state['values']['category']['parents'])) { |
| 1642 |
$form_state['values']['category']['hierarchy']['parents'] = array(); |
$form_state['values']['category']['parents'] = array(); |
| 1643 |
} |
} |
| 1644 |
|
|
| 1645 |
$current_parent_count = count($form_state['values']['category']['hierarchy']['parents']); |
$current_parent_count = count($form_state['values']['category']['parents']); |
| 1646 |
$previous_parent_count = count($form['#node']->category['parents']); |
$previous_parent_count = count($form['#node']->category['parents']); |
| 1647 |
|
|
| 1648 |
if ($current_parent_count == 1) { |
if ($current_parent_count == 1) { |
| 1649 |
$first_parent = current($form_state['values']['category']['hierarchy']['parents']); |
$first_parent = current($form_state['values']['category']['parents']); |
| 1650 |
if (!empty($first_parent)) { |
if (!empty($first_parent)) { |
| 1651 |
if (category_is_root_parent($first_parent, $container->cid)) { |
if (category_is_root_parent($first_parent, $container->cid)) { |
| 1652 |
$current_parent_count--; |
$current_parent_count--; |
| 1666 |
// parents of every category in the container value. |
// parents of every category in the container value. |
| 1667 |
$new_container = NULL; |
$new_container = NULL; |
| 1668 |
if ($current_parent_count < $previous_parent_count && $current_parent_count < 2) { |
if ($current_parent_count < $previous_parent_count && $current_parent_count < 2) { |
| 1669 |
$changed_category = (object) $form_state['values']; |
$changed_category = $form_state['values']['category']; |
|
_category_flatten_values($changed_category); |
|
|
$changed_category = $changed_category->category; |
|
| 1670 |
category_check_container_hierarchy((array) $container, $changed_category); |
category_check_container_hierarchy((array) $container, $changed_category); |
| 1671 |
if ($form['#node']->category['container'] != $form_state['values']['category']['hierarchy']['container']) { |
if ($form['#node']->category['container'] != $form_state['values']['category']['container']) { |
| 1672 |
$new_container = category_get_container($form_state['values']['category']['hierarchy']['container']); |
$new_container = category_get_container($form_state['values']['category']['container']); |
| 1673 |
$new_container->parents = _category_flatten_parents(category_get_parents($new_container->cid)); |
$new_container->parents = _category_flatten_parents(category_get_parents($new_container->cid)); |
| 1674 |
category_check_container_hierarchy((array) $new_container, $changed_category); |
category_check_container_hierarchy((array) $new_container, $changed_category); |
| 1675 |
} |
} |
| 1705 |
* Rendered node listing, or FALSE if no listing should be displayed. |
* Rendered node listing, or FALSE if no listing should be displayed. |
| 1706 |
*/ |
*/ |
| 1707 |
function category_node_listing($node) { |
function category_node_listing($node) { |
|
$nodes = category_select_nodes(array($node->category['cid']), 'or', $node->category['depth'], TRUE, TRUE); |
|
| 1708 |
$is_container = empty($node->category['cnid']); |
$is_container = empty($node->category['cnid']); |
| 1709 |
$show_nodes = FALSE; |
$show_nodes = FALSE; |
| 1710 |
$category_display = NULL; |
$category_display = NULL; |
| 1742 |
} |
} |
| 1743 |
|
|
| 1744 |
if ($use_views) { |
if ($use_views) { |
| 1745 |
return category_views_render_nodes($nodes); |
return category_views_render_nodes($node); |
| 1746 |
} |
} |
| 1747 |
else { |
else { |
| 1748 |
|
$nodes = category_select_nodes(array($node->category['cid']), 'or', $node->category['depth'], TRUE, TRUE); |
| 1749 |
return category_render_nodes($nodes, $category_display); |
return category_render_nodes($nodes, $category_display); |
| 1750 |
} |
} |
| 1751 |
} |
} |
| 1771 |
$output .= '<p>'. t('Use the list below to configure and review the containers defined on your site, and to manage the categories they contain. A container may (optionally) be tied to specific content types as shown in the <em>Type</em> column and, if so, will be displayed when creating or editing posts of that type. Multiple containers tied to the same content type will be displayed in the order shown below. To change the order of a container, grab a drag-and-drop handle under the <em>Name</em> column and drag it to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the <em>Save</em> button at the bottom of the page.') .'</p>'; |
$output .= '<p>'. t('Use the list below to configure and review the containers defined on your site, and to manage the categories they contain. A container may (optionally) be tied to specific content types as shown in the <em>Type</em> column and, if so, will be displayed when creating or editing posts of that type. Multiple containers tied to the same content type will be displayed in the order shown below. To change the order of a container, grab a drag-and-drop handle under the <em>Name</em> column and drag it to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the <em>Save</em> button at the bottom of the page.') .'</p>'; |
| 1772 |
return $output; |
return $output; |
| 1773 |
case 'admin/content/category/wrappers': |
case 'admin/content/category/wrappers': |
| 1774 |
$output = '<p>'. t('You can install and uninstall the taxonomy, book, and menu wrapper modules using the links below. It is very important that you have taxonomy, book, or menu (original or wrapper, whichever is installed) <strong>enabled</strong> on the <a href="@module-admin-page">module administration page</a> before performing an install or uninstall. Additionally, you should make sure that your web server has write permission on the file system, or the scripts may be denied access to rename the necessary files.', array('@module-admin-page' => url('admin/build/modules'))) .'</p>'; |
$output = '<p>'. t('You can install and uninstall the taxonomy and book wrapper modules using the links below. It is very important that you have taxonomy or book (original or wrapper, whichever is installed) <strong>enabled</strong> on the <a href="@module-admin-page">module administration page</a> before performing an install or uninstall. Additionally, you should make sure that your web server has write permission on the file system, or the scripts may be denied access to rename the necessary files.', array('@module-admin-page' => url('admin/build/modules'))) .'</p>'; |
| 1775 |
$output .= '<p>'. t('When performing an install, the scripts will look for the <code>modulename.module.php</code>, <code>modulename.info.php</code> and <code>modulename.install.php</code> files in the <code>wrappers/modulename</code> directory (in your category package), and it will rename them respectively to <code>modulename.module</code>, <code>modulename.info</code> and <code>modulename.install</code>. It will then update Drupal\'s module registry so that the new files are discovered. The reverse will happen when performing an uninstall. The script will determine the correct location of all necessary files automatically, based on where you have installed the category module.') .'</p>'; |
$output .= '<p>'. t('When performing an install, the scripts will look for the <code>modulename.module.php</code>, <code>modulename.info.php</code> and <code>modulename.install.php</code> files in the <code>wrappers/modulename</code> directory (in your category package), and it will rename them respectively to <code>modulename.module</code>, <code>modulename.info</code> and <code>modulename.install</code>. It will then update Drupal\'s module registry so that the new files are discovered. The reverse will happen when performing an uninstall. The script will determine the correct location of all necessary files automatically, based on where you have installed the category module.') .'</p>'; |
| 1776 |
$output .= '<p>'. t('After the operation that you invoke is completed, you will be returned to this page.') .'</p>'; |
$output .= '<p>'. t('After the operation that you invoke is completed, you will be returned to this page.') .'</p>'; |
| 1777 |
return $output; |
return $output; |
| 1842 |
* Determines whether or not the specified wrapper is enabled. |
* Determines whether or not the specified wrapper is enabled. |
| 1843 |
* |
* |
| 1844 |
* @param $type |
* @param $type |
| 1845 |
* The wrapper to check. Either 'taxonomy', 'book', or 'menu'. Default is 'taxonomy'. |
* The wrapper to check. Either 'taxonomy', or 'book'. Default is 'taxonomy'. |
| 1846 |
* |
* |
| 1847 |
* @return |
* @return |
| 1848 |
* Boolean value indicating status of the specified wrapper. |
* Boolean value indicating status of the specified wrapper. |
| 1894 |
} |
} |
| 1895 |
|
|
| 1896 |
/** |
/** |
|
* Helper function to flatten the $node->category array. This is needed because |
|
|
* the 'category' fieldset on the node form has to be 'tree = TRUE', but |
|
|
* we don't want to deal with the fieldset hierarchy all the time. |
|
|
*/ |
|
|
function _category_flatten_values(&$node) { |
|
|
$fieldsets = array( |
|
|
'hierarchy' => TRUE, |
|
|
'advanced' => TRUE, |
|
|
'identification' => TRUE, |
|
|
'content_types' => TRUE, |
|
|
'tagging' => TRUE, |
|
|
'distant' => TRUE, |
|
|
); |
|
|
foreach ($node->category as $key => $value) { |
|
|
if (isset($fieldsets[$key]) && is_array($value)) { |
|
|
$node->category += $value; |
|
|
unset($node->category[$key]); |
|
|
} |
|
|
} |
|
|
|
|
|
if (!empty($node->category['cid']) && $node->category['cid'] == 'new') { |
|
|
unset($node->category['cid']); |
|
|
} |
|
|
} |
|
|
|
|
|
/** |
|
| 1897 |
* Turns the return value of category_get_parents() into a simple array, |
* Turns the return value of category_get_parents() into a simple array, |
| 1898 |
* where both the keys and the values of each element are the node IDs of |
* where both the keys and the values of each element are the node IDs of |
| 1899 |
* the parent categories. |
* the parent categories. |