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

Routing: JComponentRouterRulesMenu to find right Itemid #5446

Closed
wants to merge 52 commits into from

Conversation

Hackwar
Copy link
Member

@Hackwar Hackwar commented Dec 16, 2014

This rule implements finding the right Itemid as a generic rule for all component routers that extend from JComponentRouterView. It makes most of the parts of the *HelperRoute classes obsolete.

How to test

  • Apply this change
  • Change the router of com_content by replacing
class ContentRouter extends JComponentRouterBase
{

with

class ContentRouter extends JComponentRouterView
{
    function __construct($app = null, $menu = null) {

        $categories = new JComponentRouterViewconfiguration('categories');
        $categories->setKey('id');
        $this->registerView($categories);
        $category = new JComponentRouterViewconfiguration('category');
        $category->setKey('id')->setParent($categories, 'id')->setNestable()->addLayout('blog');
        $this->registerView($category);
        $article = new JComponentRouterViewconfiguration('article');
        $article->setKey('id')->setParent($category, 'catid');
        $this->registerView($article);
        $this->registerView(new JComponentRouterViewconfiguration('archive'));
        $this->registerView(new JComponentRouterViewconfiguration('featured'));
        $this->registerView(new JComponentRouterViewconfiguration('form'));

        parent::__construct($app, $menu);
        $this->attachRule(new JComponentRouterRulesMenu($this));
    }

    public function getCategorySegment($id, $query)
    {
        $category = JCategories::getInstance($this->getName())->get($id);
        if ($category)
        {
            return array_reverse($category->getPath());
        }

        return array();
    }

    public function getCategoriesSegment($id, $query)
    {
        return $this->getCategorySegment($id, $query);
    }

