Now that #86462: add backend support for cck date fields has landed, we have a slight usability problem that none of the CCK date support works if event.module is still enabled. The reason is from the original design of the event/date "backend" abstraction layer, where there's a set of functions that are defined in either the event*.inc or date*.inc include file that's loaded via _signup_initialize_event_backend();

However, a big part of #86462 was making it so that these functions are almost all passed in a node type argument (or at least a field name to use). So, in principle, there's no reason we couldn't rename these backend functions, and have a "switchboard" that invokes either the date* or event* function based on the content type or field name we're working with. It'll take a bit of redesign, renaming some functions, etc, but it shouldn't be that hard.

That said, I don't feel that strongly about getting this working -- I really don't think a lot of sites will be running both event and date. So, I think I'll spend at most 30 minutes on this and see how far I get. If it's done, I'll post the patch and consider getting it in before 5.x-2.6. If it's a can of worms, I'll just punt and let someone who cares about supporting both backends pick up the torch and I'll commit if/when the code is ready. ;)

Comments

dww’s picture

Status: Active » Needs work
StatusFileSize
new29.85 KB

This is only lightly tested, and there are some parts that still aren't handled right, but I wanted to post the work-in-progress for initial feedback on the approach. To summarize:

- Adopted "scheduler" as the terminology for the "event backend", to avoid using "event" to mean anything other than "event module"

- Added a new includes/scheduler.inc file for code related to deciding which scheduler to use for a given node or type, and for all the "switchboard" functions.

- Replaced signup_node_has_date() with _signup_get_node_scheduler(), and signup_node_type_has_date() with _signup_get_node_type_scheduler(). Both of the new functions return 'none', 'date', or 'event', so you know not just if it's TRUE/FALSE, but if it's TRUE, which scheduler to use for that node type.

- Moved signup_site_has_dates() into includes/scheduler.inc, so we no longer should need includes/event.none.inc at all.

- Prefixed all the scheduler backend functions in includes/(event|date).* to use _signup_(event|date) so that there's no function conflicts if you include more than one scheduler backend at once.

TODO:

The crazy query builder stuff doesn't actually all work with both date and event enabled. ;) I think the scheduler-specific queries for event are written such that they assume {event} is the only table in town.

A) For autoclose and reminder email, I think it might be cleaner to just build and execute separate queries for each node type, instead of trying to munge it all together into a single query.

B) The user signup listing at user/N (if you don't use views) hasn't been ported to the new system at all.

C) Not sure what to do about the signup admin overview page (admin/content/signup). Currently it gets confused about what value to put in that first column, and everything is coming out [Untimed].

dww’s picture

StatusFileSize
new44.01 KB

New patch:

A) Mostly fixed -- we now just do separate queries for each content type. However, I'm getting duplicates in my testing.

B) Haven't started this.

C) Mostly fixed. See #328295: event_join() ignores $type argument ;) The only bummer is that since the start time column could now potentially be coming from many different tables, I don't know how to get tablesort_sql() to sort on that. We had this problem with the date support in the first place. So, this is a minor regression for sites using event, since they'd no longer be able to sort by start time. Not sure what to do about this, if anything.

While I was at it, I fixed up the API to the scheduling backends to just do everything based on node type, and CCK can do the somewhat funky field stuff it wanted. Previously, it was a weird mix of passing around signup date fields or node types, and that led to some bugs/confusion. I think it's a lot cleaner this way.

dww’s picture

StatusFileSize
new44.26 KB

I just had a few more minutes to think about this between other commitments. New patch fixes (C) for sites that don't have date at all by knowing that if date isn't enabled, we can sort on e.event_start on the admin page. We could probably be smarter here and even allow sorting in the date case if there's only 1 signup-enabled content type with date fields, but that's for another day. ;) So, I think (C) is done.

All that remains is debugging the duplicate reminder + autoclose stuff (probably an easy SQL bug or something) and figuring out what, if anything, to do about (B).

dww’s picture

Assigned: Unassigned » dww
StatusFileSize
new45.31 KB

Just got back and spent a little more time on this. The current patch fixes the last of the known problems with autoclose and reminder emails. Since we're doing separate queries for each signup enabled node type, I rewrote the queries a bit so that they always include a WHERE n.type = '%s' and added the type name as a query argument. Also made sure we always select n.type in our queries, so that _signup_get_node_scheduler() always gets something with a 'type' member, even if it's not a fully loaded node object.

So, all that remains is (B). I'm not sure it's worth spending much time on, since that code only appears if you're not using views, and I'm planning to make views a requirement in the near future anyway. But, I think I'll spend a few minutes right now and see if I can come up with something relatively quick and easy. Stay tuned.

p.s. I might as well assign myself to this issue, I'm clearly working on it. ;)

dww’s picture

Priority: Normal » Critical
Status: Needs work » Needs review
StatusFileSize
new49.64 KB

To solve (B), I decided to massively simplify the code by introducing a minor regression in functionality for the poor fools who aren't running views: the nasty hard-coded signup schedule on the user profile is no longer sorted by the start time on event or CCK date nodes. Instead, we just sort on the nid, which is probably a pretty close approximation to sorting by start time, anyway, and that requires no help from the scheduler backend(s). Similar to the signup admin form, I'm not even sure *how* you'd sort across multiple node types with start times from different tables. Yuck.

Also, the start time is no longer displayed at the signup schedule on user/N/signups. There are 2 possible solutions for sites that want this data:

1) Turn on views module and customize the default views for this however you want.

