kohana / core

Core system classes from Kohana
http://kohanaframework.org
634 stars 327 forks source link

Namespaces for controllers modules and helpers #571

Open rjd22 opened 9 years ago

rjd22 commented 9 years ago

We should start thinking about implementing namespaces in Kohana and it's modules but also decide on a vendor / prefix.

Like \Kohana\<module>\<class>

Also enable users to namespace their own application. And point the routes to the namespace.

What do you guy's think? (Typed this on my mobile so keeping it short)

rjd22 commented 9 years ago

@enov @lenton @acoulton @shadowhand pinging you for some opinions :)

kemo commented 9 years ago

There was discussion on this topic before; http://forum.kohanaframework.org/discussion/9740/kohana-and-namespaces/p1

Anyway, this definitely gets a :+1: from me - right after we make some things clear;

enov commented 9 years ago

I am all for using namespaces @rjd22 :smile:

But the question remains: at what stage?

Limiting the scope of features for 3.4 would help us be able to release it at some point.

A namespaced version of Kohana could go out as a separate version on it own. I mean no new features in that release, except that it is a new Kohana based on the older version, but namespaced.

Another option would be to namespace while we work on some classes. But in that case we would have partly namespaced and partly non-namespaced classes. We can give preferences to the classes that are internally instantiated first. I mean, usually, a user does not do a new Log() as it is done internally somewhere in Kohana::init. That way, the new version is upgradeable by the user. Upgradeable releases is something I care about, as opposed to all new full-rewrite releases.

Keep in mind we always support 2 dev versions. Refactoring those class names means refactoring everywhere those are instantiated. It means going farther from the previous version. It means more merge conflicts when we try to merge up bug fixes from below.

Also enable users to namespace their own application

Users can already namespace their classes in 3.3 as it is PSR-0 compliant - except for the Controller classes, I guess.

enov commented 9 years ago

Also enable users to namespace their own application. And point the routes to the namespace.

Yeah, I see now that you are concerned about the Controllers to be able to be namespaced.

acoulton commented 9 years ago

I think this would be really good - for starters it would make working with tools like PHPSpec, and integrating with other components and projects, much easier.

It does feel like a big change to get in for 3.4, and I agree with @enov that we should avoid 3.4 becoming the "fix absolutely everything to the point we never actually release it" version.

Equally, I think there's quite a bit we could do to make the upgrade be relatively painless:

Auto-upgrade script

