Skip to content
This repository

Simplified foundational classes for Model, View and Controller. #1120

Merged
merged 3 commits into from about 2 years ago
Louis Landry

This pull request introduces a new format for the model-view-controller paradigm. Principly, the classes JModel, JView and JController are now interfaces and the base abstract classes are now JModelBase, JViewBase and JControllerBase respectively. In additional, all classes have been simplified to remove a lot of coupling with the Joomla CMS that is unnecessary for standalone Joomla Platform applications.

One of the guiding principles of this change was to make the base implementations as non-prescriptive as possible. The Model, View and Controller classes simply wire up dependencies and get out of the developers way so that he or she can build things the way they make sense for the given application.

Organization

All the API for controllers, models and views has moved from the Application package into separate Controller, Model and View packages respectively. Much of the API previously devoted to adding include paths for each of the classes has been removed because of improvements in the auto-loader or by registering or discovering classes explicitly using JLoader.

Controllers

Controllers, by default, only support one executable task per class via the execute method. This differs from the legacy JController class which mapped tasks to methods in a single class. Messages and redirection are not always required so have been dropped in this base class. They can be provided in a downstream class to suit individual applications. Likewise, methods to create models and views have been dropped in favor of using application or package factory classes.

While it is easy to build a JControllerTasker (or in the case of the CMS a JControllerCMS) class that encompasses logic to support task mapping to controller methods, redirection, etc that has been removed, we strongly recommend considering using one controller to one action moving forward. The new JControllerBase class is very lightweight, and having one controller mapping to one task gives several benefits. One such benefit is the easy use of the HMVC pattern or chaining tasks. Another is the ability to serialize a controller with it's input and stored for later execution asynchronously. Either way, this implementation doesn't prescribe how you build and use controllers beyond an incredibly simple interface, and we believe that's a good thing.

Models

Models have been greatly simplified in comparison to their legacy counterpart. The base model is nothing more than a class to hold state. All database support methods have been dropped except for database object support in JModelDatabase.

Views

Views have also been greatly simplified. Views are now injected with a single model and a controller. Magic get methods have been dropped in favor of using the model directly. Similarly, assignment methods have also been dropped in favor of setting class properties explicitly. The JViewHtml class still implements layout support albeit in a simplified manner.

Jeremy Wilken

This is very interesting, may I ask why you are naming the interfaces as what would be (traditionally in the CMS at least) thought of as the base class, and then setting up an abstract class with the name of base? If that is unclear, I mean why is JController the interface instead of the abstract base class? Its mostly a question about naming conventions, since for example JDatabase (doesn't have an interface) is the root abstract class. Otherwise, I am a big fan of the base classes being simplified!

Andrew Eddie
Owner

It's so you can use the interface for type hinting, for example:

public function __construct(JModel $foo = null);

or

if ($foo instanceof JModel)

If JModel is an interface, it can be any base class (could be extended from JDate or SplFileObject for all we care). If JModel is a concrete class, it restricts the flexibility. We felt is was important that type hinting used JModel, JView, etc (neater than JModelInterface, JViewInterface, etc), so for maximum flexibility we made them interfaces (particularly for dependency injection and composition architectures).

Does that help?

Nicholas K. Dionysopoulos

If it's an interface, please name it as such. With the currently proposed naming scheme you render all existing components and all existing documentation on building components useless. Please name those classes as JModelInterface, JControllerInterface and so on. Then let the CMS provide concrete JModel, JController etc classes so that we don't completely screw up backwards compatibility and everyone who has invested on writing software for the Joomla! CMS. If you don't I can safely predict what will happen (it's not fear mongering, I have been talking to other developers about that possibility): no software will be ported to Joomla! 3.0 and 3.1, because us 3PDs have to support the current LTS version, and we will all start porting our software when 3.5 is out. It will take us some months to do that, in which timeframe 2.5 will go EOL. So, Joomla! users will have to stick with an EOL (and potentially insecure) version of the CMS if they want to use extensions (i.e. do anything useful), or migrate to 3.5 with minimal to no extensions (therefore nothing useful is possible). I don't believe this is a good strategy, as it will alienate our mutual user base – the vast majority of Platform users are the CMS users. It's either that, or each 3PD will have to fork into his own set of MVC classes, taking us back to the Joomla! 1.0 era where each extension worked completely different than the next.

Please reconsider the naming of your classes putting the problems it causes to existing CMS extension into perspective. Please remember that 99.99% of users out there (pretty much anyone except eBay?) will use the Joomla! Platform only because they also use the Joomla! CMS. If you screw up the CMS and its extensions, the Platform loses too. Thank you.

Rouven Weßling
Collaborator

Nik: This doesn't really adress your comment, but as a point of clarification I think it's highly unlikely that the CMS will use the new MVC in 3.x.

Nicholas K. Dionysopoulos

Even if it uses it in version 4.0 it will be the same. My point is not really the version number in which the Joomla! CMS will adopt the MVC changes. It's about wrecking havoc among developers because of terrible class naming. If it's an interface, tuck in the Interface suffix. I mean, we surely have JDatabaseInterface. Why should he choose to NOT add the Interface suffix to the exact set of classes which is most used?!

AmyStephen

I am glad to see HMVC and chaining in the description. I'll hold other comment until I've had a chance to play with the code. Glad to see the good documentation. Appreciate that.

HermanPeeren

I like it, that (almost 8 year's after it's introduction into PHP) interfaces are at last planned to be used in base Joomla classes. It will improve more loosely coupled OOP. Maybe it took so long, because Joomla kept supporting PHP4 in the 1.5 versions.

I see you didn't extend the base classes from JObject anymore. Maybe your intention is to get rid of JObject totally (+1 from me). I guess: as it was mainly used to get some PHP5 functionallity (like the common name of the constructor) into PHP4.

Jeremy Wilken

@eddieajau if JModel implemented JModelInterface, instanceof would still recognize it. I don't understand how it restricts the flexibility from that example at least.

HermanPeeren

Could you explain why you've put a controller-object in the base-view? I would expect a reference to the view from the controller, but not the other way around.

AmyStephen

While the sensitivity to change due to BC is not lost on me, building on @HermanPeeren 's comment - @LouisLandry - would you consider making what Joomla calls views - Controllers? That would allow what Joomla calls Layouts to be, IMO, properly identified and used as Views.

Combining that with HMVC and chaining and Joomla becomes very flexible and powerful.

Louis Landry

@gnomeontherun I personally feel that the most foundational definition of what constitutes a model, view or controller is defined by the interface not an abstract base class. To me, the abstract base is obviously something to be built on, but shouldn't be the only thing that is considered a model. Let's look at a set of examples and hopefully you'll start to see my point of view. I don't claim that it's the only one, but it's the one I hold for now and why it's done this way.

Let's assume that we have a library Foo that we want to use as a model in our MVC based application. In some languages we could use multiple inheritance to achieve this by having our model class extend both the base model class as well as Foo. There are several ways of approaching this, so let's start with the basic case using JModelInterface as the interface.

Case A

<?php
class MyModelFoo extends Foo implements JModelInterface
{
    // ...
}

So this will structurally work for sure, but I personally think it's a bit convoluted to ask if MyModelFoo is an instance of JModelInterface. I think it makes more sense to ask if MyModelFoo is an instance of JModel. This goes back to my belief that the most foundational definition of a model class is its interface, not its abstract implementation.

Case B

<?php
// Case 3
class MyModelFoo extends JModel
{
    // ...
    public function setFoo(Foo $foo)
    {
        $this->foo = $foo;
    }
}

Another option would be to use our friend composition as above. Basically in this example I get to ask if (MyModelFoo instanceof JModel), which is much simpler and more clear to me. What I don't get, however, is unfettered access to protected members of Foo. That might be OK, but it also might be problematic. Ultimately we don't know enough about Foo to know whether or not that might be important. Perhaps Foo is abstract, or perhaps it is simply meant to be customized in a child class. Another thing I don't get to do is ask whether or not (MyModelFoo instanceof Foo) There are ups and downs to this, but ultimately if we choose the following Case C we could still take this approach of composition for Foo if it is appropriate.

Case C

<?php
class MyModelFoo extends Foo implements JModel
{
    // ...
}

Here my model has access to all protected properties and methods of Foo and basically allows me to turn Foo into a model with very little trouble. Additionally I can easily and semantically ask whether or not MyModelFoo is a JModel (MyModelFoo instanceof JModel) as well as ask whether or not MyModelFoo is a Foo (MyModelFoo instanceof Foo). To me this is the best of the scenario.

Using one of @eddieajau's examples we could say the same thing for JDate instead of Foo.

<?php
class MyModelDate extends JDate implements JModel
{
    // ...
}

$isModel = (MyModelDate instanceof JModel);
$isDate   = (MyModelDate instanceof JDate);

Now my instances of MyModelDate can be used anywhere that a JModel or a JDate are expected, which is pretty cool.

There are lots of fun discussions about interface naming conventions out there. The three most common are what I'd call hungarian notation-esque IModel with accompanying JModel, JModelInterface with accompanying JModel and JModel with accompanying abstract implementation (JModelBase or JModelAbstract or JModelImpl, etc). We can get into a deeper conversation on why I prefer the last convention, but I don't know that it would be best done in this venue. Either some other channel or over beers at JAB works for me. :)

The reality here is that the Model, View and Controller interfaces and classes proposed here are very basic. They are done that way on purpose actually. It's my belief that these classes should be as simple as they can be, and let more feature-rich child classes be built at an application level. If we want to entertain more specific child implementations down the road that's fine, but the foundation implementations should follow a famous quote by Einstein, "Everything should be made as simple as possible, but not simpler."

Nicholas K. Dionysopoulos

I fully agree with the implementation as Interfaces. This is why Interfaces were introduced to OOP and I bet you know all about that much better than me (I've only ever been a self-taught programmer, not a software architect). My only beef is that by calling the Interface JModel we are forcing the CMS to use a different name for the concrete implementation (e.g. JModelCms) which breaks BC for no good reason. We can avoid this by simply naming the interface JModelInterface. In terms of what looks better, you'll asking the wrong guy if you ask me, as I prefer IModel (too many years of Delphi programming make you instinctively opt for the queer naming scheme I guess). But I proposed JModelInterface for two reasons: a. consistency with the JSomethingOrSomeother naming convention and b. I and J look way too similar and are way too close on the keyboard. But the important thing is, why break BC if we can easily avoid it? Why add a layer of complexity for 3PDs when it's equally simple to not do that?

Louis, I will buy you a beer or two at JaB and talk more about it if you'd like.

Louis Landry

@nikosdion For naming convention commentary take a look at my previous answer to @gnomeontherun. I share your concern for backward compatibility. It is one of the reasons that I created the legacy tree in the platform. Another reason is that I believe very strongly that we have to manage backward compatibility with a steady push towards forward progress in architecture and implementation.

If we were to call the controller interface JControllerInterface and the abstract base JController it still would require a change for developers if/when they are leveraged in the CMS. There are things missing from the new JControllerBase implementation that are present in the legacy JController class. Things that largely don't belong in a foundational class like that. What I would expect is that for compatibility the CMS will likely create something like:

<?php

class JControllerCMS extends JControllerBase
{
    // Add all of the things found in the legacy controller for backward compatibility and smooth transition.
}

What this means is that CMS extension developers will need to do a search and replace on JController and JControllerCMS respectively. Not an incredibly onerous change. Additionally if they do any sort of checks like ($controller instanceof JController) they would still return true or false in the same way they were done in the past. Alternatively the CMS could simply define JController as a concrete class and ignore the platform's interface definition. The autoloader will handle that gracefully actually since once it's found the class it won't look further and it would first look for classes in the CMS tree.

I don't think you are fear mongering at all, but I do think you may be overreacting a bit. I understand that these are really important, foundational things. I understand that there are a lot of stakeholders as well, with lots of different use cases. I firmly believe however that making this move does not tie our hands to handle backward compatibility in a graceful way. It does give us a lot more flexibility in using the platform in different ways moving forward though.

HermanPeeren

But if you make a new JControllerCMS to mimick the old JController, then you still have to rewrite all software that was built upon the JController. Just because that name is now used for something else, BC will be a PITA. Which is easily avoided if the old names are not used for new things. I think that is Nicholas' point.

Louis Landry

@HermanPeeren I'm glad you like it. You are correct on the use of interfaces thus far (or lack thereof). We've supported PHP4 for a long time, and while interfaces aren't necessary for everything they do provide some really useful benefits so I would expect you to see more of them crop up over time. Ultimately the answer to why they haven't been in there since 1.6 is because no one has taken the time to do the work and submit it.

As for the use of JObject. It was as you guessed initially used as a bridge between PHP4 and PHP5. It allowed us to write PHP4 code using the __construct() and __destruct() methods among other niceties. I'd like to see JObject morph into a foundational value object in the future, and not a base class to be inherited by every other class in the platform. Some work has been done on that in my team at eBay, but we aren't quite ready to share it yet to see what people think. Hopefully we can do that soon and you'll get an idea of what I mean. Obviously I'd love to hear others' thoughts on it, but I really don't see value to continuing to extend JObject everywhere. It's about as semantic as <span> and not useful for what it was originally intended any longer.

Your question about the view class having an instance of the constructor, that might have simply been a case of overzealous dependency injection. I'd be happy to remove that since it isn't really a classical MVC dependency. Thanks for the find!

@AmyStephen I don't really agree that our views are actually controllers. I do think in some cases views are misused in Joomla code, but I don't agree that the concept of what we have as JView is actually a controller. You will also note that in our implementation we have a JVewBase that doesn't involve layouts at all. This is because in its simplest form a view wouldn't need one. JViewHtml is where we've allowed for layouts, but it is still simpler in my opinion than the existing implementation of JView. I'd be open to a different name for JViewHtml if something more semantic can be found, but I am sorry I just don't think JController is that name. :) It's an interesting conversation though, and we should have it if others are interested... probably not in this thread though. I'm glad you seem to be liking what you see here though, I think this lays the groundwork for some really great things going forward.

HermanPeeren

Proposal: to make BC-adapters possible and to make the legacy-tree function, we should not give new classes and interfaces old names.

Nicholas K. Dionysopoulos

Louis, seems like our posts crossed paths :) Herman is right, that was exactly my point. I'll try to explain it a little better this time around.