    public function getArticleSegment($id, $query)
    {
        return array($id);
    }
  • Comment line 62 and 111 from /components/com_content/helpers/route.php to disable the lookup of the Itemid there.
  • See that the right menu items are still found for the items

This was updated on May 22nd 2015. All discussions prior to that point have either been integrated or are obsolete.

This was made possible through the generous donation of the people mentioned in the following link via an Indiegogo campaign: http://joomlager.de/crowdfunding/5-contributors

@johanjanssens
Copy link
Contributor

@Hackwar Did a first pass of the proposed code and added inline comments. I like the simplicity that is being proposed.

@weeblr-dev
Copy link

Hi Hannes,

How can 3rd party extensions disable/bypass those rules that could be added by components, or even if they make their way int Joomla core pre-4.0? or at least are you storing the original request somewhere so that we can revert any change made by those rules, as discussed in #5264?

"By letting any Itemid being passed in a developer can hijack a route. Connecting a component to any random Itemid. Shouldn't that be prevented ? ": Not random, but manually selected by user - as allowed by most SEF extensions, yes, absolutely.

Cheers

@Hackwar
Copy link
Member Author

Hackwar commented Dec 17, 2014

I guess JComponentRouterAdvanced will get a "removeRule()" method, that takes a rule that you can first find with a "getRules()" method and remove that from the rules to process again. Remember that you will have the buildpreprocess() step, where you can attach yourself already to, to for example add your stuff to the query.

@weeblr-dev
Copy link

This is not about attaching things to the query. This is about being able to undo things that other rules have attached, or any change they might have done to the original query. In other words not being trapped again in the problems the language filter plugins rules have created (not by themselves, but by being set in stone and unmodifiable)
getRules() and removeRules() sound good, as long as we have an event we can use to be reasonably sure all rules have been attached (so we can also be sure to remove them all). Too bad there isn't an onBeforeRoute...
I guess even if we use onAfterInitialise, we can rely on the plugins ordering so we should be good in most cases.

@Hackwar
Copy link
Member Author

Hackwar commented Dec 17, 2014

For the time being, I would add all rules in the component routers constructors, so when you cycle through all components and then use JRouterSite::getComponentRouter() and do your own stuff by adding/removing rules again in onAfterInitialise, you would be good. Since I would like to have more than one set of component rules, I could also see us having a -1 option that disables all the rule-adding in the constructor and you can do your magic.

Regarding the language filter plugin: I hope that it is a lot saner now when #5140 is merged. I can't really think of anything else that you could want in that regard...

@weeblr-dev
Copy link

Hi Hannes,
Let me clear that up first: I have no problem with the language filter rules, how they were working or whatever. The only issue was that we couldn't bypass them, or even know what the actual original request was and what the language filter rules had done to it. The same would apply to any extension adding rules, whether for parsing or building.
It was a bit more difficult with the language filter because its parse rule is always executed first, regardless of the actual system plugins ordering set by user or otherwise.

As for adding/removing rules on onAfterInitialise, I can request users to be sure my system plugin is the last one in order (and I can check that periodically) and thus be sure to remove all rules that may have been added by other extensions. An onBeforeRoute event would be more secure, but maybe not worth the added perf cost I guess. I'll make sure to do some trials in due time.

…s pretty complex and throws errors in our testing environment
@johanjanssens
Copy link
Contributor

@weeblr-dev @Hackwar Do we really need to have the ability to remove rules ? Removing rules requires knowledge about the rules being added. Wouldn't it make more sense to allow rules to override others ?

An idea can be to store the original query and do the query modifications into a different array. That way a rule can always use the original query and can also more easily override without needing to have knowledge about other rules.

@Hackwar
Copy link
Member Author

Hackwar commented Dec 25, 2014

That exactly would make it impossible to override rules. Right now, you can attach a rule to the router and clear out the query variables one by one, creating your own rule and in the end, your URL is done and the query variables are empty. Then the next part of the router only sees an empty query and directly returns. If we kept the original query, how would a later rule know that an earlier rule already processed that part?

Yes, removing rules requires you to have quite a knowledge about what has been added before, but the main situation where I see this to be used would be a plugin like sh404sef, which could remove the default behavior of Joomla and replace it with its own. It's not going to be a bunch of GUI options that let you influence that directly.

@Hackwar
Copy link
Member Author

Hackwar commented Jan 12, 2015

@johanjanssens I specifically chose JComponentRouterViewconfiguration since I did not want to use JComponentRouterView for this. I can see us wanting to have a JComponentRouterView class for different purposes.

Regarding the setName/setViewName: Please see the latest commits to this PR. Those have since been removed.

@johanjanssens
Copy link
Contributor

@Hackwar About setName/setViewName() I missed those changes. Looking much better indeed API wise.

About JComponentRouterViewconfiguration vs JComponentRouterView. I understand, still not 100% happy with JComponentRouterViewconfiguration, any alternatives ? JComponentRouterConfig maybe, or JComponentRouterContext ?

Hackwar and others added 19 commits January 21, 2015 14:28
Call-time pass-by-reference has been removed

Removing JError, using Exception instead

protecting $name and renaming register() to registerView()

Adding removeRule, getRules and renamed $id to $key in register method

Making method names consistent

Implementing JComponentRouterViewconfiguration for configuration of views in JComponentRouterAdvanced

Codestyle, smaller improvements, unittests for all component router classes except for JComponentRouterAdvanced

Removing ability to have one view with different names and implementing unittests for JComponentRouterAdvanced

Adding get<View>Slug() and get<View>Key() methods to JComponentRouterAdvanced

Updating unittest

Small fixes

Adding back in platform check

Adding back in platform check

Adding back in platform check

Adding back in platform check

Implementing feedback so far

Adding "covers" notation for unittests
…omponentrulesitemid

Conflicts:
	tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php
Fix unit test failure in JComponentRouterViewTest
@joomla-cms-bot joomla-cms-bot added the Language Change This is for Translators label May 22, 2015
@Hackwar
Copy link
Member Author

Hackwar commented May 22, 2015

I've updated this PR to work with the changed JComponentRouterView class. Please test.

@dgrammatiko
Copy link
Contributor

@Hackwar what shall we look for the output urls? just B/C or something more/else?

@Hackwar
Copy link
Member Author

Hackwar commented May 22, 2015

simply B/C. This should not change the URLs.

@Hackwar
Copy link
Member Author

Hackwar commented Aug 2, 2015

I've combined the changes from this and all other routing related PRs into a new PR: #7615 Please review and comment in the new PR. I'm closing this one, so that we can focuse on the new PR.

@Hackwar Hackwar closed this Aug 2, 2015
@Hackwar Hackwar deleted the componentrulesitemid branch January 6, 2016 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Language Change This is for Translators
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants