Mike Rockett Posted December 11, 2016 Share Posted December 11, 2016 I'd like to add support for ProcessWire 2.8 in Jumplinks, but am unable to call wire() in any PSR-4 autoloaded class. I'm using this to load my classes: $this->classLoader->addNamespace('Jumplinks', __DIR__ . '/src/Jumplinks'); In one of the classes given the Jumplinks\<Something> namespace, the file compiler does not compile wire() to \ProcessWire\wire(). Is this a known bug? Any way I can work around it? Link to comment Share on other sites More sharing options...
Mike Rockett Posted December 11, 2016 Author Share Posted December 11, 2016 I've added this to my module file, directly after the classLoader instruction: if (function_exists("\\ProcessWire\\wire")) { function wire() { return call_user_func_array("\\ProcessWire\\wire", func_get_args()); } } It works, but I'm worried that it's the wrong way to do it...? Link to comment Share on other sites More sharing options...
Mike Rockett Posted December 11, 2016 Author Share Posted December 11, 2016 Even better, I've done this instead: Classes that use wire() outside of the ProcessWire namespace now extend or call \Jumplinks\Utility\BaseUtility::wire(): /** * Call the global wire. * Retains support for PW 2.8.x and 3.x * @return mixed */ public static function wire() { $wires = ["\\ProcessWire\\wire", 'wire']; foreach ($wires as $wire) { if (function_exists($wire)) { return call_user_func_array($wire, func_get_args()); } } return Exception('Unable to call \ProcessWire\wire() or \wire().'); } Guess that's better? Link to comment Share on other sites More sharing options...
LostKobrakai Posted December 11, 2016 Share Posted December 11, 2016 How about storing the result of the function selection in a static variable, so the computation does only happen once per request. The namespace won't magically switch mid request. 1 Link to comment Share on other sites More sharing options...
Mike Rockett Posted December 11, 2016 Author Share Posted December 11, 2016 2 minutes ago, LostKobrakai said: How about storing the result of the function selection in a static variable, so the computation does only happen once per request. The namespace won't magically switch mid request. Yeah, I think that's a better idea. Thanks Link to comment Share on other sites More sharing options...
Mike Rockett Posted December 11, 2016 Author Share Posted December 11, 2016 @LostKobrakai Does this look about right to you? namespace Jumplinks\Utility; class BaseUtility { /** * Store the wire. * @var mixed */ protected static $wire = null; /** * Store the wire if not already stored and then call it. * * @return mixed */ public static function wire() { if (is_null(static::$wire)) { foreach (["\\ProcessWire\\wire", 'wire'] as $wire) { if (function_exists($wire)) { static::$wire = $wire; } } } return call_user_func_array(static::$wire, func_get_args()); } } Utilites then extend this class, and other classes that are not utilities simply call BaseUtility:wire(). Link to comment Share on other sites More sharing options...
LostKobrakai Posted December 11, 2016 Share Posted December 11, 2016 static:: (/late-) binding will result in each class doing their own calculation. You probably would want to use self:: so it's really a one time calculation for all of your classes. 1 Link to comment Share on other sites More sharing options...
Mike Rockett Posted December 11, 2016 Author Share Posted December 11, 2016 39 minutes ago, LostKobrakai said: static:: (/late-) binding will result in each class doing their own calculation. You probably would want to use self:: so it's really a one time calculation for all of your classes. Of course - that makes sense. Thanks. Link to comment Share on other sites More sharing options...
Mike Rockett Posted December 11, 2016 Author Share Posted December 11, 2016 (edited) Okay, so that's that one out of the way. But now what do I do for importing classes that may or may not be in the ProcessWire namespace? For example, I need to use ProcessWire\NullPage and ProcessWire\InputfieldWrapper() in these autoloaded classes... Edited December 11, 2016 by Mike Rockett Add InputfieldWrapper Link to comment Share on other sites More sharing options...
LostKobrakai Posted December 11, 2016 Share Posted December 11, 2016 So to answer the question of your entry post: namespaced files are never compiled. The compiler is mostly meant for 2.x to 3.x transition. As pw 2.x is namespaceless the compiler does only work on files without namespace (also makes things easier to control). So you would probably be fine if you could push all the 2.x / 3.x differences into a separate class without namespace. <?php class Bridge extends Wire { public function getNew($shortname) { switch($shortname) { case 'InputfieldWrapper': return new InputfieldWrapper(); default: throw new WireException("Classname $shortname isn't setup or is invalid."); } } } 1 Link to comment Share on other sites More sharing options...
Mike Rockett Posted December 11, 2016 Author Share Posted December 11, 2016 (edited) That looks good - I could do that for NullPage and InputfieldWrapper, but I wouldn't be able to do it for wire() because it may not be called statically, and I don't want to create a new bridge for each class that uses it - unless that is the only way to go about it. Update: I'm just using plain old wire()-> anyway, so no need for me to be calling it from the bridge itself. In fact, the bridge doesn't even need to extend Wire at all... Edited December 11, 2016 by Mike Rockett Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now