Pro vaší firmu: 3 krát stejné super tel.číslo 506 506 (vhodné pro vaše zamestnance, kolegy, rodinu atp.) NEVÁHEJTE, nebude....
Zobrazují se odpovědi 1 až 6 z 6

Ořez textu s <img>

  1. 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():

    Kód:
    $this->stripAllButImgs() 
            ->captureImgs() 
            ->stripAll() 
            ->shortenPlainText() 
            ->returnImgsInPlace();
    Ale pořád mám pocit, že to jde udělat elegantněji.
    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));

  2. Co se právě děje na Webtrhu?
  3. ja bych ciste pro jednoduchost uziti udelal asi

    public static function instance(){
    .... (tvorba instance, pokud existuje, pouzit jiz vytvorenou a vratit)
    }

    volani by pak mohlo probihat jako

    Img_Text_Shortener::instance($string)->shorten($string,150);

    jde ale spis o preference, prakticky to zkrati zapis pouze o jediny radek, takze je otazka zda se to vyplati ci ne :))

  4. Když už statickou funkci, tak bych udělal rovnou shorten()
    Kód:
    Img_Text_Shortener::shorten($string, $limit);
    Statické funkce možná mají opodstatnění u nějakých malých opakujících se funkcí, ale osobně se jim snažím vyhýbat, protože pak svádí k používání globálních dat.
    Zajímavě o tom píše Miško Hevery:
    Static methods are procedural in nature and they have no place in OO world.

  5. pravda, instance jsem zvykly pouzivat u vetsich trid, tady by to asi melo vetsi smysl primo pro fci jako takovou

  6. Poulik Hodnocení: 1 (100%) Poulik je na dobré cestě
    5
    Zdravím,

    Napadlo mě řešit tento problém přes sprintf, pak jsem to dodelal uplne jinak:

    Kód:
    function img_text_shortener($text, $length) {
    
       $images = array();
       $final_result = array();
       $final_images_count = 0;
    
       preg_match_all('/(<img[^>]*>)/iu', $text, $images);
       $text = strip_tags(preg_replace('/(<img[^>]*>)/iu', "%s", $text));
       $text = substr($text, 0, $length);
    
       preg_match_all("/%s/", $text, $final_result);
    
       $final_images_count = count($final_result[0]);
    
       for ($i = 0; $i < count($images[1]); $i++){
          if($i < $final_images_count)
             $text = preg_replace("/%s/", $images[0][$i], $text, 1);
          else
             $text .= $images[0][$i];
       }
    
       return $text;
    }
    
    $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>';
    
    echo img_text_shortener($string, 100);
    Urcite by to slo jeste optimalizovat, je to jen prvni napad, jak bych to resil...oriznute obrazky jsou nalepene nakonci. Ani by nemusel byt pouzity nakonci preg_replace, ale jen replace...

    Jinak k vašemu kódu myslím, že je logický, pro mě dobře čitelný a přehledný. Je to asi lepší řešení, než posílám já. To moje nebere obrázek za jeden char, ale za 2 - %s...kvůli tomu potom není výsledná délka zcela přesná, říkám první nápad, třeba pomůže k jinému;)
    Naposledy upravil Poulik : 05.06.2011 v 21:39

  7. vedouci Hodnocení: 3 (100%) vedouci bude brzy slavný/á
    6
    Tady je asi nejvetsim omezenim jazyk - v okamziku, kdy nemas sanci rozsirovat vestavene knihovny - jako retezec, apod., tak ztracis OO - musis pouzivat fce, staticke metody, adaptery a ruzne jine "hacky" - nejcistejsi z nich je simulace mixinu pomoci __call.

    Tvuj puvodni priklad "trpi" hlavne z logickeho pohledu, ze ta trida reprezentuje operaci a ne "tridu veci", operace ma byt metoda, nejlepe prikaz, ktery nic nevraci, ale klidne muzes pouzivat i "fcionalni" styl, pak ale nezapomen upravit jmeno metody - shortenedTo(150)

    Predstav si, jak by se ta metoda krasne vyjimala bud na retezci a nebo lepe na DOMElementu. A pravdepodobne by to bylo i mnohem jednodussi na realizaci a z dlouhodobeho hlediska i lepsi pro "udrzbu"

Hostujeme u Server powered by TELE3