Jump to content

Recommended Posts

Posted

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?

Posted

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...?

Posted

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?

Posted

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.

  • Like 1
Posted
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

Posted

@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().

Posted

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.

  • Like 1
Posted
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.

Posted (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 by Mike Rockett
Add InputfieldWrapper
Posted

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.");
    }
  }
}

 

  • Like 1
Posted (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 by Mike Rockett

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...