I am thinking about the typical scenario of developing for the CMS here. Let's assume for a minute that these changes make it into Joomla! 4.0.

Developers will have just released their software for Joomla! 3.5 where everything extends from JController, JModel, JView etc. For the next 1.5 years (at the very least) we'll have to support Joomla! 3.5, as it's the only production-quality version of the CMS. We can easily handle early adopters of the 4.0 and 4.1 versions by telling them that our software will only run on 3.x. This is, of course, very bad for the CMS as nobody can test it in real world conditions - you need 3PD extensions to do that. Let's forget that this is a factor. Then, 4.5 comes out. This means that we all now have to start working on our software for Joomla! 4.5. Given that MVC is not going to be the only thing changed, it will take us months to get there. And here we have a dire situation:

  • Joomla! 3.5 goes EOL and we still don't have all extensions ported. Users are stuck with an obsolete, insecure version of Joomla! (this is what is currently happening with some extensions and Joomla! 1.7, I'm not making this up)
  • Joomla! 4.5's active maintenance period (the first three months) passes without potentially major issues being caught and fixed (major as in what happened with J! 2.5.0 and the Javascript issues)

The way I see it, this causes a chain reaction of negativity surrounding Joomla!. Since I am, like virtually everyone else who comments here, making a living out of Joomla!, that would be a very unpleasant situation to be in.

Instead, I propose this simple solution:

  • Name your JModel as JModelInterface
  • Have JModelBase implement JModelInterface instead of JModel
  • Let the CMS provide JModel which extends JModelBase, implementing the missing functionality which is deliberately (and correctly!) not present in JModelBase

By doing that, 3PDs can add "experimental level" Joomla! 4.x support in the same codebase which supports Joomla! 3.5. This is what happened with many extensions during the 1.5 to 1.6/1.7/2.5 transitional period. I mean, yes, I have extensions which are compatible with both Joomla! 1.5 and 2.5 using the same codebase. I don't see why this shouldn't be made possible for future versions.

So, the way I look at it, it's not a matter of doing a mass search and replace. It's about making us choose between supporting only an LTS, having two codebases for the same software or choosing the easy way out to the detriment of the Joomla! community. What I state is not overreacting. I've actually talked to other 3PDs and what they will be doing is chose the easy way out.

Just for the record, I am aware that there is fourth alternative, doing something silly like:

<?php
if(version_compare(JVERSION,'4.0','ge') {
class vendorModel extends JModelCms {};
} else {
class vendorModel extends JModel {};
}

class FoobarModelSomething extends vendorModel {
// The regular code goes here
}

That works. I've tried it at some point when I was trying to make my code not throw strict warnings and still have it run under both Joomla! 1.5 and 2.5. The major problem with that approach is that we lose all code hinting, throwing us back to the 1998 way of writing code, as well as throw off all code checking features of our IDEs. It also adds unnecessary complexity. I am sure I can cope with it, but I'm not sure everyone else out there will be willing to do the same.

Rob Schley

@HermanPeeren The controller is injected in the view because the view may need the dependencies that the controller has (application, input).

AmyStephen

Removed my comments.

I need to play with this before commenting further.

Thank you for sharing this work.

HermanPeeren

@robschley I just wonder if such a need for dependencies is necessary for the proposed simplified MVC or a smell that there might be some improvement possible.

Rob Schley

@HermanPeeren Sure, there is always room for improvement.

Andrew Eddie
Owner

@nikosdion I respect your point of view (one I shared until the idea in this proposal grew on me), but I think the B/C argument is a different conversation. We implemented the legacy tree in the platform for the very purpose of buffering major changes in the CMS for at least another major cycle. However, I don't think it's fair to ask the platform to slow down even further just so extension developers can write one extension that supports both CMS 3.5 and 4.0, or 5.0, or whatever versions without any change. The reality is the CMS can choose to or not to implement so it's a conversation you need to be having on the CMS list when major versions (3.0, 4.0, etc) are being considered and we've implemented a way to make that pill easier to swallow for downstream users (with the express purpose of making the life easier for the extension developer).

To directly counter one of your arguments though, there is nothing stopping the CMS adding JModelBase to 3.0 and telling developers to extend all models from that (heck, they could add it to 2.5 if they wanted as well). If they do that, they will be ready for 4.0.

@AmyStephen I don't understand exactly what you mean by views as controllers either. I think a gist would be helpful.

AmyStephen

@eddieajau I agree - that's exactly why I removed my followup comment. No sense in all of us saying stuff - @LouisLandry put up some code so we ought to do the same, in response.

AmyStephen

@LouisLandry - you might want to change the default on the eBay repository to MVC. Otherwise, folks need to know to do so with their fork. Merging to the content branch isn't clean.

Thanks!

Louis Landry

@nikosdion and @HermanPeeren I understand your point, and respect it. I do not however think that there isn't a solve for it . If we were to say that as of 3.0, three classes were added to the CMS called JControllerCMS, JModelCMS and JViewCMS. Those classes essentially contained the existing legacy implementations of what we know as JController, JModel and JView. We can give all CMS extension developers a clean transition using (as we discussed earlier) search and replace from JController to JControllerCMS, etc.

That solves things going forward. Hopefully we can agree to that -- I think we have. What it doesn't solve is previous released versions of Joomla as you have pointed out. Well, that could be sorted out quite simply with a plugin that looks something like https://github.com/LouisLandry/plugin-compat in concept. 1.6+ you could even package it with your extension and have it install along side your extension. Now obviously there is a little nuance to the plugin required for the different versions of Joomla and such, but forgive me I only put 5 minutes into the thing to illustrate the concept.

I don't think it is reasonable to say that the platform can never re-use class names when things need to be reworked or improved. I also don't think it is reasonable to just leave developers out in the cold with respect to backward compatibility. We must find the right balance, and I'm sure we can manage it.

@AmyStephen I made the change. Thanks. As for your previous removed comment shoot me an email and we can discuss it separately.

@ All, Thanks for a great discussion on this. This is exactly why I wanted to start the platform project. :)

Jeremy Wilken

@LouisLandry Thanks Louis, that is a helpful and detailed look at the intent. I think I agree with you then, now that I see the rationale behind it all. I certainly owe you a beer just for the time you took on that.

@eddieajau @nikosdion BC is only so practical, I'm ok with the idea since we have a buffer (legacy) and can even make it optional in 3.x to prepare for 4.x when its the default (should that be the case). Refactoring code is good, especially if we have plenty of time, so if there can be an overlap (for a whole release) for support to move, then its really not much different then deprecating something.

HermanPeeren

@eddieajau JModelBase cannot be put in 2.5 as is now because it implements an interface with the same name as a class that is used in the CMS now.

My proposal to avoid the same names is just to reduce work, not to slow down development: it is less work to use a new name (like JModelInterface) than to implement a new name for an existing concept (JModel in the CMS) for 10000 JED-extensions. Of course it is allright for people at eBay to use their own preferred names, but the Joomla-platform has more stakeholders (I hope...) and I think we should look for the best compromis there. Using JModelCMS (etc.) is a compromis, but it still implies a lot of unnecessary extra work for a lot of people, which could have been easily avoided by just another name; no slowdown of development, no lack of functionallity, no change of concept. When the proposers of this pull-request are the same as the ones deciding to leave the names as they are in the pull-request or to adapt it for the ease of others, they will probably be left as they are. I doubt whether it's mainly in the interest of the whole or of a few. I guess the only correct answer is: make your own pull request. But then this whole discussion would be unnecessary and we would miss the valid arguments that were presented here. Please (re)consider the whole picture.

Don't want to pick up the discussion Amy left, but just as a clarification: in "classic" literature about MVC, you can have several views to show one set of data from a model. Now, when we just use one view and several layouts, the classical role of views is taken over by layouts. When the view can decide which layout to display, it takes over a bit of the role of the controller. That might explain some of the confusion.

Nicholas K. Dionysopoulos

OK, I finally get it. The eBay Platform, oh sorry Joomla! Platform I meant, is more important than the Joomla! CMS. So, 99.99% of the platform users who only get to use the CMS can go screw themselves. I mean, it's not like there is any naming convention or standard (hint: there is NONE published at the moment) that would be violated by renaming JModel to JModelInterface. So, between screwing millions of people who use the CMS or screwing a very few people who currently use your JModel-is-an-interface approach, you choose to screw millions?! That's exactly the kind of approach that leads 3PDs to not contribute to the project and keep on complaining: you keep us too busy having to work around pointless changes, we can't afford to spend even more time contributing. So, every man for himself. The message was loud and clear. Thank you for the clarification.

Andrew Eddie
Owner

Let's stick to commenting on technical merit and not people's places of employment, nationality, religion or anything else you'd like to throw in to make a point or don't like the fact that people might disagree with you. Please stay on "technical" topic and keep your ad hominem comments to your personal blogs where I don't have to care about or respond to them.

So on that note ... @HermanPeeren, obviously you can't have a circular reference, so JModel*** would be a concrete class that emulates the interface but doesn't implement it. See Louis's example. Whatever the case, this is all speculation because nobody knows when or what parts of the Platform the CMS is going to upgrade in any future version (fortunately not my battle to fight). Additionally, whether JModel is a class or an interface doesn't address the issue that the refactoring of "JModel" and co will result in B/C problems anyway, and downstream developers (not "users") will need to touch their code "somehow".

Now, the facts are if this pull is accepted, it will likely not come into effect in the CMS until at least March 2014 (4.0), in which time the platform has moved on in a lot of other places (and probably so has the CMS) and it will be but one thing 4.0 developers may have to worry about, but I doubt it would be the most significant. I say this not to trivialise concerns about changing names (I respect people can having a differing opinion to me - in fact, you aren't raising any questions I haven't already put to my peers), but to put the pending doom and gloom into perspective. It's not suddenly going to affect millions of users. It will affect possibly a few thousand developers but as a part of a laundry list of things they need to change 2 years from now. That's if the CMS decides to move on newer aspects of the platform and I certainly hope that discussion is conducted with maturity and courtesy (I don't like their chances personally). My understanding is that CMS 3.0 will be using Platform 12.1 legacy, so nobody's model, view or controller classes are suddenly going to break.

We implemented the legacy tree in the platform to deliberately take the concerns of the CMS into account, to buffer the changes in 12.1 yet balancing the desire for other contributors to move on from some really old code. I would say that's the kind of approach that avoids screwing millions of people, but that fact seems to be conveniently ignored. Frankly, if you don't want breaking changes to occur at all in the CMS, that's something to take up with the CMS maintainers.

So with all that in mind, for me, when I want to pass a variable that's part of a MVC triad probably by composition or dependency injection, I prefer calling a spade a spade, and that is a model, a view or a controller, which in Joomlaland translates to a JModel, a JView or a JController. The fact that those are interfaces makes the design process for me as a developer far more logical and convenient.

As for "standards", well, no, one doesn't exist because this is the first real foray into interfaces. I think a rough standard should come out of it and I would say where it's reasonable to predict a package is going to be used for composition or dependency injection, the most natural "name" should be reserved for the interface, not the concrete class, if that's the sensible thing to do (it won't be for all packages, for example, JObject should be a concrete class because it follows the value-object pattern). Please see how I did this in a proposed reworking of Joomla's access package (https://github.com/eBaySF/joomla-platform/tree/content/libraries/joomla/authorisation). That's a package with multiple interfaces and should highlight how the "interface" suffix would get clunky (to me anyway). That code has been there for a long while now with no negative comments. For what it's worth, it's a pretty good example of the strategy pattern, but I digress.

