Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: PHP: BBCodes-ongelma

Sivun loppuun

joah [25.04.2013 15:32:14]

#

Hei,
olen tehnyt tätä skriptiä jo pari päivää ja ei vieläkään toimi. Mikä olisi ongelmana?

Skripti:

<?php
$yhteys=mysqli_connect("HOSTINI","KÄYTTIKSENI","SALASANANI","DB");
$valitse = mysqli_query($yhteys,"SELECT * FROM sisalto");
$paateksti = $row['paateksti'];
$tarkista = $paateksti;
$hymiotekstit = array("<3", "[peace]", "[umbr]");
$hymiot = array("&#10084;", "&#9774;", "&#9730;");
$hymiopaateksti = str_ireplace($hymiotekstit,$hymiot,$tarkista);
echo $hymiopaateksti;
?>

DB:

SQL result

Host: HOSTINI
Database: DBni
Generation Time: Apr 25, 2013 at 08:29 AM
Generated by: phpMyAdmin 2.11.4 / MySQL 5.1.57
SQL query: SELECT * FROM `sisalto` LIMIT 0, 30 ;
Rows: 1

otsikko	paateksti
Otsikkoni	Toimiikos tää? <3 [peace] [umbr]

Olisin kiitollinen, jos vastaus tulisi, tai edes pikku vinkkiä. Mietin itse, onko tuo connecti oikeanlainen? Kiitos jo etukäteen.

peran [25.04.2013 16:38:24]

#

Missä kohtaa $row-muuttujalle tulee arvo?

Näyttäisi olevan asettamatta.

Käyttäisin tietokantakyselynä mieluummin pdo:ta kuin mysql_querya, niin hyppy toiselle tietokannalle sujuu paremmin.

https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=mysqlphp02

joah [25.04.2013 16:51:51]

#

Voi eih... Luultavasti osasin määrittää $row-muuttujan, mutta erroria pukkaa.

eli, mikä tässä on sitten väärin...?

<?php
$yhteys = mysqli_connect("hostini","käyttis","salasana","db");
$valitse = mysqli_query($yhteys,"SELECT * FROM sisalto");
$row = mysql_fetch_array( $valitse );
$paateksti = $row['paateksti'];
$tarkista = $paateksti;
$hymiotekstit = array("<3", "[peace]", "[umbr]");
$hymiot = array("&#10084;", "&#9774;", "&#9730;");
$hymiopaateksti = str_ireplace($hymiotekstit,$hymiot,$tarkista);
echo $hymiopaateksti;
echo $paateksti;
?>

EDIT: Kiva, tuli taas sit unohdettua noi salikset ja muut kivat tohon. 8D

Grez [25.04.2013 17:00:40]

#

joah kirjoitti:

Voi eih... Luultavasti osasin määrittää $row-muuttujan, mutta erroria pukkaa.

Joka on? Yleensä se virheilmoitus kertoo jo aika paljon virheestä.

joah [25.04.2013 17:05:57]

#

Grez kirjoitti:

joah kirjoitti:

Voi eih... Luultavasti osasin määrittää $row-muuttujan, mutta erroria pukkaa.

Joka on? Yleensä se virheilmoitus kertoo jo aika paljon virheestä.

Itsekkin periaatteessa selvitän virheet virheilmoituksella, mutta nyt tuli sitten tenkkapoo. Alla errori.

Error:

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /minun/pathini/public_html/sivuilleni/index.php on line 4

Metabolix [25.04.2013 17:20:55]

#

Et voi sekoittaa mysql-funktioita ja mysqli-funktioita. Kompromissina voisit heittää molemmat mäkeen ja käyttää PDO:ta, josta on opassivulla opaskin.

joah [25.04.2013 17:27:17]

#

Metabolix kirjoitti:

Et voi sekoittaa mysql-funktioita ja mysqli-funktioita. Kompromissina voisit heittää molemmat mäkeen ja käyttää PDO:ta, josta on opassivulla opaskin.

Kiitos, tuli tiedot ongittua parilta eri sivulta, nythän tämä pelittää kuin unelma 8D

Edit: vaihdos PDOhon, kiitos ehdotuksesta vaihtaa tuo PDO:hon... Itse vielä ihmettelen, onko tuo varmepi vai mikä, kun kerran mysqli on lyhyempi pätkä... Mutta suoritetaan tämä nyt PDO:lla. Kiitos vielä kerran!

Lisäys:

Nyt tuli aiheeseen liittyvä linkkitenkkapoo. Alla nyt pyörivä koodi:

<style type="text/css">
#koodi {
border: 1px solid black;
background-color: lightgrey;
padding-left: 20px;
padding-right: 20px;
}
</style>
<?php
try {
    $yhteys = new PDO("mysql:host=hostini;dbname=db", "käyttis", "salasana");
} catch (PDOException $e) {
    die("VIRHE: " . $e->getMessage());
}
$yhteys->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$yhteys->exec("SET NAMES latin1");

$kysely = $yhteys->prepare("SELECT * FROM sisalto");
$kysely->execute();
$rivi = $kysely->fetch();
$paateksti = $rivi['paateksti'];
$tarkista = $paateksti;
$korvattavat = array("<3", "hymy", "[umbr]", "[b]", "[/b]", "[i]", "[/i]", "[pallot]", "[/pallot]", "[sana]", "[/sana]", "[numerot]", "[/numerot]", "[alotetaankoodipoistetaanfoorumilta]", "[lopetetaankoodiotetaanpoisfoorumilta]", "[enter]", "[vali]", "[u]", "[/u]", "/\[link=(.*?)\](.*?)\[\/link\]/");
$korvaa = array("<img src='hymiot/Heart.png' alt='&#10084;'>", "<img src='hymiot/Smile.png' alt='&#10084;'>", "&#9730;", "<b>", "</b>", "<i>", "</i>", "<ul>", "</ul>", "<li>", "</li>", "<ol>", "</ol>", "<div id='koodi'><xmp>", "</xmp></div>", "<br />", "&nbsp;", "<u>", "</u>", "<a href="$1">$2</a>");
$okpaateksti = str_ireplace($korvattavat,$korvaa,$tarkista);

?>
<?php echo $okpaateksti; ?>

Ymmärrän, että ehkä kohdassa

... "/\[link=(.*?)\](.*?)\[\/link\]/" ...

on jotain häikkää, koska tuo (.*?) sulkee tuon aloitetun arrayn. Jos tämä on syyllinen, miten voisi tuon estää? Koodiin muutenkin liittyviä kommelluksia voi kirjoitella (älkää ottako tätä ns. "työnä" :D). Kiitos jo taas etukäteen.

The Alchemist [25.04.2013 20:57:45]

#

Tässä kohtaa on varmaan hyvä tunkea pätemään. Pyöräytin omiin tarpeisiini joskus talvella "ohjelmoitavan" bbcode-parserin, johon voi syöttää uusia tageja/sääntöjä implementaatioon koskematta.

Perusparserin voi yrittää tehdä pelkällä str_replacellakin mutta se jättää aika montaa reikää parseriin. Koska viallisella html:llä voi parhaassa tapauksessa rikkoa koko sivun leiskan, niin ei kannata ihan mitä tahansa soossia hyväksyä.

*** dtd.php

<?php
/**
 * Parserin konfiguraatio / parsimissäännöt
 */
