? Pending

User tests: Successful: Unsuccessful:

avatar clayfreeman
clayfreeman
9 Aug 2018

Summary of Changes

This PR removes the overloaded display method of AdminController which disables the base class implementation of the display method.

AdminController provides extra functionality that can be useful for the manipulation of lists of items and it makes no sense why this functionality shouldn't be available without the cost of disallowing views for a given controller. If the developer wishes to disable views for their controller, it should ultimately be their decision and not Joomla's.

Testing Instructions

Check that the behavior of any controller extending AdminController has not been adversely impacted.

Expected result

Classes extending AdminController can now be used with views.

Documentation Changes Required

No. I couldn't find any instance of AdminController discouraging use of the display method outside of its inline documentation block.

avatar clayfreeman clayfreeman - open - 9 Aug 2018
avatar clayfreeman clayfreeman - change - 9 Aug 2018
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 9 Aug 2018
Category Libraries
avatar clayfreeman clayfreeman - change - 9 Aug 2018
The description was changed
avatar clayfreeman clayfreeman - edited - 9 Aug 2018
avatar laoneo
laoneo - comment - 16 Aug 2018

I'm not sure if this has unwanted side effects.

avatar clayfreeman
clayfreeman - comment - 16 Aug 2018

FWIW, I've been running this patch on one of my testing sites for a week now and haven't noticed any issues. That's not to say that there aren't any edge cases though.

avatar clayfreeman clayfreeman - change - 18 Aug 2018
Labels Added: ?
avatar mbabker
mbabker - comment - 21 Aug 2018

There's a part of me that agrees that this is a pointless behavior, and there's a part of me that hesitates to accept this into 3.x at this point considering aside from the 3.9 feature release we really should be focusing on branch stability and not introducing potentially problematic API changes this late in the game. In theory all this does is remove a pointless restriction that someone tried to create, but we do need to be careful that this doesn't come back to bite someone in the backside.

avatar clayfreeman
clayfreeman - comment - 21 Aug 2018

If you're fairly confident that this PR won't break anything, it could always be merged and released with 3.9. Any latent failure due to oversight can be remedied with a patch release if such a failure were to occur.

I personally highly doubt that enabling extra functionality would adversely affect any extension. Those extensions with functionality dependent on AdminController would seem to already have redirects or other facilities in place to skirt by the change.

If it is preferred, I can have a couple colleagues look over this PR to test it further in production to see if we notice any additional effects among extensions that aren't in my test environment. Just let me know your preferred course of action and whether you would like supporting testing evidence.

avatar mbabker
mbabker - comment - 21 Aug 2018

whether you would like supporting testing evidence

Testing and feedback is always good.

Personally I'm just erring on the side of caution with this one. I really don't think it's actually going to cause an issue, but stranger things happen with the most innocent of changes.

avatar rdeutz
rdeutz - comment - 21 Aug 2018

The only thing I can think of is that someone extends the AdminController class and calls parent->display for whatever reason. Then the controller instantiating is different, because BaseController->display will be called and this display method is doing much more than returning $this. It might be only a very small chance that something is going wrong, but I wouldn't merge it in 3.x.

avatar clayfreeman
clayfreeman - comment - 21 Aug 2018

While I recognize that there is the potential for a bug-fix burden on some developers, I don't believe this oddly-specific code smell is worth the justification for holding back the PR until 4.x.

IMO, developers with bad practices of obtaining an indirect internal reference to $this through parent::display() without the expectation of side-effects shouldn't necessarily be rewarded with compatibility while simultaneously holding back further improvement of the CMS.

avatar jeremyvii
jeremyvii - comment - 21 Aug 2018

I was able to test this successfully without issue. It is a little surprising to find out that AdminController doesn't support display views by default. In my opinion, it seems more realistic that most people using this class would not be relying on display() returning $this.

avatar franz-wohlkoenig
franz-wohlkoenig - comment - 21 Aug 2018

@jeremyvii please mark your Test as successfully:

  • open Issue Tracker
  • Login with your github-Account
  • Click on blue "Test this"-Button above Authors-Picture
  • mark your Test as successfully
  • hit "submit test result"
avatar ggppdk
ggppdk - comment - 21 Aug 2018

@clayfreeman

I have not found any issues in our extension,
but you can not predict what with happen with a NNN 3rd party extension,
also there might be some smaller or bigger security issue with some extension

why don't you just declare display task in you derived controller
and in it just call the grandparent display task ?

then if this is change is made in J4 your could also add an IF there to call the parent display task for J4

avatar mbabker
mbabker - comment - 21 Aug 2018

why don't you just declare display task in you derived controller
and in it just call the grandparent display task ?

Without Reflection PHP doesn't have a concept of "call the grandparent display task", meaning you either copy the grandparent method code into your class or you use Reflection to do something that you weren't intended to do in the first place.

avatar ggppdk
ggppdk - comment - 21 Aug 2018

Without Reflection PHP doesn't have a concept of ...

hhmm, is there a known problem if one uses
get_parent_class()
?

	public function display($cachable = false, $urlparams = false)
	{
		return get_parent_class(get_parent_class($this))::display($cachable, $urlparams);
	}

[EDIT]

		return get_parent_class(get_parent_class(get_class()))::display($cachable, $urlparams);

this is better alternative, it will work even when you have derived classes,

get_parent_class(get_parent_class($this)))::display()
will work only if you do not have more derived classes,

because in the case that $this is an object of the derived class ... you will have a loop

avatar mbabker
mbabker - comment - 21 Aug 2018

That works if you're accessing a static method, in which case you should just use the class name of the class whose static method you want to call in the first place.

You get a class name from get_parent_class(). With your code, you are invoking Joomla\CMS\MVC\Controller\BaseController::display() in a static context, meaning you're going to create errors because $this won't be defined.

Again, PHP does not have the concept of direct access to a grandparent method. If it did, we would have a grandparent keyword. You might get lucky and through inheritance $this->foo() can access a method two levels up, but that's just class inheritance 101.

avatar ggppdk
ggppdk - comment - 21 Aug 2018

I really do not know since which PHP version this works correctly
it may have since PHP 4 or some PHP 5.x

i know it is weird, but

somename::somemethod()

is a static call
only if somename is not found in the inheritage change chain of the class ancestors
if found it works as a regular method call

thus $this is bound correctly and visibility rules (like private, protected) are also respected

i printed $this just now to confirm, the correct object is printed (my derived class object)

avatar mbabker
mbabker - comment - 21 Aug 2018

Turn on E_STRICT reporting and you're going to have problems. That is not a supported PHP behavior and should not be relied on at all in anything except a 3v4l.org demonstration.

avatar jeremyvii jeremyvii - test_item - 21 Aug 2018 - Tested successfully
avatar jeremyvii
jeremyvii - comment - 21 Aug 2018

I have tested this item successfully on 1f2cd4b


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

avatar jeremyvii
jeremyvii - comment - 21 Aug 2018

I have tested this item successfully on 1f2cd4b


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

avatar clayfreeman
clayfreeman - comment - 21 Aug 2018

@ggppdk You're correct in saying that you can use the scope resolution operator to explicitly specify which method in the inheritance chain is used. This is my current workaround in one of my controllers that extends AdminController:

  /**
   * Allow this controller to be used with a view.
   *
   * This method overrides the default implementation to circumvent the
   * restriction placed on the `AdminController::display()` method by Joomla!
   *
   * @param   bool            $cachable   Whether the result of this method
   *                                      should be cached (if enabled).
   * @param   array           $urlparams  An array of sanitized URL parameters.
   *
   * @return  BaseController              `$this` to support method chaining.
   */
  public function display($cachable = FALSE, $urlparams = []) {
    // Override the inherited display method to /actually/ do something
    return BaseController::display($cachable, $urlparams);
  }

While it's completely possible for me to include this workaround in all children of AdminController, the point of this PR is that I shouldn't have to do so.


@mbabker Please see the following:

ini_set('display_errors', '1');
error_reporting(~0); // enables all errors as `~0 === 0xFFFF...`
class Foo {public function hello(){echo "hi\n"; return $this;}}
class Bar extends Foo {public function hello(){return $this;}}
class FooBar extends Bar {public function hello(){return Foo::hello();}}
$fb = new FooBar();
var_export($fb->hello());
error_reporting(E_ALL | E_STRICT);
var_export($fb->hello());

You can safely use the scope resolution operator with no repercussions in latest PHP.

avatar clayfreeman
clayfreeman - comment - 21 Aug 2018

@ggppdk I'd also like to state that given the name of the method, if a developer is expecting no side-effects from parent::display(), then security should be the least of their concerns.

avatar ggppdk
ggppdk - comment - 21 Aug 2018
    return BaseController::display($cachable, $urlparams);

I was going to offer this as an alternative,
but then wondered if you have are using the non-namespaced names

also i thought something safer that does not hard code grandparent class name without real need,

although of course we know these class names will never change in during the lifetime of major version, it would be a big B/C break if they changed

I'd also like to state that given the name of the method, if a developer is expecting no side-effects from parent::display(), then security should be the least of their concerns.

it is not important if you are right or wrong
if you have read some angry comments in the past here about things broken by a change that was not so much needed, then you would understand why people managing this repository are cautious about a change that they can not predict if it will have side-effects,

myself i was just a little worried of this change for our extension, although i did not find something

avatar travisrisner travisrisner - test_item - 21 Aug 2018 - Tested successfully
avatar travisrisner
travisrisner - comment - 21 Aug 2018

I have tested this item successfully on 1f2cd4b


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

avatar clayfreeman
clayfreeman - comment - 21 Aug 2018

As stated on this page:

We have a promise that a Joomla 3 extension will run on Joomla 4 and a namespaced Joomla 4 extension on Joomla 3.9.

In the pursuit of keeping this promise, I argue that this PR should be accepted for the 3.x branch if it is considered acceptable for the 4.x branch. If not in 3.9, then 3.10. This change is not necessary, no, but is recommended to provide functionality that should have been available for AdminController all along.

If this PR is rejected in favor of only applying these changes to the 4.x branch, then Joomla's original promise will be broken in this instance. I hope this can be avoided, as I would like to reduce the number of bodges that are required to have cross-version extension support.

avatar clayfreeman clayfreeman - change - 24 Aug 2018
Title
[3.9] enable AdminController display method
[3.9] Remove AdminController::display() method overload which disables the inherited functionality from BaseController::display()
avatar clayfreeman clayfreeman - edited - 24 Aug 2018
avatar clayfreeman
clayfreeman - comment - 4 Sep 2018

@mbabker Should I close this request in favor of delaying it until 3.10?

avatar mbabker
mbabker - comment - 9 Sep 2018

Made up my mind. Let's just merge this and roll with it (ensuring the change is documented). The FormController does not impose this same restriction and there is really no logical reason to have it. If it does prove to be problematic this should be reverted and applied to 4.0 only.

avatar mbabker mbabker - change - 9 Sep 2018
Status Pending Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2018-09-09 17:12:28
Closed_By mbabker
avatar mbabker mbabker - close - 9 Sep 2018
avatar mbabker mbabker - merge - 9 Sep 2018

Add a Comment

Login with GitHub to post a comment