Conjunto de cambios dafc8d8 en sipes para modules_contrib/cck/content.module
- Fecha y hora:
- 26/05/2016 19:20:21 (hace 8 años)
- Branches:
- stable, version-3.0
- Children:
- f3eebcf
- Parents:
- 2efe680
- Fichero:
-
- 1 editado
Leyenda
- No modificado
- Añadido
- Eliminado
-
modules_contrib/cck/content.module
r177a560 rdafc8d8 1 1 <?php 2 // $Id: content.module,v 1.301.2.123 2011/01/03 11:03:47 yched Exp $3 2 /** 4 3 * @file … … 15 14 define('CONTENT_HANDLE_CORE', 0x0001); 16 15 define('CONTENT_HANDLE_MODULE', 0x0002); 16 17 // We do not use hook_init(), since that hook is not fired in update.php, and we 18 // need token generation to be active within hook_update_N() (e.g. for 19 // node_save() calls.) 20 require_once dirname(__FILE__) . '/includes/content.token.inc'; 17 21 18 22 function content_help($path, $arg) { … … 46 50 function content_init() { 47 51 drupal_add_css(drupal_get_path('module', 'content') .'/theme/content-module.css'); 48 if (module_exists('token') && !function_exists('content_token_values')) {49 module_load_include('inc', 'content', 'includes/content.token');50 }51 52 if (module_exists('diff') && !function_exists('content_diff')) { 52 53 module_load_include('inc', 'content', 'includes/content.diff'); … … 175 176 function content_theme() { 176 177 $path = drupal_get_path('module', 'content') .'/theme'; 177 require_once "./$path/theme.inc";178 module_load_include('inc', 'content', 'theme/theme'); 178 179 179 180 return array( … … 267 268 */ 268 269 function content_validate(&$node, $form = NULL) { 270 _content_field_invoke_default('validate', $node, $form); 269 271 _content_field_invoke('validate', $node, $form); 270 _content_field_invoke_default('validate', $node, $form);271 272 } 272 273 … … 334 335 // Merge fields. 335 336 $additions = _content_field_invoke_default('view', $node, $teaser, $page); 336 $node->content = array_merge((array) $node->content, $additions); 337 $old = isset($node->content) ? (array) $node->content : array(); 338 $node->content = array_merge($old, $additions); 337 339 } 338 340 … … 478 480 479 481 /** 482 * Proxy function to call content_multiple_value_after_build(), because it might 483 * not be included yet when the form is processed and invokes the callback. 484 */ 485 function content_multiple_value_after_build_proxy($elements, &$form_state) { 486 module_load_include('inc', 'content', 'includes/content.node_form'); 487 return content_multiple_value_after_build($elements, $form_state); 488 } 489 490 /** 480 491 * Theme an individual form element. 481 492 * … … 497 508 'colspan' => 2 498 509 ), 499 t('Order'),510 array('data' => t('Order'), 'class' => 'content-multiple-weight-header'), 500 511 ); 512 if ($field['multiple'] == 1) { 513 $header[] = array('data' => '<span>'. t('Remove') .'</span>', 'class' => 'content-multiple-remove-header'); 514 } 501 515 $rows = array(); 502 516 … … 506 520 foreach (element_children($element) as $key) { 507 521 if ($key !== $element['#field_name'] .'_add_more') { 508 $items[ ] = &$element[$key];509 } 510 } 511 u sort($items, '_content_sort_items_value_helper');522 $items[$element[$key]['#delta']] = &$element[$key]; 523 } 524 } 525 uasort($items, '_content_sort_items_value_helper'); 512 526 513 527 // Add the items as table rows. 514 foreach ($items as $ key=> $item) {528 foreach ($items as $delta => $item) { 515 529 $item['_weight']['#attributes']['class'] = $order_class; 516 530 $delta_element = drupal_render($item['_weight']); 531 if ($field['multiple'] == 1) { 532 $remove_element = drupal_render($item['_remove']); 533 } 517 534 $cells = array( 518 535 array('data' => '', 'class' => 'content-multiple-drag'), … … 520 537 array('data' => $delta_element, 'class' => 'delta-order'), 521 538 ); 522 $rows[] = array( 523 'data' => $cells, 524 'class' => 'draggable', 525 ); 539 $row_class = 'draggable'; 540 if ($field['multiple'] == 1) { 541 if (!empty($item['_remove']['#default_value'])) { 542 $row_class .= ' content-multiple-removed-row'; 543 } 544 $cells[] = array('data' => $remove_element, 'class' => 'content-multiple-remove-cell'); 545 } 546 $rows[] = array('data' => $cells, 'class' => $row_class); 526 547 } 527 548 … … 531 552 532 553 drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class); 554 drupal_add_js(drupal_get_path('module', 'content') .'/js/content.node_form.js'); 533 555 } 534 556 else { … … 684 706 * ); 685 707 */ 686 function content_field($op, &$node, $field, &$items, $teaser, $page ) {708 function content_field($op, &$node, $field, &$items, $teaser, $page, $wrappers = NULL) { 687 709 switch ($op) { 688 710 case 'validate': 689 // TODO: here we could validate that the number of multiple data is correct ? 690 // We're controlling the number of fields to fill out and saving empty 691 // ones if a specified number is requested, so no reason to do any validation 692 // here right now, but if later create a method to indicate whether 693 // 'required' means all values must be filled out, we can come back 694 // here and check that they're not empty. 711 // If the field is configured for multiple values and these are handled 712 // by content module, we need to filter out items flagged for removal and 713 // count non-empty items to enforce field requirement settings. 714 if ($field['multiple'] >= 1 && content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { 715 module_load_include('inc', 'content', 'includes/content.node_form'); 716 // Note that the $teaser argument for nodeapi('validate') is the $form. 717 content_multiple_value_nodeapi_validate($node, $field, $items, $teaser); 718 } 695 719 break; 696 720 … … 723 747 } 724 748 725 // Filter out empty values.749 // Filter out items flagged for removal. 726 750 $items = content_set_empty($field, $items); 727 751 … … 731 755 $addition = array(); 732 756 733 // Previewed nodes bypass the 'presave' op, so we need to some massaging.734 if ($node->build_mode == NODE_BUILD_PREVIEW && content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {757 // Previewed nodes bypass the 'presave' op, so we need to do some massaging. 758 if ($node->build_mode == NODE_BUILD_PREVIEW) { 735 759 if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { 736 760 // Reorder items to account for drag-n-drop reordering. … … 738 762 } 739 763 740 // Filter out empty values.764 // Filter out items flagged for removal. 741 765 $items = content_set_empty($field, $items); 742 766 } … … 777 801 778 802 // Fill-in items. 779 foreach ( $items as $delta => $item) {803 foreach (array_keys($items) as $weight => $delta) { 780 804 $element['items'][$delta] = array( 781 '#item' => $item ,782 '#weight' => $ delta,805 '#item' => $items[$delta], 806 '#weight' => $weight, 783 807 ); 784 808 } … … 826 850 827 851 // The location of the field's rendered output depends on whether the 828 // field is in a fieldgroup or not. 829 $wrapper = NULL; 830 if (isset($node->content[$field['field_name']])) { 831 $wrapper = $node->content[$field['field_name']]; 832 } 833 elseif (module_exists('fieldgroup') && ($group_name = fieldgroup_get_group($node->type, $field['field_name'])) && isset($node->content[$group_name]['group'][$field['field_name']])) { 834 $wrapper = $node->content[$group_name]['group'][$field['field_name']]; 835 } 836 837 if ($wrapper) { 852 // field is in a fieldgroup or not. _content_field_invoke_default() takes 853 // care of pre-searching all fields and providing the wrappers. In case of 854 // direct calls, search the wrappers ourselves. 855 if (is_null($wrappers)) { 856 $wrappers = content_get_nested_elements($node->content, $field['field_name']); 857 } 858 859 foreach ($wrappers as $wrapper) { 838 860 $element = $wrapper['field']; 839 861 // '#single' is not set if the field is hidden or inaccessible. … … 842 864 // Single value formatter. 843 865 foreach (element_children($element['items']) as $delta) { 844 // '#chil ren' is not set if the field is empty.866 // '#children' is not set if the field is empty. 845 867 $items[$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : ''; 846 868 } … … 860 882 case 'preprocess_node': 861 883 // Add $FIELD_NAME_rendered variables. 862 $addition = array( );884 $addition = array($field['field_name'] .'_rendered' => ''); 863 885 864 886 // The location of the field's rendered output depends on whether the 865 // field is in a fieldgroup or not. 866 $wrapper = NULL; 867 if (isset($node->content[$field['field_name']])) { 868 $wrapper = $node->content[$field['field_name']]; 869 } 870 elseif (module_exists('fieldgroup') && ($group_name = fieldgroup_get_group($node->type, $field['field_name'])) && isset($node->content[$group_name]['group'][$field['field_name']])) { 871 $wrapper = $node->content[$group_name]['group'][$field['field_name']]; 872 } 873 874 if ($wrapper) { 875 // '#chilren' is not set if the field is empty. 876 $addition[$field['field_name'] .'_rendered'] = isset($wrapper['#children']) ? $wrapper['#children'] : ''; 877 } 878 887 // field is in a fieldgroup or not. _content_field_invoke_default() takes 888 // care of pre-searching all fields and providing the wrappers. In case of 889 // direct calls, search the wrappers ourselves. 890 if (is_null($wrappers)) { 891 $wrappers = content_get_nested_elements($node->content, $field['field_name']); 892 } 893 foreach ($wrappers as $wrapper) { 894 // '#children' is not set if the field is empty. 895 $addition[$field['field_name'] .'_rendered'] .= isset($wrapper['#children']) ? $wrapper['#children'] : ''; 896 } 879 897 return $addition; 880 898 … … 889 907 890 908 /** 891 * Helper function to filter out empty values.909 * Helper function to filter out items flagged for removal. 892 910 * 893 911 * On order to keep marker rows in the database, the function ensures … … 900 918 */ 901 919 function content_set_empty($field, $items) { 902 // Filter out empty values. 920 // Prepare an empty item. 921 $empty = array(); 922 foreach (array_keys($field['columns']) as $column) { 923 $empty[$column] = NULL; 924 } 925 926 // Filter out items flagged for removal. 903 927 $filtered = array(); 904 928 $function = $field['module'] .'_content_is_empty'; 905 929 foreach ((array) $items as $delta => $item) { 906 if ( !$function($item, $field)) {907 $filtered[] = $item;930 if (empty($item['_remove'])) { 931 $filtered[] = ($function($item, $field) ? $empty : $item); 908 932 } 909 933 } 910 934 911 935 // Make sure we store the right number of 'empty' values. 912 $empty = array();913 foreach (array_keys($field['columns']) as $column) {914 $empty[$column] = NULL;915 }916 936 $pad = $field['multiple'] > 1 ? $field['multiple'] : 1; 917 937 $filtered = array_pad($filtered, $pad, $empty); … … 928 948 usort($items, '_content_sort_items_helper'); 929 949 foreach ($items as $delta => $item) { 930 if (is_array($item s[$delta])) {950 if (is_array($item) && isset($item['_weight'])) { 931 951 unset($items[$delta]['_weight']); 932 952 } … … 1009 1029 $additions[$field_name] = array(); 1010 1030 } 1011 $additions[$field_name][] = $item; 1031 1032 // Preserve deltas when loading items from database. 1033 if (isset($row['delta'])) { 1034 // Make sure multiple value fields have consecutive deltas. 1035 if ($row['delta'] > 0 && !isset($additions[$field_name][$row['delta']-1])) { 1036 $empty = array(); 1037 foreach (array_keys($db_info['columns']) as $column) { 1038 $empty[$column] = NULL; 1039 } 1040 $next_delta = !empty($additions[$field_name]) ? (max(array_keys($additions[$field_name])) + 1) : 0; 1041 for ($delta = $next_delta; $delta < $row['delta']; $delta++) { 1042 if (!isset($additions[$field_name][$delta])) { 1043 $additions[$field_name][$delta] = $empty; 1044 } 1045 } 1046 } 1047 $additions[$field_name][$row['delta']] = $item; 1048 } 1049 else { 1050 $additions[$field_name][] = $item; 1051 } 1012 1052 } 1013 1053 } … … 1066 1106 db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid); 1067 1107 } 1108 // Collect records for non-empty items. 1109 $function = $field['module'] .'_content_is_empty'; 1110 $records = array(); 1068 1111 foreach ($node->$field['field_name'] as $delta => $item) { 1112 if (!$function($item, $field)) { 1113 $record = array(); 1114 foreach ($db_info['columns'] as $column => $attributes) { 1115 $record[$attributes['column']] = $item[$column]; 1116 } 1117 $record['nid'] = $node->nid; 1118 $record['vid'] = $node->vid; 1119 $record['delta'] = $delta; 1120 $records[] = $record; 1121 } 1122 } 1123 // If there was no non-empty item, insert delta 0 with NULL values. 1124 if (empty($records)) { 1069 1125 $record = array(); 1070 1126 foreach ($db_info['columns'] as $column => $attributes) { 1071 $record[$attributes['column']] = $item[$column];1127 $record[$attributes['column']] = NULL; 1072 1128 } 1073 1129 $record['nid'] = $node->nid; 1074 1130 $record['vid'] = $node->vid; 1075 $record['delta'] = $delta; 1131 $record['delta'] = 0; 1132 $records[] = $record; 1133 } 1134 // Insert the collected records for this field into database. 1135 foreach ($records as $record) { 1076 1136 content_write_record($db_info['table'], $record); 1077 1137 } … … 1282 1342 } 1283 1343 else { 1344 // The 'alter' and 'preprocess_node' ops need the location of each field 1345 // within the $node->content array. Search once for all fields rather than 1346 // letting content_field() search for each field individually. 1347 if (in_array($op, array('alter', 'preprocess_node'))) { 1348 $all_wrappers = content_get_nested_elements($node->content, array_keys($type['fields'])); 1349 } 1284 1350 foreach ($type['fields'] as $field) { 1285 1351 $items = isset($node->$field['field_name']) ? $node->$field['field_name'] : array(); 1286 $result = content_field($op, $node, $field, $items, $teaser, $page); 1352 $wrappers = isset($all_wrappers) ? $all_wrappers[$field['field_name']] : NULL; 1353 $result = content_field($op, $node, $field, $items, $teaser, $page, $wrappers); 1287 1354 if (is_array($result)) { 1288 1355 $return = array_merge($return, $result); … … 2682 2749 } 2683 2750 2684 2685 2751 /** 2686 2752 * Helper function to identify inactive instances. 2687 2753 * This will be the same results as content_inactive_fields(), 2688 * EXCEPT that his function will return inactive instances even 2754 * EXCEPT that his function will return inactive instances even 2689 2755 * if the fields have other (shared) instances that are still active. 2690 2756 */ … … 2708 2774 return $inactive; 2709 2775 } 2776 2777 /** 2778 * Return the nested form elements for a field by name. 2779 * This can be used either to retrieve the entire sub-element 2780 * for a field by name, no matter how deeply nested it is within 2781 * fieldgroups or multigroups, or to find the multiple value 2782 * sub-elements within a field element by name (i.e. 'value' or 2783 * 'nid'). You can also use this function to see if an item exists 2784 * in a form (the return will be an empty array if it does not exist). 2785 * 2786 * A field/group will generally only exist once in a form but the 2787 * function can also be used to locate all the 'value' elements 2788 * within a multiple value field if you pass the multiple value field 2789 * as the $form argument; 2790 * 2791 * For example, for a field named field_custom, the following will 2792 * pluck out the form element for this field from the node form, 2793 * no matter how deeply it is nested within fieldgroups or fieldsets: 2794 * 2795 * $element = array_shift(content_get_nested_elements($node_form, 'field_custom')); 2796 * 2797 * You can prefix the function with '&' to retrieve the element by 2798 * reference to alter it directly: 2799 * 2800 * $elements = &content_get_nested_elements($form, 'field_custom'); 2801 * foreach ($elements as $element) { 2802 * $element['#after_build'][] = 'my_field_afterbuild'; 2803 * } 2804 * 2805 * During the #after_build you could then do something like the 2806 * following to alter each individual part of a multiple value field: 2807 * 2808 * $sub_elements = &content_get_nested_elements($element, 'value', 'all'); 2809 * foreach ($sub_elements as $sub_element) { 2810 * $sub_element['#element_validate'][] = 'custom_validation'; 2811 * } 2812 * 2813 * @param $form 2814 * The form array to search. 2815 * @param $field_name 2816 * The key of the form elements to return (can be a field name, a group name, 2817 * or a sub-field), or an array of names. 2818 * @return 2819 * An array of all matching form elements, returned by reference. 2820 */ 2821 function &content_get_nested_elements(&$form, $field_name) { 2822 // Handle single-field and multi-fields calls. 2823 if (is_array($field_name)) { 2824 $single = FALSE; 2825 $names = drupal_map_assoc($field_name); 2826 } 2827 else { 2828 $single = TRUE; 2829 $names = array($field_name => $field_name); 2830 } 2831 2832 // Initialize the results array (array_fill_keys() is only available in PHP 2833 // 5.2+). 2834 $results = array(); 2835 foreach ($names as $name) { 2836 $results[$name] = array(); 2837 } 2838 2839 // Search for the elements within the $form. Start at the top-level, 2840 // sub-elements will be added as we walk the form. 2841 $queue = array(&$form); 2842 while ($current = &_content_shift($queue)) { 2843 foreach (element_children($current) as $key) { 2844 // If this is one of the elements we are looking for, push it in the 2845 // results. 2846 if (isset($names[$key])) { 2847 $results[$key][] = &$current[$key]; 2848 } 2849 // Else push the element in our search queue. 2850 elseif (is_array($current[$key]) && !empty($current[$key])) { 2851 $queue[] = &$current[$key]; 2852 } 2853 } 2854 } 2855 2856 return $single ? $results[$field_name] : $results; 2857 } 2858 2859 /** 2860 * Returns the first element of an array by reference. 2861 * 2862 * This is conceptually equivalent to PHP built-in array_shift, but the 2863 * element is returned by reference to allow the caller to modify it. 2864 * 2865 * @param $array 2866 * The array whose first element's should be returned. 2867 * @return mixed 2868 * A reference to the variable that was the first array element. 2869 */ 2870 function &_content_shift(&$array) { 2871 reset($array); 2872 $k = key($array); 2873 $v = &$array[$k]; 2874 unset($array[$k]); 2875 return $v; 2876 } 2877 2878 /** 2879 * Helper function to set a value in a form element, 2880 * no matter how deeply nested it is in the form. 2881 * 2882 * @param $form 2883 * The form array to search. 2884 * @param $field_name 2885 * The name or key of the form elements to return. Can be a field name, a group name, or a sub-field. 2886 * @param $value 2887 * The value to set the element to. Should be an array that matches the part of the form that is being altered. 2888 * @return 2889 * TRUE or FALSE, depending on whether the element was discovered and set. 2890 */ 2891 function content_set_nested_elements(&$form, $field_name, $value) { 2892 $success = FALSE; 2893 $elements = &content_get_nested_elements($form, $field_name); 2894 if (!empty($elements)) { 2895 foreach ($elements as &$element) { 2896 $element = $value; 2897 $success = TRUE; 2898 } 2899 } 2900 return $success; 2901 }
Nota: Vea TracChangeset
para ayuda en el uso del visor de conjuntos de cambios.