In conclusion, I hereby certify that my "preference" for naming convention comes from my capacity to use my own brain as a sentient member of the human population on this planet - neither my employer, my dog nor anyone related to me actually has a say in it, just in case anyone was worried I'd become a zombie ;) (zombies rock btw!)

Nicholas K. Dionysopoulos

Andrew: OK, I'll stick in pure technical terms.

In pure technical terms, there is no way that the CMS will not continue using the latest version of the Platform. At some point PHP 5.3 will be EOL, 5.4 will be deprecated and the next version (6.0?) will most likely introduce even bigger changes. In order to stay abreast with current versions of PHP, the CMS has no other choice but to use the latest platform. The other choice is forking the platform and maintaining it into the CMS, which would be an 180 degrees turn. So, please, don't imply that the CMS may not be using the latest Platform, downplaying the significance of Platform changes to the CMS. We all very well understand that the CMS can't technically exist without the Platform.

Now some purely technical questions.

  1. If JModelBase implement JModel (an interface), how can the CMS provide another JModel class which extends from JModelBase?
  2. Are there plans in the works to use PHP Namespaces in the Platform and the 3.0 version of the CMS which would address that concern, enabling developers to use e.g. the JCMS namespace for the CMS libraries?
  3. I was under the impression that you said that backwards compatibility breaking without deprecation was considered a bug. Did that change at any point, or that was never really the case? The thing is,what exactly is the policy regarding backwards compatibility?
  4. For the "how the classes should be named" question, is the official answer "we'll be adding interfaces with the same name as existing concrete classes"? Since this is a matter of coding style, I'd like to see that (or whatever the convention you want to use is) written in the coding style documentation. If there is a policy, make it public. If there is no policy, create the policy and make it public. Don't startle us.
  5. Given that policy(?), should I safely expect any other random platform class I'm currently using to suddenly change name without a deprecation path? In other words, should I consider the Platform API to be in a constant Alpha stage?

There you go. Technical questions. Thank you in advance for your answers.

Andrew Eddie
Owner

@nikosdion I'll take that as a sort of apology for your outburst ;)

If JModelBase implement JModel (an interface), how can the CMS provide another
JModel class which extends from JModelBase?

If can't but see Louis's example for how to work around this.

Are there plans in the works to use PHP Namespaces in the Platform and the 3.0
version of the CMS which would address that concern, enabling developers to use
e.g. the JCMS namespace for the CMS libraries?

There are plans once all classes follow the auto-loader convention but I doubt that will be ready for CMS 3.0. It's a conversation to have but we aren't ready to have it. It could, however, be a reality for CMS 4.0 - your problem dissolves then.

You do understand what the legacy tree is doing in the platform don't you? I somehow feel you don't and that you are worried about a problem that we have already discussed and solved.

I was under the impression that you said that backwards compatibility breaking without
deprecation was considered a bug. Did that change at any point, or that was never really
the case? The thing is,what exactly is the policy regarding backwards compatibility?

The MVC refactor was always going to be a breaking change - that's been no secret. However, we implemented the legacy tree to be able to do this "safely" and allow the CMS and other downstream users (developers) the choice of when to make the move. The old MVC still exists, but you have to bootstrap with import.legacy.php which is what the CMS should be doing in 3.0. A lot of thought has been put into how these types of situations can work were everyone wins.

To be perfectly honest, the new auto-loader allows you to now override any core class at all, so in that respect, the concern is moot, but that doesn't mean I'm not trying to listen to what you are saying. Developers can be using 2.5 code well into 7.0 or 8.0 for what it's worth.

For the "how the classes should be named" question, is the official answer

No, that's just my opinion - you can assign whatever weight you like to it expect "official" (that comes from the PLT alone and I am most certainly not PLT). You have the liberty to disagree and I promise I will not use how you are employed or how you make your money against you ;)

"we'll be adding \interfaces with the same name as existing concrete classes"?

That, again, is my personal opinion and it has to be looked at case by case. This topic has not really been discussed on list yet but likely will as a result of this pull. The way we do it in the platform is someone makes a pull request, and if the maintainers feel that insufficient comment is being made, they'll ask the person to discuss it a bit on list first to take the platform community's temperature. It's all very open and organic and, most importantly, public.

Since this is a matter of coding style, I'd like to see that (or whatever the convention you
want to use is) written in the coding style documentation. If there is a policy, make it
public. If there is no policy, create the policy and make it public. Don't startle us.

I won't startle you if you don't make irrational claims (yes, we can all see what you put on Facebook). Fair? I don't know if you follow the platform list, but if you do, you'll see a good history of being open and transparent about various issues and semi-regular reports about decisions that have been made internally. We always try to point out pull requests or changes that are going to be potentially controversial either on list or some other social media (and there's always pull RSS for the really serious players). Nothing's changed on my end and nothing is cast in stone. This is the first pull request that actually touches interfaces in a serious way so it will likely precipitate a standard.

But let me say again, because this seems to be lost in the conversation, this won't affect the CMS extension developers until at least March 2014 if timing is still on track for CMS 4.0 and if the CMS decides to change it. This is because we implemented a legacy tree to delay the effects of breaking changes (even though we have every right to do them with a major increment). This was promoted heavily at the time and widely accepted. I'm struggling to see why this measure is now being treated with hostility.

Andrew Eddie
Owner

@HermanPeeren

Now, when we just use one view and several layouts, the classical role of views is taken over by layouts.

That's only in JViewHtml because it's still useful to follow the paradigm we use in the CMS. JViewBase doesn't have any layouts at all so there's basis for your "classical" solution.

Andrew Eddie
Owner

@nikosdion

In pure technical terms, there is no way that the CMS will not continue
using the latest version of the Platform. At some point PHP 5.3 will be
EOL, 5.4 will be deprecated and the next version (6.0?) will most likely
introduce even bigger changes.

Just on that point, we are trying to follow the version of PHP support on Ubuntu's LTS. When it moves is probably when the Platform will allow upward movement. But even so, the CMS can, today, set the minimum spec to PHP 5.3.2 and it will all work (it has to for 3.0 anyway). The version of PHP won't affect the ability to support a legacy and non-legacy tree. PHP EOL is something the platform has no control over but we'd have to respond to it as best we can, just as the CMS will have to do. However, speculating on the arrival date of PHP 6 has no bearing on considering the technical merits of this pull request, in my opinion. But I can assure you we aren't trying to pull a Nooku, where the only thing you can be sure of is something will break in a big way. Give us a bit of credit ;)

Nicholas K. Dionysopoulos

It's not an outburst and I don't apologise for what I said. I insist that the way this is implemented is absurd, even though the code is good.

Louis' approach requires changing our components' classes. Do I have to say again why this is a bad idea, or the previous "outburst" is good enough? Also note that in that "outburst" I also mentioned another workaround which does work even if the interface is called JModel, but it's ugly as hell and removes all code hinting in the IDEs. Also note that I absolutely detest having to repeat myself, especially when what I've said is written 800 or so pixels above on the same web page.

So, I take it that using PHP Namespaces is not an option, at least not for the foreseeable future. Of course you wrote that reply in a way that the Oracle of Delphi would be envious of. It can mean that they may be used, maybe they won't, maybe you'll discuss about them, maybe you won't. A simple "we have no idea yet" would have been more clear, I guess.

Yes, I do understand what the libraries/cms tree is for, like I understand that the Earth is round and revolves around itself. Please remember that I am actually using that Joomla! thing, I didn't land here accidentally from outer space ;) However, if the CMS doesn't want to startle developers and have JModel & co as a concrete classes which will be used by 3PD extensions, then the CMS has to essentially fork JModel, JModelBase & co inside the lirbaries/cms tree. Do you honestly think that having the CMS fork the Platform which was originally forked by the CMS is or even remotely sounds like something sane? So I will stick to my Facebook comments (which, BTW, come from Twitter and intended to be public) about what this argument really is...

So, there is no official rule about the naming of interfaces and classes, you are not in PLT, the PLT does not have an answer for that, yet the decision made(?) is to keep the JModel etc naming for the Interfaces which breaks 3PD extesions. Am I the only one which sees a lack of continuity in this train of thought? Shouldn't we assume that both you and me are completely wrong unless the PLT rules on which is the best approach (maybe there's a third approach we don't see)? I never realised that this was a PLT matter until you told me, thank you about that.

I agree that I don't closely follow the platform list, but I knew the MVC change would happen. It was being discussed for ages, it was very hard to not hear anything about it :) However, what I had gathered is that it would be a total rework of the MVC paradigm in Joomla!. Well, it is and it isn't. Surely, it's a huge change in the Platform and –as I've said again– it's a step to the right direction. I have to give credit about that and I think I did over and over in my comments. However, I also see that the CMS can pretty much escape unscathed by this change if and only if the interfaces are suffixed with Interface or are at the very least not named the same as existing concrete classes of the CMS.

For the record, I'd like to address your last post's points:

  • I surely understand that you have no control over PHP EOL. I'm not an idiot, please stop replying to me as if I were. You are underestimating my intelligence and the intelligence of everyone reading these comments.
  • I made the point about a PHP version becoming EOL to stress one reason why the CMS can't fork off the platform and HAS to follow the platform changes. There simply isn't enough manpower in the CMS to also maintain a forked framework and do major changes like the ones required in a PHP version going EOL.
  • As a result of the above, any implication that the CMS could fork off the Platform is, how shall I put it, misleading. Ergo my remarks which upset you (I apologise about my strong use of language in those comments, I forgot that's considered very vulgar outside the Balkan area)
  • I do understand that you are not trying to "pull a Nooku"; if I believed that, I'd have become a Drupal developer or would have forked the CMS :D
  • I do give you guys a lot of credit. I've already said that this is going towards the right direction. I believe that I had said to Louis while at J! Day Chicago last August that the MVC should be decoupled from the CMS and this is when I first heard that an MVC rewrite was going to happen at some point. How could I ever not give you credit for doing something which I believe is good for the Platform's architecture? My only beef (and I repeat: my *******ONLY******* beef) with this merge request is the naming of the interfaces. The current naming does not have any other merit (technical or otherwise) than being "the way you like it" and breaks BC in the CMS.

You have still not given me one good TECHNICAL argument about WHY should we name the interfaces JModel etc and break BC when we can name them JModelInterface etc and NOT break BC. In the latter case this will be possible THANKS to the libraries/cms tree WITHOUT the CMS having to fork off the entire MVC structure. Is there a TECHNICAL reason for doing that, or it's "Just because we can"? It's either technical, or personal, it's either a PLT decision or your decision. Please make up your mind. Which one is it and why? If it's a good technical reason, backed by the PLT I'll just shut up.

HermanPeeren

Did I understand it well? Correct me if I'm wrong.

  • If this pull-request is accepted as it was presented now (so: with the short names for the interfaces), then the current mvc-classes, like JModel etc., will be added to the legacy-tree with changed names, like JModelCMS etc.
  • If that would be the case for 12.1, as is stated in the docblocks, so that probaly was the intention, then as soon as the CMS would use Platform 12.1 all existing code of the CMS and Joomla-developers that extends from those mvc-classes has to be adapted to the new names of the legacy-classes if they want to keep them working in that CMS-version.
  • Was it intended that CMS 3.0 would use at least Platform 12.1?
  • CMS 2.5 will not use a Platform-version with those new mvc-classes/interfaces

Louis'plugin was a schetch, intended to show how you could use an extension both for a new CMS-version (with the interfaces in the framework) as well as for the "old" one. I think it doesnt work as sketched now, but we can produce something that works (as Nicholas allready showed). Still it will need quite some reworking of existing code, only for the sake of renaming.

What I don't like about this is: that we cannot use the current and the new MVC together in one installation, without changing the current code. That would give the possibility to experiment with this very nice and very needed improvement of the platform while at the same time the old stuff keeps working. The odd thing is, that such a smooth transition is possible if only the old mvc-class-names would not be reused.

I wrote this before Nicholas last posting... but I'm much slower than he is (in may aspects). Still posting it, but neglect the overlap.

OctavianC

Hi everyone,
I have to agree with Nicholas on this one. It would make better sense for backwards compatibility's sake to let the CMS define JModel.
I also understand his frustration - we've been maintaining most of our extensions for 2 versions of Joomla! for quite some time now (first 1.0 and 1.5, now 1.5 and 2.5) and it's overkill which could be avoided.

Fotis Evangelou

If you eat your own dog food, you always stay away from such pitfalls...

If you don't on the other hand, well...

Rob Schley

@HermanPeeren

Your first statement is not correct. The old MVC classes have already been moved to the legacy tree and have kept their original names. See https://github.com/joomla/joomla-platform/blob/staging/libraries/legacy/controller/controller.php When using the legacy platform, the classes in the legacy package are loaded instead of the main joomla classes. So you can still use the familiar MVC classes with no changes by using the legacy import file.

ianmacl
Owner

My sense is that the issue here is the desire to allow some component developers to use the newer MVC packages without breaking backwards compatibility for legacy extensions. The legacy bootstrapper is not the answer to that question. What you'll notice though is that the new MVC package has been significantly decoupled from most of the platform. Meaning - it does not depend on having a bunch of other classes from the legacy tree as well.

The result is that newer extensions can use the new MVC packages by loading those particular files. The MVC classes are unique in a sense in the context of Joomla extensions because none of those classes get loaded until the component itself loads them. This means that newer components can use the new MVC classes by simply manually loading them.

Legacy extensions would by default use the legacy implementation of JModel, JController and JView. IMO this solves the problem rather nicely.

I balance all of this with the discussion of the fact that CMS 4.0 is expected to be released in 2014 - approximately two years from now. I would expect that two years of development will bring with it a good amount of changes especially with the rather significant shifts we are seeing in the web.

HermanPeeren

OK, thank you, Rob, for the correction! I misunderstood something, sorry. I incorrectly thought the legacy tree was an additional library, but it is used instead of the platform tree.

Now I also better understand Louis' plugin: as a layer between the old and new classes. But that is not the way it is used in the legacy-tree.

The only thing that is not possible now is to play around with the interfaces while using the legacy-tree, but well, that's overseeable. Much of my worries have been taken away.

The only difference of the legacy tree with the current library is, that the MVC-classes have been moved to their own folders instead of residing under /application/component. But that is probably a better place anyway when using the autoloader.

Louis Landry

@nikosdion With respect to a naming convention, it should be based on use rather than whether something is an Interface or Class. The only time when it really matters is when you instantiate objects or syntactically in the class definition (extends vs implements). Once an object is instantiated all that matters is the object's type, and in this case there is no difference. In general, the notion of some namespace prefix or postfix declaring something an interface is unnecessary. If you are unsure whether you have to extend or implement a type then you probably shouldn't be using it yet. That's what documentation and to some degree IDEs are for.

Serializable, ArrayAccess, Iterator are all native PHP interfaces among others. I think each of them are reasonably named interfaces and none of them adopt a prefix or postfix to indicate that they are namespaces. In reality it doesn't matter that they are interfaces. What matters is that they describe the objects which implement them.

Serializable is obviously describing a property of an object (sometimes called a "marker interface"). This is actually a very common use of interfaces as adjectives to describe something about an object. ArrayAccess is also describing a property of an object. It's really more of a verb than an adjective, but it still fairly clearly describes something about the object that implements it. I think there could be potentially be improvement there in maybe changing ArrayAccess to ArrayAccessible so that it better reflects the fact that the interface is describing a property of an object, not the type of object.

Iterator is a slightly different animal. It is still an interface, but it is describing slightly more than just a property of the object in my opinion. Sure, it could have also been called Iterable I suppose, but I think there's a little more to it. I think Iterator gets a little closer to describing the type of thing (even though admittedly the concept of what is an iterator is very abstract).

If you look at work I did a couple of months ago around streams, https://github.com/LouisLandry/joomla-platform/tree/streams/libraries/joomla/streams (that admittedly isn't quite done yet), you'll see something similar though I didn't follow the *able naming convention with the interfaces that define the properties of a stream (so it's closer in concept to ArrayAccess). There are a lot of interfaces in that package. Most of them are marker interfaces, but there is one… one special one. JStream is an interface. I think of it in the same way I think of Iterator. If an object implements JStream than you can trust that it is a stream handler. Similarly if an object implements JStreamSeek then you can trust that you can seek along the object as a stream.

This is not dissimilar to a model. Inherently a model is essentially what it models. In the physical world if I were to ask you to create a model of a chair, and you did a good job, the model would be hardly distinguishable from an actual chair. In OOP if I were to ask you to create a model of an document, and you did a good job, it would be simply an object representation of the document. Because of this, calling it a JModel makes a bunch of sense to me. Calling it a JModelInterface is like me calling you a human being instead of just a human. It's wordy, repetative and ultimately unnecessary.

I certainly didn't make this way of thinking up, I just happen to agree with it. There are lots of conversations all over the web about how interfaces and classes should be named and how they should relate to each other. For what it's worth Martin Fowler agrees with me (http://c2.com/cgi/wiki?DontDistinguishBetweenClassesAndInterfaces) though he is hilighting a reason I haven't touched on here that I also happen to agree with. It's OK if that doesn't mean anything to you, but as one of the leading minds in OOP design and architecture I thought it was worth mentioning. It isn't something out of the blue that we came up with to make people's lives harder. The idea is driven by a hope to keep names simple and semantic, and be as forward thinking as possible as we make iterative improvements.

Andrew Eddie
Owner

@nikosdion

My concern with your comments is that you chose to malign where people work for a living, and you continue to dance on the edge of personal ridicule to embellish your arguments. Please keep your replies technical and objective so they can't be misinterpreted - I don't want to have to ask a third time.

So, I take it that using PHP Namespaces is not an option, at least not for the foreseeable future.
Of course you wrote that reply in a way that the Oracle of Delphi would be envious of. It can mean
that they may be used, maybe they won't, maybe you'll discuss about them, maybe you won't.
A simple "we have no idea yet" would have been more clear, I guess.

If I had no idea I would have said so. Let me put this another way that is hopefully clearer for you. So my answer was that name spacing is on the table (yes, it is an option), but it is not worth having the discussion until all the classes in the platform conform to the auto-loader conventions (a clear and definable goal). I certainly can't give you a date as to when that will be. That relies on community contribution which has been happening steadily over the past few months but I'm not going to force anyone to do anything they don't want.

I am very much in favour of using namespacing but I am not in favour of doing it piecemeal. If we do it, we do it, not pick one package here or there at a time. That would be truly insane. I would hope it's something we can drop into 13.1.

If you want to start that discussion now on the platform list, you are most welcome but we (the maintainers) felt it wasn't the most important discussion for us to be leading at this precise moment. When everything auto loads, it should be a relatively short conversation and a couple of pull requests and we are done.

Having said that though, adding name spacing does not necessarily equate to "no change required for extension developers". It's another layer that needs to be understood and managed. It will address the ability to use different implementations of the same classes/interfaces in the one execution, but that's not to say it isn't without it's fair share of gotcha's. There's nothing to say the standards we come up with for name spacing won't still require you to change your code in, for example, Joomla 4.0. I guess we'll have to wait and see what comes out of the discussion when we have it.

@HermanPeeren

Just some additional clarification. The /joomla/ tree and the /legacy/ trees are still all the one platform. However, when you bootstrap with "import.legacy.php" it tells the autoloader to look in /legacy/ first, then in /joomla/. In that case, when you write $model = new JModel it will look in /legacy/ and find that JModel class and use that.

When you bootstrap with "import.php", the auto-loader, by default, knows nothing about /legacy/ and so JModel will be an interface (on the basis of this pull), but it won't find JModelForm in the legacy tree because it has not been told to look there at all.

The auto-loader is actually quite powerful (you can see that in Louis's plugin) and I have on my todo list to add some more documentation about it.

Jeremy Wilken

@ianmacl I see the challenge in the CMS of having a class in the legacy folder and in the Platform with the same name but with different implementations. JModel (legacy) can be used by a module to load records on the same page where a component tries to use the new JModel (interface), for example, so we could actually experience a collision of class names. Am I thinking that through right?

If so, that might make it impossible to make them both available in the CMS, there would have to be a specified break where everything has to be updated. There are ways to ease that, perhaps by adding a legacy JModelBase that extends the current JModel and hopefully in the coming months people would update their code. Then when the JModel changes for good, if nobody is directly extending it in the CMS or extensions, we have a bit better transition. However that is a discussion for the CMS more than for here I suppose.

Nicholas K. Dionysopoulos

The way the MVC transition is being handled does not harbour the conditions for graceful deprecation of the old, concrete MVC classes. It merely drops the problem on the feet of the CMS, which has to provide its own MVC implementation (at this point it's no longer clear to me if this should happen in the legacy or the cms tree, or a new one). Given that the heart and soul of Joomla!'s API is the MVC implementation –and that's the "selling point" of the Joomla! vs any other PHP CMS elevator pitch– this does sound like a bad idea to me. We are essentially telling people to start using a deprecated API which will most likely get removed / break hard in the not so distant future. There are no guarantees that the CMS will maintain these classes forever (and if you ask me, it shouldn't - I believe we all agree on that). When that happens, existing extensions will have to be refactored with the new classes in order to work at all. Even if that's in two years, it doesn't make it any better. It makes it worse. In two years each one of us will have even more code to refactor than today and will have to do an overnight refactor, too.

In practical terms, this will not / cannot happen overnight. I mean, over two months into the Joomla! 2.5 release cycle, I still see clients running Joomla! 1.6 and 1.7 on live sites (despite being vulnerable and end of life) because some of the extensions they use are not ported to 2.5 yet. The amount of changes required to move an extension from 1.6 to 1.7 are relatively small and from 1.7 to 2.5 are minimal. Yet, code migration is a huge issue. If you have to do a huge amount of work to get extensions written for J! 3.x to do as much as run on 4.x I can safely assume that it will take significantly more than 2 months.

And that's the root of my concern. I don't want to see a Joomla! version released with no compatible extensions. This is bad for the Joomla! CMS, bad for the Platform and bad for 3PDs. I honestly don't care who works where or why someone decided to do this or that. I am only concerned of the long term consequences to my business and the businesses of everyone using Joomla! (not just 3PDs, but also site builders, trainers, template makers, freelance developers and so on). Since this doesn't appear to be such a big concern to anyone else, I won't say anything more. I already know what I have to do for my software to keep ticking across Joomla! CMS and Joomla! Platform versions, so this all really is somebody else's problem, not mine. Please ignore my comments and my concerns as they apparently do not apply to anyone else than me.

Rouven Weßling
Collaborator

I don't wanna get into the whole name debate - I don't care all that much TBH - but there are ways to ease the transition even with conflicting names. Joomla 3.0 is still 5 months off. We could add aliases to the current MVC classes called JViewLegacy, JControllerLegacy and JModelLegacy. That either with 3.0 or 4.0 (I'd leave that up to debate) the old class names wouldn't be supported anymore giving developers access to the new MVC classes/interfaces.

So the question would come down to this: Would it be reasonable for extensions that support 3.0 to not work on 1.6 to 2.5.4 but work with 2.5.5 and up?

I do think we should move this discussion to a better venue, since at that point it becomes only relevant for the CMS. I'd like to see more discussion on the code than just about the name of three interfaces.

Andrew Eddie
Owner

@nikosdion thanks for that reply. It's really helpful.

The way the MVC transition is being handled does not harbour the conditions
for graceful deprecation of the old, concrete MVC classes.

Correct, that's why we've moved the old code to the legacy tree.

It merely drops the problem on the feet of the CMS, which has to provide its own
MVC implementation (at this point it's no longer clear to me if this should happen
in the legacy or the cms tree, or a new one).

The intention is that the CMS will still use the legacy tree. It can implement whatever it wants, but it doesn't have to, nor is there a pressing need to.

We are essentially telling people to start using a deprecated API which will most
likely get removed / break hard in the not so distant future.

We can rename the /legacy/ folder to something more palatable. I understand your concerns but I don't believe that in 2 years time, this will be the biggest issue extension developers face, nor the only one. I'd actually be very concerned for the well-being of the CMS if that wasn't the case (in other words, development has probably stagnated).

There are no guarantees that the CMS will maintain these classes forever
(and if you ask me, it shouldn't - I believe we all agree on that). When that happens,
existing extensions will have to be refactored with the new classes in order to work at all.

There is nothing to suggest they won't have to do that anyway. You may disagree, and it's speculation, but it's equally valid. I'd gladly take a 20-point search-and-replace list for my extensions than forcing CMS users to go through another painful migration to 4.0. But even worse would be if 4.0 has no significant benefit over 3.x - but that's really off topic for this discussion.

Yet, code migration is a huge issue. If you have to do a huge amount of work
to get extensions written for J! 3.x to do as much as run on 4.x I can safely
assume that it will take significantly more than 2 months.

That's really an issue for the CMS to decide (for 3.0). However, if this pull is the only forced change imposed on you in 4.0 (which I sincerely doubt), you'll complete it well within 2 months and there are already strategies here to make that near painless. I'm hearing what you are saying (I am listening), but I don't think the imposition on developers is unreasonable, and it's certainly allowed for in the development strategy.

And that's the root of my concern. I don't want to see a Joomla! version released
with no compatible extensions. This is bad for the Joomla! CMS, bad for the
Platform and bad for 3PDs.

I agree completely.

Nils Rückmann

@nik i don't think that no one cares about those problems. but it seems like everyone has surrendered because it doesn't matter what people are thinking. the plattform goes it own way or better: the way which one-two guys want ..

Nicholas K. Dionysopoulos

@realityking +1. This is a much better solution than what I proposed. Thank you.

@eddieajau Seems like my English skills and the cohesiveness of my thoughts are at their best around midnight :) Thank you for clarifying the intent of the legacy tree. The name is a little misleading, especially if some classes in there are supposed to be an at least mid-term solution. The term "legacy" usually brings to mind the 1.0 legacy layer and its relatively short lifespan (it was practically abandoned and started causing problems with properly written code two years into the 1.5 release).

Regarding keeping the old JModel concrete class and the new JModel interface in parallel, I could see a problem before Rouven's suggestion. Since the new MVC structure supports HMVC, it is more than fathomable that developers will use it to render views of their components in modules. This would mean that at a given page we could have both an HMVC-powered module (the new JModel interface would be required) and a legacy component (the old JModel concrete class would be required). Without namespaces it would be impossible not to throw a Fatal error in this case, hence my question about namespaces. I know that namespaces are not easy to implement, but they'd be a good long-term solution if we were to keep the legacy classes named as JModel. However, if Rouven's suggestion is implemented this is no longer a concern and we can forget about it.

I agree that 4.x would be different than 3.x in many more ways. I will tell you what I was thinking. When 1.6 was still in beta stage, I began making my components compatible with both 1.5 and 1.6. The 1.5 support was considered stable and the 1.6 support was experimental. The upside of this approach is that once 1.6 was out, I had a version of my software which was perfectly compatible with the new CMS version. That's what I want to ensure for me and other developers: that we can start working on supporting the new STS without dropping support of the current LTS and without maintaining dual codebases for each component. Reading what I wrote, I see that I never quite spelled it out, making it impossible for anyone else to understand the context of what I was saying. Again, Rouven's suggestion solves that, as it would be relatively easy for 3PDs to fully support 2.5 and start working on 3.x compatibility.

One off-topic side note: 2 months for implementing big changes may sound plenty, but they're not. If the only thing I'd have to do all day long is write code, the MVC change would take me 4-6 days to complete for one component. Unfortunately, I have many components (I have 11 code repositories and 6 components) to maintain and I also have to do support, documentation, testing across different odd servers, write presentations and so on. This is pretty much how every other developer's day is, which means that 2 months is barely enough for one component. We need to start working on compatibility before a new version is out. Again, if Rouven's suggestion is implemented, this is no longer a concern.

I am glad we all agree on what's good for the CMS and please excuse my outburst.

@sybrek Well, I think it really all comes down to the apparent lack of planning or lack of communicating it. Right now there is a rough roadmap for the platform, but there is no roadmap for the CMS. The community is not aware of whether Platform changes will be adopted by the CMS, when/if that would happen and so on. This doesn't allow us to plan our releases and site roll outs and upgrades in a sustainable way. But that's another topic for another venue.

Andrew Eddie
Owner

@nikosdion thanks for your reply (and you are excused). Appreciate it. I've added auto-loading and namespacing to the roadmap if people are looking for things to do :)

Matias Griese

I have to join the discussion (even if it took 2 days to write it). The new MVC implementation looks very cool and I would love to use it, rather sooner than later.

That said, I must agree with Nicholas, Herman and the others that backwards compatibility to the previous version (both CMS and Framework) must be kept at all cost. In this case the whole issue could be easily avoided by using different, but non-optimal naming.

Like @gnomeonterun said, having two different implementations from the same class will never work in practice. This is because of Joomla loads more than just the component: there are plugins, modules, libraries, language and templates and any of those can depend on legacy classes. As a result you cannot have both legacy and new extensions in the same page as you will likely end up loading the wrong implementations of the classes. Components are also often using models from other components -- if nothing else, many of the public APIs are using models to do the real work.

This means that there will be a lot of dependencies, where you end up on upgrading every extension in your system in order to get your site back up and running. As there's no dependency management, migration to the next Joomla version will likely break up your site (if not right away, the first component upgrade can do that). Even if Joomla had the best possible dependency management, most Joomla sites would be forced to run deprecated software for a prolonged time, waiting for the new releases that will be compatible not only with the new Joomla, but with all the other extensions they have installed into their sites.

I'm sorry to say this, but the names JController, JModel and JView are reserved words from the earlier versions of the framework and cannot be reused until they have been properly deprecated. Doing anything else will -- in my eyes -- be considered as being a critical bug.

I also disagree that this is only a CMS bug. This is incompatibility in the Joomla Platform itself -- my current platform code cannot be made to work in both the current and the next version. As Nicholas says, applications are always at least one version back in their development compared to the framework (or CMS), and that is the best possible scenario.

Changing a few class names with a global replace is not an issue for developers. It can be done in a few minutes, no big deal. But changes like this become easily very expensive for the companies which create sites for hundreds of customers with small maintenance budgets.

I'm doing a contract work for a company, which is now in the process of migrating ~100 relatively small sites to Joomla! 2.5. Migration will cost them $50-80k and it will still take something like 4-6 months to get everything up and running on the new version -- and we started conversions 2 months before Joomla! 2.5 was released. Migration from J!1.0 to J!1.5 was easier, mostly because of they are now relaying more on the framework, mootools and highly customized templates. As the result they are not using any 3rd party components, Joomla! Framework or Mootools anymore (for the new sites) and now they are considering of moving to another CMS/platform, which is cheaper to maintain.

In short:

I'm not that worried about the extension developers. I'm much more worried of the end users (individuals, small organizations and companies) who have tight budgets and limited resources.

Matias Griese

I just saw the newest comments, so my last reply may look a bit "old". It looks like we could have a working solution:

+1 @realityking That partly solves the deprecation issue in CMS -- it's the best solution so far if using new names for the classes is out of the question. I don't think that there are optimal solutions for this discussion, but that's something I could accept as being an extension developer. It would leave us clean naming conventions for the future, too.

AmyStephen

@LouisLandry -

Glad to see the controller serialized with its input - that certainly takes care of a major weakness with the current MVC implementation and opens the door for chaining and HMVC.

I do not understand why the application itself is passed into the Controller. Could you please expand on the benefits or provide examples that highlight how this might be useful?

AmyStephen

@HermanPeeren Thank you for helping to explain my point on the "What should a View really be?" question for a MVC application. And, how it's my opinion that the View should be what we call a layout, and what we call a View should be a Controller.

@eddieajau Your response to Herman suggests this other way of looking at it might not be clear. So, first, just to see if we can get to an understanding without saying one way is right or wrong. From there, it will be easier to think about the pro's and con's of each. I agree with you that the JViewHtml is elegant, simple, easy to extend, lovely code. But, I very much believe it's a Controller.

A controller is the only structure in the triad that should be directing logic. It should be asking the model for data, not the view. The simple fact that this new rewrite is passing the Controller into the View is an indication that the View is a Controller.

Here are two very good examples of what Views look like - note how these look like what we call Layouts in Joomla:

http://msdn.microsoft.com/en-us/library/dd410123.aspx

In this MVC Tutorial - please look for the phrase "Now let's look at some views" - http://www.thecoderush.com/mvc-tutorial

The reason this matters is that properly separating the three elements creates a great deal of flexibility. That's what is missing in Joomla's architecture and I very much believe a large part of that inflexibility is due to incorrect definition of the View.

As I study what is going on with Drupal 8, it strikes me that Joomla's strength is it's JDoc statements. I think JDocument needs simplification, but even in it's current form, it's pretty awesome.

Where Joomla's architecture falls short is reuse of code and poor information sharing between extensions. I hope that you'll take a bit of time to think about the "View as a Controller' - play with it. Take JViewHtml and make it JControllerDisplay and have it extend JControllerBase. Consider a central place for sharing Views (Layouts) that can be used by any extension. I have personally found things open up in surprising ways when that takes place.

Andrew Eddie
Owner

@AmyStephen great comments/questions.

I agree with you that the JViewHtml is elegant, simple, easy to extend, lovely code.
But, I very much believe it's a Controller.

Well, it is sort of. I guess it depends on how far away from the existing Joomla paradigm you want to shift. I think it's important to at least support the current paradigm in principle. In theory (and I don't advise this), you could drop this MVC into Joomla 3.0 and while the conversion would be a pain in the butt, developers would still be able to logically map controllers to controller classes, models to model classes and views to view classes. To tell them to start mapping views to display controllers, I feel, would be inflicting too much pain.

A controller is the only structure in the triad that should be directing logic.

In a classical approach, yes, but the classical approach was invented for stateful applications (Java apps) where the controller broadcast instructions hither and thither (and views were objects that updated form controls and things, and you could argue they were controllers of sorts as well). We don't have that luxury in a stateless web world necessarily so the classical paradigm has shifted a bit. I asked Stefan Priebsch about this last year at ZendCon and that was the essence of his reply. All that means is that it's ok for the view to have access to the model to go get the data. The important thing is to ensure the separation of duties, even if the view is kind of bending the rules a bit. Like all things, the design patterns are there to assist, but "bending" them to is also permitted. Having said that, your own application can be as strict as it likes - there's nothing preventing you from doing that (just opt out of using the view package).

The reason this matters is that properly separating the three elements creates a
great deal of flexibility. That's what is missing in Joomla's architecture and I very
much believe a large part of that inflexibility is due to incorrect definition of the View.

No, I don't think it's the incorrect definition of a view, it's certainly an "accepted" implementation, but I think the tight coupling to the "extension" paradigm, and not an "application" paradigm is where the road block is. This proposal does away with all that baggage.

Where Joomla's architecture falls short is reuse of code and poor information sharing between extensions.

Correct. Hopefully we'll see some good examples of platform applications that show how this can be done better, architecturally at least, and the CMS can follow suit when it can. Were all classes in the CMS, including extensions, to follow the auto-loader convention, it would make life a lot easier.

Take JViewHtml and make it JControllerDisplay and have it extend JControllerBase.

I think that's too big a jump but, as I've said, there's nothing stopping you from developing a proof of concept around the idea of JControllerDisplay and I actually believe this pull request would help you do that. As I said, I think we must keep the views more or less in line with how Joomla expects them to behave (just a lot cleaner) ... for now. I think it's easier to talk with code so throw an example together and let's all see what we think about it and making sure we are debating the same idea.

Consider a central place for sharing Views (Layouts) that can be used by any extension.

That's already possible. Note the SplPriorityQueue that holds paths (have a look at the unit tests and you'll get a feel for how amazingly powerful that is). So, for example, you can inject a "common" path at a low priority into the path queue (maybe at the framework level, maybe via a plugin), and your extensions can add their own, or even provide overrides for the common layouts. It's layout overrides on steroids and a very cool and very simple solution to what is a very complex problem in the CMS today.

Does that help?

AmyStephen

Good, we're on the same page in terms of concepts.

In a classical approach, yes, but the classical approach was invented for
stateful applications (Java apps) where the controller broadcast instructions

Agree. However, you solved the problem of maintaining state within the MVC with serialization.

That's already possible. Note the SplPriorityQueue that holds paths (have
a look at the unit tests and you'll get a feel for how amazingly powerful
that is

Yes, I did see that (and should have mentioned it). Big thumbs up. Another problem solved.

Above in the description, Louis said:

we strongly recommend considering using one controller to one action moving forward.

I totally agree with that. Combined with the Controller serialization, it sets up chaining and HMVC neatly.

But, 'display' is a nothing more than task, just like create and update and delete. Consider, you wouldn't have to inject that View with the Controller if you just let it be the JViewHTML be the Controller it wants to be. Sets up RESTful applications nicely, too.

I guess it depends on how far away from the existing 'Joomla paradigm'
you want to shift. I think it's important to at least support the current
paradigm in principle.

I'm confident from your response that the platform team understands the point and it sounds like this has been considered but believed to be too much of a change to thrust on the existing developer community.

I do not envy the job of balancing those competing goals of keeping software viable for new development and mitigating the cost of keeping pace with the API and alienating the existing Joomla commercial developer market.

The one question I would ask those who are resisting platform change in the name of not killing the CMS, are you certain which poses a bigger danger? Change? or a lack of it?

Consider, there is absolutely no reason for an extension to have code specific to an application (and therefore be split into administrator and site components). Should architectural constraints that force redundant code be retained so that current extensions don't need to be changed?

Would a goal of achieving codeless components driven by parameters be a good goal or something that should be blocked at any cost? Which is better for the CMS?

The CMS does not have a captive audience, folks. The market naturally shifts to better solutions. The first priority must be ensuring Joomla is in that position and the big gains are going to come from the platform. Don't fight 'em - they are helping you.

Thank you for your response @eddieajau - I'd like to see the View step taken. I hear the concern on how much change to introduce. I believe you understand the point. So, you guys gotta do what you think is best. I can respect that.

AmyStephen

@LouisLandry - also, why separate the classes into their own folder? It'll be easier to use independently of other platform packages if contained within a single MVC subfolder/package. (And, I can't imagine wanting to use one element of the triad without the others.) Thanks.

Rouven Weßling
Collaborator

@AmyStephen
I can answer that one. It's due to how the autoloader works. Otherwise we'd have to either special case these classes in the autoloader or use much uglier class names.

AmyStephen

Makes sense, thanks @realityking

Matias Griese

@realityking
In my own autoloader we allow class to be in 2 different places: libraries/kunena/myclass.php or libraries/kunena/myclass/myclass.php. It's pretty easy to archive that in the autoloader without needing any special cases (it's one check more, though).

@AmyStephen
For going forward question, I would prefer going forward, but during the transition Joomla should offer the old way for those extensions which haven't yet been updated. Preferably the old code should keep on working without making any changes (same code working on the current and the next version), because of it allows people to upgrade to the next Joomla version right away -- without needing to wait months for all the installed extensions to catch up. So while going forward is mandatory for project to stay alive, so is keeping the current users.

If upgrading Joomla means that you (as a site administrator) have to wait 6 months your favorite extensions to catch up or build your site from scratch every time, that's barely a solution. All my code has been running from Joomla 1.7 upwards, but I still cannot install Joomla! 2.5 into any of my sites because of issues in some other extensions I'm using.

So if I'm resisting the change, that's not because of as a developer I don't want to maintain my own code -- it's because of as a site administrator I'm relaying on other developers who haven't done the same. I could port the code by myself or replace those extensions, but I'd rather deal with it later when I have some extra time (hoping that there will be an update before that).

I'm also not resisting the change itself. On contrary, I cannot wait to be able to use it. I have even considered of taking the new code into my own component and start using it in Joomla! 2.5. The only reason why I so strongly opposed the change was that it was replacing existing classes instead of creating a new API, which could then be used alongside with the old one.

For my part I'm very happy on the proposal that adds class aliases to Joomla! 2.5. I would be even happier if no changes to the existing code was needed, but in reality it would just postpone the issues with non-maintained code to the next Joomla! release.

