Skip to content

Conversation

@laoneo
Copy link
Member

@laoneo laoneo commented Aug 27, 2021

Summary of Changes

In media manager we have events for the CUD operations but not for the read one. This pr adds the missing events.

During all events the objects can be manipulated, except the getUrl one. There it is possible for subscribers to provide a new url.

@wilsonge code review as there is nothing to test when all system tests are passing.

Testing Instructions

Open the media manager in the back end.

Actual result BEFORE applying this Pull Request

All is working as expected.

Expected result AFTER applying this Pull Request

All is working as expected.

@dgrammatiko
Copy link
Contributor

I have tested this item ✅ successfully on e5dc8dd


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/35396.

@alikon
Copy link
Contributor

alikon commented Sep 4, 2021

I have tested this item ✅ successfully on 40c3b81


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/35396.

1 similar comment
@dgrammatiko
Copy link
Contributor

I have tested this item ✅ successfully on 40c3b81


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/35396.

@Fedik
Copy link
Member

Fedik commented Sep 4, 2021

@laoneo I have thought about that thing with result for $newUrl, and I think correct would be to get result from the event instead of dispatcher. I suggest you next:

The event class, that have defined URL get/set:

namespace Joomla\Component\Media\Administrator\Event;

class MediaFileUrlEvent extends AbstractEvent
{
    public function __construct($name, array $arguments = array())
    {
        parent::__construct($name, $arguments);

        // Check for required arguments
        if (empty($arguments['url']) || !is_string($arguments['url']))
        {
            throw new BadMethodCallException("Argument 'url' of event $name is empty or not of the expected type");
        }
    }
    public function getUrl(): string
    {
        return parent::getArgument('url');
    }

    public function setUrl(string $url)
    {
        parent::setArgument('url');
    }
}

Triggering the Event:

$url   = $this->getAdapter($adapter)->getUrl($path);
$event = new MediaFileUrlEvent('onFetchMediaFileUrl', ['url' => $url]);

Factory::getApplication()->getDispatcher()->dispatch(
  $event->getName(),
  $event
);

$newUrl = $event->getUrl();

Plugin listener:

public function onFetchMediaFileUrl(MediaFileUrlEvent $event)
{
    $event->setUrl('blabla/my/url.jpg');
}

As you see it more straightforward ;)

@nibra @HLeithner please confirm, or maybe I wrong

@nibra
Copy link
Member

nibra commented Sep 4, 2021

Regarding 'get result from the event instead of dispatcher':
This is more a matter of taste. One big source of confusion is that in Joomla, calling a plugin is always called triggering an event, although plugins can be event handlers but also just hooks.

Events are usually just emitted without expecting (or waiting for) results. Other parts of the software or even other systems may or may not react on those events.

Hooks are a technique to inject code - they get some input data and have a return value. Thus they can alter values or provide new data.

In Joomla, we have no distinction between those two approaches. We just have plugins that might or might not return values. In Joomla, we're using events to communicate with the plugins. If a plugin returns a value, it is expected that the value is returned by the dispatch() method.

In the present case, both @laneo's and @Fedik's approaches are valid an can be considered 'clean', while @laoneo's is more 'Joomla like'.

@Fedik
Copy link
Member

Fedik commented Sep 4, 2021

@nibra thanks for clarification

@laoneo
Copy link
Member Author

laoneo commented Sep 6, 2021

So boys, I hope now everybody is happy and we can get it merged.

@Fedik
Copy link
Member

Fedik commented Sep 6, 2021

@laoneo I made PR to your branch,
then it should be good

@laoneo
Copy link
Member Author

laoneo commented Sep 6, 2021

Merged

Fedik and others added 2 commits September 6, 2021 19:42
* Class per event

* Argument validations

* global
@laoneo
Copy link
Member Author

laoneo commented Sep 7, 2021

Event calls are now the same across all methods. Can be tested now again.

@HLeithner
Copy link
Member

The event set functions need validators, Like is_array at least for setFiles and is_string for setUrls like in the constructor. Also the parameters must be Immutable (which is already done in the events).

@laoneo
Copy link
Member Author

laoneo commented Sep 23, 2021

There are no set functions in the new events.

@HLeithner
Copy link
Member

There are no set functions in the new events.

in this case it makes no sense to use return $event->getFiles(); when it's not planned that t he values can be changed by a plugin.

@HLeithner
Copy link
Member

Re reading your opening post you say

During all events the objects can be manipulated, except the getUrl one. There it is possible for subscribers to provide a new url.

