0

UPDATE: 1

I am using this method with DarkBee's help

$detect = new Mobile_Detect;
class Project_Twig_Extensions extends Twig_Extension{
    public function getFunctions(){
        return array(new Twig_SimpleFunction('detectDevice', function() use($detect){
            if($detect->isMobile()){
                return true;
            } else {
                return false;
            }
        }));
    }
}

I am calling it in Twig using

{% if detectDevice %}

There is no value being passes and the condition isn't being met so checking the documentation I wrote another method just in case https://twig.symfony.com/doc/2.x/advanced.html#functions

$twig = new Twig_environment($loader);
$function = new Twig_Function('detectDevice', function() use($detect){
    if($detect->isMobile()){
         return true;
    } else {
         return false;
    }
});
$twig->addFunction($function);

Which also passes no values, my 500 Server Errors have happily stopped thanks to DarkBee but i still can't seem to pass this properly into Twig.

Original Question

I am having immense trouble installing the brilliant Mobile_Detect plugin into my Opencart 3.0 project (https://github.com/serbanghita/Mobile-Detect) I have inserted it and successfully checked if the device is desktop or mobile within php.

I've learned in order to pass this php check into twig, i can either add it to global variables

  $twig = new Twig_Environment($loader);
  $mobTwig->addGlobal('isMobile', true);

or create a public function that extends twig

require_once(DIR_SYSTEM . 'detect/mobiledetectlib/Mobile_Detect.php');
$detect = new Mobile_Detect;
$detectFunction = new function(){
    if($detect->isMobile()){
       return true;
    } else {
       return false;
    }
}

class Project_Twig_Extensions extends Twig_Extension{
    public function getFunctions(){
        return array(new Twig_SimpleFunction('detectDevice', '$detectFunction'));
    }
}

Both options return a 500 Internal Server Error and immediately stop the page loading. For the last few days i cannot figure out why. No amount of googling has helped me. Does anyone have any insight why this might be happening?

Doodles
  • 37
  • 8

1 Answers1

0

You have quite some issues in the code you've posted:

  1. Anonmynous functions

In PHP you can't instantiate a new function(), to define an anomynous function you just use this syntax

$foo = function() {
    return 'foo';
}
echo $foo(); //output: foo
  1. Passing variables to an anomynous function

Inside you function $detectMobile you are trying to access the variable $detect, this variable however is not defined in the scope of the anomynous function.

To correctly use $detect inside your function you would need to use the language construct use.

$detectFunction = new function() use($detect) {
    if ($detect->isMobile()) return true;
    else return false;
}   

You could also use the global language construct but this is not recommended

$detectFunction = new function() {
    global $detect;
    if ($detect->isMobile()) return true;
    else return false;
}   
  1. Passing the anomynous function

Don't use quotes to pass around variables of instances.

  • Using new Twig_SimpleFunction('detectDevice', '$detectFunction') will tell twig to run the global function $detectFunction

  • Using new Twig_SimpleFunction('detectDevice', "$detectFunction") will try to convert the anomynous function to a string. Which is not possible

The only correct way to pass the anonmynous function is just by passing the reference:

new Twig_SimpleFunction('detectDevice', $detectFunction)

Now if you combine everything you could become something like this

class Project_Twig_Extensions extends Twig_Extension{
    public function getFunctions() {
        $detect = new Mobile_Detect();

        return array(new Twig_SimpleFunction('detectDevice', function() use($detect) {
            if ($detect->isMobile()) return true;
            else return false;
        }));
    }
}

Or even better

class Project_Twig_Extensions extends Twig_Extension{
    protected $detect = null

    protected function getDetector() {
        if ($this->detect === null) $this->detect = new \Mobile_Detect();
        return $this->detect;
    }

    public function getFunctions() {

        return array(new Twig_SimpleFunction('detectDevice', function() {
            return $this->getDetector()->isMobile();
        }));
    }
}

On a lost note please make sure to show all errors while you are developing..

DarkBee
  • 16,592
  • 6
  • 46
  • 58
  • Ok, i am realising some mistakes, but with the end code and calling the function in twig `{% if detectDevice %}` the condition isn't being met somehow.. I have multiple variations including my modified old one, yours and one tailored to the documentation (https://twig.symfony.com/doc/2.x/advanced.html#functions) with the knowledge you provided. Posted in update. – Doodles Sep 07 '18 at 05:55
  • Just do something like `return array(new Twig_SimpleFunction('detectDevice', function() { return 42; }));` - `{{ detectDevice() }}` to test if the function is working – DarkBee Sep 07 '18 at 06:01
  • Nothing? Just a white page, if so please enable `twig` debug also – DarkBee Sep 07 '18 at 06:56
  • Twig debug is dump() right? Calling dump on the function `{{ dump(detectDevice) }}` returns NULL, likewise with dump(user). – Doodles Sep 07 '18 at 07:40
  • It's `detectDevice()`, not `detectDevice`. Otherwise you are calling a variable instead of the function – DarkBee Sep 07 '18 at 07:46
  • sorry, with `{{ dump(detectDevice()) }}` the website crashes to Error 500 which made me assume it was incorrect syntax – Doodles Sep 07 '18 at 07:59
  • Not showing up at all in any error logs i can find, still trudging away, re-linked and rewrote a bunch of things , i've narrowed it down to creating `$twig = new Twig_Environment($loader)` is what sends me error 500 also creating a Twig extension class, anything i'm doing involving new twig falls flat. – Doodles Sep 10 '18 at 02:10
  • Found in the Apache error logs `PHP Fatal error: Class 'Twig_Environment' not found` and i learned this Opencart had twig installed without Composer and the autoloader isn't aware of a twig installation so the basic twig commands are unknown causing the 500 errors. Are you aware of any ways to install twig with autoloader.php or installing Composer on an existing Opencart? – Doodles Sep 13 '18 at 05:07
  • You could just try to edit `vendor/composer/autoload_namespace.php` and add `'Twig_' => array($vendorDir . '/twig/twig/lib'),` to the existing array – DarkBee Sep 13 '18 at 05:27