0

Simply put: I need to sort an array of objects based on a specific value of a specific array element inside a class property.

This would be great, if it worked: Psuedo code that illustrates what I need

In this picture, the code illustrates what I want: I want to be able to tell usort to look in a specific array element and find the priority key, and sort based on that integer value.

So, for a given hook (hook-foo), I would need the comparison to be done on:

 $plugin->hooks['hook-foo']['priority']

For another hook (hook-bar), for which the same plugin might act upon, I need the sort to look at:

 $plugin->hooks['hook-bar']['priority']

if usort supported me sending an arbitrary argument to it, this would be solved. But, the code pictured below was written to illustrate my point and then tested because "maybe it will work". It didn't.

How do I rearrange this to get the sort I need?

(Note: Plugin::hooks is an array of arrays and represents all the metadata required to execute a plugin on a given hook. So, it may contain 'hook-foo' and 'hook-bar', which do not execute at the same time. It may also contain one or the other, or... neither.)

Edit: Here are the example structures, which may help illustrate my point. This shows 2 of 14 plugins loaded.

Example of two plugins

You can see that each plugin responds to multiple different hooks.

So, if I wanted to control the order for a given hook, I should only have to change the priority of that hook.

For example, here: you can see the cli-init hook fires a method of the class declareMySelf, which simply says: "Plugin XYZ loaded" in the command line interface. Both of the priorities are 50, so it will display them in whatever order the system finds the plugins.

But, if I wanted to display "PHP Mailer loaded" BEFORE I display "Config / Settings management loaded", all I should have to do is drop the PHP Mailer plugin priority to 40.

7
  • 1
    Seriously - a printscreen? Commented Dec 30, 2015 at 19:21
  • The brute force solution is having one method for each different key. Are these hooks a well known set or they are a potentially infinite set? Commented Dec 30, 2015 at 19:23
  • Maybe set a global variable (for the hook) juste before calling usort and get the global within sortByHookPriority... (but this is ugly) Commented Dec 30, 2015 at 19:24
  • @HenriqueBarcelos Brute force won't work. This is a potentially infinite set. Commented Dec 30, 2015 at 19:26
  • 1
    An intermediate approach between global variables and brute force would be having a property within the object that would hold the value of the key currently used to sort. Commented Dec 30, 2015 at 19:28

1 Answer 1

1

You should probably have a $hookSearchKey property within your class and set it with a setHookSearchKey() method when needed:

class Whatever {
    // ...
    private $hookSearchKey

    public function setHookSearchKey($key) {
        $this->hookSearchKey = $key;
    }

    //... this is your method of sorting:
    public function fooSort(...) {
        $this->setHookSearchKey('hook-foo');
        usort(...); // do your thing
    }

    //... this is your method of sorting:
    public function barSort(...) {
        $this->setHookSearchKey('hook-bar');
        usort(...); // do your thing
    }

    //...

    public function sortByHookPriority(...) {
        if($a[$this->hookSearchKey] == $b[$this->hookSearchKey]) return 0;

        // ...
    }
}

Would this work for you?

Sign up to request clarification or add additional context in comments.

1 Comment

This was not the full answer, but it got me where I needed to go. I was trying to pass the required hook as an argument, when (in reality) storing it in the class as a property was enough to "transport" it from the scope where I had it to the scope where it needed to be accessible. I still had to do some additional loops and tests to find the plugin's key (the hash) that contained the item I needed to sort by. But, in the end, this is what I needed. Thanks @henrique!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.