How to Fix Breaking 5.7.4 Namespace Change?
Permalink 2 users found helpfulSo I must be daft. How do I fix the 5.7.4 namespace breaking change?
According to frz this is a "one or two line fix" and he points to the documentation athttp://www.concrete5.org/documentation/developers/5.7/environment/a... . He also says Andrew has been posting detailed responses in the forums, which I guess refers tohttp://www.concrete5.org/developers/pro-accounts/community-leaders-... but I'm still having issues and don't have enough time for developing by trial-and-error.
I'm getting a whole slew of errors from the linter:
lerteco_membership/models/checkout_session.php Invalid segment 'Model' in namespace: namespace Concrete\Package\LertecoMembership\Model; .... lerteco_membership/tools/txns/manual_edit.php Invalid segment 'Tools' in namespace: namespace Concrete\Package\LertecoMembership\Tools\Txns;
What are the minimum changes I can make to get this working?
I thought about just registering an autoloader function, but I doubt that the linter is smart enough to check for that? Is an autoloader function plus a marketplace exemption all that's needed here? If so, does anybody have any examples?
Otherwise it looks like (based off of andrew's response to someone else's problem):
a) I need to move the [helpers|models|tools|libraries] directories into [package root]/src
b) Change all references to Concrete\Package\LertecoMembership\Src\Model
--> This contradicts Andy's post, but I can't see how it'd work if I were to name it Concrete\Package\LertecoMembership\Model\Src
Is that it?
protected $pkgAutoloaderRegistries = array( 'models' => 'Concrete\\Package\\LertecoMembership\\Model' );
I think this essentially registers the 'models' directory (relative to the package) to 'Concrete\Package\LertecoMemeber\Model' namespace. Hope this helps.
Ideally you really should move things to Src if/when you can (I think the linter will still flag your package if you use this method but prb admins should be able to override that). This is simply a bandaid.
For example: I moved /packages/problog/models/problog_list.php to
/packages/problog/src/Problog/ProblogList.php (note caps)
Once inside your /src you need strict PSR4 naming.
The namespace for this is \Concrete\Packages\Problog\Src\Problog\ProblogList
One bug with src is composer. Some composer references are not routed correctly. Such as target types - They currently are incorrectly using \Concrete\Package\src\..... instead of \Concrete\Package\Src\.... So you end up having to register a bogus namespace to trick it. (dumb)
You could just as well register a custom namespace in your package controller with:
$psr4_loader = new Psr4ClassLoader(); $psr4_loader->addPrefix('\\Concrete\\Package\\Problog\\Custom', __DIR__ . '/custom'); $psr4_loader->register();
ChadStrat
Have you tried to submit anything to the MP with this setup?
I want to keep my Models / Tools / Libraries directories, and the linter has flagged them. I can't imagine the linter is that smart, so is it just matching on the text "models", "tools", etc? Or does it exclude instances where it's after /src?
Edit: To clarify
namespace Concrete\Package\LertecoMembership\Src\Models
Is completely valid and the preferred way for you to include your own classes that aren't one of them that fall into those special namespace areas (attributes, controllers, authentication, blocks, etc). Note that this requires you put your models directory beneath the src folder.
ChadStrat
I couldn't get models, libraries etc to work in 5.7.4 and ended up with Chad's solution, everything is beneath controllers or src.
As far as the PRB is concerned with loading, the strategy for anything, new or legacy, has been that as long as it doesn't use include and it works and there is nothing obviously funny about it, then its pretty much OK. The reason is that without any documentation on packages, we don't have anything to judge against.
Guys these namespaces that you define yourself are simply PSR-4 prefixes, you tell the class loader "'THIS\ARBITRARY\STRING' is mapped to '/this/arbitrary/path'". Later when you try to autoload "\THIS\ARBITRARY\STRING\Some\ClassName", the class loader says "I know that this prefix maps to '/this/arbitrary/path', I know the classname is "ClassName", so I know the class MUST be located within "/this/arbitrary/path/Some/ClassName.php".
There is certainly fancy stuff going on with the namespaces that we register for you, but we've only removed this automatic PSR-4 namespace.
Make sure your addon works properly in 5.7.4 and then get a hold of me or one of the other admins and we can exempt it.
It's easy/obvious to ask for an exemption during the PRB process but not after.
In fact, FWIW, the email that Korvin sent out linked to the PRB page which we can't access after it goes live, and the post-approval linter page doesn't even make it obvious which errors have been exempted.
I had some problems just renaming directories because I had other stuff in the same directories that relied on a c5 directory structure to work. So I wrote an autoloader that anybody should be able to use:
public static function autoLoader($class) { $masterPrefix = 'Concrete\Package\LertecoMembership\\'; $mpLen = strlen($masterPrefix); $secondaryPrefixes = array( 'helpers', 'libraries', 'models', 'tools', ); if (substr($class, 0, $mpLen) === $masterPrefix) { $classWithoutPrefix = lcfirst(substr($class, $mpLen)); $segments = explode('\\', $classWithoutPrefix); if (in_array($segments[0], $secondaryPrefixes)) { $file = preg_replace_callback( '/\\\\(\w)/',
Register with
spl_autoload_register('\Concrete\Package\LertecoMembership\Controller::autoLoader', true, true);
@John and @Mike -- I'll be PMing you for exemption because the linter is still catching the references to PackageName\Models\
without registering your own autoloader. Come into the irc during standard
hours and we can help you with it.
On Wed, Apr 29, 2015, 11:17 PM concrete5 Community <
discussions@concretecms.com> wrote:
When you write documentation and howtos, you help everyone.
https://github.com/concrete5/concrete5-5.7.0/blob/48436f09d85dd02ccc...
In retrospect, I might have wanted to just create one of c5's ModifiedLoaders and set it up with my prefix and basedir, but I was overly focused on having my $secondaryPrefixes list.
https://github.com/Buttress/addon_legacy_package_concepts/...
I simply set up the PSR-4 namespaces here: https://github.com/Buttress/addon_legacy_package_concepts/blob/maste...
This will autoload any classes that start with "\Concrete\Package\LegacySample\Models" (or 'Libraries' or 'Helpers') using the PSR-4 namespace standard.
If I were to do it again, I'd look at doing something similar with c5's ModifiedPsr4ClassLoader()
James
Slick :)
There is also a way to invoke the Symphony loader to achieve the same thing. But yours will do fine. You're obviously a man after my own heart - find the crack and stick a crowbar in!
Maybe its time to show how to integrate Miser into 5.7 in 3 lines of code.
The only thing I'm not 100% sure if model/models is a special case and whether there is some automatic renaming between the folder name models and the singular 'model' in the namespace path.
My understanding though is that everything in the src directory (including concrete5's core) doesn't change between singular and plural between the namespace and the folder names.
The exceptions are places outside of the src folder where there are folder names that have come from 5.6 - folders named as plurals (controllers, blocks, tools). In these cases, to keep this convention, but (I think) conform to PSR4 naming rules, there is a bit of automagic going on. controllers->Controller, blocks->Block, etc.
So my suggestion would be to keep everything singular folder name wise in your package src directory and have all the name spaces matching the folders.
In Vivid's recently open sourced ecommerce package for 5.7 there are lots of namespacing examples, perhaps that will help pattern wise -https://github.com/VividWeb/vivid_store...