It would be fairly simple to build a small script that finds all references to official Kohana classes (scoped to only consider modules active in the project, so that it doesn't conflict with some third-party "Auth" class for eg if the user isn't using Kohana Auth.

It could then just add appropriate use statements to the top of the relevant files, so the rest of the file remains unchanged. We could use that script on the kohana packages themselves, and users could also use it on their own applications.

This would mean the only major diffs between versions would be the use blocks themselves in the file headers - so there should be fairly limited potential for merge conflicts.

There's no real reason the class files themselves have to move, but even if they do so long as that's done properly with git it will follow the rename/move when merging up in future and apply the patch to the new path without conflicts.

Legacy shim

We could easily provide a separate package that just defines all the old non-namespaced classes, either as aliases or as class definitions. So end-user code could still refer to \Log but get an instance of \Kohana\Core\Log - not sure whether alias or extension is better, it possibly depends on how aliases behave with instanceof.

Potential related changes

Moving to ohanzee (or any other third-party) components

I think this is too big to do it at the same time - but properly namespacing would help with this in future and we should be moving in that direction.

Dropping the CFS and transparent extension

+1 from me. I like the CFS for things like config files, view templates, messages and stuff (though there would be other, possibly more explicit, ways to achieve the same thing). I used to love transparent extension, but now I think that properly mapping the classes in use in the project makes more sense.

IMO the best solution is to drop transparent extension altogether, and have end-users and module developers just depend directly on the (namespaced) interfaces and/or class implementations they actually need. That would also allow us to drop our autoloader and use composer directly which would simplify quite a lot.

Again, I think it would be easy enough to build a tool to help with this migration - look through the application and modules for customised transparent extension classes, add a custom namespace to the top of the file and then add a use statement to anything that uses it. The only issue would be where people are using transparent extension to customise behaviour of methods called by other kohana/core classes - where you wouldn't be able to change the imports.

One idea proposed in the past was virtual namespacing (using class aliases, I think) where Kohana/Log wouldn't actually exist and the system would automatically map it to Application/Custom/Log or Kohana/Core/Log as required. That might be an OK transition plan, while we work on making it easier to inject implementations into the core rather than relying on monkeypatching the classes the core is hardcoded to use.

It feels to me like that would be better done with some sort of development-time compilation step rather than a magical run-time autoloader defining aliases on the fly. So all the empty extensions would be removed from the core packages, in favour of a script that developers run to spit out appropriate autoloadable class definitions / class aliases somewhere in their /application directory. Any time you add a module or application class that "transparently" extends core you explicitly re-run the script and probably commit the result. That way both developers and IDEs are always clear on actually what class is being used. Note that you'd run this on the developer machine, it doesn't require any shell access to "compile" on the server.

Move to PSR1/PSR2

I fairly dislike quite a bit of these, though I'm gradually accepting that consistency is more important than preference.

But trying to migrate the existing code wholesale will create huge diffs and make merge conflicts between versions almost guaranteed. We could adopt PSR1/PSR2 for entirely new files, but I think we should stick with what we have for the existing stuff - otherwise maintenance is going to become a nightmare.

acoulton commented 9 years ago

Sorry, long post - should have followed @rjd22 example and posted on my mobile! Also to say of course there's no reason we can't make routes support namespaces separately from actually namespacing the core - that could be a 3.4 feature without any major issue I think?

acoulton commented 9 years ago

@cyrgit PSR4 - absolutely.

Coding style - only if you're volunteering to be in charge of merging up bugfixes from the 3.x series to whatever version we introduce all the changes. Every commit will have merge conflicts over casing and whitespace to the point it'll potentially be easier to rewrite patches by hand.

Unless we change the release policy so that only one version is supported at a time, and bugfixes never get merged up between versions but IMHO that would be a much worse outcome for users than having a mix of conventions (frustrating though that is).

Ohanzee can do it because it's starting from scratch.

lenton commented 9 years ago

I say we split the core into separate kohana modules in 3.4, then in 4.0 we can convert them to fully namespaced composer packages or switch them out with their ohanzee counterpart.

shadowhand commented 9 years ago

Ohanzee has already moved in that direction (PSR4/camel case), why leave Kohana behind?

It sounds like you are treating Ohanzee as a separate project, one which is totally alien to Kohana. This is not the case. Ohanzee is part of the Kohana Foundation and anyone from Kohana is welcome to participate in Ohanzee.

This entire discussion seems to be largely an echo of what I was talking about ~8 months ago. Kohana is a legacy framework because it failed to make the jump to namespaces and PSR standards. Ohanzee was intended to resolve that in a clean way, by dropping the Kohana name and making a clean break on code style, offering a way to transition the best modules of Kohana to Composer packages.

IMO, Ohanzee is still the best way forward to transition Kohana to modern PHP code. Deprecate Kohana, say that the next 3.x release will be the last one, and put effort into porting the best of Kohana into Ohanzee. Attempting to modernize Kohana without putting effort into Ohanzee just ensures that Ohanzee will never gain traction. Just my $0.02.

lenton commented 9 years ago

I think we all agree that the ohanzee components are the way forward for Kohana, the updates we are making to kohana are really just a slow transition to using them.

I'm going to start work again on my "kohana module manager" package, I feel this will really be key for the transition. It would allow kohana to use a mixture of both proper components and kohana modules.

rjd22 commented 9 years ago

(From mobile again)

I think we should just make a empty 4.0 branch and start building only the core components there with namespace support.

So only the bootstrapping capabilities first and focus on working together with other libraries.

There are so many libraries that solve the issues really well like Doctrine for DB.

I think it's okay to have our own libraries but we shouldn't forget the dame problem has been solved many times so we won't have to rewrite the whole framework right away.

rjd22 commented 9 years ago

@lenton @shadowhand @cyrgit @acoulton @enov @kemo

Let's do a clear vote on the following questions. Please keep it short:

rjd22 commented 9 years ago
Girt commented 9 years ago

I think we should keep an transparent extension. Otherwise, the philosophy of the kohana will change.

enov commented 9 years ago
ursoforte commented 9 years ago

What Version should implement it? 4.0 Are we implementing PSR 1 and 2? Yes Will we keep transparent extension? No What modules / functionality should be in the first version? Core, Request, Response, Session, Cookie, Controller, Routing, Log (That seems to be essential for most projects start.)

Ikke commented 9 years ago
JackEllis commented 9 years ago

What Version should implement it? 4.0

Are we implementing PSR 1 and 2? Yes

Will we keep transparent extension? _

What modules / functionality should be in the first version? Request (controllers / views etc.), routing and helper methods... Kohana as delivery only is very appealing to me personally...

enov commented 9 years ago

I had to elaborate on the question.

I see the need of 2 kinds of modules:

I would like to see kohana/core split into several packages, similar to the suggestion of @lenton. Maybe we need to drop ORM, Auth, codebench as well as the unittest modules, if possible.

shadowhand commented 9 years ago

v4

Yes! PSR-1, 2, and 4.

Namespaces make it unnecessary, so no.

Easier to say what NOT to keep. Drop ORM, Auth, Unittest, and Codebench. Ideally, replace as many modules as possible with Composer packages and write thin wrappers around them.

But I heard a strong argument that Kohana was supposed to have an upgrade path and I'm not sure this satisfies that. In many ways, it would be better to build a thin layer around Kohana to allow it to run on top of (eg) Symfony.

enov commented 9 years ago

@shadowhand (and maybe also @cyrgit)

Namespaces make it unnecessary, so no.

Is there a way namespacing can support CFS without classes transparently extending other classes?

shadowhand commented 9 years ago

Is there a way namespacing can support CFS

No, but namespaces make it unnecessary:

namespace Acme\Database;

use Kohana\Database\Query as KohanaQuery;

class Query extends KohanaQuery { ... }

The implication here is that everything has to be properly DI too. But it would be... right? ;)