doesn't that mean the plugins should/can change the event attributes?

@laoneo
Copy link
Member Author

laoneo commented Sep 23, 2021

You can change by setArgument() which is a public function in the event. It is intended to give the plugin full control over the returned data. Better would be to make a proposal, instead of getting into an argument. All I want is to have these events in MM without over engineering the whole thing.

@Fedik
Copy link
Member

Fedik commented Sep 23, 2021

@laoneo I think @HLeithner means something like there:

/**
* Setter for the subject argument
*
* @param JTableInterface $value The value to set
*
* @return JTableInterface
*
* @throws BadMethodCallException if the argument is not of the expected type
*/
protected function setSubject($value)
{
if (!\is_object($value) || !($value instanceof JTableInterface))
{
throw new BadMethodCallException("Argument 'subject' of event {$this->name} is not of the expected type");
}
return $value;
}

It does not have setter for subject, however the Event class will call protected setSubject, to validate the subject if someone will do $event->setArgument('subject', $foobar);

So we have validation in both cases, in __constructor and setArgument

@HLeithner
Copy link
Member

You can change by setArgument() which is a public function in the event. It is intended to give the plugin full control over the returned data. Better would be to make a proposal, instead of getting into an argument. All I want is to have these events in MM without over engineering the whole thing.

It's not about over engineering it's that the new event system should be clean and safe, that's the reason for validation.

Fedir already wrote it.

Adding

    public function setUrl(string $url)
    {
        if (empty(url))
        {
            throw new BadMethodCallException("Argument 'url' is empty");
        }
        parent::setArgument('url');
    }

would fit the needs (at least for the one plugin).

@Fedik
Copy link
Member

Fedik commented Sep 23, 2021

@HLeithner there a caveat,

public function setUrl(string $url)
{
  if (empty(url))
  {
    throw new BadMethodCallException("Argument 'url' is empty");
  }
  parent::setArgument('url');
}

This will lead to infinity loop ;)
The method should be protected.

@laoneo
Copy link
Member Author

laoneo commented Nov 16, 2021

Events have been renamed. @HLeithner can you please fix your part please.

@laoneo
Copy link
Member Author

laoneo commented Nov 23, 2021

@HLeithner can you please have a look on the errors?

@Fedik
Copy link
Member

Fedik commented Dec 5, 2021

I have tested this item ✅ successfully on c42a582


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/35396.

@Fedik
Copy link
Member

Fedik commented Dec 5, 2021

All seems works now, @HLeithner please confirm when you will have a min.

@HLeithner
Copy link
Member

thanks @laoneo for fixing it your self and simplify the validation. thanks @Fedik for testing.
It looks ok for me. Maintainers have to decide in which branch it should be merged @bembelimen

@BPBlueprint
Copy link

I have tested this item ✅ successfully on c42a582


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/35396.

@alikon
Copy link
Contributor

alikon commented Dec 11, 2021

RTC


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/35396.

@joomla-cms-bot joomla-cms-bot added the RTC This Pull Request is Ready To Commit label Dec 11, 2021
@bembelimen
Copy link
Contributor

I'm pretty sure, this should go into 4.1.

@laoneo laoneo changed the base branch from 4.0-dev to 4.1-dev December 11, 2021 10:57
@laoneo
Copy link
Member Author

laoneo commented Dec 11, 2021

Initially the changes have been small so it made sense at that time to go into 4.0. Now it makes more sense for 4.1. Rebased.

@laoneo laoneo changed the title [4.0] Add some events when fetching media data [4.1] Add some events when fetching media data Dec 11, 2021
@Quy Quy removed the PR-4.0-dev label Dec 11, 2021
@bembelimen
Copy link
Contributor

If you allow maintainer to change your code, I could trigger the sync with the base branch and merge. So for you you have to do it @laoneo , could you please do it?

@laoneo
Copy link
Member Author

laoneo commented Dec 16, 2021

@bembelimen
Copy link
Contributor

Ah ok, thx.
Would you mind updating it so I can merge?

@laoneo
Copy link
Member Author

laoneo commented Dec 16, 2021

Did already

@Quy Quy added this to the Joomla 4.1 milestone Dec 16, 2021
@bembelimen bembelimen merged commit c64bee8 into joomla:4.1-dev Dec 16, 2021
@joomla-cms-bot joomla-cms-bot removed the RTC This Pull Request is Ready To Commit label Dec 16, 2021
@bembelimen
Copy link
Contributor

Thx

@laoneo laoneo deleted the j4/mm/file/events branch December 17, 2021 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.