Now I'm going to take another look into the proposed code itself. :)

AmyStephen

Removing my non-code related response. :-P

If someone wants to discuss the topic of change, let's get a discussion going somewhere outside of the PR. I'm happy to join in.

Rouven Weßling
Collaborator

@mahagr
We already do that in the CMS for the J prefix, we look in both libraries/cms and libraries/joomla - in Joomla 3.0 the solution will be more elegant. The Platform actually does the same with libraries/legacy and libraries/joomla.

However to have JModel, JController and JView being in the same folder (let's call him mvc) under libraries/joomla like this
libraries/joomla/mvc/model.php
libraries/joomla/mvc/controller.php
etc.

We'd either have to register the classes individually or add some sort of special logic to the autoloader just for the MVC classes.

Shyam Sunder Verma

+1 to @realityking way of deprecating stuff.

I can share concerns which will effect me and my team are -

  • We should not mix two different purpose with a single class name. Even if we do search-and-replace, we cannot maintain one codebase for multiple versions.

  • While deprecating, please provide a programmable path rather then force us to separate the code base for different versions. Thats double-up the work for ANY developer/designer.

  • Initial comment regarding negative vibrations for Joomla by @nikosdion, is very true and still holds. The breaking changes will only broadcast negative vibration (thats my personal opinion obviously). Smaller the change, easier the adoption.

Andrew Eddie
Owner

@ssv445

We should not mix two different purpose with a single class name.
Even if we do search-and-replace, we cannot maintain one codebase for multiple versions.

That depends on how many versions of Joomla you want to support. I don't think one codebase to work on 2.5+3.0+4.0 is realistic. The CMS should aim to make 2.5+3.x workable, and the same with 3.x+4.x. But any other combination is your responsibility in my opinion. Rouven's CMS idea should allow you to do either. But remember, this is not the only change that will be required by the time we get to 4.0.

While deprecating, please provide a programmable path rather then force us
to separate the code base for different versions. Thats double-up the work for ANY developer/designer.

We almost always do in the platform, but the CMS is on a longer upgrade cycle so you will have to talk to them about when they will deprecate code. I cannot stress enough that you need to be having this conversation with the CMS, not the platform (because the CMS ultimately decided how long they delay the changes).

Initial comment regarding negative vibrations for Joomla by @nikosdion,
is very true and still holds. The breaking changes will only broadcast negative
vibration (thats my personal opinion obviously). Smaller the change, easier the adoption.

I actually agree and that's why we implemented a path for the CMS to delay these changes for at least 2 years. That's a very fair period of time, and as I've said, it won't be the only change you have to manage when moving into Joomla 4.x - but that's something for you to discuss with the CMS team.

Does that help explain the situation better?

Shyam Sunder Verma

@eddieajau Your response no doubt helps, it looks that platform developers are listening to 3PD developers. Thats build up trust. Thanks for your answer. We hope that the changes will spread positive vibrations.

elinw elinw commented on the diff April 11, 2012
docs/manual/en-US/chapters/classes/jviewhtml.xml
((55 lines not shown))
  55
+	 */
  56
+class MyHtmlView extends JViewHtml
  57
+{
  58
+	/**
  59
+	 * Redefine the model so the correct type hinting is available in the layout.
  60
+	 *
  61
+	 * @var     MyDatabaseModel
  62
+	 * @since   12.1
  63
+	 */
  64
+	protected $model;
  65
+}
  66
+
  67
+try
  68
+{
  69
+	$paths = new SplPriorityQueue;
  70
+	$paths-&gt;insert(__DIR__ . '/layouts');
2
elinw
elinw added a note April 11, 2012

When I tried this I got a warning saying that insert() requires two parameters.

Rob Schley
robschley added a note April 11, 2012

Elin, you're right. It is missing the priority. Not sure how this got missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
elinw elinw commented on the diff April 11, 2012
docs/manual/en-US/chapters/classes/jviewhtml.xml
((57 lines not shown))
  57
+{
  58
+	/**
  59
+	 * Redefine the model so the correct type hinting is available in the layout.
  60
+	 *
  61
+	 * @var     MyDatabaseModel
  62
+	 * @since   12.1
  63
+	 */
  64
+	protected $model;
  65
+}
  66
+
  67
+try
  68
+{
  69
+	$paths = new SplPriorityQueue;
  70
+	$paths-&gt;insert(__DIR__ . '/layouts');
  71
+
  72
+	$view = new MyView(new MyDatabaseModel, new MyController, $paths);
1
elinw
elinw added a note April 11, 2012

Should this (MyView) match the name of the class?

Also this does not match the signature for JViewHtml is that is what it is supposed to be ... that takes only two arguments and the second own should be the splPriorityQueue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
AmyStephen

Now that we have had a bit of time to consider this, it's become clear that the only impact on existing components in the Joomla CMS is that the phrase "extends JView" will have to be changed to "extends JViewCms" some time in the next couple of years. It really turned out to be a very minor impact.

My sense is there are no objections, anymore. Does anyone object to this PR? I think it can be merged, given the documentation changes proposed above.

Nicholas K. Dionysopoulos

If JViewCms & co are made available at least since Joomla! 3.0, it would absolutely perfect with all 3PDs as it allows for graceful transition. If that's included in 2.5.5 or 2.5.6, as Rouven suggested, it will allow us to adapt our code with even less friction and much earlier.

Rouven Weßling
Collaborator

@nikosdion
My plan is to submit a patch for JViewLegacy & Co. as soon as this is merged. (I'm using Legacy because we'll likely wanna build some CMS specific classes on top of the new MVC interfaces that may or may not be compatible with the current classes and I don't want another name collision ;) )

That said I think we should seriously consider dropping the old class names (JView, JController and JModel) to allow extensions to use the new Interfaces/Classes if they want to. But that's really a discussion for the CMS list and doesn't belong here.

Nicholas K. Dionysopoulos

Yes, that sounds like a good plan and, as you said, that's a discussion for the CMS. Just tweet the URL of the CMS discussion when it starts. There are so many lists and places for CMS discussions that I can't keep track of all of them any more :)

gpongelli

+1 @realityking about ease transition without conflicting name and BC.
Anyway @LouisLandry have done a real good job.

My suggestion is to introduce this big improvement, maybe with namespaces, without breaking compatibility and doing it gracefully.

Eng. Gabriele Pongelli

AmyStephen

Just as a reminder, two of the classes are buried in the framework and extensions are not impacted by the name change.

The only change that impacts Components is the 'extends JView' literal where 'JView' needs to be changed to 'JViewLegacy'.

Developers have a couple of years to make this change.

The patch that @RealityKing is putting in will allow developers to make that change to their extensions now so that the same names work in 2.5.x as in future releases.

Truly, this ends up being a very low impact change.

ianmacl
Owner

So I think the majority of the concerns have been satisfied. Assent has been given from the CMS representatives on the platform team. I'm going to go ahead and merge this pull request.

ianmacl ianmacl merged commit 050eef3 into from April 16, 2012
ianmacl ianmacl closed this April 16, 2012
Piotr

I suggest that authors of this PR will write an article at http://developer.joomla.org/ describing how to access legacy MVC methods, the differences to new MVC and link the documentation

Andrew Eddie
Owner

@piotr-cz already done :) One of the luxuries we have is the time to put documentation together during work time (a wonderfully pleasant change).

http://developer.joomla.org/platform-manual.html

See: 1.2.2. Legacy Platform, and 2.5. The Model-View-Controller Packages

In terms of differences it was far easier to document what the new classes did rather than list out all the things they didn't know do. If you are using the CMS, there will be no change in terms of accessing them because the CMS will bootstrap the legacy platform first. If there are any notes you want me to add just let me know and I'll be more than happy to put them in.

Piotr

@eddieajau
Thanks, Is it possible to somehow use new MVC with legacy MVC in one component?
Let's say I'm using legacy CMS as user interface but access external APIs for other where new MVC seems much better way.

BTW, good work on documentation.

Andrew Eddie
Owner

@piotr-cz you can't access both MVC's in the same script, but yes, you could write a CMS component using the old MVC (actually probably just a view), and a web services platform using the new API to actually do all the work. Keep an eye out for one of the GSOC projects which will cover that topic to some degree.

Don Gilbert
Owner

Why was the reference to JController unnecessary for the JViewBase class __construct method? Is it just because it was not needed or used by the view ever? Just curious what the thought here was.

Don Gilbert
Owner

I asked that question because the platform docs for 12.1 still say that type hinted JController arg is still required when creating a view, but in the code it has been removed. Please update the docs to reflect this.

Andrew Eddie
Owner

Ok, I've made a note to do that. If you happen to have time to do a pull request yourself that would be great.

Don Gilbert
Owner

@eddieajau - pull is requested. :)

#1493

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.

Showing 35 changed files with 2,032 additions and 0 deletions. Show diff stats Hide diff stats

  1. 69  docs/manual/en-US/chapters/classes/jcontrollerbase.xml
  2. 51  docs/manual/en-US/chapters/classes/jmodelbase.xml
  3. 73  docs/manual/en-US/chapters/classes/jmodeldatabase.xml
  4. 75  docs/manual/en-US/chapters/classes/jviewbase.xml
  5. 83  docs/manual/en-US/chapters/classes/jviewhtml.xml
  6. 13  docs/manual/en-US/chapters/interfaces/jcontroller.xml
  7. 12  docs/manual/en-US/chapters/interfaces/jmodel.xml
  8. 12  docs/manual/en-US/chapters/interfaces/jview.xml
  9. 2  docs/manual/en-US/chapters/packages.xml
  10. 57  docs/manual/en-US/chapters/packages/mvc.xml
  11. 137  libraries/joomla/controller/base.php
  12. 51  libraries/joomla/controller/controller.php
  13. 79  libraries/joomla/model/base.php
  14. 82  libraries/joomla/model/database.php
  15. 40  libraries/joomla/model/model.php
  16. 56  libraries/joomla/view/base.php
  17. 185  libraries/joomla/view/html.php
  18. 41  libraries/joomla/view/view.php
  19. 54  tests/core/mock/controller.php
  20. 186  tests/suites/unit/joomla/controller/JControllerBaseTest.php
  21. 31  tests/suites/unit/joomla/controller/stubs/tbase.php
  22. 101  tests/suites/unit/joomla/model/JModelBaseTest.php
  23. 122  tests/suites/unit/joomla/model/JModelDatabaseTest.php
  24. 19  tests/suites/unit/joomla/model/stubs/tbase.php
  25. 19  tests/suites/unit/joomla/model/stubs/tdatabase.php
  26. 69  tests/suites/unit/joomla/view/JViewBaseTest.php
  27. 211  tests/suites/unit/joomla/view/JViewHtmlTest.php
  28. 1  tests/suites/unit/joomla/view/layouts1/fringe/division.php
  29. 1  tests/suites/unit/joomla/view/layouts1/olivia.php
  30. 1  tests/suites/unit/joomla/view/layouts1/peter.php
  31. 1  tests/suites/unit/joomla/view/layouts2/fauxlivia.php
  32. 1  tests/suites/unit/joomla/view/layouts2/olivia.php
  33. 48  tests/suites/unit/joomla/view/mocks/JModelMock.php
  34. 30  tests/suites/unit/joomla/view/stubs/tbase.php
  35. 19  tests/suites/unit/joomla/view/stubs/thtml.php
69  docs/manual/en-US/chapters/classes/jcontrollerbase.xml
... ...
@@ -0,0 +1,69 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JControllerBase</title>
  9
+
  10
+  <section>
  11
+    <title>Construction</title>
  12
+
  13
+    <para>The constructor for <classname>JControllerBase</classname> takes an optional <classname>JInput</classname> object and an
  14
+    optional <classname>JApplciationBase</classname> object. If either is omitted, the constructor defers to the protected
  15
+    loadInput and loadApplication methods respectively. These methods can be overriden in derived classes if the default
  16
+    application and request input is not appropriate.</para>
  17
+  </section>
  18
+
  19
+  <section>
  20
+    <title>Usage</title>
  21
+
  22
+    <para>The <classname>JControllerBase</classname> class is abstract so cannot be used directly. The derived class must
  23
+    implement the execute method to satisfy the interface requirements. Note that the execute method no longer takes a "task"
  24
+    argument as each controller class. Multi-task controllers are still possible but not recommended. Each controller class should
  25
+    do just one sort of 'thing', just as saving, deleting, checking in, checking out and so on. However, controllers, or even
  26
+    models and views, have the liberty of invoking other controllers to allow for HMVC architectures.</para>
  27
+
  28
+    <example>
  29
+      <title>Example controller</title>
  30
+
  31
+      <programlisting>	/**
  32
+	 * My custom controller.
  33
+	 *
  34
+	 * @package  Examples
  35
+	 *
  36
+	 * @since   12.1
  37
+	 */
  38
+class MyController extends JControllerBase
  39
+{
  40
+	/**
  41
+	 * Method to execute the controller.
  42
+	 *
  43
+	 * @return  void
  44
+	 *
  45
+	 * @since   12.1
  46
+	 * @throws  RuntimeException
  47
+	 */
  48
+	public function execute()
  49
+	{
  50
+		echo time();
  51
+	}
  52
+}
  53
+
  54
+// Instantiate the controller.
  55
+$controller = new MyController;
  56
+
  57
+// Print the time.
  58
+$controller-&gt;execute();</programlisting>
  59
+    </example>
  60
+  </section>
  61
+
  62
+  <section>
  63
+    <title>Serialization</title>
  64
+
  65
+    <para>The <classname>JControllerBase</classname> class implements <interfacename>Serializable</interfacename>. When
  66
+    serializing, only the input property is serialized. When unserializing, the input variable is unserialized and the internal
  67
+    application property is loaded at runtime.</para>
  68
+  </section>
  69
+</section>
51  docs/manual/en-US/chapters/classes/jmodelbase.xml
... ...
@@ -0,0 +1,51 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JModelBase</title>
  9
+
  10
+  <section>
  11
+    <title>Construction</title>
  12
+
  13
+    <para>The contructor for <classname>JModelBase</classname> takes an optional <classname>JRegistry</classname> object that
  14
+    defines the state of the model. If omitted, the contructor defers to the protected <methodname>loadState</methodname> method.
  15
+    This method can be overriden in a derived class and takes the place of the <methodname>populateState</methodname> method used
  16
+    in the legacy model class.</para>
  17
+  </section>
  18
+
  19
+  <section>
  20
+    <title>Usage</title>
  21
+
  22
+    <para>The <classname>JModelBase</classname> class is abstract so cannot be used directly. All requirements of the interface
  23
+    are already satisfied by the base class.</para>
  24
+
  25
+    <example>
  26
+      <title>Example model</title>
  27
+
  28
+      <programlisting>	/**
  29
+	 * My custom model.
  30
+	 *
  31
+	 * @pacakge  Examples
  32
+	 *
  33
+	 * @since   12.1
  34
+	 */
  35
+class MyModel extends JModelBase
  36
+{
  37
+	/**
  38
+	 * Get the time.
  39
+	 *
  40
+	 * @return  integer
  41
+	 *
  42
+	 * @since   12.1
  43
+	 */
  44
+	public function getTime()
  45
+	{
  46
+		return time();
  47
+	}
  48
+}</programlisting>
  49
+    </example>
  50
+  </section>
  51
+</section>
73  docs/manual/en-US/chapters/classes/jmodeldatabase.xml
... ...
@@ -0,0 +1,73 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JModelDatabase</title>
  9
+
  10
+  <section>
  11
+    <title>Construction</title>
  12
+
  13
+    <para><classname>JModelDatabase</classname> is extended from <classname>JModelBase</classname> and the contructor takes an
  14
+    optional <classname>JDatabaseDriver</classname> object and an optional <classname>JRegistry</classname> object (the same one
  15
+    that <classname>JModelBase</classname> uses). If the database object is omitted, the contructor defers to the protected
  16
+    <methodname>loadDb</methodname> method which loads the database object from the platform factory.</para>
  17
+  </section>
  18
+
  19
+  <section>
  20
+    <title>Usage</title>
  21
+
  22
+    <para>The <classname>JModelDatabase</classname> class is abstract so cannot be used directly. It forms a base for any model
  23
+    that needs to interact with a database.</para>
  24
+
  25
+    <example>
  26
+      <title>Example database model</title>
  27
+
  28
+      <programlisting>	/**
  29
+	 * My custom database model.
  30
+	 *
  31
+	 * @package  Examples
  32
+	 *
  33
+	 * @since   12.1
  34
+	 */
  35
+class MyDatabaseModel extends JModelDatabase
  36
+{
  37
+	/**
  38
+	 * Get the content count.
  39
+	 *
  40
+	 * @return  integer
  41
+	 *
  42
+	 * @since   12.1
  43
+	 * @throws  RuntimeException on database error.
  44
+	 */
  45
+	public function getCount()
  46
+	{
  47
+		// Get the query builder from the internal database object.
  48
+		$q = $this-&gt;db-&gt;getQuery(true);
  49
+
  50
+		// Prepare the query to count the number of content records.
  51
+		$q-&gt;select('COUNT(*)')
  52
+			-&gt;from($q-&gt;qn('#__content'));
  53
+
  54
+		$this-&gt;db-&gt;setQuery($q);
  55
+
  56
+		// Execute and return the result.
  57
+		return $this-&gt;db-&gt;loadResult();
  58
+	}
  59
+}
  60
+
  61
+try
  62
+{
  63
+	$model = new MyDatabaseModel;
  64
+	$count = $model-&gt;getCount();
  65
+}
  66
+catch (RuntimeException $e)
  67
+{
  68
+	// Handle database error.
  69
+}
  70
+</programlisting>
  71
+    </example>
  72
+  </section>
  73
+</section>
75  docs/manual/en-US/chapters/classes/jviewbase.xml
... ...
@@ -0,0 +1,75 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JViewBase</title>
  9
+
  10
+  <section>
  11
+    <title>Construction</title>
  12
+
  13
+    <para>The contructor for <classname>JViewBase</classname> takes a <classname>JModel</classname> object and a
  14
+    <classname>JController</classname> object. Both are mandatory.</para>
  15
+
  16
+    <para>Note that these are interfaces so the objects do no necessarily have to extend from <classname>JModelBase</classname> or
  17
+    <classname>JControllerBase</classname> classes. Given that, the view should only rely on the API that is exposed by the
  18
+    interface and not concrete classes unless the contructor is changed in a derived class to take more explicit classes or
  19
+    interaces as required by the developer.</para>
  20
+  </section>
  21
+
  22
+  <section>
  23
+    <title>Usage</title>
  24
+
  25
+    <para>The <classname>JViewBase</classname> class is abstract so cannot be used directly. It forms a simple base for rendering
  26
+    any kind of data. The class already implements the <methodname>escape</methodname> method so only a
  27
+    <methodname>render</methodname> method need to be added. Views derived from this class would be used to support very simple
  28
+    cases, well suited to supporting web services returning JSON, XML or possibly binary data types. This class does not support
  29
+    layouts.</para>
  30
+
  31
+    <example>
  32
+      <title>Example view</title>
  33
+
  34
+      <programlisting>	/**
  35
+	 * My custom view.
  36
+	 *
  37
+	 * @package  Examples
  38
+	 *
  39
+	 * @since   12.1
  40
+	 */
  41
+class MyView extends JViewBase
  42
+{
  43
+	/**
  44
+	 * Render some data
  45
+	 *
  46
+	 * @return  string  The rendered view.
  47
+	 *
  48
+	 * @since   12.1
  49
+	 * @throws  RuntimeException on database error.
  50
+	 */
  51
+	public function render()
  52
+	{
  53
+		// Prepare some data from the model.
  54
+		$data = array(
  55
+			'count' =&gt; $this-&gt;model-&gt;getCount()
  56
+		);
  57
+
  58
+		// Convert the data to JSON format.
  59
+		return json_encode($data);
  60
+	}
  61
+}
  62
+
  63
+try
  64
+{
  65
+	$view = new MyView(new MyDatabaseModel, new MyController);
  66
+	echo $view-&gt;render();
  67
+}
  68
+catch (RuntimeException $e)
  69
+{
  70
+	// Handle database error.
  71
+}
  72
+</programlisting>
  73
+    </example>
  74
+  </section>
  75
+</section>
83  docs/manual/en-US/chapters/classes/jviewhtml.xml
... ...
@@ -0,0 +1,83 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JViewHtml</title>
  9
+
  10
+  <section>
  11
+    <title>Construction</title>
  12
+
  13
+    <para><classname>JViewHtml</classname> is extended from <classname>JViewBase</classname>. The constructor, in addition to the
  14
+    model and controller arguments, take an optional <classname>SplPriorityQueue</classname> object that serves as a lookup for
  15
+    layouts. If omitted, the view defers to the protected <methodname>loadPaths</methodname> method.</para>
  16
+  </section>
  17
+
  18
+  <section>
  19
+    <title>Usage</title>
  20
+
  21
+    <para>The <classname>JViewHtml</classname> class is abstract so cannot be used directly. This view class implements render. It
  22
+    will try to find the layout, include it using output buffering and return the result. The following examples show a layout
  23
+    file that is assumed to be stored in a generic layout folder not stored under the web-server root.</para>
  24
+
  25
+    <example>
  26
+      <title>Example HTML layout</title>
  27
+
  28
+      <programlisting>&lt;?php
  29
+/**
  30
+ * Example layout "layouts/count.php".
  31
+ *
  32
+ * @package  Examples
  33
+ * @since    12.1
  34
+ */
  35
+
  36
+// Declare variables to support type hinting.
  37
+
  38
+/** @var $this MyHtmlView */
  39
+?&gt;
  40
+
  41
+&lt;dl&gt;
  42
+	&lt;dt&gt;Count&lt;/dt&gt;
  43
+	&lt;dd&gt;&lt;?php echo $this-&gt;model-&gt;getCount(); ?&gt;&lt;/dd&gt;
  44
+&lt;/dl&gt;</programlisting>
  45
+    </example>
  46
+
  47
+    <example>
  48
+      <title>Example HTML view</title>
  49
+
  50
+      <programlisting>	/**
  51
+	 * My custom HTML view.
  52
+	 *
  53
+	 * @package  Examples
  54
+	 * @since    12.1
  55
+	 */
  56
+class MyHtmlView extends JViewHtml
  57
+{
  58
+	/**
  59
+	 * Redefine the model so the correct type hinting is available in the layout.
  60
+	 *
  61
+	 * @var     MyDatabaseModel
  62
+	 * @since   12.1
  63
+	 */
  64
+	protected $model;
  65
+}
  66
+
  67
+try
  68
+{
  69
+	$paths = new SplPriorityQueue;
  70
+	$paths-&gt;insert(__DIR__ . '/layouts');
  71
+
  72
+	$view = new MyView(new MyDatabaseModel, new MyController, $paths);
  73
+	$view-&gt;setLayout('count');
  74
+	echo $view-&gt;render();
  75
+}
  76
+catch (RuntimeException $e)
  77
+{
  78
+	// Handle database error.
  79
+}
  80
+</programlisting>
  81
+    </example>
  82
+  </section>
  83
+</section>
13  docs/manual/en-US/chapters/interfaces/jcontroller.xml
... ...
@@ -0,0 +1,13 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JController</title>
  9
+
  10
+  <para><interfacename>JController</interfacename> is an interface that requires a class to be implemented with an
  11
+  <methodname>execute</methodname>, a <methodname>getApplication</methodname> and a <methodname>getInput</methodname>
  12
+  method.</para>
  13
+</section>
12  docs/manual/en-US/chapters/interfaces/jmodel.xml
... ...
@@ -0,0 +1,12 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JModel</title>
  9
+
  10
+  <para><interfacename>JModel</interfacename> is an interface that requires a class to be implemented with a
  11
+  <methodname>getState</methodname> and a <methodname>setState</methodname> method.</para>
  12
+</section>
12  docs/manual/en-US/chapters/interfaces/jview.xml
... ...
@@ -0,0 +1,12 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section>
  8
+  <title>JView</title>
  9
+
  10
+  <para><interfacename>JView</interfacename> is an interface that requires a class to be implemented with an
  11
+  <methodname>escape</methodname> and a <methodname>render</methodname> method.</para>
  12
+</section>
2  docs/manual/en-US/chapters/packages.xml
@@ -16,5 +16,7 @@
16 16
   <xi:include href="packages/log.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
17 17
 
18 18
   <xi:include href="packages/database.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  19
+  
  20
+  <xi:include href="packages/mvc.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
19 21
 </chapter>
20 22
 
57  docs/manual/en-US/chapters/packages/mvc.xml
... ...
@@ -0,0 +1,57 @@
  1
+<?xml version="1.0" encoding="UTF-8"?>
  2
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  4
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
  5
+%BOOK_ENTITIES;
  6
+]>
  7