lenton commented 9 years ago

4.0

Yes

We can have a mixture of both kohana modules (which use the CFS), and modern packages (ohanzee). Supporting old kohana modules would make the transition to these modern standards considerably easier for users.

If 4.0 has support for kohana modules then we could retain all of the functionality from 3.4.

enov commented 9 years ago

@cyrgit

If it read an \App\ folder, and then a \Kohana\ folder, it would serve as a CFS-like loader. If it finds the needed class in \App\ namespace, then it requires and returns true, else it continues to Kohana base.

Yes, but in that case, the "extending" class that is found in the \App folder should include all the functionality (methods and properties) of the class that's in \Kohana folder. It can not just extend the class to change, say, a method.

rakucmr commented 9 years ago

@shadowhand drop ORM, Auth in favour of what?

shadowhand commented 9 years ago

@raku Auth is horrible, absolutely pathetic, for security. The new password_hash function and the password_compat library eliminate the need for it. There are many better packages that are easy to integrate for those that want it "easier".

ORM... well, if you're using ORM, I don't have any recommendations. Use Doctrine, maybe? ORM is the worst possible thing you can do for architecture, and I've been saying that it should be dropped for years. A new major version (v4) finally gives the opportunity to clean out the crap code and we should take it.

(And FWIW, I wrote the original versions of both Auth and ORM. Mistakes were made.)

rakucmr commented 9 years ago

@shadowhand for ORM, what you say about this project https://github.com/spadefoot/kohana-orm-leap

shadowhand commented 9 years ago

@raku ORM is bad for architecture, no matter who creates it. Kohana ORM, LEAP, Doctrine... they all have the exact same architectural problem: combining the data model with persistence is Doing It Wrong.

zombor commented 9 years ago

Unless it's kept in a repository layer abstracted away from the main application (like all db access should be anyway).

rakucmr commented 9 years ago

So if ORM and other's ActiveRecord kind libraries are bad, why are they still used in other frameworks? Then let's use plain sql with pdo or mysql/mysqli php extensions. What is the meaning of a framework, not to make our life easier?

shadowhand commented 9 years ago

@raku because programming is not taught well. :) Frameworks can, and should, make life easier. But not by violating good programming practices.

zombor commented 9 years ago

Frameworks quite frequently attempt to get you to couple your business logic to their apis. Coupling your business logic to an ORM framework just locks you in to their api. Abstract it and it doesn't matter what you use. Use DI and other SOLID principles and things will go well.

rakucmr commented 9 years ago

Is not easier/faster this?


namespace Framework\Controller; use Framework\Models\User;

class Example { public function upgradeAccount($id) { $user = new User($id); $user->level('vip'); $user->save(); } }


namespace Framework\Model; use Framework\Orm\Model;

class User extends Model{}

zombor commented 9 years ago

Easier/Faster is not the primary goal of software development. In fact it's one of the last things to consider.

rakucmr commented 9 years ago

Ok you are right! Let's write 100 lines of code when we can write 10 line of code that make same thing.

zombor commented 9 years ago

It's actually not the same thing. The "longer" version is decoupled from the framework, making it easier to maintain, easier to change, and easier to reason about. Doing it this way makes changes easier to make when your framework changes APIs out from under you (which is what is being discussed in this issue).

The "long" way has the business logic (the thing that your company is paying you to write and support) decoupled from the vendor code (which you have no control over).

rakucmr commented 9 years ago

Google for Android framework use deprecation (and this is only an example) for they functions on classes. You want to drop ORM because is not Business Logic ... why don't improve your framework classes and functions in that classes? If there is a better way to do it, why not implement in that framework? Then let's drop the frameworks and do it with what that programming language offers!

shadowhand commented 9 years ago

@raku you can't implement system architecture within a framework, because a framework is a knife and architecture is knowledge on how to use the knife. In fact, the better the knife, the easier it will be to cut yourself. Documentation is the best answer to this problem, but documentation can be ignored by the user. This is why developers have to choose to learn their craft.

enov commented 9 years ago

You want to drop ORM because is not Business Logic

@raku we are not suggesting to drop things just for the sake of dropping. It is not fun to discontinue projects, at least viewed from my side. However note that Kohana ORM was not that powerful from the beginning, and others did better - some specific for Kohana framework. At first glance, spadefoot/kohana-orm-leap looks good to me. It seems to me that it is well maintained and more powerful than Kohana's official ORM.

Frankly, I also do not clean code (that's what some people call it - to separate your business logic from the repository, the delivery and other layers of your application), that's because faster is part of my business. I do not ORM either. Maybe I combine the fun part and profitability part, the best of the both worlds... Or maybe it's the worst of both worlds, who knows :stuck_out_tongue_winking_eye:

why don't improve your framework classes and functions in that classes?

Well, that's what we are trying to do. Also to reply to @shadowhand's comment somewhere above, it's not the lack of namespaces and PSRs that made from the Kohana framework a legacy framework, it's the code that's showing its age. Static methods all around, URL helper tied to base url can not help me with another url? Modules that I include set routes on my application? Why do I need to feed Upload with my file array every time I want to use a method? So basically there are problems that needs to be solved.

There are lots of projects that do not use namespacing and are considered modern, like the Twig templating engine. And there are lots of modern projects that are still PSR-0 and not PSR-4. I am not undermining what @rjd22 is doing here, on the contrary, I want Kohana to resurrect and become one of the important frameworks, the way it used to be. But Namespacing, PSR-1 and PSR-2 are more or less coding styles and will not change the architecture of the framework.

shadowhand commented 9 years ago

@enov you're right to say that PSR-1&2 will not dramatically change the framework, but code style does matter. When you need to fix something in someone else's code and it looks "weird", the average developer will typically just close the file and ignore it. When everyone writes the same style, less brain power is wasted understanding dialect.

Going back to ORM, I think Kohana has often suffered from "not invented here" syndrome, rather than "proudly found elsewhere". I'm still not enthused about promoting any ORM, because it is too easily abused. But I'm not going to be a zealot about it.

enov commented 9 years ago

I think Kohana has often suffered from "not invented here" syndrome, rather than "proudly found elsewhere".

:+1:

enov commented 9 years ago

@shadowhand how about fixing things with the FIG to represent us there?

shadowhand commented 9 years ago

@enov what makes you think that Kohana has enough market share or respect within the PHP community to warrant a seat at the FIG table? And for that matter, you could represent Kohana. I'm not interested. :)

enov commented 9 years ago

@shadowhand I am not a native English speaker, and there are others more experienced developers around here. Maybe @acoulton :wink:?

JackEllis commented 9 years ago

I nominate @zombor ;)

rjd22 commented 9 years ago

@JackEllis don't start nomination people without asking them ;).

@shadowhand I would ask you to take a good look at Doctrine BTW. Since it's not really just a ORM anymore. But also repository layer with proper mapping. The only reason why it's still called a ORM is because of the old days.

I think it is clear what direction we want to go to. And I think it's awesome that we came to such a clear consensus.

I would like to ask ask everyone what the namespace for the framework should be. I was thinking about something like \Kohana\Framework\<classes> in place of \Kohana\Core\<classes>. Any other opinions?

acoulton commented 9 years ago

Sorry haven't got to this. I can see I'm outvoted, but my $0.02 anyway:

What Version should implement it?

4.0 - BUT 3.4 should support namespaced application code eg routing to controllers.

Are we implementing PSR 1 and 2?

No, not in existing packages - but we should have a roadmap to move away from most of the current packages and classes in favour of external (Ohanzee or third-party) ones which should be PSR-compliant.

Will we keep transparent extension?

No. And we shouldn't add our own DI container / config files / whatever. Make kohana/core etc just take collaborators as constructor arguments and ship separate packages with default configuration for common DI containers that already exist. We might recommend one in particular, but users should be able to choose whichever one they want.

What modules / functionality should be in the first version?

Routing, request handling, cascading config, cascading view templates, messages, logging. BUT some of those we might implement by wrapping (or even just choosing and recommending in composer.json) existing third-party components.

@enov - thanks for the FIG nomination, but afraid I don't have time or inclination to get involved with that :)

kemo commented 9 years ago

I was thinking about something like \Kohana\Framework\<classes> in place of \Kohana\Core\<classes>

I'd stick to Core - the repo is called core, it's easier to type + framework isn't a popular word nowadays anyway :smile:

acoulton commented 9 years ago

However, as a followup I think there's one major question not on @rjd22's list:

I think that distinction's important, because we need to be clear whether backwards compatibility (in code, as well as in just developer's mental models of the architecture etc) is important.

Personally, I'm not sure if our developer team is big enough, or our ideas unique enough, to completely rebuild 4.0 as a modern "framework". If end-users are going to have a lot of work to upgrade anyway, why shouldn't they just start migrating now to something that already exists, has a more active development team, and has solved lots of the questions we're debating already?

zombor commented 9 years ago

I nominate @zombor ;)

I have zero interest in this ;)

I haven't even written a line of php in like a year and a half.