milesj / decoda

A lightweight lexical string parser for BBCode styled markup.
MIT License
196 stars 52 forks source link

Call to a member function tag() on a non-object in ... Decoda.php on line 864 #23

Closed bzis closed 12 years ago

bzis commented 12 years ago

Just tried to execute an example:

$string = 'Hello, my name is [b]Miles Johnson[/b], you may visit my website at [url]http://milesj.me/[/url].';

// Load the text and parse
$code = new Decoda($string);
echo $code->parse();

and got an error Call to a member function tag() on a non-object in ... Decoda.php on line 864

When I started discovering a reason, I found a problem with namespaces. on line 864 there is a call to $this->getFilter('Empty')->tag('root') but $this->getFilter('Empty') returns nothing, because instead of 'Empty' key in $_filters array there is a key 'mjohnson\decoda\filters\Empty' (with full namespace).

If I change in Decoda::addFilter() $class = str_replace(array('Filter', __NAMESPACE__.'\\filters\\'), '', basename(get_class($filter))); instead of $class = str_replace('Filter', '', basename(get_class($filter)));

then everything seems to be fine. Is it only my problem?

milesj commented 12 years ago

You shouldn't be using master yet.

milesj commented 12 years ago

I just tested this in v4 with no problems.

armandabric commented 12 years ago

I have the same problem.

After some debug, I've found that is the basename() funtion the source of the issue. The namespace separator (backslash '\') is only use as a directory separator on Windows OS, on linux, the directory separator is the slash '/'. And this case, the class name clean will not work.

See the basename doc : http://fr.php.net/manual/en/function.basename.php

Debug code use:

public function addFilter(Filter $filter) {
    $filter->setParser($this);

    var_dump(get_class($filter));  // string 'mjohnson\decoda\filters\EmptyFilter' (length=35)
    var_dump(basename(get_class($filter))); // string 'mjohnson\decoda\filters\EmptyFilter' (length=35)

    var_dump(str_replace('\\', '/', get_class($filter))); // string 'mjohnson/decoda/filters/EmptyFilter' (length=35)
    var_dump(basename(str_replace('\\', '/', get_class($filter)))); // string 'EmptyFilter' (length=11)

    $class = str_replace('Filter', '', basename(get_class($filter)));

    // [...]

    return $this;
}
milesj commented 12 years ago

I see, I'll just add a \ to / conversion.

milesj commented 12 years ago

Fixed in 4.0.0!

armandabric commented 12 years ago

Thank you !