2) Implement your own version of theme_signup_user_schedule() and display whatever you want (since on that page, each node is already fully loaded).

I think this is acceptable, and it really simplifies things (removes a few functions from the scheduler API, etc). Note that the existing code isn't fully implemented, anyway (some of the functions were missing from event.5x-2.inc for example).

Therefore, all the known problems from this issue have been addressed, so this is now ready for review. Note, the patch is huge, but I don't see any way to split it up any smaller than this. Furthermore, it actually rips out more code (481 lines) than it introduces (385 lines), and IMHO the code makes more sense and is easier to understand, especially for the scheduler backend stuff.

dww’s picture

StatusFileSize
new49.22 KB

Whoops, I left a switchboard version of signup_list_user_signups_sql() in includes/scheduler.inc in the last patch. Now gone.

dww’s picture

StatusFileSize
new49.3 KB

Fixed an unfinished code comment.

shanefjordan’s picture

Just a quick glance through the code and one comment I have is that you are checking the node type to be equal to 'event' to determine if it is a date or event node. The one issue I could possibly see with that is that if someone is using the date module and create a content type to hold all of their events and calls it 'event' then it will try to use the event module. However, they are really using the date module, just a content type called event.

I think it may need wrapped to say, if they have event and the node type equals event, use event. That way, it should still use date if the node type is event.

I thought of this because I started with the event module and am switching to the date module. Since I currently have a node type 'event', I was going to continue using that same node type with the date module and just add the date fields to it.

- Shane

dww’s picture

@shane_jordan: Thanks for looking at the code. However, I didn't (intend to) write the code how you describe. Don't be confused by the return value from _signup_get_node_scheduler() and _signup_get_node_type_scheduler(). Those indeed return 'event' vs. 'date' (or 'none'), but if you look at how they're implemented, you'll see that they handle CCK node types called 'event' that have CCK date fields and are signup-enabled...

That said, it's possible I missed a spot. Can you post any snippets from the patch that makes you think it works the way you described in your comment?

Thanks,
-Derek

shanefjordan’s picture

function _signup_get_node_scheduler($node) {
  switch (_signup_get_node_type_scheduler($node->type)) {
    case 'event':
      return _signup_event_get_node_scheduler($node);
    case 'date':
      return _signup_date_get_node_scheduler($node);
    default:
      return 'none';
  }
}

function _signup_event_get_node_scheduler($node) {
  return isset($node->event_start) ? 'event' : 'none';
 }

Doesn't this say that if it is event, get the event start date/time. Then, if there isn't a start date/time it would return none. Once again, I very well could be reading it wrong.

- Shane

dww’s picture

Right, you're reading it wrong. ;) _signup_get_node_type_scheduler() tells you the scheduler to use for a given node type:

/**
 * Determine which scheduler backend to use for the given node type.
 *
 * @param $type
 *   Machine-readable name of the node type to test.
 *
 * @return
 *   'event' to use the event.module, 'date' for the date.module, or 'none' if
 *   the node type is untimed.
 */
function _signup_get_node_type_scheduler($type) {
  if (module_exists('event') && variable_get('event_nodeapi_'. $type, 'never') != 'never') {
    return 'event';
  }
  if (module_exists('date')) {
    $date_field = variable_get('signup_date_field_'. $type, 0);
    if (!empty($date_field) && $date_field != 'none') {
      return 'date';
    }
  }
  return 'none';
}

In english: "which backend scheduler system should I use for a node type called 'event'?", the answer can be 'event' (event.module), 'date' (date.module), or 'none' (this node doesn't have time, at least not as far as signup.module is concerned).

It does mean that if you have event.module on your site, and you have a node type that has both event fields and CCK date fields, signup.module assumes you're using the event fields for the purpose of signup. I think that's a reasonable assumption in the interest of trying not to overly complicate the code or the UI.

shanefjordan’s picture

Thank you, I knew i was missing some aspect of it. I agree that it would be a reasonable assumption to assume event if it has both event and date. At some point in time, there has to be some stop to it :)

Great work and turn around time!

dww’s picture

Status: Needs review » Fixed

Decided no one's actually going to carefully review this entire patch. ;) So, I committed to HEAD. If interested parties could test HEAD as much as possible in various combinations of event vs. date vs. nothing and views or not, it'd be lovely. If you find a problem, please just open a new issue about it. Thanks.

karens’s picture

Sorry I haven't been much help here, but I'm glad to see you got things working. I agree it's most likely to get put through the wringer if you commit it.

Also I am one of those people using a node called 'event' for my dates, because they started out as Event module nodes and I didn't want my links to break so I just added date fields to the same nodes. So there are logical reasons for that. But it sounds like that's not a problem. I actually do sometimes run with both Date and Event and both fields on those nodes, but that's just because I'm a crazy person trying to figure out what is broken, I totally agree that we don't have to support that scenario :)

dww’s picture

"I am one of those people using a node called 'event' for my dates ... So there are logical reasons for that."

Absolutely. The last thing I would do is hard-code anything based on the name of the node type. ;) See #328647: Purge "event" from the UI (and code) unless we're talking about event.module in fact, about fixing places in the user-facing text where the code used to use 'event' and now uses the human-readable node type name.

dww’s picture

Whoops, this introduced a bug I just noticed. If you visit admin/content/signup and set the signup status filter to either 'Open' or 'Closed', you get a bunch of PHP errors from $where not being defined. Committed the fix to HEAD and DRUPAL-5--2:
http://drupal.org/cvs?commit=151224
http://drupal.org/cvs?commit=151225

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.