Několik dní zpět jsem v jednom vlákně nastřelil zkracovač textu, který nebere v potaz a zachovává obrázky.
Hlavní logika je v metodě shorten():
Ale pořád mám pocit, že to jde udělat elegantněji.Kód:$this->stripAllButImgs() ->captureImgs() ->stripAll() ->shortenPlainText() ->returnImgsInPlace();
Jak byste kód vylepšili? Je pochopitelný a čitelný?
Třída odhaluje jedinou metodu - právě shorten()
Používá fluid interface pro řetězení metod, ale neměl jsem k tomu žádný vážný důvod.
Proměnná $shortenedString by se mohla jmenovat $processedString, abych předjímal možné rozšíření funkčnosti. Z třídy by se mohl stát nějaký univerzálnější manipulátor s HTML, ne jen zkracovač textu s obrázky.
Třeba by mohl volitelně přehodit první nalezený obrázek úplně na začátek textu a přidat mu třídu. Pak by jméno $shortenedString nemělo smysl.
Kód:class Img_Text_Shortener { private $originalString; private $shortenedString; private $capturedImgs; private $limit; private $limitWithImgs; public function __construct($string) { $this->originalString = $string; } public function shorten($limit) { $this->limit = $limit; $this->limitWithImgs = $limit; $this->stripAllButImgs() ->captureImgs() ->stripAll() ->shortenPlainText() ->returnImgsInPlace(); return $this->shortenedString; } private function stripAllButImgs() { $this->shortenedString = strip_tags($this->originalString, '<img>'); return $this; } private function captureImgs() { preg_match_all('@(<img[^>]*>)@iU', $this->shortenedString, $captures, PREG_OFFSET_CAPTURE); $this->capturedImgs = $captures[1]; return $this; } private function stripAll() { $this->shortenedString = strip_tags($this->shortenedString); return $this; } private function shortenPlainText() { $this->shortenedString = mb_substr($this->shortenedString, 0, $this->limit, 'UTF-8'); return $this; } private function returnImgsInPlace() { foreach($this->capturedImgs AS $capture) { $imgPosition = $capture[1]; if($this->outOfBounds($imgPosition)) { break; } $imgString = $capture[0]; $imgLength = mb_strlen($imgString); $this->limitWithImgs += $imgLength; $this->shortenedString = $this->insertString($imgString, $this->shortenedString, $imgPosition); } return $this; } private function outOfBounds($position) { return $this->limitWithImgs < $position; } private function insertString($insertedString, $targetString, $position) { return mb_substr($targetString, 0, $position) . $insertedString . mb_substr($targetString, $position); } } $string = '<h1>HTML Ipsum Presents</h1> <p><strong>Pellentesque habitant morbi <img title="Img 1">tristique</strong> senectus et netus et malesuada fames <img title="Img 2">ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae <img title="Img 3">est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean <img title="Img 4">fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>'; $shortener = new Img_Text_Shortener($string); var_dump($string); var_dump($shortener->shorten(150)); var_dump($shortener->shorten(300));