return array(
    'b' => array(
        'tag' => 'b',
        'attributes' => array(
            'class' => 'bbcode-b',
        ),
    ),

    'i' => array(
        'tag' => 'span',
        'attributes' => array(
            'class' => 'bbcode-i',
        ),
    ),

    'u' => array(
        'tag' => 'span',
        'attributes' => array(
            'class' => 'bbcode-u',
        ),
    ),

    'url' => array(
        'tag' => 'a',
        'attributes' => array(
            'class' => 'bbcode-url',
            'href' => '{value}',
        ),
    ),

    'color' => array(
        'tag' => 'span',
        'nested' => true,
        'attributes' => array(
            'class' => 'bbcode-color',
            'style' => 'color: {value}',
        ),
    ),

    'img' => array(
        'tag' => 'img',
        'attributes' => array(
            'class' => 'bbcode-img',
            'src' => '{content}',
        ),

        'options' => array(
            'empty' => true,
        ),
    ),

    'size' => array(
        'tag' => 'span',
        'attributes' => array(
            'class' => 'bbcode-size size-{value}',
        ),
    ),

    'code' => array(
        'tag' => 'code',
        'attributes' => array(
            'class' => 'bbcode-code',
        ),
        'options' => array(
            'parse_contents' => false,
            'callback' => 'bbcode_syntax_coloring',
        ),
    ),

    'quote' => array(
        'tag' => 'blockquote',
        'nested' => true,
        'attributes' => array(
            'class' => 'bbcode-quote',
        ),
        'options' => array(
            'callback' => 'bbcode_format_quotes',
        ),
    ),
);
*** BBCode/Parser.php

<?php
namespace BBCode;

/**
 * Bbcode-koodin parseri / renderöijä
 */
class Parser {
    private $dtd;
    private $source;
    private $encode_html;

    /**
     * Constructor
     *
     * @param $dtd associative array of compiler instructions
     * @param $encode_html whether or not to make the string HTML-safe
     **/
    public function __construct(array $dtd, $encode_html = true) {
        $this->encode_html = (bool)$encode_html;

        $defaults = array(
            // Corresponding HTML tag for the BBCode element
            'tag' => '',

            // HTML attributes that will be written into the element
            'attributes' => array(),

            // Special configuration for the compiler instruction
            'options' => array(

                // Run parser on the BBCode tag's contents or not
                'parse_contents' => true,

                // Is the resulting HTML element empty or not (use short end tag)
                'empty' => false,

                // Callable method that can perform additional transformations
                // on the element's contents
                // The function will get three arguments: content, value, tag
                // Example: [tag=value]content here[/tag]
                'callback' => null,
            ),
        );

        foreach ($dtd as $key => $data) {
            $this->dtd[$key] = $this->merge($data, $defaults);
        }
    }

    /**
     * Compile given string with BBCode to HTML.
     *
     * @param $string string to compile
     * @return string
     **/
    public function compile($string) {
        if ($this->encode_html) {
            $string = htmlspecialchars($string);
        }

        $compiled = $this->process($string);

        return $compiled;
    }

    private function process($string) {
        $string = trim($string);
        $tags = array_keys($this->dtd);
        $tag_string = implode('|', $tags);
        $regex = "#(\[({$tag_string})=?(.*?)?\])|(\[/({$tag_string})\])#s";

        preg_match_all($regex, $string, $matches, PREG_OFFSET_CAPTURE);

        $matches = $matches[0];
        $stack = array();
        $cache = array();
        $valid = array();
        $fix = 0;
        $ignore = 0;
        $replace = array();

        // Validate matches. Will filter out any tags who lack their opening/closing
        // pair or are closed in the wrong order.
        foreach ($matches as $i => $match) {
            list($tag, $offset) = $match;
            $name = $this->tagName($tag);

            if ($this->isOpenTag($tag)) {
                // Push opening tags into cache.

                $stack[] = $name;
                $cache[] = $match;
            }

            if ($this->isCloseTag($tag)) {
                // If a closing tag has a pair in the tag cache, accept the pair.
                // Any tags in the cache that come after the matching element
                // are considered to be invalid and are removed from the cache.

                $x = $this->findLastMatch($name, $stack);

                if ($x !== false) {
                    $valid[] = array($cache[$x], $match);
                    $stack = array_slice($stack, 0, $x);
                    $cache = array_slice($cache, 0, $x);
                }
            }
        }

        // Sort matches in the order of appearance of their opening tags.
        usort($valid, function($a, $b) { return $a[0][1] - $b[0][1]; });

        // Remove matches that are nested inside a "do not parse contents" element.
        foreach ($valid as $i => $pair) {
            $defs = $this->dtd[$this->tagName($pair[0][0])];

            if ($pair[1][1] < $ignore) {
                unset($valid[$i]);
            } elseif ($defs['options']['parse_contents'] == false) {
                $ignore = $pair[1][1];
            }
        }

        // Compile matches
        foreach ($valid as $pair) {
            list($a, $b) = $pair;
            $start = $a[1] + $fix;
            $length = $b[1] - $a[1];

            $raw = substr($string, $start, $length + strlen($b[0]));
            $content = substr($raw, strlen($a[0]), -1 * strlen($b[0]));
            $tag = $this->tagName($a[0]);
            $value = $this->tagValue($a[0]);
            $compiled = $this->compileTag(array($raw, $tag, $value, $content));

            $replace[] = array($raw, $compiled);
        }

        // Finally replace matches with compiled code.
        foreach ($replace as $pair) {
            $start = strpos($string, $pair[0]);
            $string = substr_replace($string, $pair[1], $start, strlen($pair[0]));
        }

        return $string;
    }

    private function tagName($tag) {
        preg_match('#^\[/?(\w+)#', $tag, $m);
        return $m[1];
    }

    private function tagValue($tag) {
        preg_match('#^\[\w+=(.*?)\]$#', $tag, $m);
        return isset($m[1]) ? $m[1] : null;
    }

    private function isOpenTag($tag) {
        return $tag[1] != '/';
    }

    private function isCloseTag($tag) {
        return !$this->isOpenTag($tag);
    }

    private function findLastMatch($needle, $haystack) {
        for ($i = count($haystack) - 1; $i >= 0; $i--) {
            if ($haystack[$i] == $needle) {
                return $i;
            }
        }

        return false;
    }

    private function compileTag($match) {
        list($raw, $tag, $value, $content) = $match;

        $dtd = $this->dtd[$tag];

        if ($dtd['options']['callback']) {
            $content = $dtd['options']['callback']($content, $value, $tag);
        }

        $markup = '<' . $dtd['tag'];

        foreach ($dtd['attributes'] as $name => $value) {
            if (is_array($value)) {
                $value = implode(' ', $value);
            }

            $value = $this->compileValue($value, $match);
            $markup .= " {$name}=\"{$value}\"";
        }

        if ($dtd['options']['empty']) {
            $markup .= '/>';
        } else {
            $markup .= '>';
            $markup .= $content;
            $markup .= "</{$dtd['tag']}>";
        }

        return $markup;
    }

    private function compileValue($string, $match) {
        list($raw, $tag, $value, $content) = $match;

        $string = str_replace('{value}', $value, $string);
        $string = str_replace('{tag}', $tag, $string);
        $string = str_replace('{content}', $content, $string);

        return $string;
    }

    private function merge($target, $source) {
        foreach ($source as $key => $value) {
            if (!isset($target[$key]) || is_array($value) && !is_array($target[$key])) {
                $target[$key] = $value;
            }

            if (is_array($value)) {
                $target[$key] = $this->merge($target[$key], $value);
            }
        }

        return $target;
    }
}
*** demo.php

<?php
require 'vendor/BBCode/Parser.php';

$dtd = require 'dtd.php';
$bbcode = new BBCode\Parser($dtd);
$string = 'Lorem [b]ipsum[/b] dolor [color=green]sit [u]amet[/u][/color]. [url=http://www.google.com]Googel[/url]';

print $bbcode->compile($string);

joah [25.04.2013 21:44:21]

#

Kiitos koodista, The Alchemist! :)

Testaan koodia aamusella koneella, vaikuttaa simppeliltä ;) Tossa alussa ei tullut pälkäsen häivää tajuttua mitään, mutta toihan on simppelimpi kuin simppeli 8D Normaalit HTML-tagit siihen niin hola¡ kiitos taas, toivottavasti en vaivannut.

Edit: Kirjoitusvirheet; iltasella puhelimella.

timoh [26.04.2013 00:02:58]

#

The Alchemistin koodiin viitaten, niin ajakaa matsku aina HTML Purifierin läpi vielä juuri ennen kuin tulostatte parsereidenne tuotokset ruudulle. XSS yms. validointiongelmien takia.

joah [26.04.2013 07:45:03]

#

Eikäh, toi parseri ei toimi mulla, tai sitten tein jotain pahasti väärin. Eli: kopsasin noi kaikki mun palvelimellle, ja tulee tällänen errori:

Parse error: syntax error, unexpected T_STRING in /minun/pathini/public_html/tänne/BBCode/Parser.php on line 2

Sitten jos poistan kokonaan rivin kaksi tulee tälläinen:

Parse error: syntax error, unexpected T_FUNCTION in /minun/pathini/public_html/tänne/BBCode/Parser.php on line 101

Ja jos rivi 101 myöksin poistetaan...

Fatal error: Class 'BBCode' not found in /minun/pathini/public_html/tänne/index.php on line 26

En tuota riviä 26 ruvennut poistamaan, luulen että tuolta jäi BBCodes-sana väliin, jolloin koko juttu meni sekaisin. Itse luin jostain, että minun palvelimella on liian vanha PHP-versio, jolloin ei tue jotain koodinpätkää tosta. Mitä teen?

qeijo [26.04.2013 08:04:39]

#

Mikä php versio sinulla on käytössä?

Ilmeisesti tökkää heti nimiavaruuden määrittelyyn, senhän voit toki poistaa. Toinen juttu on anonyymit funktiot, nehän voit korvata omalla vastaavalla tavanomaisella funktiolla.

joah [26.04.2013 08:09:38]

#

qeijo kirjoitti:

Mikä php versio sinulla on käytössä?

Näyttäisi olevan 5.2.

qeijo [26.04.2013 08:10:25]

#

joah kirjoitti:

qeijo kirjoitti:

Mikä php versio sinulla on käytössä?

Näyttäisi olevan 5.2.

Ei riitä, jos et voi päivittää versiota, tee aluksi mainistemani toimeenpiteet ja kokeile uudestaan.


Eli poista nimiavaruus ja korvaa:

usort($valid, function($a, $b) { return $a[0][1] - $b[0][1]; });

Esimerkiksi:

function sortByOpeningTags($a, $b) {

    return $a[0][1] - $b[0][1];
}

usort($valid, 'sortByOpeningTags');

The Alchemist [26.04.2013 09:34:10]

#

Kannattaa ehkä tarkistaa aluksi, että voiko sinun palvelimellesi saada php 5.3:n käyttöön. Monissa web-hotelleissa on asennettuna useampi versio php-tulkeista, jolloin voit ehkä valita niiden välillä ihan jotain asetusta muuttamalla. Php 5.3(.3) on usein minimivaatimus kirjastoille, joten siihen siirtyminen olisi parempi vaihtoehto kuin koodin backporttaaminen.

Mikäli php:n version vaihtaminen ei onnistu, niin sitten tuossa koodissa on kourallinen kohtia, jotka vaativat purkkaamista. Tässä jo aiemmin käsiteltyjen ongelmakohtien lisäksi ainakin Parser.php:n rivi 184 taitaa olla sellainen, ettei 5.2 tue vielä kyseistä syntaksia.

// Parser.php:184
$content = $dtd['options']['callback']($content, $value, $tag);

// Php 5.2 -yhteensopiva versio
$content = call_user_func($dtd['options']['callback'], $content, $value, $tag);

Callbackien käyttöä en tosin tuossa demossani esitellytkään...

joah [26.04.2013 14:24:57]

#

qeijo kirjoitti:

Eli poista nimiavaruus ja korvaa:

Kiitos, tein tämän.

The Alchemist kirjoitti:

Mikäli php:n version vaihtaminen ei onnistu, niin sitten tuossa koodissa on kourallinen kohtia, jotka vaativat purkkaamista. Tässä jo aiemmin käsiteltyjen ongelmakohtien lisäksi ainakin Parser.php:n rivi 184 taitaa olla sellainen, ettei 5.2 tue vielä kyseistä syntaksia.

Kiitos, tein myöskin tämän.

Mutta ongelmathan ei tuohon lopu, error:

Parse error: syntax error, unexpected ';', expecting T_FUNCTION in /minun/pathini/public_html/tänne/BBCode/Parser.php on line 234

Ja helpottaaksesi, ettei tarvitse etsiä, rivillä lukee vain PHP:n loppumismerkit, eli ?>.

The Alchemist kirjoitti:

Kannattaa ehkä tarkistaa aluksi, että voiko sinun palvelimellesi saada php 5.3:n käyttöön. Monissa web-hotelleissa on asennettuna useampi versio php-tulkeista, jolloin voit ehkä valita niiden välillä ihan jotain asetusta muuttamalla. Php 5.3(.3) on usein minimivaatimus kirjastoille, joten siihen siirtyminen olisi parempi vaihtoehto kuin koodin backporttaaminen.

Juu, ei saa vaihettua. Minun web-hotellissani on vain tuo 5.2, eikä sitä pysty muuttamaan, ellei maksa korkeampiarvoista (esim. Bronze, Silver, Gold niin minulla olisi vaikkapa bronze -> vain silverillä olisi mahdollisuus 5.3) jäsenyyttä.

dartvaneri [26.04.2013 15:09:31]

#

Heitäppä koodisi, jossa näkyy tuo rivi 234 ja sen ympäriltä jonkin verran rivejä. Nimittäin tuo error kertoo hyvinkin selkesti syntaksi virheestä, eli sulta puuttuu jostain jokin tärkeä merkki.

joah [26.04.2013 15:16:25]

#

dartvaneri kirjoitti:

Heitäppä koodisi, jossa näkyy tuo rivi 234 ja sen ympäriltä jonkin verran rivejä. Nimittäin tuo error kertoo hyvinkin selkesti syntaksi virheestä, eli sulta puuttuu jostain jokin tärkeä merkki.

Selviö, laitan pelkästään ton parserin, tarvittaessa voin muutkin.

<?php

/**
 * Bbcode-koodin parseri / renderöijä
 */
class Parser {
    private $dtd;
    private $source;
    private $encode_html;

    /**
     * Constructor
     *
     * @param $dtd associative array of compiler instructions
     * @param $encode_html whether or not to make the string HTML-safe
     **/
    public function __construct(array $dtd, $encode_html = true) {
        $this->encode_html = (bool)$encode_html;

        $defaults = array(
            // Corresponding HTML tag for the BBCode element
            'tag' => '',

            // HTML attributes that will be written into the element
            'attributes' => array(),

            // Special configuration for the compiler instruction
            'options' => array(

                // Run parser on the BBCode tag's contents or not
                'parse_contents' => true,

                // Is the resulting HTML element empty or not (use short end tag)
                'empty' => false,

                // Callable method that can perform additional transformations
                // on the element's contents
                // The function will get three arguments: content, value, tag
                // Example: [tag=value]content here[/tag]
                'callback' => null,
            ),
        );

        foreach ($dtd as $key => $data) {
            $this->dtd[$key] = $this->merge($data, $defaults);
        }
    }

    /**
     * Compile given string with BBCode to HTML.
     *
     * @param $string string to compile
     * @return string
     **/
    public function compile($string) {
        if ($this->encode_html) {
            $string = htmlspecialchars($string);
        }

        $compiled = $this->process($string);

        return $compiled;
    }

    private function process($string) {
        $string = trim($string);
        $tags = array_keys($this->dtd);
        $tag_string = implode('|', $tags);
        $regex = "#(\[({$tag_string})=?(.*?)?\])|(\[/({$tag_string})\])#s";

        preg_match_all($regex, $string, $matches, PREG_OFFSET_CAPTURE);

        $matches = $matches[0];
        $stack = array();
        $cache = array();
        $valid = array();
        $fix = 0;
        $ignore = 0;
        $replace = array();

        // Validate matches. Will filter out any tags who lack their opening/closing
        // pair or are closed in the wrong order.
        foreach ($matches as $i => $match) {
            list($tag, $offset) = $match;
            $name = $this->tagName($tag);

            if ($this->isOpenTag($tag)) {
                // Push opening tags into cache.

                $stack[] = $name;
                $cache[] = $match;
            }

            if ($this->isCloseTag($tag)) {
                // If a closing tag has a pair in the tag cache, accept the pair.
                // Any tags in the cache that come after the matching element
                // are considered to be invalid and are removed from the cache.

                $x = $this->findLastMatch($name, $stack);

                if ($x !== false) {
                    $valid[] = array($cache[$x], $match);
                    $stack = array_slice($stack, 0, $x);
                    $cache = array_slice($cache, 0, $x);
                }
            }
        }

        // Sort matches in the order of appearance of their opening tags.
function sortByOpeningTags($a, $b) {

    return $a[0][1] - $b[0][1];
}

usort($valid, 'sortByOpeningTags');

        // Remove matches that are nested inside a "do not parse contents" element.
        foreach ($valid as $i => $pair) {
            $defs = $this->dtd[$this->tagName($pair[0][0])];

            if ($pair[1][1] < $ignore) {
                unset($valid[$i]);
            } elseif ($defs['options']['parse_contents'] == false) {
                $ignore = $pair[1][1];
            }
        }

        // Compile matches
        foreach ($valid as $pair) {
            list($a, $b) = $pair;
            $start = $a[1] + $fix;
            $length = $b[1] - $a[1];

            $raw = substr($string, $start, $length + strlen($b[0]));
            $content = substr($raw, strlen($a[0]), -1 * strlen($b[0]));
            $tag = $this->tagName($a[0]);
            $value = $this->tagValue($a[0]);
            $compiled = $this->compileTag(array($raw, $tag, $value, $content));

            $replace[] = array($raw, $compiled);
        }

        // Finally replace matches with compiled code.
        foreach ($replace as $pair) {
            $start = strpos($string, $pair[0]);
            $string = substr_replace($string, $pair[1], $start, strlen($pair[0]));
        }

        return $string;
    }

    private function tagName($tag) {
        preg_match('#^\[/?(\w+)#', $tag, $m);
        return $m[1];
    }

    private function tagValue($tag) {
        preg_match('#^\[\w+=(.*?)\]$#', $tag, $m);
        return isset($m[1]) ? $m[1] : null;
    }

    private function isOpenTag($tag) {
        return $tag[1] != '/';
    }

    private function isCloseTag($tag) {
        return !$this->isOpenTag($tag);
    }

    private function findLastMatch($needle, $haystack) {
        for ($i = count($haystack) - 1; $i >= 0; $i--) {
            if ($haystack[$i] == $needle) {
                return $i;
            }
        }

        return false;
    }

    private function compileTag($match) {
        list($raw, $tag, $value, $content) = $match;

        $dtd = $this->dtd[$tag];

        if ($dtd['options']['callback']) {
$content = call_user_func($dtd['options']['callback'], $content, $value, $tag);
        }

        $markup = '<' . $dtd['tag'];

        foreach ($dtd['attributes'] as $name => $value) {
            if (is_array($value)) {
                $value = implode(' ', $value);
            }

            $value = $this->compileValue($value, $match);
            $markup .= " {$name}=\"{$value}\"";
        }

        if ($dtd['options']['empty']) {
            $markup .= '/>';
        } else {
            $markup .= '>';
            $markup .= $content;
            $markup .= "</{$dtd['tag']}>";
        }

        return $markup;
    }

    private function compileValue($string, $match) {
        list($raw, $tag, $value, $content) = $match;

        $string = str_replace('{value}', $value, $string);
        $string = str_replace('{tag}', $tag, $string);
        $string = str_replace('{content}', $content, $string);

        return $string;
    }

    private function merge($target, $source) {
        foreach ($source as $key => $value) {
            if (!isset($target[$key]) || is_array($value) && !is_array($target[$key])) {
                $target[$key] = $value;
            }

            if (is_array($value)) {
                $target[$key] = $this->merge($target[$key], $value);
            }
        }

        return $target;
    }
?>

qeijo [26.04.2013 15:20:08]

#

Luokka kiinni!

        return $target;
    }
}
?>

joah [26.04.2013 15:46:02]

#

qeijo kirjoitti:

Luokka kiinni!

        return $target;
    }
}
?>

Noniin, hikiset mietiskelytunnit on nyt onneksi ohi... HUH! Eli koodi toimii kuin unelma. Kiitos auttaneille!


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta