diff -urN ../composite-6.x-1.0-beta8/composite.admin.inc ./composite.admin.inc --- ../composite-6.x-1.0-beta8/composite.admin.inc 1970-01-01 08:00:00.000000000 +0800 +++ ./composite.admin.inc 2010-06-22 13:22:10.000000000 +0800 @@ -0,0 +1,21 @@ + 'checkbox', + '#title' => t("Display recursion errors"), + '#description' => t("If checked, composite module will display an error message when blocking a node display recursion to user. Messages will be shown only if user can modify the currently being rendered node."), + '#default_value' => variable_get('composite_recursion_message', FALSE), + ); + return system_settings_form($form); +} diff -urN ../composite-6.x-1.0-beta8/composite.block.inc ./composite.block.inc --- ../composite-6.x-1.0-beta8/composite.block.inc 2008-12-06 13:44:05.000000000 +0900 +++ ./composite.block.inc 2010-06-22 14:12:16.000000000 +0800 @@ -19,6 +19,8 @@ $block = new StdClass(); $block->module = $reference['module']; $block->delta = $reference['delta']; + // Add a region to avoid PHP warnings. + $block->region = $reference['zone']; $array = module_invoke($block->module, 'block', 'view', $block->delta); if (isset($array) && is_array($array)) { foreach ($array as $k => $v) { @@ -43,7 +45,7 @@ /** * Generates and returns a keyed array of potential composite references - * so composite.module can create a meaningful local task. + * so composite.module can create a meaningful local task. */ function composite_composite_block_potentials($node) { // Build a list of blocks diff -urN ../composite-6.x-1.0-beta8/composite.module ./composite.module --- ../composite-6.x-1.0-beta8/composite.module 2009-09-12 14:56:17.000000000 +0800 +++ ./composite.module 2010-06-22 14:03:36.000000000 +0800 @@ -66,37 +66,49 @@ } function composite_get_types($type = '') { - static $types = null; + static $types; - if (empty($types)) { - $types = array(); - foreach (module_implements('composite_types') as $module) { - $data = module_invoke($module, 'composite_types'); - - foreach ($data as $k => $unused) { - // Fill in 'module' if not specified - if (!$data[$k]['module']) { - $data[$k]['module'] = $module; - } + if (!isset($types)) { + // Aptempt to fetch it from cache. + if ($cache = cache_get('composite_types')) { + $types = &$cache->data; + } + // Else build data. + else { + $types = array(); + foreach (module_implements('composite_types') as $module) { + $data = module_invoke($module, 'composite_types'); - // Prefix 'file' with module dir - if ($data[$k]['file']) { - $data[$k]['file'] = drupal_get_path('module', $module) .'/'. $data[$k]['file']; + foreach ($data as $k => $unused) { + // Fill in 'module' if not specified + if (!isset($data[$k]['module']) || empty($data[$k]['module'])) { + $data[$k]['module'] = $module; + } + + // Prefix 'file' with module dir + if (isset($data[$k]['file'])) { + $data[$k]['file'] = drupal_get_path('module', $module) .'/'. $data[$k]['file']; + } } + $types = array_merge_recursive($types, $data); + } + + foreach (module_implements('composite_types_alter') as $module) { + $function = $module . '_composite_types_alter'; + $function($types); } - $types = array_merge_recursive($types, $data); - } - foreach (module_implements('composite_types_alter') as $module) { - $function = $module . '_composite_types_alter'; - $function($types); + // Save new data to cache. + cache_set('composite_types', $types); } } - if ($type == '') + if (empty($type)) { return $types; - else if (array_key_exists($type, $types)) + } + else if (array_key_exists($type, $types)) { return $types[$type]; + } } // Includes the 'file' parameter of a reference type, if defined. @@ -141,21 +153,21 @@ // Construct a select list for convenience foreach ($layouts as $key => $v) { $key_dashed = strtr($key, '_', '-'); - if (!$layouts[$key]['template']) { + if (!isset($layouts[$key]['template'])) { $layouts[$key]['template'] = 'composite-layout-' . $key_dashed; } - if (!$layouts[$key]['path']) { + if (!isset($layouts[$key]['path'])) { $layouts[$key]['path'] = drupal_get_path('module', $layouts[$key]['module']); } - $css = $layouts[$key]['css'] ? $layouts[$key]['css'] : 'composite-layout-' . $key_dashed . '.css'; + $css = isset($layouts[$key]['css']) ? $layouts[$key]['css'] : 'composite-layout-' . $key_dashed . '.css'; $css = $layouts[$key]['path'] . '/' . $css; if (is_file($css)) { $layouts[$key]['css'] = $css; } - $icon = $layouts[$key]['icon'] ? $layouts[$key]['icon'] : 'composite-layout-' . $key_dashed . '.icon.png'; + $icon = isset($layouts[$key]['icon']) ? $layouts[$key]['icon'] : 'composite-layout-' . $key_dashed . '.icon.png'; $icon = $layouts[$key]['path'] . '/' . $icon; if (is_file($icon)) { $layouts[$key]['icon'] = $icon; @@ -195,7 +207,7 @@ // Generate local task for each reference type that requests it $types = composite_get_types(); foreach ($types as $type) { - if ($type['local task']) { + if (isset($type['local task'])) { $items['node/%node/composite_' . $type['type']] = array( 'title' => $type['label']['plural'], 'page callback' => 'composite_general_select_page', @@ -218,7 +230,17 @@ 'weight' => 3, 'file' => 'composite.pages.inc', ); - + + // Administration pages. + $items['admin/settings/composite'] = array( + 'title' => t("Composite"), + 'description' => t("Configure global parameters for composite module."), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('composite_admin_settings'), + 'access arguments' => array('administer site configuration'), + 'file' => 'composite.admin.inc', + ); + return $items; } @@ -227,8 +249,8 @@ */ function composite_access($tab, $op, $node) { $access = FALSE; - - if ((user_access('edit composite layouts') || user_access('administer nodes')) && composite_enabled($node) && $node->composite_layout) { + + if ((user_access('edit composite layouts') || user_access('administer nodes')) && composite_enabled($node) && isset($node->composite_layout)) { $access_function = 'node_access'; // Change access function if this tab was generated for a reference type // and the optional task access function is defined @@ -264,23 +286,23 @@ '#title' => t('Composite layout'), '#description' => t('Select the desired composite layout of this node.'), '#collapsible' => TRUE, - '#collapsed' => !$node->composite_layout && $default_set == '--', + '#collapsed' => !isset($node->composite_layout) && $default_set == '--', '#weight' => 10, ); $form['composite_settings']['composite_references'] = array( '#type' => 'value', - '#value' => $node->composite_references, + '#value' => isset($node->composite_references) ? $node->composite_references : NULL, ); $form['composite_settings']['composite_layout_data'] = array( '#type' => 'value', - '#value' => $node->composite_layout_data, + '#value' => isset($node->composite_layout_data) ? $node->composite_layout_data : NULL, ); $form['composite_settings']['composite_layout'] = array( '#title' => t('Layout'), '#type' => 'composite_layout_radios', '#options' => array('--' => t('No composite layout')) + composite_get_layouts('select'), - '#default_value' => $node->composite_layout ? $node->composite_layout : '--', + '#default_value' => isset($node->composite_layout) ? $node->composite_layout : '--', ); $form['composite_settings']['composite_content_reference'] = array( '#type' => 'checkbox', @@ -451,38 +473,29 @@ case 'alter': if (isset($node->composite_content)) { // Have to do our 'view' stuff in the alter hook because we have to wait - // for other modules to do their processing first. - $layout = composite_get_layout($node->composite_layout); - if ($layout) { - $layout['data'] = $node->composite_layout_data; - $node->composite_content = composite_view($node, $layout, $node->composite_references); - foreach ($node->composite_content as $zone => $zone_item) { - $node->composite_content[$zone] = drupal_render($zone_item); - } - - // Add this layout's css, if any - if ($layout['css']) { - drupal_add_css($layout['css']); + // for other modules to do their processing first. + if ($layout = composite_get_layout($node->composite_layout)) { + // Check for infinite loops + if (_composite_nodes_recursion_check($node->nid)) { + // FIXME: If the node is being rendered more than once, the message + // will appear more than once. + if (composite_access('zones', 'update', $node)) { + if (variable_get('composite_recursion_message', FALSE)) { + drupal_set_message(t('You have created an infinite loop. One node is displaying a second node which in turn displays the first node.'), 'error'); + } + } + // Return here to avoid the end of the function unmarking the node + // as being rendered. + return; } - // Call the appropriate theme('composite_layout...', ...) function. - // However, because the number of arguments depends on the number - // of zones in the layout layout, we have to use call_user_func_array - - // Add in the theme hook name and the first two arguments - $args = array( - 'composite_layout_' . $layout['key'], // theme hook - $layout, // layout - $node->composite_content // composite_content - ); - - // Now add an argument for the contents of each zone - foreach ($layout['zones'] as $zone => $unused) { - $args[] = $node->composite_content[$zone]; - } - - // And call it - $node->body = call_user_func_array('theme', $args); + // Render the composite layout using the node information. + $layout += array('node' => $node); + $node->body = theme('composite_layout', $layout, $node); + + // Unmark the node as being redenred, this will happen only the in + // first loop thanks to the upper return statement. + _composite_nodes_recursion_check($node->nid, FALSE); } } break; @@ -504,7 +517,7 @@ // Just delete everything, and then add back in later composite_delete_revision($node); - if ($node->composite_layout && $node->composite_layout != '--') { + if (!empty($node->composite_layout) && $node->composite_layout != '--') { // Treat the content_reference specially if we came in from an edit form. if (isset($node->composite_content_reference)) { if ($node->composite_content_reference) { @@ -561,7 +574,11 @@ $types = composite_get_types(); $additions = array(); - $result = db_fetch_object(db_query('SELECT layout, data FROM {node_composite} WHERE vid = %d', $node->vid)); + // Do not go any further if node has no layout set. + if (!$result = db_fetch_object(db_query('SELECT layout, data FROM {node_composite} WHERE vid = %d', $node->vid))) { + return $additions; + } + $additions['composite_layout'] = $result->layout; $additions['composite_layout_data'] = unserialize($result->data); @@ -571,7 +588,7 @@ $sublists[$type['type']] = array(); } - $result = db_query("SELECT type, weight, id, data, zone FROM {node_composite_references} WHERE vid = %d", $node->vid); + $result = db_query("SELECT type, weight, id, data, zone FROM {node_composite_references} WHERE vid = %d ORDER BY weight", $node->vid); while ($object = db_fetch_object($result)) { // Some common manipulations $object = (array) $object; @@ -620,6 +637,37 @@ return $composite_content; } +/** + * Recursion check helper. + * + * @param mixed $identifier + * Any object identifier, mostly used is nid. + * @param bool $unmark = FALSE + * (optional) Set this to TRUE when you get out from the recursion loop + * to ensure this can be used in another site part which is getting + * rendered. + * + * @return boolean + * TRUE if identifier is marked as being rendered, FALSE else. + */ +function _composite_nodes_recursion_check($identifier, $unmark = FALSE) { + static $rendered = array(); + + if ($unmark) { + $rendered[$identifier] = FALSE; + } + + if (!isset($rendered[$identifier])) { + $rendered[$identifier] = TRUE; + // If not set, always return TRUE. + return FALSE; + } + + // Identidifier already set, then check if it's marked as currently + // being redered. + return $rendered[$identifier]; +} + /*********************************************************** * COMPOSITE LAYOUT SETS * ************************************************************/ @@ -739,23 +787,66 @@ * Implementation of hook_theme() */ function composite_theme() { - $data = array( - 'composite_layout_radios' => array( - 'arguments' => array('element' => NULL), - ), - 'composite_layout_icon' => array( - 'arguments' => array('file' => NULL, 'layout' => NULL), - ), - 'composite_zones_form' => array( - 'template' => 'composite-zones-form', - 'file' => 'composite.pages.inc', - 'arguments' => array('form' => NULL), + $data = array(); + + $path = drupal_get_path('module', 'composite') . '/theme'; + $file = 'theme.inc'; + + $data['composite_layout_radios'] = array( + 'path' => $path, + 'file' => $file, + 'arguments' => array('element' => NULL), + ); + $data['composite_layout_icon'] = array( + 'path' => $path, + 'file' => $file, + 'arguments' => array('file' => NULL, 'layout' => NULL), + ); + $data['composite_zones_form'] = array( + 'path' => $path, + 'file' => $file, + 'template' => 'composite-zones-form', + 'arguments' => array('form' => NULL), + ); + $data['composite_zones_preview'] = array( + 'path' => $path, + 'file' => $file, + 'arguments' => array('node' => NULL), + ); + $data['composite_node_title'] = array( + 'path' => $path, + 'file' => $file, + 'arguments' => array('title' => ''), + ); + // Deport zone render to an external function for code encapsulation + // and code readability. + $data['composite_layout'] = array( + 'path' => $path, + 'file' => $file, + 'template' => 'composite-layout', + 'arguments' => array( + 'layout' => NULL, + 'node' => NULL, ), - 'composite_zones_preview' => array( - 'arguments' => array('node' => NULL), + ); + // Adds a default template for zones. + $data['composite_zone'] = array( + 'path' => $path, + 'file' => $file, + 'template' => 'composite-zone', + 'arguments' => array( + 'zone' => '', + 'node' => NULL, ), - 'composite_node_title' => array( - 'arguments' => array('title' => ''), + ); + // Adds a default template for reference. + $data['composite_reference'] = array( + 'path' => $path, + 'file' => $file, + 'template' => 'composite-reference', + 'arguments' => array( + 'reference' => NULL, + 'node' => NULL, ), ); @@ -783,25 +874,6 @@ return $data; } -function theme_composite_layout_radios($element) { - return theme('radios', $element); -} - -function theme_composite_layout_icon($file, $layout) { - return '' . $layout['template'] . ''; -} - -function theme_composite_zones_preview($node) { - if (isset($node->nid)) { - $output = '
' . node_view($node, FALSE, FALSE) .'
'; - return $output; - } -} - -function theme_composite_node_title($title) { - return '
' . $title . '
'; -} - /*********************************************************** * REFERENCE TYPE DEFINITIONS * ************************************************************/ @@ -1015,4 +1087,3 @@ break; } } - diff -urN ../composite-6.x-1.0-beta8/composite.node.inc ./composite.node.inc --- ../composite-6.x-1.0-beta8/composite.node.inc 2009-03-03 09:39:05.000000000 +0900 +++ ./composite.node.inc 2010-06-22 13:22:10.000000000 +0800 @@ -134,16 +134,3 @@ return array(); } } - -// Returns true if we there is an infinite loop. -function _composite_nodes_recursion_check($node) { - static $nodes = array(); - - if (array_key_exists($node->nid, $nodes)) { - return true; - } - else { - $nodes[$node->nid] = $node->nid; - return false; - } -} diff -urN ../composite-6.x-1.0-beta8/composite.pages.inc ./composite.pages.inc --- ../composite-6.x-1.0-beta8/composite.pages.inc 2009-09-12 14:56:17.000000000 +0800 +++ ./composite.pages.inc 2010-06-22 13:52:50.000000000 +0800 @@ -388,48 +388,6 @@ return; } - -// This function borrows some code from template_preprocess_block_admin_display_form -function template_preprocess_composite_zones_form(&$variables) { - $layout_zones = $variables['form']['#zones']; - $layout_zones[COMPOSITE_ZONE_NONE] = t('Disabled'); - $variables['layout_zones'] = $layout_zones; - - foreach ($layout_zones as $key => $value) { - // Highlight regions on page to provide visual reference. - // drupal_set_content($key, '
'. $value .'
'); - // Initialize an empty array for the region. - $variables['zone_listing'][$key] = array(); - } - $variables['zone_listing'][COMPOSITE_ZONE_NONE] = array(); - - foreach (element_children($variables['form']) as $i) { - $reference = &$variables['form'][$i]; - - // Only take form elements that are references. - if (isset($reference['id'])) { - // Fetch zone for current block. - $zone = $reference['zone']['#default_value']; - - // Set special classes needed for table drag and drop. - $variables['form'][$i]['zone']['#attributes']['class'] = 'block-region-select block-region-'. $zone; - $variables['form'][$i]['weight']['#attributes']['class'] = 'block-weight block-weight-'. $zone; - - $variables['zone_listing'][$zone][$i]->row_class = isset($reference['#attributes']['class']) ? $reference['#attributes']['class'] : ''; - $variables['zone_listing'][$zone][$i]->reference_modified = isset($reference['#attributes']['class']) && strpos($reference['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE; - $variables['zone_listing'][$zone][$i]->reference_title = drupal_render($reference['info']); - $variables['zone_listing'][$zone][$i]->zone_select = drupal_render($reference['zone']); //. drupal_render($block['theme']); - $variables['zone_listing'][$zone][$i]->weight_select = drupal_render($reference['weight']); - $variables['zone_listing'][$zone][$i]->data_widget = drupal_render($reference['data']); - $variables['zone_listing'][$zone][$i]->checkbox = drupal_render($reference['checkbox']); - $variables['zone_listing'][$zone][$i]->printed = FALSE; - } - } - - $variables['form_layout_settings'] = drupal_render($variables['form']['layout_settings']); - $variables['form_submit'] = drupal_render($variables['form']); -} - /*********************************************************** * COMPOSITE LAYOUT SETS * ************************************************************/ diff -urN ../composite-6.x-1.0-beta8/composite-zones-form.tpl.php ./composite-zones-form.tpl.php --- ../composite-6.x-1.0-beta8/composite-zones-form.tpl.php 2008-11-20 00:10:07.000000000 +0900 +++ ./composite-zones-form.tpl.php 1970-01-01 08:00:00.000000000 +0800 @@ -1,75 +0,0 @@ -reference_title: Item title. - * - $data->zone_select: Drop-down menu for assigning a zone. - * - $data->weight_select: Drop-down menu for setting weights. - * - $data->configure_link: Configuration link. - * - $data->delete_link: For deleting user added items ?? - * - * @see template_preprocess_composite_layout_form() - */ -?> - - $title) { - drupal_add_tabledrag('blocks', 'match', 'sibling', 'block-region-select', 'block-region-'. $region, NULL, FALSE); - drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight', 'block-weight-'. $region); - } -?> - - - - - - - - - - - - - $title): ?> - - - - - - - $data): ?> - - - - - - - - - - - -
reference_title; ?>zone_select; ?>weight_select; ?>data_widget; ?>checkbox; ?>
- - diff -urN ../composite-6.x-1.0-beta8/crud.test ./crud.test --- ../composite-6.x-1.0-beta8/crud.test 1970-01-01 08:00:00.000000000 +0800 +++ ./crud.test 2010-06-22 13:22:10.000000000 +0800 @@ -0,0 +1,86 @@ + t("Composite CRUD"), + 'description' => t("Will test some basic CRUD tests using block references."), + 'group' => t("Composite"), + ); + } + + public function setUp() { + parent::setUp('composite'); + } + + public function tearDown() { + parent::tearDown(); + } + + /** + * Basic CRUD operations in a single test. + */ + public function testCrud() { + // Create content type. + $type = 'compType'; + $this->drupalCreateContentType(array('type' => $type)); + variable_set('composite_enabled_' . $type, 1); + + // Create a powerful enougth user in order to manipulate composite + // nodes. + $user = $this->drupalCreateUser(array( + 'access content', 'create ' . $type . ' content', 'edit own ' . $type . ' content', 'edit composite layouts' + )); + + // Create a node. + $node = $this->drupalCreateNode(array( + 'type' => $type, + 'uid' => $user->uid, + )); + + // Check user can modify this node. + $this->drupalLogin($user); + $this->drupalGet('node/' . $node->nid . '/edit'); + + // Set its layout. + $this->drupalPost('node/' . $node->nid . '/edit', array( + 'composite_layout' => 'onecol', + ), t('Save')); + + // Check layout has been kept. + $checkNode = node_load($node->nid, NULL, TRUE); + $this->assertEqual($checkNode->composite_layout, 'onecol', "Layout has been successfully saved"); + + // Add some block references (using core blocks). + $checkNode->composite_references = array(); + // User module block delta 2 is "Who's new". + $reference_key = 'user-' . 2; + $reference = array( + 'type' => 'block', + 'weight' => -10, + 'id' => $reference_key, + 'data' => FALSE, + 'zone' => 'left', // Left is the only region of onecol layout. + 'delta' => 2, + 'module' => 'user', + ); + $checkNode->composite_references = array( + $reference_key => &$reference, + ); + node_save($checkNode); + + // Checks blocks have been saved. + // Go to page, and see if blocks are displayed. + $this->drupalGet('node'); + $this->assertNoRaw("Who's new", "Block Who's new not found on front page."); + $this->drupalGet('node/' . $node->nid); + $this->assertRaw("Who's new", "Block Who's new found on node page."); + } +} diff -urN ../composite-6.x-1.0-beta8/theme/composite-layout.tpl.php ./theme/composite-layout.tpl.php --- ../composite-6.x-1.0-beta8/theme/composite-layout.tpl.php 1970-01-01 08:00:00.000000000 +0800 +++ ./theme/composite-layout.tpl.php 2010-06-22 13:22:10.000000000 +0800 @@ -0,0 +1,9 @@ + + diff -urN ../composite-6.x-1.0-beta8/theme/composite-reference.tpl.php ./theme/composite-reference.tpl.php --- ../composite-6.x-1.0-beta8/theme/composite-reference.tpl.php 1970-01-01 08:00:00.000000000 +0800 +++ ./theme/composite-reference.tpl.php 2010-06-22 13:22:10.000000000 +0800 @@ -0,0 +1,9 @@ + + diff -urN ../composite-6.x-1.0-beta8/theme/composite-zones-form.tpl.php ./theme/composite-zones-form.tpl.php --- ../composite-6.x-1.0-beta8/theme/composite-zones-form.tpl.php 1970-01-01 08:00:00.000000000 +0800 +++ ./theme/composite-zones-form.tpl.php 2010-06-22 13:22:10.000000000 +0800 @@ -0,0 +1,75 @@ +reference_title: Item title. + * - $data->zone_select: Drop-down menu for assigning a zone. + * - $data->weight_select: Drop-down menu for setting weights. + * - $data->configure_link: Configuration link. + * - $data->delete_link: For deleting user added items ?? + * + * @see template_preprocess_composite_layout_form() + */ +?> + + $title) { + drupal_add_tabledrag('blocks', 'match', 'sibling', 'block-region-select', 'block-region-'. $region, NULL, FALSE); + drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight', 'block-weight-'. $region); + } +?> + + + + + + + + + + + + + $title): ?> + + + + + + + $data): ?> + + + + + + + + + + + +
reference_title; ?>zone_select; ?>weight_select; ?>data_widget; ?>checkbox; ?>
+ + diff -urN ../composite-6.x-1.0-beta8/theme/composite-zone.tpl.php ./theme/composite-zone.tpl.php --- ../composite-6.x-1.0-beta8/theme/composite-zone.tpl.php 1970-01-01 08:00:00.000000000 +0800 +++ ./theme/composite-zone.tpl.php 2010-06-22 13:22:10.000000000 +0800 @@ -0,0 +1,9 @@ + + diff -urN ../composite-6.x-1.0-beta8/theme/theme.inc ./theme/theme.inc --- ../composite-6.x-1.0-beta8/theme/theme.inc 1970-01-01 08:00:00.000000000 +0800 +++ ./theme/theme.inc 2010-06-22 14:00:19.000000000 +0800 @@ -0,0 +1,131 @@ + $value) { + // Highlight regions on page to provide visual reference. + // drupal_set_content($key, '
'. $value .'
'); + // Initialize an empty array for the region. + $variables['zone_listing'][$key] = array(); + } + $variables['zone_listing'][COMPOSITE_ZONE_NONE] = array(); + + foreach (element_children($variables['form']) as $i) { + $reference = &$variables['form'][$i]; + + // Only take form elements that are references. + if (isset($reference['id'])) { + // Fetch zone for current block. + $zone = $reference['zone']['#default_value']; + + // Set special classes needed for table drag and drop. + $variables['form'][$i]['zone']['#attributes']['class'] = 'block-region-select block-region-'. $zone; + $variables['form'][$i]['weight']['#attributes']['class'] = 'block-weight block-weight-'. $zone; + + $variables['zone_listing'][$zone][$i]->row_class = isset($reference['#attributes']['class']) ? $reference['#attributes']['class'] : ''; + $variables['zone_listing'][$zone][$i]->reference_modified = isset($reference['#attributes']['class']) && strpos($reference['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE; + $variables['zone_listing'][$zone][$i]->reference_title = drupal_render($reference['info']); + $variables['zone_listing'][$zone][$i]->zone_select = drupal_render($reference['zone']); //. drupal_render($block['theme']); + $variables['zone_listing'][$zone][$i]->weight_select = drupal_render($reference['weight']); + $variables['zone_listing'][$zone][$i]->data_widget = drupal_render($reference['data']); + $variables['zone_listing'][$zone][$i]->checkbox = drupal_render($reference['checkbox']); + $variables['zone_listing'][$zone][$i]->printed = FALSE; + } + } + + $variables['form_layout_settings'] = drupal_render($variables['form']['layout_settings']); + $variables['form_submit'] = drupal_render($variables['form']); +} + +/** + * Implementation of template_preprocess_TEMPLATE(). + * Render a node layout. + */ +function template_preprocess_composite_layout(&$variables) { + $layout = $variables['layout']; + $node = $layout['node']; + + // Add this layout's css, if any. + if ($layout['css']) { + drupal_add_css($layout['css']); + } + + // Fetch layout data. + $layout['data'] = $node->composite_layout_data; + + // Call the appropriate theme('composite_layout...', ...) function. + // However, because the number of arguments depends on the number + // of zones in the layout layout, we have to use call_user_func_array. + // Add in the theme hook name and the first two arguments + $args = array('composite_layout_' . $layout['key'], $layout, $node->composite_content); + + // Preprocess references. + $zones = array(); + $references = _composite_references_preprocess($node->composite_references, $layout['zones'], FALSE); + // Build zones content temporary array. I'm not fond of this part of the + // algorithm, but should suffice for a start. + foreach (element_children($references) as $key) { + $zone = $references[$key]['zone']; + // Avoid PHP warnings. + if (!isset($zones[$zone])) { + $zones[$zone] = array(); + } + $zones[$zone][] = &$references[$key]; + } + + // Render all zones and populate the composite_content array. + foreach ($layout['zones'] as $zone => $useless) { + $args[] = theme('composite_zone', array( + 'name' => $zone, + 'references' => isset($zones[$zone]) ? $zones[$zone] : array(), + ), $node); + } + + // Call the specific theme function for the given layout. + $variables['content'] = call_user_func_array('theme', $args); +} + +/** + * Implementation of template_preprocess_TEMPLATE(). + * Render a layout zone. + */ +function template_preprocess_composite_zone(&$variables) { + // Prepare content. + $variables['content'] = ''; + // Iterate over references and render each one of them. + foreach ($variables['zone']['references'] as &$reference) { + $variables['content'] .= theme('composite_reference', $reference, $variables['node']); + } +} + +/** + * Implementation of template_preprocess_TEMPLATE(). + * Render a zone reference. + */ +function template_preprocess_composite_reference(&$variables) { + $variables['content'] = composite_invoke_referenceapi($variables['reference'], 'view', $variables['node']); +} + +function theme_composite_layout_radios($element) { + return theme('radios', $element); +} + +function theme_composite_layout_icon($file, $layout) { + return '' . $layout['template'] . ''; +} + +function theme_composite_zones_preview($node) { + if (isset($node->nid)) { + $output = '
' . node_view($node, FALSE, FALSE) .'
'; + return $output; + } +} + +function theme_composite_node_title($title) { + return '
' . $title . '
'; +}