Project:Date
Version:5.x-2.0-rc
Component:Code
Category:bug report
Priority:critical
Assigned:Unassigned
Status:closed (works as designed)

Issue Summary

I've written a script to automatically create a bunch of CCK nodes.

$node = array();
$node['uid'] = $user->uid;
$node['name'] = $user->name;
$node['type'] = 'myCalendarNode';

$values['field_day'][0]['value'] = $date;
...

drupal_execute($node['type'] . '_node_form', $values, $node);

As you can see one of the fields has the CCK type Date.

When assigning the field the widget type "Text Field with jquery pop-up calendar" validation throws an error: "Day 2 2 not valid"
When assigning the field the widget type "Text Field with strtotime validation" nodes get created properly

The following function reveals another symptom:

date_popup_input_value($element) {
$input = $element['#value']['date'];
...

$element['#value']['date'] doesn't exist when jquery is used because

$element['#value'] = '2008-05-14';

This string gets truncated to '2' when accessed by ['date'].

Comments

#1

Status:active» fixed

Update to the latest dev version of the Date module.

#2

emeidi, has this fixed your problem? I'm still getting it on the most recent DEV.

#3

Status:fixed» active

Issue still not fixed.

Neither

$values['field_day'][0]['value'] = $date . 'T00:00:00';

nor

$values['field_day'][0]['value']['date'] = $date;

works when field type uses the JQuery Pop-Up Calendar.

#4

date_text_input_value() expects the value to be an array. When I'm submitting an array ...

$values['field_day'][0]['value']['date'] = $date . 'T00:00:00';

... there are other errors showing up:

warning: preg_match() expects parameter 2 to be string, array given in ./date/date_api.module on line 1006.

warning: mysql_real_escape_string() expects parameter 1 to be string, array given in ./includes/database.mysql.inc on line 400.

When reverting back to

$values['field_day'][0]['value'] = $date . 'T00:00:00';

the first time date_text_input_value() is called the string gets truncated to '2' (generally speaking: the first char of the year) and doesn't get validated. The corresponding node ends up with no date set. All further nodes have the correct date set.

So ... in order to get this mess up and running, I decided to hack date_text_input_value():

function date_text_input_value($element) {
  $form_values = $element['#value'];
 
  // emeidi @ liip fix
  if(is_array($form_values)) {
$input = $form_values['date'];
  }
  else {
$input = $form_values;
  }
  // /emeidi @ liip fix
 
  if (!$element['#required'] && trim($input) == '') {
return NULL;
  }
 
  $value = date_convert_from_custom($input, $element['#date_format']);

  // If it creates a valid date, use it.
  if (date_is_valid($value)) {
    return $value;
  }
  // If that didn't work, try strtotime().
  else {
   $date = strtotime($input, 0);
   if (date_is_valid($date, DATE_UNIX)) {
     return date_convert($date, DATE_UNIX, DATE_DATETIME);
   }
  }
  return NULL;
}

#5

I suggest using node_save() instead of drupal_execute(). The date elements do some complex handling using #process and #validate and it could be quite difficult to get all those values right since you have to build a form element with all the complexities of the form handling taken into account.

On the other hand node_save() it very straightforward -- you need to create a node with the values exactly as they are stored in the database and everything usually works just fine.

#6

Thank you for your suggestion, but switching from drupal_execute() to node_save() won't cure bugs in the Date module, will it? It's still there, buried in this mess ...

Choosing drupal_execute() over node_save() was suggested in a few places:

Using drupal_execute() or drupal_execute_macro() is a nasty, evil, slow, and
ugly way to programmatically create users and nodes. It's also usually the
only way that will reliably work. :-)

[development] programmatic creation of node

Recently I needed to import a small (100-200) node set from an 'old' database to a CCK content type. I used the following code, which serves as a nice example of the drupal_execute() function.

Quick-and-dirty CCK imports

#7

Status:active» closed (works as designed)

Note the rest of the comment you quoted above:

Using drupal_execute() or drupal_execute_macro() is a nasty, evil, slow, and
ugly way to programmatically create users and nodes. It's also usually the
only way that will reliably work. :-) I have, however, run into cases where
it does not. For those, I have to fall back to creating the $node object
myself and saving it. Fortunately I've only had to do that for one-off
imports, so I could hard-code defaults.

There is no real good answer here, not until we get a real Data API in core.
We're working on it. :-)

And my response to Quick-and-dirty CCK imports.

And note what I ran into when I tried it in http://drupal.org/node/258572.

It is not a 'bug' in the Date module that this doesn't work well. It works for simple, uncomplicated fields. It doesn't always work for complicated fields.

nobody click here