Diskuze: Stránkování článků po znacích - problém s obrázky
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 9 zpráv z 9.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
co nahradit tag obrázku nějakým znakem třeba #, pak upravit text na 1000 znaků a pak tento znak zpět nahradit obrázkem?
Ahoj,
nevím, zda to bude fungovat správně, ale zkusil bych funkci strip_tags(),
která odstraní z řetězce tagy HTML a PHP. Pak bys měl jen čistý text,
který budeš ořezávat. Musíš ho samozřejmě pak zvlášť naformátovat,
protože ti veškeré <p></p>, <div></div>, <a>,
atd... odstraní.
O něco jsem se pokusil. Je to celkem dlouhé a možná i dost těžkopádné, ale na druhou stranu vždy dostaneš původní text (rozdělený do položek pole) bez jakékoliv deformace:
/**
* Rozdělí text do pole po částech o $countChars znacích
* @param string $text zdrojový text
* @param int $countChars max. počet znaků v jedné části
* @param array $allowed seznam tagů, které se nebudou započítávat do délky textu
* @return array rozdělený text
*/
function partition($text, $countChars, $allowed = ['p', 'img'])
{
$tag = false; // Příznak tagu (rozlišuje, zda se aktuální znak bude počítat docelkové délky textu)
$temp = ''; // Dočasný text, který má max. délku $countChars a po naplnění se uloží do výsledného pole a opět vyprázdní
$char = 0; // Počet znaků mimo tagy v $temp
$result = []; // Konečný výsledek
// Pomocí cyklu se projedou všechny znaky
for ($i = 0, $l = mb_strlen($text); $i < $l; $i++) {
// Pokud zde začíná počáteční nebo ukončovací tag, nastaví se příznak $tag = true
for ($j = 0, $k = count($allowed); $j < $k; $j++) {
if (mb_substr($text, $i, mb_strlen($allowed[$j]) + 1) === '<' . $allowed[$j] || mb_substr($text, $i, mb_strlen($allowed[$j]) + 2) === '</' . $allowed[$j]) {
$tag = true;
break;
}
}
$temp .= mb_substr($text, $i, 1);
// Pouze pokud aktuální znak není součástí tagu, započítá se do počtu znaků
if (!$tag) {
$char++;
}
// Při dosažení počtu max. znaků se aktuální část uloží jako nová položka do výsledku a začne se počítat další část o $countChars znacích
if ($char === $countChars) {
$char = 0;
$result[] = $temp;
$temp = '';
}
// Pokud zde končí tag, nastaví se příznak $tag = false
if (mb_substr($text, $i, 1) === '>') {
$tag = false;
}
}
// Zbytek se uloží jako další položka do výsledku
if(preg_match('/^<[^>]*>$/', $temp)) {
$result[count($result) - 1] .= $temp;
} else {
$result[] = $temp;
}
return $result;
}
U každého použití pak bude stačit napsat:
$array = partition($text, 10);
což rozdělí text na části o maximální délce 10 znaků (tagy se nepočítají).
$text = '<p>nějaký text....</p><p><img src="https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx" alt="" /></p><p>nějaký text....</p>';
var_dump(partition($text, 10));
// Výsledek
array (size=3)
0 => string '<p>nějaký tex' (length=15)
1 => string 't....</p><p><img src="https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx" alt="" /></p><p>nějak' (length=139)
2 => string 'ý text....</p>' (length=15)
K jednotlivým částem textu o 10 znacích máš pak přístup jednoduše přes index toho pole, kam si výsledek uložil ($array[0], $array[1], ...).
Tak jsem si vzpomněl, že jsem něco podobného v minulosti dělal a skutečně to takto funguje:
<?php
$textSTagy = '<p>TADY JE TEXT S TAGY</p>' ;
$textBezTagu = strip_tags($textSTagy) ;
$text = substr($textBezTagu,0,1000) ;
$delkaTextu = strlen($textBezTagu) ;
echo $text ; if($delkaTextu >= 1000) {echo '...' ;}
?>
strip_tags() mi odstraní všechny HTML a PHP znaky, substr() zkrátí text na požadovanou délku a ještě přes strlen() si spočítám délku textu a pokud je delší, tak přes if podmínku případně doplním tři tečky na konec.
Samozřejmě si z toho můžeš udělat i funkci.
P.S. také ořezávám text z TinyMCE.
Když jsem nad tím tak přemýšlel, tak se mi nápad, abych nahradil celý tag <img> za nějaký znak, docela zamlouvá. Jak by ale mohl vypadat příkaz pro nahrazení za nějaký jednoduchý znak? Protože samozřejmě je
<img src='xxx' alt='xxx'>
a poté třeba tag
<img src='yyy' alt='yyy'>
vždycky je vnitřek tagu jiný a já bych potřeboval udělat nějakou funkci, která by našla začátek tagu - tudíž <img src= - to je na začátku vždy stejně a poté i konec - tudíž pouze >.
Tudíž teď pracuji na funkci, která nestraně dokáže nahradit např. toto
<img src="https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx" alt="" />
nebo toto
<img src="jakákoliAdresa...." alt="" />
například na znak #..
Je to dobrý cesta, popřípadě napadá Vás lepší? Budu vděčný za rady,
jak lze toto zkonstruovat.
Díky moc...
To né já, to Kosmas
<?php
$r = "Lorem ipsum dolor sit amet <img src='http://www.ditom.cz/img/zateplene-montovana-hala-predni-cast.jpg' alt='img' title='hala' /> consectetuer turpis velit nibh interdum dapibus. Feugiat ut convallis Morbi.";
// vytažení obrázku z textu
preg_match('/(<img.*\/>)/', $r, $r_img);
echo $r_img[1];
// výpis s náhradou za obrázek, moznost delat s textem psi kusy
$r_nahrada = preg_replace('/(<img.*\/>)/',"#",$r );
echo $r_nahrada;
echo "<br />";
// a zpet obrazek na misto kam to patři
$r_obnova = preg_replace('/(#)/',$r_img[1],$r_nahrada );
echo $r_obnova;
?>
úplně jsem zapomenul ošetřit "hladovost" regulárního příkazu, změň si je takto:
preg_match('/(<img.*?\/>)/', $r, $r_img);
$r_nahrada = preg_replace('/(<img.*?\/>)/',"#",$r );
Je to přidání toho otazníku, nebude pak tolik hladový, jinak by ti
"sežral" všechno mezi začátkem prvního a koncem posledního obrázku. Kdyby
tam bylo v textu více obrázků, pak budou uloženy v poli. Ty pak musíš
projet cyklem text a podle pořadí náhradního znaku nahradit obrázkem ve
stejném pořadí. Tedy první znak # prvním obrázkem a td.
Ať to slouží
Zobrazeno 9 zpráv z 9.