Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Use the Symfony event dispatcher for hooks and callbacks #204

Closed
wants to merge 85 commits into from

Conversation

leofeyer
Copy link
Member

This is the PR for #97. Can you please confirm that this is the way to go, so I can adjust the other hooks as well?

@leofeyer leofeyer self-assigned this Apr 15, 2015
@leofeyer leofeyer added this to the 4.0.0 milestone Apr 15, 2015
@Toflar
Copy link
Member

Toflar commented Apr 15, 2015

Looks good to me!! My input: I would place all hook listeners in an extra subnamespace so it becomes Contao\CoreBundle\EventListener\Hooks\InitializeSystemListener. Otherwise the EventListener namespace containing new code already becomes really cluttered with listeners that only provide support for old hooks and will get removed in v5 anyway :)

@leofeyer
Copy link
Member Author

Good point, will change it accordingly.

@aschempp
Copy link
Member

I would suggest to use one class for all hook events. That will make the old stuff much cleaner. Also we only need one service with just a lot of tags.

@leofeyer
Copy link
Member Author

I don't think Insights and Scrutinizer would like that. They already don't like that we have only two controllers with too many methods.

@Toflar
Copy link
Member

Toflar commented Apr 15, 2015

Well, Scruitinizer should not be the issue for code that only provides BC layers. https://scrutinizer-ci.com/docs/reviews/excluding_files_from_analysis

@leofeyer
Copy link
Member Author

I know. Still we should always follow the best practices, because people will look at how we've done things.

@Toflar
Copy link
Member

Toflar commented Apr 15, 2015 via email

@leofeyer
Copy link
Member Author

This will also solve our arguments order problem:

// Call
$strTemp = $this->$callback[0]->$callback[1]($row, $blnWriteToFile, $vars, $parent);

// Usage
public function compileDefinition($row, $blnWriteToFile, $vars, $parent)
{
    // do something
}

But if we are using events, it will all be in the event object:

// Call
$event = new CompileDefinitionEvent();
$event->setRow($row);
$event->setWriteToFile($blnWriteToFile);
$event->setVars($vars);
$event->setParent($parent);

$this->container->get('event_dispatcher')->dispatch('contao.initialize_system', $event);

// Usage
public function compileDefinition(CompileDefinitionEvent $event)
{
    print_r($event->getRow());
}

If we ever want to add or remove parameters, we don't have to stick to an argument order anymore :)

@Toflar
Copy link
Member

Toflar commented Apr 15, 2015

Did you only realize this now? :D

@leofeyer
Copy link
Member Author

No, I just wanted to mention it :)

@leofeyer leofeyer force-pushed the feature/hooks-to-events branch 2 times, most recently from 9869e88 to 381547c Compare April 15, 2015 12:10
@aschempp
Copy link
Member

I'm still for one class, also using event subscribers (see http://symfony.com/doc/current/components/event_dispatcher/introduction.html#using-event-subscribers). Let's discuss that later today.

@leofeyer
Copy link
Member Author

Yes. I have still added another example to my POC to see how it works with parameters.

@discordier
Copy link
Contributor

You might want to have a look how we did it in dc-general.

*
* @return string The root directory
*/
public function getRootDir()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a setter method is missing here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no setter method. The variable is only injected to include the initialize.php file.

@aschempp
Copy link
Member

In addition to setting the event variables from hook references, you also need to set the variables where the event is fired. Otherwise the variables could still not be changed by reference. Example:

// Trigger the getPageLayout hook (see #4736)
$event = new PageEvent($objPage, $objLayout, $this);
$kernel->getContainer()->get('event_dispatcher')->dispatch(ContaoEvents::GENERATE_PAGE, $event);
$objPage = $event->getPage();
$objLayout = $event->getLayout();

@leofeyer
Copy link
Member Author

No, I found a better solution. Check my latest commit :)

@aschempp
Copy link
Member

Not sure if that's not a problem. Now we are deciding wether the variables are passed by reference, instead of the hook developer…

@leofeyer
Copy link
Member Author

The developer will still have to put an ampersand before the argument, otherwise they will not receive the reference. Here's how you can test:

// vendor/contao/calendar-bundle/src/Resources/config.php
$GLOBALS['TL_HOOKS']['modifyFrontendPage'][] = function ($page, $template, $handler) {
    $template = 'fe_foo';

    return $page;
};

