Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

12 Stron V   1 2 3 > »   
Reply to this topicStart new topic
> [klasa] Zaawansowany parser bbcode (php5), advanced bbcode parser
wookieb
post 2.03.2009, 14:10:58
Post #1





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Projekt jest już na githubie pod adresem
https://github.com/wookieb/bbcode

Proszę o dodawanie informacji o bugach właśnie tam.

UPDATE Wersja 1.2
[php bbcode, parser bbcode, advanced bbcode parser]
Chciałbym dziś zaprezentować swój mechanizm parsujący kod bbcode oraz ułatwiający nam kontrolę nad tym czy tagi są prawidłowo używane.
Klasa do pobrania:
https://github.com/wookieb/bbcode/zipball/master

Przykład działania:
http://wookieb.pl/bbcode/test.php

Readme.html w paczce oraz pod adresem http://wookieb.pl/bbcode/readme.html


Licencja
Skrypt wydany na licencji BSD. Dla własnego jak i komercyjnego użytku.

Ustawienia parsera
Ustawienia dla parsera znajdują się teraz w klasie BbCodeSettings. Ciekawsze z ustawień to

Zaufany kod
  1. $settings->trustText = false; // kod niezaufany
  2. $settings->trustText = true; // kod zaufany


Ustawienie kontroluje stopień sprawdzenia danych. Gdy kod bbcode sparsowaliśmy wcześniej to pobieramy jest wersję zaufaną i zapisujemy.
  1. $code = $bbcode->getBbcode();


Przy ponownym odczytaniu kodu, możemy oznaczyć kod jak zaufany. Spowoduje to ominięcie wielu operacji kontroli atrybutów, przez co parsowanie jest szybsze.

Kod
$bbcode = new BbCode();

$text='[b] Bla Bla [i] Hehe';
$bbcode->parse($text, false); // nie chcemy wyniku wiec ustawiamy na false
$code=$bbcode->getBbcode(); // [b] Bla Bla [i] Hehe[/i][/b]

// $code zapisujemy


// po pewnym czasie odczytujemy i parsujemy go jeszcze raz
$bbcode->getSettings()->trustText = true;
echo $bbcode->parse($code);


Dostępność tagów
Możliwe jest włączenie tylko niektórych tagów parsera

Kod
$bbcode = new BbCode();
$text = '[b]Pogrubienie[/b]
[i]Kursywa[/i]';

echo $bbcode->parse($text);
// <b>Pogrubienie</b>
// <i>Kursywa</i>

$bbcode->getSettings()->availableTags = array('b');
echo $bbcode->parse($text);
// <b>Pogrubienie</b>
// Kursywa



Walidacja HTML (kolejności użycia)
Domyślnie parser poprawia kolejność użycia tagów.
np kod
Kod
[b] pogrubienie [i] Kursywa[/b]
[ul]
    [li]Element listy
[/b]
[/i]

Zamieni na

Kod
[b] pogrubienie [i] Kursywa[/i][/b]
[ul]
    [li]Element listy[/li]
[/ul]


Tworzenie zajawek
Parser potrafi tworzyć zajawke o odpowiedniej ilości znaków (ignorując przy tym tagi bbcode).
Wspiera różne kodowania.

Test pod adresem http://wookieb.pl/bbcode/cut_test.php


Rozszerzanie możliwości
Za pomocą tworzenia nowych tagów i dodawania ich specjalnych ustawień można rozszerzyć bbcode o dodatkowe tagi, możliwości.
Szczególnie chciałbym zwrócić uwage na możliwość "przetrzepania" kodu przez funkcje filtrów, dzięki którym możemy tworzyć zaawansowane zależności.
Informacje na temat ustawień dostępne pod linkiem http://wookieb.pl/bbcode/readme.html

