Using URL parameters in custom plugin via $_GET does not work

Hi folks,

I made up an example plugin, which is embedded via twig in a pages content via
{{ example() }}

I have the following lines of code:

public function exampleFunction()
{
global $_GET;
echo htmlspecialchars($_GET['myvariable']);
}

If I call www.mydomain.de/test?myvariable=test it results in showing

test

within the content. But if I call www.mydomain.de/test, it causes a crikey!

An exception has been thrown during the rendering of a template (“Undefined index: myvariable”) in “@Page:C:/xampp/htdocs/spielwiese/user/pages/04.test” at line

In “normal” php and other cms this is not a problem at all, the script does not crash like in grav.

Another approach:

public function exampleFunction()
{
$array_url_parse=parse_url($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
var_dump($array_url_parse);
echo '<br/>'.$array_url_parse['query'].'<br/>';
if($array_url_parse['query']) echo 'URL contains variables';
else echo 'URL does not contain variables';
}

Calling www.mydomain.de/test?myvariable=test results in showing

array(2) { [“path”]=> string(25) “localhost/spielwiese/test” [“query”]=> string(15) “myvariable=test” }
myvariable=test
URL contains variables

Calling www.mydomain.de/test is causing an error:

An exception has been thrown during the rendering of a template (“Undefined index: query”) in “@Page:C:/xampp/htdocs/spielwiese/user/pages/04.test” at line

Final approach:

public static function getQueryVar($var)
{
return Grav:: instance()['uri']->query($var);
}
	
public function exampleFunction()
{
echo getQueryVar('myvariable');
}

Even calling www.mydomain.de/test?myvariable=test results the next, at least a different error:

Call to undefined function Grav\Plugin\getQueryVar()

Well, you see, I don’t get it… :frowning:

Thanks for hints!

Markus

In normal PHP it would still show you a notice (or is it a warning :thinking: ), which you might never actually notice. It’s much better you get an exception and fix it before errors pile up.

So about Undefined index - what would you expect to happen, when it is undefined? You have to check yourself if it’s defined, before using. Eg $_GET['myvariable'] ?? ''

About undefined function - why would you expect the function to be in the method, when it’s not there? It’s in the class (I assume). You should probably call it like self::getQueryVar() if it’s static

1 Like

@Markus, To extend on the remark of @Karmalakas

PHP (AFAIK, there is only one of it) considers accessing a non existing index of an array as an error and reports an E_NOTICE: “to report uninitialized variables or catch variable name misspellings …”

However:

  • Apache can be configured to shown/silence certain errors by using setting error_reporting in its php.ini.
  • Also in PHP one can define which errors should be shown/silenced using error_reporting().

After having a quick look at “other cms” (you are probably referring to Contenido), it seems that on startup, index.php includes ./includes/startup.php which contains:

// Report all errors except warnings
error_reporting(E_ALL ^E_NOTICE);

Contenido might have a good reason to silence E_NOTICE issues, but it doesn’t feel right to me…

Please also note that variable $_GET is a superglobal:

" Several predefined variables in PHP are “superglobals”, which means they are available in all scopes throughout a script. There is no need to do global $variable; to access them within functions or methods."

Since Contenido uses a lot of global variables for which global is required, the use of global has probably become a habit. Using global variables is not considered a good practice though…

1 Like

Thanks for your input! Feeling a bit dumb at the moment, because that simple isset solved the problem with $_GET:

if(isset($_GET['myvariable'])) echo htmlspecialchars($_GET['myvariable']);
  else echo'nope';

For parsing the url, my brainbug was the same. This version works after adding array_key_exists:

$array_url_parse=parse_url($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
var_dump($array_url_parse);
if(array_key_exists('query', $array_url_parse))
  {
  echo '<br/>'.$array_url_parse['query'].'<br/>';
  echo 'URL contains variables';
  }
  else echo 'URL does not contain variables';

So two checkmarks set, thanks to your hints - I should not be writing code at midnight anymore, I think.



I have to admit, that my knowledge about functions and classes is limited. I tried to get along with your suggested self::getQueryVar(), but still something is missing and I have no clue solving this error:

“Class ‘Grav\Plugin\Grav’ not found”

I did not find a solution within learn.getgrav.org or other forum threads.

use Grav\Common\Twig\Extension\GravExtension;

works, there is a folder and file within

root\system\src\Grav\Common\Twig\TwigExtension.php

But I do not find a folder

root\system\src\Grav\Plugin

within my local install via xampp, so

use Grav\Plugin\Grav;

seems to be useless. Theory: If the path starts with “Grav\Common”, it pushes one to root\system\src\Grav\Common and if a path starts with “*Grav\Plugins*”, it directs to root\user\plugins where there ist no folder and plugin named Grav that can be found?

My complete code is

<?php
namespace Grav\Plugin;
use Grav\Common\Twig\Extension\GravExtension;
use Grav\Plugin\Grav;

class ExampleTwigExtension extends GravExtension
{

public function getName()
  {
  return 'ExampleTwigExtension';
  }

public function getFunctions(): array
  {
  return [
    new \Twig_SimpleFunction('example', [$this, 'exampleFunction'])
  ];
  }

public static function getQueryVar($var)
  {
  return Grav::instance()['uri']->query($var);
  }

public function exampleFunction()
  {
  echo self::getQueryVar('myvariable');
  }

}


About notices and warnings.
Yes, I considered primarily Contenido. I digged quite deep into that cms, but - because I am not a studied programmer and everything I know came time after time by dealing with JS, PHP, HTML and CSS in my spare time - I did not get that deep into the core as necessary to be more than a versatile user. So my knowledge is most of the time on point for what I want to do and if something does not work, I rtfm and also depend on community feedback. Again: Thanks to you!

So, learning more about functions and classes in general and especially using them within grav will be my next big chapter to deal with. There are different ways to walk for achieving goals in grav than in Contenido. learn.getgrav.org is quite good, but often it is - to me - more of a knowlege puzzle than a linear approach from a to z. Quite often the given information stays on top of the iceberg. Don’t get me wrong, I know how much work this is (I guess you saw this? [Handbuch für Einsteiger (contenido.org)](Handbuch für Einsteiger - Yes, although my questions might cause thoughts “Ah, some noob.”, that book works for so many people and considers quite an amount of indiviually developed modules. The approach is different and can be compared to a complete guided tour instead of a lexicon.) Well, I’ll dig through it till I become more familiar with all those dependencies and principles of grav. And, like I do with Contenido, I’ll of course help others with their issues if I can. I am not that kind of user which is just consuming.

Have a nice day!

Markus

@Markus, A bit of nitpicking:

  • Although your example works because the value is a string, the Twig extension should return a value instead of echo-ing a value.

    What if you would like to do something like:

    {{ getInteger() * 3 }}     --> 30
    - or -
    {{ getArray()[0] }}        --> value0
    

    This will only work when using return:

    return 10;
    - or -
    return ['value0', 'value1'];
    
  • What is your rationale to use a static method instead of an instance method?

1 Like

Again :slight_smile: Why did you use this specific namespace and class? Was there an example somewhere? I believe it should be

use Grav\Common\Grav;
1 Like

A bit of nitpicking:

Details are always important.

the Twig extension should return a value instead of echo -ing a value.

I am just playing around in a quick way. But I will keep that in mind.

What is your rationale to use a static method instead of an instance method?

Okay, to answer this question I have to learn a bit more. I just took an example and looked what happend.

Why did you use this specific namespace and class?

Well, I took the path from the error-message. The static function indeed was a suggested solution for a similar problem, within this forum. Sorry for not having that link handy at the moment.
But, nevertheless, after changing the path to Grav\Commom\Grav it works. Thank you :slight_smile:
So, the error-message is misleading…

Not really. Error message just says the class you’re trying to use does not exist. If you change that Common to any random string, error message would reappear. It’s definitely not misleading, it says exactly what you’re doing wrong

Thanks, Karmalakas for staying tuned.

After looking at my comments again, I see that I did not explain from the very first. At the beginning I had no line
use Grav\Plugin\Grav;
in my code. Then the error-message said

Class ‘Grav\Plugin\Grav’ not found

So I ended up adding this path with use. - But the error-message did not change. For me, this is not logical. Where does it come from to expect this? Anywhere from out of one of the functions?

Next thing: why does
use Grav\Common\Grav;
work, when there is no Grav folder within root\system\src\Grav\Common ?

… Stopping myself.

Okay, the last element does not represent a folder, but a php-file. Okay, that one is actually contained within …\Grav\Common

Another thing learned…

Happy weekend!

Still same thing.

<?php
namespace Grav\Plugin;

class ExampleTwigExtension extends GravExtension
{
  public static function getQueryVar($var)
  {
    return Grav::instance()['uri']->query($var);
  }
}

You tried to use Grav::instance() under Grav\Plugin namespace. Which means you tried to use Grav\Plugin\Grav, which does not exist

You tried to use Grav::instance() under Grav\Plugin namespace.

Okay. I habe not crawled the complete learn.getgrav.org - but that colours the white spot where the error-message path came from. Pretty obvious, if you hear that and get the connection.

It’s not about Grav - it’s just basic PHP

I’m sorry for any lack of knowledge. :wink: