Split from #1545618: Various state issues

Allow states to be associated on a per registration-type basis.

Implementation would likely involve inventing bundles for registration_state entities, where bundle names are bundles of registration_type. Removing the default_state field from registration_state, and moving it to a new column of registration_type would also be required.

An observation, if this was to be implemented the state system would begin to resemble the field system (fields, instances etc). I still have the opinion that commandeering a field attached to registration types may serve better. If implemented using fields, restricting roles who can modify state would use something like field_permissions.

Comments

dpi’s picture

As an in production use case of using fields instead of a the state system:

I have two fields on registration types, which would also be served well by this state system:

attending (set by registration owner): can set whether the user will be attending.
attended (set by entity owner): can set if the registration was used, ie: whether a user 'attended' the entity.

levelos’s picture

Implementation would likely involve inventing bundles for registration_state entities, where bundle names are bundles of registration_type. Removing the default_state field from registration_state, and moving it to a new column of registration_type would also be required.

I think we would just need to add a registration_type col to the states schema, and default state would have to be unique across rows with the same registration type.

Re: fields, it's great to explore, but I'm still skeptical. E.g., how would we handle designating which states should be "active" and with that approach?

dpi’s picture

I dont think we should throw away the entirety of the existing state code, much of the UI would be changed and made optional. However if an administrator decides to add state to a registration type, then they get bonus functionality.

I'll arrange some proof of concept code in the near future.

dpi’s picture

Status: Active » Needs review
StatusFileSize
new44.44 KB

Well, here's my shot at doing states as fields.

Lots of notes regarding the attached patch.

Schema

  • Remove {registration_state}.default_state.
  • Remove {registration}.state: State is held in field system.
  • Add {registration_state}.registration_type
  • Rename show_on_form to hidden

Forms

  • Remove state element on registration_form

Fields

  • New field 'registration_state'
  • New formatter, and widget created for 'registration_state'
  • Default value can be set with regular field form, instead of [global] table column.

## Builtin States

  • Automatically create builtin states when a registration_type is created.
  • Automatically delete builtin states when a registration_type is deleted.

Misc

  • Remove various mentions to Registration::state
  • Remove various mentions to {registration_state}.default_state
  • Rename show_on_form to hidden.
  • Removed state creation on install, moved to when a registration_type is created.
  • Added CONSTANT for the three builtin states.
  • Add edit link to each registration state in administration
  • Change registration_type_load() to load by id as it is does the same thing as registration_type_load_by_name().
  • various other related small changes
  • If a registration type has a state field attached to it, then the active rules apply to count and broadcast. If there is no state field, then all registrations on the host entity are recognised.

Additional Questions

  • Need to explain what active means to users, and why broadcasted emails and entity capacity are only processed with active states. 'active' is very vague.
  • Entity capacity should be a column like: counts towards total or 'counts'?
  • What if I want to send an email all registrations? even if they do not have a state, or their state is not active?

None of this has tests (yet). And there are some very minor things that need to be cleaned up.

Patch is diffed from c6eaa1ecbbb3706eb7c7e929d88d9ca4c8870081.

Whether or not this is actually implemented, I think the state system needs more cleanup before it is ready for prime time.

It would be great to get some feedback on any of this.

dpi’s picture

StatusFileSize
new144.04 KB

Who doesn't love pictures?

levelos’s picture

Status: Needs review » Needs work

@dpi, thanks for your work on exploring this solution. I couldn't apply the patch cleanly, and received loads of errors after cleaning it up to apply enough to update, including calling non-existent functions and like. Taking it further, I was able to create a state, but there was no default state field applied to registration bundles. After I added one, I had two state fields appearing on the form.

Mind taking another pass at it so we can get a clear sense of what you're proposing?

dpi’s picture

Perhaps check out the above commit and apply the patch on a new Drupal install as it will mess with your schema.

I'll work on rerolling against HEAD in the meantime.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new66.99 KB

This patch is against HEAD, ee749ff67bd8509cc80dcdbbcb8450912be9d824.

Like I said, schema changes. Recommend a new install since there's no upgrade path included.

levelos’s picture

Status: Needs review » Needs work

@dpi, thanks this applied, although there are lots of spacing issues with the patch. Not saying that to be obstinate / anal (;), just much harder to review the patch.

I also don't see a state field being added when a new registration type is being created.

dpi’s picture

Right, the state field instance is not automatically created, I thought this would be by design. It wouldnt be hard to do this programmatically. The code will operate regardless of whether there are any states on a registration type.

Its not complete. Needs to be checked for coding style, add tests etc. Specifically, what do you mean by spacing issues?

levelos’s picture

Specifically, what do you mean by spacing issues?

Indentation changed (incorrectly) in every modified file. E.g.,

function registration_field_extra_fields() {
  // expose the email property on the fields and display settings forms.
  $extra = array();
  foreach (registration_get_types() as $type => $reg_type) {
    $extra['registration'][$type] = array(
      'form' => array(
        'anon_mail' => array(
          'label' => t('Email'),
          'description' => t('Registrant\'s email address.'),
          'weight' => 0,
    ),
    ),
      'display' => array(
        'mail' => array(
          'label' => t('Email'),
          'description' => t('Registrant\'s email address.'),
          'weight' => 0,
    ),
        'host_entity_link' => array(
          'label' => t('Entity Link'),
          'description' => t('Link to host entity.'),
          'weight' => 0,
    ),
        'created' => array(
          'label' => t('Created'),
          'description' => t('When the registration was created.'),
          'weight' => 0,
    ),
        'updated' => array(
          'label' => t('Updated'),
          'description' => t('When the registration was updated.'),
          'weight' => 0,
    ),
        'slots' => array(
          'label' => t('Slots Used'),
          'description' => t('How many slots were used in this registration.'),
          'weight' => 0,
    ),
        'author' => array(
          'label' => t('Author'),
          'description' => t('User who created the registration.'),
          'weight' => 0,
    ),
        'user' => array(
          'label' => t('User'),
          'description' => t('User associated with this registration.'),
          'weight' => 0,
    ),
        'state' => array(
          'label' => t('State'),
          'description' => t('State of the registration.'),
          'weight' => 0,
    ),
    )
    );
  }
dpi’s picture

Wow. weird. IDE bug of the day.

dpi’s picture

StatusFileSize
new47.75 KB

I apologise.

levelos’s picture

Thanks @dpi, applied clean and some great ideas in there. I see the benefits of the hybrid field approach, but still not sure. Below are some issues and thoughts.

  • From my perspective, a registration needs to have a single, canonical, state. Otherwise, well, how do you know what state it's in? I don't think basing it on weight is sufficient.
  • Similarly, we'd need to prevent adding more than one state field to registration bundles.
  • I think there should at least be an option to automatically add state fields to registration bundles.
  • Why the refactor of registration_states() to exclude a condition parameter? Seems less efficient and forces you to call EFQ directly in several places rather than using the API. Very minor point, but why also move them to a different file? Makes patch review harder ...
  • registration_states_active() is testing for the hidden rather than active flag().
  • What is registration_get_state_id() for?
  • I think removing the active state filter from broadcast forms decreases utility for most use cases. The point is to email people who are registered for an event. If there state is, say, "canceled", we don't want to include them. I can see an additional form element allowing admins to select which states to include in the broadcase.
dpi’s picture

  • From my perspective, a registration needs to have a single, canonical, state. Otherwise, well, how do you know what state it's in? I don't think basing it on weight is sufficient.
  • Similarly, we'd need to prevent adding more than one state field to registration bundles.
  • I think there should at least be an option to automatically add state fields to registration bundles.

Can all be solved by settings the state field type property 'no_ui' to true. Creating a field on install, and automatically attaching instances of this field to bundles.

A constant for the one canonical state field name would be created for this.

  • Why the refactor of registration_states() to exclude a condition parameter? Seems less efficient and forces you to call EFQ directly in several places rather than using the API. Very minor point, but why also move them to a different file? Makes patch review harder ...

It just loads every state into memory, leaving conditionals to be done in code. The static caching for conditionals was very quirky, I've never seen such code before. If there is conditionals, then do it uncached? Creating new EFQ's arn't that hard ;)

Arguably, its unlikely there will be an excessively large state table.

registration_states doesnt have to be in entity.inc. Although I believe it makes sense since its an entity utility function.

  • registration_states_active() is testing for the hidden rather than active flag().

You're right.

  • What is registration_get_state_id() for?

It was for the admin section, but I realised I didnt need it. Scrap it.

  • I think removing the active state filter from broadcast forms decreases utility for most use cases. The point is to email people who are registered for an event. If there state is, say, "canceled", we don't want to include them. I can see an additional form element allowing admins to select which states to include in the broadcase.

Thats fine, but per #4. A definition of 'active' needs to be exposed in the UI.

I figured adding an element in broadcast would be covered by a different issue. I removed the state business from registration_send_broadcast() because it was relevant.

dpi’s picture

StatusFileSize
new54.32 KB

Changes since last patch. Taking into account IRC discussion.

  • Added states parameter to registration_send_broadcast().
  • Added tag to EntityFieldQuery in registration_send_broadcast().
  • Made registration_state field_type have no_ui
  • Creates field on hook_enable
  • Creates field instance on registration_type insert
  • Deletes field on uninstall
  • Add upgrade path (rename before commit!)
  • Introduced constant for state field.
  • Modified broadcast form to include states
  • Reasonable defaults for broadcast state element.
  • Added helper to get all states of a host, regardless of which state is active. See #1553122: Changing a host entities registration type / Helps with #1565504: Support multiple registration fields per host entity

Patch is inclusive of previous patches.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new54.43 KB

Merged with 7.x-1.x
Added schema upgrade path.
And various other minor issues I have found.

jerdavis’s picture

This sounds very promising, particularly with some of the broadcast changes you mention in the last update. What's the state (no pun intended) of review on this? I'll probably be testing this patch early next week as this will potentially cover some needs for a client of ours.

Thanks!

Jeremiah

jerdavis’s picture

Status: Needs review » Needs work

Hi DPI,

I'm not having a lot of luck applying this patch. The patch doesn't apply to 7.x-1.x HEAD (of course). I was able to apply it with warnings to a checkout of 7.x-1.x from commit d720a0a4d29debb941831d77637d6de903f58f92 (May 14th from Brandon).

I then attempted to enable Registration on a clean Drupal install.

When attempting to enable Registration I get:

FieldException: Attempt to create a field of unknown type <em class="placeholder">registration_state</em>. in field_create_field() (line 110 of /www/managed/managed/drupal/releases/drupal-7/gose/drupal/modules/field/field.crud.inc).

This leaves me unable to create registration states or registration types. Creating a registration type results in:

ieldException: Attempt to create an instance of a field registration_state that doesn't exist or is currently inactive. in field_create_instance() (line 457 of /www/managed/managed/drupal/releases/drupal-7/gose/drupal/modules/field/field.crud.inc).

I'm really interested in seeing this move forward personally, your description above makes this sounds like a great direction for State handling in the module. I'd be interested to hear more from the maintainers about the direction and future of this. It'll probably be a bit of work by DPI or anyone else to bring this up to date with other changes that have been committed so it might be nice to hear more about the acceptance of the suggested changes?

Thanks for your work DPI, I'm really hoping this moves forward!

Jeremiah

dpi’s picture

@jerdavis Thanks

As you suspected, the patch relies on an older HEAD. If you would like to experiment with it, it is best to install Drupal and Registration new and checkout directly from my Git sandbox:

Branch 'states-as-fields-new' from http://drupal.org/sandbox/danph/1423784

I will bring this patch up to speed if there is still interest from @levelos et all.

dpi’s picture

Title: Restricting states per registration type » States per registration type / states as fields
Status: Needs work » Needs review
StatusFileSize
new54.21 KB

Reroll (also pushed to sandbox)

shawn dearmond’s picture

Status: Needs review » Needs work

Patch needs to be rerolled. It fails to apply.

socialnicheguru’s picture

i could not get it to apply cleanly to test either

shawn dearmond’s picture

StatusFileSize
new52.68 KB

Okay, I **MANUALLY** applied this patch to 7.x-1.x. It is now re-rolled, and the attached patch should now apply.

However, as I feared/expected, it still needs considerable work. For instance, when I enable the module now, I get:

FieldException: Attempt to create a field of unknown type <em class="placeholder">registration_state</em>. in field_create_field() (line 110 of /path/to/drupal/modules/field/field.crud.inc).

And tests can't be run. It gives a similar error.

shawn dearmond’s picture

Issue tags: +Needs tests
StatusFileSize
new53.58 KB

My bad. I forgot a chunk of the code.

Attached is a better patch that not only applies, but actually works... mostly.

I'll keep this as "needs work" because 13 tests now fail. Also, tests should probably be written for the new functionality.

jerdavis’s picture

Checking in on this. More flexible registration would be a great thing to have, and while the new wait list functionality gets part way towards what we're looking for, it's not quite there. The project this is related to isn't completely ready to go - so we've been waiting and hoping these tools would mature more. At some point in the near future we'll probably be getting rolling though, and I'll need to decide how best to move forward.

That may include working on this patch, but I'd only want to invest that kind of time here if there's a high likelyhood of the work being accepted. All that to say, what are the maintainers feelings on this approach? I took Shawn's work on it in September as a positive sign, but hit hasn't been touched since and things like the waitlist and http://drupal.org/node/1871570 have been developed around this, rather than finishing this work first (likely making the implementation of this state handling rewrite more complex).

Just looking for some input here so I can judge how best to proceed when the time comes.

Thanks!

Jeremiah

levelos’s picture

@jerdavis, this is not hight our list nor have we heard much of outcry for adding this feature. I'm more inclined towards the states per type change than using fields for states at this point. So a patch addressing the former w/o the latter would certainly get serious considerations. Thanks for getting involved!

igorik’s picture

I am a big fan of this work, thinking that could be useful to have registration states for reach registration type, not same for every registration types on whole site.
Hope it will be working soon and it could be integrated into Registration core module.

Thanks for your work, guys

igorik’s picture

Issue summary: View changes

field per

rattusrattus’s picture

Issue summary: View changes

If anyone is looking to have a default state per registration type, check out #2055145: Allow different default statuses for different registration types

caxy4’s picture

As @ratface mentions - #2055145: Allow different default statuses for different registration types has been resolved, provides the ability to set a default state per registration type (if none is set, the global default registration state will be used), and will be available in the upcoming 7.x-1.4 release.

igorik’s picture

this sounds good! Looking forward to new release! :)

john.oltman’s picture

Version: 7.x-1.x-dev » 3.0.x-dev
Status: Needs work » Closed (works as designed)

This is supported by the 3.x version of the module. Each registration type can have a different workflow.