Probleem met callback functie in parser
Echter krijg ik de callback-functie voor MyBorderFunction niet aan de praat. Deze wordt niet geparsed. Mis ik iets in de functie, gezien dit script met namespaces werkt? Of ligt het probleem dieper?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
require_once(__DIR__ . "/../vendor/autoload.php");
use Nbbc\BBCode;
/* Custom Callback-function for 'MyBorderFunction' */
function MyBorderFunction($bbcode, $action, $name,
$default, $params, $content) {
if ($action == 'BBCODE_CHECK') {
if (isset($params['color'])
&& !preg_match('/^#[0-9a-fA-F]+|[a-zA-Z]+$/', $params['color']))
return false;
if (isset($params['size'])
&& !preg_match('/^[1-9][0-9]*$/', $params['size']))
return false;
return true;
}
$color = isset($params['color']) ? $params['color'] : "blue";
$size = isset($params['size']) ? $params['size'] : 1;
// return the content
return "<div style=\"border: {$size}px solid $color\">$content</div>";
}
$input = "[scroll]tralalala[/scroll][border color=red size=3]This text is in a medium red border![/border]"
. "[border size=10]This text is in a fat blue border![/border]"
. "[border color=green]This text is in a normal green border![/border]";
$bbcode = new BBCode();
$bbcode->AddRule('border', Array(
'mode' => BBCODE_MODE_CALLBACK,
'method' => 'MyBorderFunction',
'class' => 'block',
'allow_in' => Array('listitem', 'block', 'columns'),
));
$marquee = Array(
'simple_start' => '<marquee>',
'simple_end' => '</marquee>',
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
);
$bbcode->AddRule('scroll', $marquee);
// Parse the UBBtags.
$output = $bbcode->Parse($input);
print "<div class='bbcode'>$output</div>";
?>
require_once(__DIR__ . "/../vendor/autoload.php");
use Nbbc\BBCode;
/* Custom Callback-function for 'MyBorderFunction' */
function MyBorderFunction($bbcode, $action, $name,
$default, $params, $content) {
if ($action == 'BBCODE_CHECK') {
if (isset($params['color'])
&& !preg_match('/^#[0-9a-fA-F]+|[a-zA-Z]+$/', $params['color']))
return false;
if (isset($params['size'])
&& !preg_match('/^[1-9][0-9]*$/', $params['size']))
return false;
return true;
}
$color = isset($params['color']) ? $params['color'] : "blue";
$size = isset($params['size']) ? $params['size'] : 1;
// return the content
return "<div style=\"border: {$size}px solid $color\">$content</div>";
}
$input = "[scroll]tralalala[/scroll][border color=red size=3]This text is in a medium red border![/border]"
. "[border size=10]This text is in a fat blue border![/border]"
. "[border color=green]This text is in a normal green border![/border]";
$bbcode = new BBCode();
$bbcode->AddRule('border', Array(
'mode' => BBCODE_MODE_CALLBACK,
'method' => 'MyBorderFunction',
'class' => 'block',
'allow_in' => Array('listitem', 'block', 'columns'),
));
$marquee = Array(
'simple_start' => '<marquee>',
'simple_end' => '</marquee>',
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
);
$bbcode->AddRule('scroll', $marquee);
// Parse the UBBtags.
$output = $bbcode->Parse($input);
print "<div class='bbcode'>$output</div>";
?>
Errors in errorlog?
Misschien een verbose mode in de andere classes?
Maar wat bedoel je met verbose-mode?
Ik heb ontdekt dat de configuratie wel prima werkt, want met een oud script werkt het wel. Maar ik heb liever de nieuwe source. Maar misschien zijn er ook wel betere UBB-parsers die even zo geavanceerd zijn, en betere updates krijgen.
Ook daar sta ik voor open.
Gewijzigd op 30/09/2020 23:10:21 door - Ariën -
Maar retourneert de methode uberhaupt iets of krijg je foutmeldingen?
Welke waarden heeft $action? Iets wat afwijkt van BBCODE_CHECK? Anders retourneert dat ding alleen maar true of false.
Valt het gebruik van borders wel binnen toegestane elementen?
Heb je ergens de bron van de classes?
Heb je gekeken of jouw implementatie op een of andere manier afwijkt van andere tag-implementaties?
Wat gebeurt er "concreet"? Ziet het er naar uit dat er helemaal niets gedaan wordt met je border-elementen?
https://github.com/vanilla/nbbc
Mijn implementatie wijkt verder niet af, en heb ik gecheckt op de oude versie. De nieuwe versie zou ook niet mogen afwijken, want de documentatie is niet eens geupdated. :P
Het zijn niet enkel de border-elementen die het niet doen, maar ook de hele functie aanroep naar MyBorderFunction die niet werkt. Er zit wel wat rotzooi met dit in:
Morgen eens kijken wat ze hier precies mee doen, want aanpassen heeft ook weinig nut, nou ja... het verhelpt die error weer. Kijken wat ze in de array doen als er naar die string geluisterd wordt.
Het is een flink script die ik op mijn gemak even moet doorgronden. Bij de oude versie werkt het wel, maar de nieuwe lijkt ergens niet die functie uit te lezen. Het gaat om deze Github-repo: Mijn implementatie wijkt verder niet af, en heb ik gecheckt op de oude versie. De nieuwe versie zou ook niet mogen afwijken, want de documentatie is niet eens geupdated. :P
Het zijn niet enkel de border-elementen die het niet doen, maar ook de hele functie aanroep naar MyBorderFunction die niet werkt. Er zit wel wat rotzooi met dit in:
Quote:
Warning: Use of undefined constant BBCODE_MODE_CALLBACK - assumed 'BBCODE_MODE_CALLBACK'
Warning: Use of undefined constant BBCODE_MODE_CALLBACK - assumed 'BBCODE_MODE_CALLBACK'
Morgen eens kijken wat ze hier precies mee doen, want aanpassen heeft ook weinig nut, nou ja... het verhelpt die error weer. Kijken wat ze in de array doen als er naar die string geluisterd wordt.
Gewijzigd op 01/10/2020 01:21:55 door - Ariën -
Zonder uitgebreid naar de code van die parser te kijken:
Die constant wordt waarschijnlijk gebruikt om te bepalen in wat voor 'mode' de parser werkt.
Aangezien jouw code deze constant niet kent (want hij is enkel binnen de scope van de Nbbc\BBCode class beschikbaar) neemt de PHP parser aan dat je de string "BBCODE_MODE_CALLBACK" bedoelde. Hier kan de parser niet mee overweg en dus wordt je callback niet aangeroepen.
De juiste manier om constants uit een (namespaced)class te refereren is als volgt:
Ik heb zo'n vermoeden dat die aanpassing aan jouw code het probleem zou moeten verhelpen.
Gewijzigd op 01/10/2020 09:18:08 door Thom nvt
Ik neem ook aan dat MyBorderFunction onderdeel uitmaakt van een soort van abstracte standaard tag-class en dat het bovenstaande codefragment een gedeeltelijk fragment is? Ik kan mij zo voorstellen dat elke tag wel een set van standaard gedragingen en variabelen heeft (een soort basis blauwdruk voor een tag), en dat je niet zomaar losse functies aan een BBCode() object kunt hangen?
De code in de library dwingt dat in ieder geval niet af (code inline om een klik te besparen):
https://github.com/vanilla/nbbc/blob/master/src/BBCode.php#L1939
Code (php)
1
2
3
4
5
2
3
4
5
case self::BBCODE_MODE_CALLBACK:
if (is_callable($tag_rule['method'])) {
$result = @call_user_func($tag_rule['method'], $this, self::BBCODE_CHECK, $tag_name, $default_value, $params, $contents);
}
break;
if (is_callable($tag_rule['method'])) {
$result = @call_user_func($tag_rule['method'], $this, self::BBCODE_CHECK, $tag_name, $default_value, $params, $contents);
}
break;
en https://github.com/vanilla/nbbc/blob/master/src/BBCode.php#L2042
Zie het als een configuratie van de NBBC UBB-parser, waarbij het even omgebouwd is tot testcase om de parser uit te testen. Als je de documentatie leest dan zie je dat er diverse soort configuratieopties zijn, waarbij callbacks (BBCODE_MODE_CALLBACK) speciaal bedoeld zijn om logica in een tag te hangen. validaties bijvoorbeeld, of uitzonderingen.
Of BBCODE_MODE_ENHANCED voor geen extra logica en standaard output-templates.
Of geen BBCODE_MODE_* voor een normale tag, zoals mijn nostalgische marquee voorbeeld.
Ik zal er vanavond nog even induiken, en kijken of die namespace tip van Thom werkt.
Toevoeging op 01/10/2020 19:58:21:
Yes...
Het werkt! Die namespace-top van @Thom was inderdaad de oplossing.
Maar Thom bedoelt dus dat ik beter de source van NBBC kan aanpassen om te voorkomen dat ik die namespace in mijn UBB-configuratie moet afdwingen? Hoe zou je dat dan doen?
Gewijzigd op 01/10/2020 17:23:05 door - Ariën -
Conventie is dat je sources die niet van jou zijn niet aanpast. Extension over modification.
Als je iets wil aanpassen zul je dus die class moeten extenden.
In dit geval is een wrapper om de AddRule method heen voldoende zou moeten zijn, daar kun je dan in controleren of de rule het type "BBCODE_MODE_CALLBACK" heeft en daarna valideren dat de method zelf een bepaalde interface implementeerd.
Zoiets (pseudo-code, niet getest):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
Class MyBBCode extends Nbbc\BBCode {
public function AddRule($name, $rule) {
if ($rule['type'] == self::BBCODE_METHOD_CALLBACK) {
if (!$rule['method'] instanceof MyCallbackInterface) {
throw new MyCallbackException('Method should implement MyCallbackInterface!');
}
}
return parent::AddRule($name, $rule); // Call parent class' implementation
}
}
Interface MyCallbackInterface {
public function __call($name, $params); // Magic call method
}
Class MyCallbackException extends RuntimeException {
}
[/code]
Class MyBBCode extends Nbbc\BBCode {
public function AddRule($name, $rule) {
if ($rule['type'] == self::BBCODE_METHOD_CALLBACK) {
if (!$rule['method'] instanceof MyCallbackInterface) {
throw new MyCallbackException('Method should implement MyCallbackInterface!');
}
}
return parent::AddRule($name, $rule); // Call parent class' implementation
}
}
Interface MyCallbackInterface {
public function __call($name, $params); // Magic call method
}
Class MyCallbackException extends RuntimeException {
}
[/code]
Ik zal er eens naar kijken. Hoewel ik ook dacht aan een pull-request.
Gewijzigd op 01/10/2020 20:50:48 door - Ariën -
Gewijzigd op 03/10/2020 07:34:47 door - Ariën -