I see this error when running drush cr or manually flushing the cache. I have a view with three Data Export displays:

Error: Call to undefined method Drupal\views\Plugin\views\style\DefaultStyle::getFormats() in Drupal\rest\Plugin\views\display\RestExport->collectRoutes() (line 368 of /mnt/www/html/naswastg/docroot/core/modules/rest/src/Plugin/views/display/RestExport.php) #0 /mnt/www/html/naswastg/docroot/core/modules/views/src/EventSubscriber/RouteSubscriber.php(120): Drupal\rest\Plugin\views\display\RestExport->collectRoutes(Object(Symfony\Component\Routing\RouteCollection)) #1 [internal function]: Drupal\views\EventSubscriber\RouteSubscriber->routes() #2 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/Routing/RouteBuilder.php(146): call_user_func(Array) #3 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/ProxyClass/Routing/RouteBuilder.php(83): Drupal\Core\Routing\RouteBuilder->rebuild() #4 /mnt/www/html/naswastg/docroot/core/includes/common.inc(1156): Drupal\Core\ProxyClass\Routing\RouteBuilder->rebuild() #5 /mnt/www/html/naswastg/docroot/core/modules/system/src/Form/PerformanceForm.php(176): drupal_flush_all_caches() #6 [internal function]: Drupal\system\Form\PerformanceForm->submitCacheClear(Array, Object(Drupal\Core\Form\FormState)) #7 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/Form/FormSubmitter.php(111): call_user_func_array(Array, Array) #8 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/Form/FormSubmitter.php(51): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object(Drupal\Core\Form\FormState)) #9 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(585): Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object(Drupal\Core\Form\FormState)) #10 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(314): Drupal\Core\Form\FormBuilder->processForm('system_performa...', Array, Object(Drupal\Core\Form\FormState)) #11 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/Controller/FormController.php(74): Drupal\Core\Form\FormBuilder->buildForm('system_performa...', Object(Drupal\Core\Form\FormState)) #12 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch)) #13 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #14 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #15 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #16 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #17 /mnt/www/html/naswastg/vendor/symfony/http-kernel/HttpKernel.php(151): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #18 /mnt/www/html/naswastg/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #19 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #20 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #21 /mnt/www/html/naswastg/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #22 /mnt/www/html/naswastg/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23 /mnt/www/html/naswastg/docroot/modules/contrib/shield/src/ShieldMiddleware.php(99): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\shield\ShieldMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26 /mnt/www/html/naswastg/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #27 /mnt/www/html/naswastg/docroot/core/lib/Drupal/Core/DrupalKernel.php(657): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #28 /mnt/www/html/naswastg/docroot/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #29 {main}.

CommentFileSizeAuthor
#6 Screen Shot 2018-03-23 at 12.24.42.png332.35 KBwim leers

Comments

brooke_heaton created an issue. See original summary.

wim leers’s picture

\Drupal\views_data_export\Plugin\views\display\DataExport does class DataExport extends RestExport {…}.
And \Drupal\views_data_export\Plugin\views\style\DataExport does class DataExport extends Serializer {…}.

It looks like #2449143: REST views specify HTML as a possible request format, so if there is a "regular" HTML view on the same path, it will serve JSON made changes that caused the already-brittly-defined \Drupal\rest\Plugin\views\display\RestExport + \Drupal\rest\Plugin\views\style\Serializer to change in slight ways that broke views_data_export's subclasses.

Unfortunately, it looks like this module is not actively maintained. Last release in December 2016, and an alpha release at that. No automated testing set up against the current and next core minor. Then this would have been discovered back in October of 2017…

wim leers’s picture

Title: Fatal error on Drupal 8.5 » Fatal error on Drupal 8.5, on a data_export display that uses not the data_export style but the *default* style
Status: Active » Postponed (maintainer needs more info)

@brooke_heaton provided an export of his failing view at #2954768-6: REST views: Uncaught Error: Call to undefined method Drupal\views\Plugin\views\style\DefaultStyle::getFormats() .

The relevant bits are these:

  data_export_1:
    display_plugin: data_export
    id: data_export_1
    display_title: 'Job Description Export'
    position: 5
    display_options:
…
      style:
        type: data_export
…

  data_export_2:
    display_plugin: data_export
    id: data_export_2
    display_title: 'Active Users Export'
    position: 1
    display_options:
…
      style:
        type: data_export
  data_export_3:
    display_plugin: data_export
    id: data_export_3
    display_title: 'Board of Directors Export'
    position: 1
    display_options:
…
      style:
        type: data_export
…
  data_export_4:
    display_plugin: data_export
    id: data_export_4
    display_title: 'Committee Members Export'
    position: 1
    display_options:
      style:
        type: default

Note how the first four all of have display_options[style][type]=data_export. But the last has display_options[style][type]=default.

That last one is problematic. The data_export display builds on top of the rest_export display, i.e. \Drupal\rest\Plugin\views\display\RestExport. But AFAICT this should never have worked, because already since before Drupal 8.0.0 was released did \Drupal\rest\Plugin\views\display\RestExport::collectRoutes() call $style_plugin->getFormats()!

(This is the problem with subclassing existing coupled classes that do not constitute an API — if the coupling between those classes changes, your subclasses need to be updated as well!)

steven jones’s picture

I sort of minimally maintain the Drupal 7 branch.

No automated testing set up against the current and next core minor. Then this would have been discovered back in October of 2017…

Can you point me at some docs for how this should be set up for a contrib module?
Whenever I edit the automated testing settings the forms seem to have changed and there are more labels and options that ever.
It also doesn't help that the interface is well...very Drupally.

wim leers’s picture

StatusFileSize
new332.35 KB

I agree the interface is pretty painful :(

You want something like in the attached screenshot — that's for https://www.drupal.org/project/http2_server_push.

brooke_heaton’s picture

@Wim - any direction on anything I can do here. Is this an error in how I built the view or is this requiring a patch?

brooke_heaton’s picture

Stepping back from this a bit - is the solution to simply implement a better way to generate a csv export View? Seeing that the views_data_export is not actively maintained, perhaps there's a better solution? Might this not make a better alternative? https://www.drupal.org/project/csv_serialization Seems there are some competing modules here.

sseto’s picture

Hey guys,

I'm getting the same issue too...Did anyone get a fix for this? I even uninstalled the module and still have the issue.

EDIT: I was able to fix the issue when I click "serializer" inside my views..Is this some sort of glitch?

Thanks!

alex.bukach’s picture

In our case it happened because of migrated views that originally used XLS data export in Drupal 7 which is not available in Drupal 9. Therefore they used default style plugin instead of the missing XLS one. Switching the style plugin to CSV fixed the issue.

arne_hortell’s picture

In core/modules/rest/src/Plugin/views/display/RestExport.php function collectRoutes

find the line
$formats = $style_plugin->getFormats();

replace with
$formats=false;
if (method_exists($style_plugin,'getFormats'))
$formats = $style_plugin->getFormats();

steven jones’s picture

Related issues: +#3552653: Release 8.x-1.7
steven jones’s picture

Status: Postponed (maintainer needs more info) » Needs work
Related issues: +#3551130: Improve cloning in views to prevent crashes.

Urgh, this really is a core bug, as you can reproduce it with a plain Drupal 11.2 site.

Steps:

  1. Create a new view
  2. Add a page display, and override the default display plugin, but set it to the 'default' plugin, which is called 'Unformatted' in the UI.
  3. Use the 'Duplicate as REST export' functionality to produce another display
  4. Tweak the path of this display so that you can save the view
  5. Save the view
  6. On collecting routes, this will now cause a fatal error, since the Rest Export display plugin assumes that the style plugin is compatible, but it isn't because it's the 'default' plugin and doesn't have a getFormats method.

This is actually related to another VDE issue: #3551130: Improve cloning in views to prevent crashes.

steven jones’s picture

Yeah, Drupal core doesn't bother to validate that a selected style plugin is valid.

I've got some code in https://git.drupalcode.org/project/views_data_export/-/merge_requests/90 that does, and that at least stops you from creating new views with this issue via the views UI. Not sure if that method gets called at other points to stop views that have made it to the config system already, and are incorrect...but honestly you could break lots of things like that.

I think that the fix over there will cover off the most common way to get to this error, and we can work on 'migration' support, and we can also raise the core bug and let that one sail off into the 'never fixed' ether.

steven jones’s picture

Status: Needs work » Closed (won't fix)

Okay, so in #3551130: Improve cloning in views to prevent crashes. I've added some code that will validate the display as having valid style and row plugins, so that'll avoid users getting into this sort of situation I believe.

If some migration framework is simply cobbling together some random YAML and hoping that it'll work in Views, then that's the thing that needs fixing really. You could break lots of Drupal by playing around with config at a very low level. And there's plenty of code that'll break etc.

At least now, if you were to edit the view you'd get some helpful messaging.

I'll raise a ticket against core, explaining the issue etc. and maybe it'll get sorted and in.

I think I'll mark this ticket as a 'won't fix' because I'm not sure there's much we can do here.

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

steven jones’s picture