ZACHĘCAM DO OCEN, WNOSZENIA WŁASNYCH UWAG A TAKŻE PROPOZYCJI ZMIAN
Mam nadzieję, że przyda się niejednej osobie, która dostrzeże możliwości użycia parsera NIE TYLKO do Bbcode smile.gif i nie tylko.

Update - 2009.05.31
Dodałem tag youtube do paczki.


Inne zmiany:
- poprawiony generowany kod html dla taga IMG
- poprawiona metoda wyszukiwania nazwy taga
- poprawiona szybkość działania
- przeniesienie ustawień do BbCodeSettings
- poprawiona walidacji urli
- dodatkowe zabezpieczenia przed XSS

Ten post edytował wookieb 23.08.2011, 19:46:20
Powód edycji: [wookieb]: [wookieb]: [Spawnm]: update


--------------------
Go to the top of the page
+Quote Post
.radex
post 2.03.2009, 19:05:57
Post #2





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


No nie wiem, czy zapis do bazy jest szybszy od sprawdzenia poprawności tagów. Wydaje mi się, że lepszym (szybszym) rozwiązaniem byłoby cache'owanie na dysku.

@down: a no fakt, nie zrozumiałem przeznaczenia. Mógłbyś dopisać do tej klasy cache'owanie - gdy implementowałem bbcode u siebie i robiłem benchmark, to przykładowy bbcode parsował się średnio 4ms, a przy włączonym cache'owaniu wczytywanie trwało średnio koło 0.2ms. jest różnica tongue.gif

Ten post edytował .radex 2.03.2009, 20:16:07


--------------------
blog | Tadam — minutnik do Pomodoro na Maka :)
Go to the top of the page
+Quote Post
wookieb
post 2.03.2009, 19:14:15
Post #3





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat(.radex @ 2.03.2009, 19:05:57 ) *
No nie wiem, czy zapis do bazy jest szybszy od sprawdzenia poprawności tagów. Wydaje mi się, że lepszym (szybszym) rozwiązaniem byłoby cache'owanie na dysku.

Mi bardziej chodziło o to, że np gdy zapisujemy post to najpierw tworzymy wersję z poprawnym kodem i dopiero zapisujemy post w bazie. Przez co przy wyświetlaniu posta na stronie możemy zastosować szybszą wersję parsowania (z zaufanym kodem bb). No chyba, że ktoś zapisuje w bazie wersję htmlową ale to już jego sprawa smile.gif

Co do zapisywania na dysku to jak najbardziej. Ale to już zostawmy mechanizmowi cachowania smile.gif

//UP Cachowanie mam zrobione ale to już oddzielny mechanizm smile.gif.

Ten post edytował wookieb 3.03.2009, 12:38:28


--------------------
Go to the top of the page
+Quote Post
WebKing
post 9.03.2009, 18:28:58
Post #4





Grupa: Zarejestrowani
Postów: 219
Pomógł: 16
Dołączył: 16.07.2007

Ostrzeżenie: (0%)
-----


Cytat(wookieb @ 2.03.2009, 14:10:58 ) *
  1. <?php
  2. echo $bb->getParseText();
  3. ?>

Nie możesz w funkcji getParseText dać echo zamiast to ciągnąć?
Go to the top of the page
+Quote Post
pyro
post 9.03.2009, 18:49:06
Post #5





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(WebKing @ 9.03.2009, 18:28:58 ) *
Nie możesz w funkcji getParseText dać echo zamiast to ciągnąć?


NIE

Tak jest ok.


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
bim2
post 10.03.2009, 18:35:29
Post #6





Grupa: Zarejestrowani
Postów: 1 873
Pomógł: 152
Dołączył: 9.04.2006
Skąd: Berlin

Ostrzeżenie: (0%)
-----


Cytat(WebKing @ 9.03.2009, 18:28:58 ) *
Nie możesz w funkcji getParseText dać echo zamiast to ciągnąć?

A jakbym chciał
mojaFunkcja($oBb->getParseText()) to co wtedy? Return zawsze jest najlepszym wyjściem.