The template name will not be changed, therefore fe_page is rendered. However, if you add the ampersand and make $template a reference:

// vendor/contao/calendar-bundle/src/Resources/config.php
$GLOBALS['TL_HOOKS']['modifyFrontendPage'][] = function ($page, &$template, $handler) {
    $template = 'fe_foo';

    return $page;
};

Then you get a Could not find template "fe_foo" exception.

@leofeyer
Copy link
Member Author

I'm going to write the tests tonight.

@bytehead
Copy link
Member

👍 Is it still realistic for 4.1? :)

Conflicts:
	src/EventListener/InitializeSystemListener.php
	src/Resources/contao/classes/FrontendTemplate.php
	src/Resources/contao/classes/RebuildIndex.php
	src/Resources/contao/drivers/DC_Table.php
	src/Resources/contao/library/Contao/Automator.php
	src/Resources/contao/library/Contao/Date.php
	src/Resources/contao/library/Contao/DcaLoader.php
	src/Resources/contao/library/Contao/Search.php
	src/Resources/contao/library/Contao/System.php
	src/Resources/contao/library/Contao/Template.php
	src/Resources/contao/library/Contao/User.php
	src/Resources/contao/library/Contao/Widget.php
	src/Resources/contao/modules/ModuleChangePassword.php
	src/Resources/contao/modules/ModulePassword.php
	tests/TestCase.php
@leofeyer
Copy link
Member Author

Here is the list of the currently available hooks in the core distribution:

  1. activateAccount
  2. activateRecipient
  3. addComment
  4. addCustomRegexp
  5. addFileMetaInformationToRequest
  6. addLogEntry
  7. checkCredentials
  8. closeAccount
  9. colorizeLogEntries
  10. compareThemeFiles
  11. compileArticle
  12. compileDefinition
  13. compileFormFields
  14. createDefinition
  15. createNewUser
  16. customizeSearch
  17. executePostActions
  18. executePreActions
  19. executeResize
  20. exportTheme
  21. extractThemeFiles
  22. generateBreadcrumb
  23. generateFrontendUrl
  24. generatePage
  25. generateXmlFiles
  26. getAllEvents
  27. getArticle
  28. getArticles
  29. getAttributesFromDca
  30. getCacheKey
  31. getCombinedFile
  32. getContentElement
  33. getCountries
  34. getForm
  35. getFrontendModule
  36. getImage
  37. getLanguages
  38. getPageIdFromUrl
  39. getPageLayout
  40. getPageStatusIcon
  41. getRootPageFromUrl
  42. getSearchablePages
  43. getSystemMessages
  44. getUserNavigation
  45. importUser
  46. indexPage
  47. initializeSystem
  48. insertTagFlags
  49. isAllowedToEditComment
  50. isVisibleElement
  51. listComments
  52. loadDataContainer
  53. loadFormField
  54. loadLanguageFile
  55. modifyFrontendPage
  56. newsListCountItems
  57. newsListFetchItems
  58. outputBackendTemplate
  59. outputFrontendTemplate
  60. parseBackendTemplate
  61. parseDate
  62. parseFrontendTemplate
  63. parseTemplate
  64. parseWidget
  65. postAuthenticate
  66. postDownload
  67. postLogin
  68. postLogout
  69. postUpload
  70. prepareFormData
  71. printArticleAsPdf
  72. processFormData
  73. removeOldFeeds
  74. removeRecipient
  75. replaceDynamicScriptTags
  76. replaceInsertTags
  77. reviseTable
  78. sendNewsletter
  79. setCookie
  80. setNewPassword
  81. sqlCompileCommands
  82. sqlGetFromDB
  83. sqlGetFromDca
  84. sqlGetFromFile
  85. storeFormData
  86. updatePersonalData
  87. validateFormField

The highlighted ones have been added already in the PR.

@leofeyer
Copy link
Member Author

As discussed on Mumble, @aschempp wants to try to set up a general service which allows to map events to hooks. If he succeeds, we do not need this PR at all.

@leofeyer leofeyer removed this from the 4.1.0 milestone Oct 28, 2015
@leofeyer
Copy link
Member Author

Closed in favor of #376.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants