Currently the Calendar Block module only supports one block and hook_calendar_block() will only affect that one particular block.

There exist circumstances where more than one calendar block are necessary. For example: using Calendar Block to create links that send arguments to multiple Views. These views could have different URLs, have different days which provide arguments, have different visiblity permissions, have different regions, etc.

The attached patch enables multiple calendar blocks with individual settings available. Blocks are added via a local menu task 'Add calendar block' on the blocks administration page. Each block will require a machine-readable name (that equates to $delta in hook_block).

In hook_calendar_block(), the $calendar parameter now has a property $calendar->delta which corresponds to the machine-readable name. This can be used via a switch statement in both $op = 'load' and $op = 'alter.'

Sample:


function gallery_calendar_block(&$calendar, &$date, $op) {
  switch($op) {
    case 'load':
      switch ($calendar->delta) {
        case 'my_calendar':
          // For the delta 'my_calendar' the date is fixed on October 1978
          $calendar->month = 10;
          $calendar->year = 1978;
          break;
        case 'your_calendar':
          // For the delta 'your_calendar' the date is being parsed out from arguments. 
          // This is sometimes useful with views arguments.
          $calendar->month = arg(2);
          $calendar->year = arg(3);
          break;
      }

// ... etc ...

Because there will be multiple settings for multiple calendar blocks, I changed how the module stores this information. Thus, if you apply the patch, you will need to reconfigure your colors, width, and first-day-of-week and the existing block will have the machine-readable name '0' (i.e. $calendar->delta). CSS and HTML were also changed to support multiple instances (which required element classes instead of element ids).

Alternatively, if you just want to try it out new instead of applying the patch, I have included the entire module code in the attached calendar_block-multiple.tar.gz.

To the maintainer: Since Calendar Block has not been updated in nearly a year, I am interested in becoming co-maintainer of this module.

Comments

sun’s picture

Status: Needs review » Needs work
+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+        'info' => t('Calendar block: !title', array('!title' => $title)),

$title needs to be properly escaped, use the @ placeholder.

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+function calendar_block_remove_hash($item) {
+  return str_replace('#', '', $item);
+}

Needs more explanation/reasoning.

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+function calendar_block_delta_validate($element, &$form_state) {
...
+  if (!preg_match('/^[a-z0-9_]+$/', $element['#value'])) {
...
+  if (db_result(db_query("SELECT bid FROM {blocks} WHERE module = 'calendar_block' AND delta = '%s'", $element['#value']))) {

$element['#value'] does not necessarily hold the entered value. $form_state['values'] contains the user input for validation.

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+  if ($form_state['values']['delta_input']) {
+    $form_state['values']['delta'] = $form_state['values']['delta_input'];
+  }

What's that?

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+  // Run the normal new block submission (borrowed from block_add_block_form_submit).
+  foreach (list_themes() as $key => $theme) {
+    if ($theme->status) {
+      db_query("INSERT INTO {blocks} (visibility, pages, custom, title, module, theme, status, weight, delta, cache) VALUES(%d, '%s', %d, '%s', '%s', '%s', %d, %d, '%s', %d)", $form_state['values']['visibility'], trim($form_state['values']['pages']), $form_state['values']['custom'], $form_state['values']['title'], $form_state['values']['module'], $theme->name, 0, 0, $delta, BLOCK_NO_CACHE);
+    }
+  }
+
+  foreach (array_filter($form_state['values']['roles']) as $rid) {
+    db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_state['values']['module'], $delta);
+  }

So why don't you simply re-use the regular block add/edit form? See menu_block module for examples.

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+ * _submit handler for deletion
+ */
+function calendar_block_delete_block_form_submit($form, &$form_state) {
+  $delta = $form_state['values']['delta'];

Missing 'confirm' condition.

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+  if (is_null($delta)) {

(and elsewhere) Should use !isset() instead of is_null(), since the latter may throw PHP notices.

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -112,35 +147,261 @@ function calendar_block_block($op = 'lis
+function calendar_block_settings_set($delta, $settings) {
+  $all_settings = variable_get('calendar_block_settings', $array);

Looks like this should be stored in an own table instead.

+++ calendar_block.module	24 Dec 2009 18:57:31 -0000
@@ -225,15 +487,16 @@ function theme_calendar_block($calendar)
+  $output[] = '    <div id="' . $cal_id . '_row'. $row_counter .'" class="clear-block">';

@@ -247,7 +510,7 @@ function theme_calendar_block($calendar)
+  $output[] = '    <div class="week calendar_row' . $row_counter . '" id="' . $cal_id . '_row' . $row_counter . '">';

@@ -285,7 +548,7 @@ function theme_calendar_block($calendar)
+      $output[] = '    <div class="week calendar_row' . $row_counter . '" id="' . $cal_id . '_row' . $row_counter . '">';

Looks like the same HTML ID is repeated here (invalid).

Powered by Dreditor.

c4rl’s picture

Status: Needs work » Needs review
StatusFileSize
new39.64 KB

Most of the items mentioned in #1 are fixed, with a few caveats.

So why don't you simply re-use the regular block add/edit form? See menu_block module for examples.

I checked and this is indeed how menu_block handles this. Please see menu_block_add_block_form_submit() in menu_block.admin.inc
http://drupalcode.org/viewvc/drupal/contributions/modules/menu_block/men...

Missing 'confirm' condition.

Can you please clarify what you mean? confirm_form() usage in core seems similar to mine.

Looks like this should be stored in an own table instead.

Unless unserialization is a bottleneck, a separate table simply for settings seems overkill. The method I'm using saves a $delta keyed array to the variable table which seems cleaner than how menu_block approaches it. Menu block saves every setting for every block as a separate name/value pair in variable. Especially if these are to be removed in hook_uninstall() (Currently not implemented).

Looks like the same HTML ID is repeated here (invalid).

$row_counter is incremented with each instance of these, so they are indeed unique.

skilip’s picture

This patch is way too large. There are too many little improvements to be done before this patch is near RTBC. First of all try to move each admin related stuff into a separate .inc file, to avoid the .module becoming very large. Secondly I'd prefer a separate admin page for adding and deleting calendar blocks, (but that's a personal preference). Would it be possible to separate this in several issues?

skilip’s picture

Oh and use Coder to check your coding before rolling out a patch ;).

c4rl’s picture

The patch is making sweeping and fundamental changes to how the module works, so it indeed is large. I agree that creating inc files would make it cleaner.

A few questions:

@skilip What do you mean by "little improvements" in #3?

@skilip What would be the result of separating this issue into "several issues" in #3? I am not sure what the "several issues" would be. If you have ideas, please suggest or create the issues.

skilip’s picture

@c4rl I wrote 'little improvements' to point out fixing all the minor 'non-coding-standard' issues. The problem with this patch is that it is too large to keep focus. My experience with large patches is that you will get into enormous discussions and debates (bikeshedding) before the patch gets near RTBC.

First separate patch could be for example: 'Create an admin interface for creating multiple blocks'.

Cheers!