+<section id="chap-Joomla_Platform_Manual-MVC">
  8
+  <title>The Model-View-Controller Packages</title>
  9
+
  10
+  <section>
  11
+    <title>Introduction</title>
  12
+
  13
+    <para>Version 12.1 of the platform introduced a new format for model-view-controller paradigm. Principly, the classes
  14
+    <classname>JModel</classname>, <classname>JView</classname> and <classname>JController</classname> are now interfaces and the
  15
+    base abstract classes are now <classname>JModelBase</classname>, <classname>JViewBase</classname> and
  16
+    <classname>JControllerBase</classname> respectively. In additional, all classes have been simplified removing a lot of
  17
+    coupling with the Joomla CMS that is unnecessary for standalone Joomla Platform applications.</para>
  18
+
  19
+    <para>All the API for controllers, models and views has moved from the Application package into separate Controller, Model and
  20
+    View packages respectively. Much of the API previously devoted to adding include paths for each of the classes has been
  21
+    removed because of improvements in the auto-loader or by registering or discovering classes explicitly using
  22
+    <classname>JLoader</classname>.</para>
  23
+
  24
+    <para>Controllers only support one executable task per class via the execute method. This differs from the legacy
  25
+    <classname>JController</classname> class which mapped tasks to methods in a single class. Messages and redirection are not
  26
+    always required so have been dropped in this base class. They can be provided in a downstream class to suit individual
  27
+    applications. Likewise, methods to create models and views have been dropped in favor of using application or package factory
  28
+    classes.</para>
  29
+
  30
+    <para>Models have been greatly simplified in comparison to their legacy counterpart. The base model is nothing more than a
  31
+    class to hold state. All database support methods have been dropped except for database object support in
  32
+    <classname>JModelDatabase</classname>. Extended model classes such as <classname>JModelAdmin</classname>,
  33
+    <classname>JModelForm</classname>, <classname>JModelItem</classname> and <classname>JModelList</classname> are part of the
  34
+    legacy platform. Most of their function has been replaced by API availble in the Content package also new in 12.1.</para>
  35
+
  36
+    <para>Views have also been greatly simplified. Views are now injected with a single model and a controller. Magic get methods
  37
+    have been dropped in favor of using the model directly. Similarly, assignment methods have also been dropped in favor of
  38
+    setting class properties explicitly. The <classname>JViewHtml</classname> class still implements layout support albeit in a
  39
+    simplified manner.</para>
  40
+  </section>
  41
+
  42
+  <xi:include href="../interfaces/jcontroller.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  43
+
  44
+  <xi:include href="../classes/jcontrollerbase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  45
+
  46
+  <xi:include href="../interfaces/jmodel.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  47
+
  48
+  <xi:include href="../classes/jmodelbase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  49
+
  50
+  <xi:include href="../classes/jmodeldatabase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  51
+
  52
+  <xi:include href="../interfaces/jview.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  53
+
  54
+  <xi:include href="../classes/jviewbase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  55
+
  56
+  <xi:include href="../classes/jviewhtml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
  57
+</section>
137  libraries/joomla/controller/base.php
... ...
@@ -0,0 +1,137 @@
  1
+<?php
  2
+/**
  3
+ * @package     Joomla.Platform
  4
+ * @subpackage  Controller
  5
+ *
  6
+ * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7
+ * @license     GNU General Public License version 2 or later; see LICENSE
  8
+ */
  9
+
  10
+defined('JPATH_PLATFORM') or die;
  11
+
  12
+/**
  13
+ * Joomla Platform Base Controller Class
  14
+ *
  15
+ * @package     Joomla.Platform
  16
+ * @subpackage  Controller
  17
+ * @since       12.1
  18
+ */
  19
+abstract class JControllerBase implements JController
  20
+{
  21
+	/**
  22
+	 * The application object.
  23
+	 *
  24
+	 * @var    JApplicationBase
  25
+	 * @since  12.1
  26
+	 */
  27
+	protected $app;
  28
+
  29
+	/**
  30
+	 * The input object.
  31
+	 *
  32
+	 * @var    JInput
  33
+	 * @since  12.1
  34
+	 */
  35
+	protected $input;
  36
+
  37
+	/**
  38
+	 * Instantiate the controller.
  39
+	 *
  40
+	 * @param   JInput            $input  The input object.
  41
+	 * @param   JApplicationBase  $app    The application object.
  42
+	 *
  43
+	 * @since  12.1
  44
+	 */
  45
+	public function __construct(JInput $input = null, JApplicationBase $app = null)
  46
+	{
  47
+		// Setup dependencies.
  48
+		$this->app = isset($app) ? $app : $this->loadApplication();
  49
+		$this->input = isset($input) ? $input : $this->loadInput();
  50
+	}
  51
+
  52
+	/**
  53
+	 * Get the application object.
  54
+	 *
  55
+	 * @return  JApplicationBase  The application object.
  56
+	 *
  57
+	 * @since   12.1
  58
+	 */
  59
+	public function getApplication()
  60
+	{
  61
+		return $this->app;
  62
+	}
  63
+
  64
+	/**
  65
+	 * Get the input object.
  66
+	 *
  67
+	 * @return  JInput  The input object.
  68
+	 *
  69
+	 * @since   12.1
  70
+	 */
  71
+	public function getInput()
  72
+	{
  73
+		return $this->input;
  74
+	}
  75
+
  76
+	/**
  77
+	 * Serialize the controller.
  78
+	 *
  79
+	 * @return  string  The serialized controller.
  80
+	 *
  81
+	 * @since   12.1
  82
+	 */
  83
+	public function serialize()
  84
+	{
  85
+		return serialize($this->input);
  86
+	}
  87
+
  88
+	/**
  89
+	 * Unserialize the controller.
  90
+	 *
  91
+	 * @param   string  $input  The serialized controller.
  92
+	 *
  93
+	 * @return  JController  Supports chaining.
  94
+	 *
  95
+	 * @since   12.1
  96
+	 * @throws  UnexpectedValueException if input is not the right class.
  97
+	 */
  98
+	public function unserialize($input)
  99
+	{
  100
+		// Setup dependencies.
  101
+		$this->app = $this->loadApplication();
  102
+
  103
+		// Unserialize the input.
  104
+		$this->input = unserialize($input);
  105
+
  106
+		if (!($this->input instanceof JInput))
  107
+		{
  108
+			throw new UnexpectedValueException(sprintf('%s::unserialize would not accept a `%s`.', get_class($this), gettype($this->input)));
  109
+		}
  110
+
  111
+		return $this;
  112
+	}
  113
+
  114
+	/**
  115
+	 * Load the application object.
  116
+	 *
  117
+	 * @return  JApplicationBase  The application object.
  118
+	 *
  119
+	 * @since   12.1
  120
+	 */
  121
+	protected function loadApplication()
  122
+	{
  123
+		return JFactory::getApplication();
  124
+	}
  125
+
  126
+	/**
  127
+	 * Load the input object.
  128
+	 *
  129
+	 * @return  JInput  The input object.
  130
+	 *
  131
+	 * @since   12.1
  132
+	 */
  133
+	protected function loadInput()
  134
+	{
  135
+		return $this->app->input;
  136
+	}
  137
+}
51  libraries/joomla/controller/controller.php
... ...
@@ -0,0 +1,51 @@
  1
+<?php
  2
+/**
  3
+ * @package     Joomla.Platform
  4
+ * @subpackage  Controller
  5
+ *
  6
+ * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7
+ * @license     GNU General Public License version 2 or later; see LICENSE
  8
+ */
  9
+
  10
+defined('JPATH_PLATFORM') or die;
  11
+
  12
+/**
  13
+ * Joomla Platform Controller Interface
  14
+ *
  15
+ * @package     Joomla.Platform
  16
+ * @subpackage  Controller
  17
+ * @since       12.1
  18
+ */
  19
+interface JController extends Serializable
  20
+{
  21
+	/**
  22
+	 * Execute the controller.
  23
+	 *
  24
+	 * @return  boolean  True if controller finished execution, false if the controller did not
  25
+	 *                   finish execution. A controller might return false if some precondition for
  26
+	 *                   the controller to run has not been satisfied.
  27
+	 *
  28
+	 * @since   12.1
  29
+	 * @throws  LogicException
  30
+	 * @throws  RuntimeException
  31
+	 */
  32
+	public function execute();
  33
+
  34
+	/**
  35
+	 * Get the application object.
  36
+	 *
  37
+	 * @return  JApplicationBase  The application object.
  38
+	 *
  39
+	 * @since   12.1
  40
+	 */
  41
+	public function getApplication();
  42
+
  43
+	/**
  44
+	 * Get the input object.
  45
+	 *
  46
+	 * @return  JInput  The input object.
  47
+	 *
  48
+	 * @since   12.1
  49
+	 */
  50
+	public function getInput();
  51
+}
79  libraries/joomla/model/base.php
... ...
@@ -0,0 +1,79 @@
  1
+<?php
  2
+/**
  3
+ * @package     Joomla.Platform
  4
+ * @subpackage  Model
  5
+ *
  6
+ * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7
+ * @license     GNU General Public License version 2 or later; see LICENSE
  8
+ */
  9
+
  10
+defined('JPATH_PLATFORM') or die;
  11
+
  12
+/**
  13
+ * Joomla Platform Base Model Class
  14
+ *
  15
+ * @package     Joomla.Platform
  16
+ * @subpackage  Model
  17
+ * @since       12.1
  18
+ */
  19
+abstract class JModelBase implements JModel
  20
+{
  21
+	/**
  22
+	 * The model state.
  23
+	 *
  24
+	 * @var    JRegistry
  25
+	 * @since  12.1
  26
+	 */
  27
+	protected $state;
  28
+
  29
+	/**
  30
+	 * Instantiate the model.
  31
+	 *
  32
+	 * @param   JRegistry  $state  The model state.
  33
+	 *
  34
+	 * @since   12.1
  35
+	 */
  36
+	public function __construct(JRegistry $state = null)
  37
+	{
  38
+		// Setup the model.
  39
+		$this->state = isset($state) ? $state : $this->loadState();
  40
+	}
  41
+
  42
+	/**
  43
+	 * Get the model state.
  44
+	 *
  45
+	 * @return  JRegistry  The state object.
  46
+	 *
  47
+	 * @since   12.1
  48
+	 */
  49
+	public function getState()
  50
+	{
  51
+		return $this->state;
  52
+	}
  53
+
  54
+	/**
  55
+	 * Set the model state.
  56
+	 *
  57
+	 * @param   JRegistry  $state  The state object.
  58
+	 *
  59
+	 * @return  void
  60
+	 *
  61
+	 * @since   12.1
  62
+	 */
  63
+	public function setState(JRegistry $state)
  64
+	{
  65
+		$this->state = $state;
  66
+	}
  67
+
  68
+	/**
  69
+	 * Load the model state.
  70
+	 *
  71
+	 * @return  JRegistry  The state object.
  72
+	 *
  73
+	 * @since   12.1
  74
+	 */
  75
+	protected function loadState()
  76
+	{
  77
+		return new JRegistry;
  78
+	}
  79
+}
82  libraries/joomla/model/database.php
... ...
@@ -0,0 +1,82 @@
  1
+<?php
  2
+/**
  3
+ * @package     Joomla.Platform
  4
+ * @subpackage  Model
  5
+ *
  6
+ * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7
+ * @license     GNU General Public License version 2 or later; see LICENSE
  8
+ */
  9
+
  10
+defined('JPATH_PLATFORM') or die;
  11
+
  12
+/**
  13
+ * Joomla Platform Database Model Class
  14
+ *
  15
+ * @package     Joomla.Platform
  16
+ * @subpackage  Model
  17
+ * @since       12.1
  18
+ */
  19
+abstract class JModelDatabase extends JModelBase
  20
+{
  21
+	/**
  22
+	 * The database driver.
  23
+	 *
  24
+	 * @var    JDatabaseDriver
  25
+	 * @since  12.1
  26
+	 */
  27
+	protected $db;
  28
+
  29
+	/**
  30
+	 * Instantiate the model.
  31
+	 *
  32
+	 * @param   JRegistry        $state  The model state.
  33
+	 * @param   JDatabaseDriver  $db     The database adpater.
  34
+	 *
  35
+	 * @since   12.1
  36
+	 */