Add a static class for Smart Date, other contrib compatibility

Created on 23 June 2023, over 1 year ago
Updated 19 July 2023, over 1 year ago

Problem/Motivation

I tried to use this module to provide a datepicker for a filter (min / max) for node's "created" date, but the date popup does not appear. Same for the "updated" date.

Does this module only support date / date range fields?

Steps to reproduce

Proposed resolution

If you agree this would make sense (it does), please change this into a feature request. If I did something wrong, please let me know.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ“Œ Task
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @Anybody
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    The module works by changing the plugin class for the date, search_api_date and datetime filter plugins.

    Looking at \Drupal\views\EntityViewsData::mapSingleFieldViewsData

    They all use the 'date' filter plugin, so in theory, it should work.

    Can you perhaps dump your views data and see whether those columns are set to use the 'date' filter plugin?

    drush php-eval "var_export(\Drupal::service('views.views_data')->get('node_field_data')['created']['filter'])";
    
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Thanks @larowlan, here's my the dump of my view in the "filters" (exposed) area:

    created:
              id: created
              table: node_field_data
              field: created
              relationship: none
              group_type: group
              admin_label: ''
              entity_type: node
              entity_field: created
              plugin_id: date
              operator: between
              value:
                min: ''
                max: ''
                value: ''
                type: date
                granularity: second
              group: 1
              exposed: true
              expose:
                operator_id: created_op
                label: Zeitraum
                description: ''
                use_operator: false
                operator: created_op
                operator_limit_selection: false
                operator_list: {  }
                identifier: created
                required: false
                remember: false
                multiple: false
                remember_roles:
                  authenticated: authenticated
                  anonymous: '0'
                  autor: '0'
                  author: '0'
                  translator: '0'
                  redakteur: '0'
                  content_administrator: '0'
                  manager: '0'
                  administrator: '0'
                min_placeholder: Von
                max_placeholder: Bis
                placeholder: ''
              is_grouped: false
              group_info:
                label: ''
                description: ''
                identifier: ''
                optional: true
                widget: select
                multiple: false
                remember: false
                default_group: All
                default_group_multiple: {  }
                group_items: {  }
    

    The command
    drush php-eval "var_export(\Drupal::service('views.views_data')->get('node_field_data')['created']['filter'])";
    returns:

    array (
      'id' => 'date',
    )

    Can you see any issues here?

    For now, I switched to BEF (which uses an ugly jQuery datepicker) but that's the only module that works to make this a date picker.
    Really strange...

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    How about this

    drush php-eval "var_export(\Drupal::service('plugin.manager.views.filter')->getDefinition('date'))";

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Suuuuuuper good question @larowlan - you nailed it!

    drush php-eval "var_export(\Drupal::service('plugin.manager.views.filter')->getDefinition('date'))";

    array (
      'plugin_type' => 'filter',
      'id' => 'date',
      'class' => 'Drupal\\smart_date\\Plugin\\views\\filter\\Date',
      'provider' => 'smart_date',
    )

    Smart Date is quite common, I guess: https://www.drupal.org/project/smart_date β†’ > 15.000 installations.

    Should we create an issue over there for the conflict? I've had the same issue with date_filter:
    πŸ’¬ Doesn't work with smart_date module Closed: works as designed

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    S comes after D so it wins

  • Status changed to Fixed over 1 year ago
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @larowlan thank you! Would you see this as an issue in smart_date?
    I'm unsure what would be the best way to fix this... but I tend to creating an issue at smart_date, especially because I don't see any effect smart_date has on the filter...

  • Status changed to Active over 1 year ago
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    I'm not familiar with that module, what does it do?

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Looks like it provides a granularity option to the filter

    https://git.drupalcode.org/project/smart_date/-/blob/3.7.x/src/Plugin/vi...

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @larowlan: I created an issue over at smart_date but don't think there's a good technical solution to solve this. Same situation for date_popup: ✨ Integrate with date_popup Fixed

    So from my perspective, the best fix would be to integrate the functionality from both modules into smart_date or core so that users don't run into this.

    Until this is fixed, I'd suggest putting a warning on the module page, linking this issue and the smart_date issue and informing users about incompatibilities.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    I'm not familiar with that module, what does it do?

    Quite common for more complex date / time / calendar handling, e.g. with recurring dates etc. and as you can see by the number of installations, it's widely adopted already.

  • Status changed to Fixed over 1 year ago
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Ok, I'm going to mark this fixed, not much we can do when lots of modules want to have their say.

    I agree, fixing this in core is the best bet.

    See ✨ [PP-2] Use form element of type date instead textfield when selecting a date in an exposed filter Needs work

  • πŸ‡¨πŸ‡¦Canada mandclu

    Smart Date maintainer here. I can see the need to have both capabilities, the granularity and the date popup. I always prefer to leverage existing solutions where they exist, and I also agree that getting the latter fixed in core would be ideal, but there's really no predicting how soon that might land.

    Thinking out loud, maybe a stopgap solution would be to make a sandbox project, something like smart_date_popup. Presumably it would load last of the three modules (date_popup and smart_date being the other two). It could extend the date_popup filter plugin instead of the core class. Or maybe it could extend the Smart Date filter plugin and add the Date Popup trait, and whatever additional code is needed to add the popup.

    Open to any other ideas.

  • πŸ‡¨πŸ‡¦Canada mandclu

    Here's a quick first draft of what I was proposing in my previous comment: https://www.drupal.org/sandbox/mandclu/3370890 β†’

    Seems to work, would love to hear how this works for others.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Thanks @mandclu for the super fast reply. What do you think about integrating the HTML5 datepicker functionality into Smart Date instead, until the core issue is resolved?

    I guess that would be easier to understand for users and all smart_date users would benefit from that.
    Yes, it's another feature on top, but date filters aren't really usable without a datepicker at all, from my perspective ... so why shouldn't smarte_date improve that?

    Looking at the code of date_popup and date_filter, both are more or less simple.

    (We could move the discussion over to the smart_date issue)

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    I'd be happy to bundle this into smart date and mark it as deprecated in favour of that if that made sense

  • πŸ‡¨πŸ‡¦Canada mandclu

    Thinking about this some more, perhaps a more elegant solution would be to expose applyDatePopupToForm as a service, effectively making it an API. Give that it's already in a trait, adding a class to expose as a service would require minimal effort.

    Smart Date could check for this service, and if it exists, call it on the form object. @larowlan if you're on board with this idea, I could create an MR.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    @mandclu I'm happy to do whatever makes sense for smart date, its a bigger module with more installs

  • Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    Waiting for branch to pass
  • @mandclu opened merge request.
  • Status changed to Needs review over 1 year ago
  • πŸ‡¨πŸ‡¦Canada mandclu

    Here's an MR that creates a service wrapper for the existing trait. If this can be committed, I'll add code to Smart Date to look for the service and use it if found.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Playing devils advocate, but could this just be a static class?

    There's no use of $this, so I think so.

    Then you could just use class_exists to see if the class exists and if so, call the static methods

  • πŸ‡¨πŸ‡¦Canada mandclu

    I had tried doing that a while back within Smart Date, but newer versions of PHP seemed to complain about mixing static and non-static code. If that would be your preference I could try it out, though.

  • πŸ‡¨πŸ‡¦Canada mandclu

    I took a look at this again and I don't think it would work as a static class, at least not without some refactoring. The applyDatePopupToForm method in the DatePopupTrait uses $this to retrieve the identifier of the field to modify, and in turn to retrieve the field itself, so it can be modified.

  • Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    Waiting for branch to pass
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    I've refactored it to a static and pushed

    Let me know if that works for you @mandclu and if so I can merge and cut a new release

    You should be able to use it with

    use Drupal\date_popup\DatePopupHelper;
    
    if (class_exists('\Drupal\date_popup\DatePopupHelper')) {
      DatePopupHelper::applyDatePopup($form, $this->options);
    }
    
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10
  • Status changed to RTBC over 1 year ago
  • πŸ‡¨πŸ‡¦Canada mandclu

    Thanks @larowlan, the static class works great. Your changes here are good to go, and I'll merge in the Smart Date changes and cut a new release there too. Appreciate your help with this!

  • πŸ‡¨πŸ‡¦Canada mandclu

    As an update, there is now a new release for Smart Date β†’ which will work with this module's static class.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Thanks, I do contrib module contrib on Wednesdays, so will get this out next week

  • πŸ‡¨πŸ‡¦Canada mandclu

    That sounds great. Thanks again for your work on this!

  • Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    Waiting for branch to pass
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Thanks I'm cutting a 2.0.0 now

    There are BC breaks in the changes so best to be safe

  • Status changed to Fixed over 1 year ago
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024