--------------------
Go to the top of the page
+Quote Post
gebp
post 11.03.2009, 21:33:51
Post #7





Grupa: Zarejestrowani
Postów: 180
Pomógł: 6
Dołączył: 10.04.2006

Ostrzeżenie: (0%)
-----


Klasa działa fajnie. Jefnak z danego tutka nie jestem w stanie stworzyć dodatkowego znacznika. Chodzi mi o kolor.
Czyli
  1. CZERWONY


z podglądu wykoncypowałem tak ( dodane do filtra baisic po font)
  1. <?php
  2. ....
  3. 'color'=>array( 'open'=>'span',
  4.              'close'=>'span',
  5.              'attributes'=>array('color'=>array('attr'=>'style',
  6.                                                    'type'=>'string',
  7.                                                    'name'=>'color:'
  8.                    
  9.                                                       )
  10.                                           )
  11.            )    
  12. ...
  13. ?>


Jeżeli można proszę o pokazanie gdzie leży błąd.
Jak będę pewny to dodam sobie jeszcze underline
Go to the top of the page
+Quote Post
wookieb
post 11.03.2009, 23:01:22
Post #8





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




I to był właśnie mój błąd którego nie ująłem we wstępnej dokumentacji
Wstępnie zakładałem następujące możliwości podania parametru:
"parametr ze spacja itd"
'parametr ze spacja'
[0-9][a-z] - tutaj nie łapało koloru.
Oczywiście był to mój błąd w założeniu.
Poprawka polega na zamianie liniii 391 na następującą
  1. <?php
  2. preg_match_all('/s*([a-z0-9-_]+)=('.+?'|".+?"|S*)s*/i', $text, $matches, PREG_SET_ORDER);
  3. ?>

Uaktualniłem paczkę na serwerze.

Ten post edytował wookieb 12.03.2009, 09:46:03


--------------------
Go to the top of the page
+Quote Post
gebp
post 12.03.2009, 12:01:24
Post #9





Grupa: Zarejestrowani
Postów: 180
Pomógł: 6
Dołączył: 10.04.2006

Ostrzeżenie: (0%)
-----


Dięki ~wookieb.

Z kolorem od razu pomogło.
Ja jednak (bardzo prawdopodone!) upośledzony. Nie czaje dokumentacji o dodawaniu dodatkowych znaczników. Od 2h próbuje utworzyć
  1. <span style="text-decoration: underline" ></span>

Jeżeli nie stanowi to problemu mógłbyś dać przykład tworzenia znacznika z "zaprogramowanymi" atrybutami (np. text-decoration: underline) jak i z dołączanymi (np. text-align: wyrównanie ).

no może z wyrównaniem sobie poradzę (jak wcześniej zrobiłem z "color") ale tak ku potomnym bo klasa działa naprawdę extra.
Go to the top of the page
+Quote Post
wookieb
post 12.03.2009, 12:03:07
Post #10





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat(gebp @ 12.03.2009, 12:01:24 ) *
Jeżeli nie stanowi to problemu mógłbyś dać przykład tworzenia znacznika z "zaprogramowanymi" atrybutami (np. text-decoration: underline) jak i z dołączanymi (np. text-align: wyrównanie ).


Właśnie coś takiego robie i na dziś wieczorem ma być możliwośc dodawania domyślnych atrybutów i ich wartości.


--------------------
Go to the top of the page
+Quote Post
zegarek84
post 12.03.2009, 12:21:00
Post #11





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


aż z ciekawości jak wrócę ze studiów po weekendzie to sobie zerknę w kod... swoją drogą jak tak na szybko na przewijaniu zerknąłem to nie powinno być trudne w stosowaniu, składnią przypomina ale tak pobieżnie patrząc DOM z php


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
nrm
post 12.03.2009, 19:16:52
Post #12





Grupa: Zarejestrowani
Postów: 627
Pomógł: 33
Dołączył: 1.05.2005
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Bardzo ciekawa klasa, gratulacje. Wiem co mówię bo swego czasu wytestowałem takich z 10 i z każdą były większe lub mniejsze problemy winksmiley.jpg Trzeba tą odpicować i będzie gites winksmiley.jpg

Na szybko to co wpadło mi w oczy:
- brak automatycznej zamiany URLa na link (czyli http://jakisurl.pl/cos)
- tym samym brak skracania zbyt długich URLi (skracania samego opisu linka aby nie rozjechał treści serwisu)
- brak obsługi
Kod
[img]http://link.do.img[/img] jest tylko dziwne [img=url]

- od razu dodam żeby sprawdzać czy URL jest na pewno IMG
- include_once 'filters/'.$filter.'.php'; -> wywal bbcode aby można to było bez modyfikacji wszędzie ładować

Kod
application/libraries/bbcode/bbcode.class.php [458]:
in_array() [function.in-array]: Wrong datatype for second argument

bb_code->parse( [url=&quot;http://test.pl&quot;]
[url=http://test.pl]
[url='http://test.pl]
[url]http://test.pl[/url] )

musi być idiotoodporne winksmiley.jpg

Jak wrzucisz kolejną wersję to na pewno przetestuje. Mam ogromne ilości danych na których mogę to testować (w sensie treści userów z for).


--------------------
Go to the top of the page
+Quote Post
SHiP
post 17.03.2009, 17:44:53
Post #13





Grupa: Zarejestrowani
Postów: 697
Pomógł: 47
Dołączył: 19.12.2003
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Ok sprawdziłem i dwie uwagi winksmiley.jpg

1. jeśli umieścimy coś między [ul] a [li] to nie zostanie to usunięte co powoduje wygenerowanie nievalidującego się kodu html
2. Wyrzuca błędy
  1. Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file in /home/hellson/public_html/bbcode/bbcode/bbcode.class.php on line 234


Ja przy okazji zaspamuje i podrzucę link do swojego rozwiązania: http://forum.php.pl/index.php?showtopic=55195 winksmiley.jpg

Pozdrawiam


--------------------
Warsztat: openSUSE, NetBeans, Photoshop
Mój Blog
Go to the top of the page
+Quote Post
wookieb
post 14.05.2009, 08:49:51
Post #14





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Klasa została poprawiona i usprawniona. Dodałem wszystkie standardowe tagi bbcode.
Można ściągać i sprawdzić teraz.


--------------------
Go to the top of the page
+Quote Post
slewin
post 14.05.2009, 13:38:36
Post #15





Grupa: Zarejestrowani
Postów: 104
Pomógł: 7
Dołączył: 9.12.2008
Skąd: wroc

Ostrzeżenie: (0%)
-----


a ja pobrałem klasę ,wypakowałem ją do katalogu na serwer oraz uruchomiłem plik test.php i moim oczom ukazał się błąd :
Kod
<b>Parse error</b>:  syntax error, unexpected T_ARRAY, expecting '&' or T_VARIABLE in <b>e:\usr\krasnal\www\paser bb\bbcode\data_validator.class.php</b> on line <b>251</b>

o co chodzi ? może to chodzi o serwer ,sprawdzę na innym .

faktycznie na innym działa dobrze ;] .

Ten post edytował slewin 14.05.2009, 13:42:11
Go to the top of the page
+Quote Post
wookieb
post 14.05.2009, 13:43:08
Post #16





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Zapewne masz php4 zamiast php5


--------------------
Go to the top of the page
+Quote Post
slewin
post 14.05.2009, 13:47:14
Post #17





Grupa: Zarejestrowani
Postów: 104
Pomógł: 7
Dołączył: 9.12.2008
Skąd: wroc

Ostrzeżenie: (0%)
-----


na jednym mam PHP Version 5.0.4 a na tym gdzie paser działa : PHP Version 5.2.6 .
Go to the top of the page
+Quote Post
wookieb
post 14.05.2009, 13:50:47
Post #18





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat
PHP 5 introduces Type Hinting. Functions are now able to force parameters to be objects (by specifying the name of the class in the function prototype) or arrays (since PHP 5.1). However, if NULL is used as the default parameter value, it will be allowed as an argument for any later call.


--------------------
Go to the top of the page
+Quote Post
slewin
post 28.05.2009, 13:48:38
Post #19





Grupa: Zarejestrowani
Postów: 104
Pomógł: 7
Dołączył: 9.12.2008
Skąd: wroc

Ostrzeżenie: (0%)
-----


testuje paser od jakiegoś czasu i przyzna,m że jest świetny . Mam tylko jedno pytanie : np. w bazie mam tresc a w tresci jest url z filmem do youtube i chcial bym go odrazu podmienic na odtwarzacz jak to zrobic ?

Ten post edytował slewin 28.05.2009, 13:49:05
Go to the top of the page
+Quote Post
wookieb
post 28.05.2009, 14:09:51
Post #20





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Przykładowy filtr
youtube.php
  1. <?php
  2. class bbcode_filter_youtube
  3. {
  4.  
  5.    public $tags = array(
  6.        'youtube'=>array(
  7.            'open'    =>    'youtube', // tak naprawde moze byc tutaj cokolwiek bo i tak potem to wywalimy
  8.            'close'    =>    'youtube',
  9.            'notallowed_childs'=>    'all', // zadnych innych tagow w srodku nie potrzebujemy
  10.            'parseBody'    =>    'checkMovie'
  11.        );
  12.    );
  13.  
  14.    //$tag - wszystkie informacje o tagu. W naszym przypadku to co powyzej
  15.    // $openNode - tag otwierajacy
  16.    // $body - lista elementow zawartych pomiedzy tagami
  17.    // $closeNode - tag zamykajacy
  18.    public function checkMovie($tag, &$openNode, &$body, &$closeNode)
  19.    {
  20.        // wyciagamy caly tekst
  21.        $bodyStr='';
  22.        foreach($body as $el) $bodyStr.=$el['text'];
  23.        
  24.        // sprawdzamy czy ciag jest urlem
  25.        $str=data_validator::checkUrl($bodyStr);
  26.        
  27.        if($str==false)
  28.        {
  29.            return false;
  30.        }
  31.        
  32.        
  33.        // tag zamykajacy nie jest nam potrzebny wiec usuwamy z niego sam tekst
  34.        $closeNode['text']='';
  35.        
  36.        
  37.        $openNode['text']=' tutaj wpisujemy kod odpowiadajacy za wyswietlenie filmiku youtube ';
  38.        
  39.    }
  40. }
  41. ?>


Użycie tagu
Kod
[youtube]http://link/do/filmiku[/youtube]



Filtr dodajemy poprzez dodanie wartosci 'youtube' do tablicy
  1. <?php
  2. private $defaultFilters=array('basic', 'code', 'url', 'list', 'image', 'youtube');
  3. ?>

albo ładujemy do dynamicznie
  1. <?php
  2. $bbcode->loadFilter('youtube');
  3. ?>


UWAGA! Jest to tylko taki template do samodzielnego dokończenia kodu. To jak wyswietlimy filmik i co bedziemy chcieli wyciagnac z adresu potrzebne dane zalezy tylko od nas.

Według standardów na http://bbcode.org powinno sie używać
Kod
[youtube]id_movie[/youtube]

więc nic nie stoi na przeszkodzie, żeby to dorobić.

Ten post edytował wookieb 28.05.2009, 14:49:48


--------------------
Go to the top of the page
+Quote Post

12 Stron V   1 2 3 > » 
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 15.08.2018 - 13:56