Exemplo n.º 1
0
 /**
  * Render the cropped text
  *
  * @param integer $maxCharacters Place where to truncate the string
  * @param string $append What to append, if truncation happened
  * @param boolean $respectBoundaries If TRUE and division is in the middle of a word, the remains of that word is removed.
  * @param boolean $respectHtml If TRUE the cropped string will respect HTML tags and entities. Technically that means, that cropHTML() is called rather than crop()
  * @return string cropped text
  * @author Andreas Pattynama <*****@*****.**>
  * @author Sebastian Kurfürst <*****@*****.**>
  * @author Bastian Waidelich <*****@*****.**>
  * @author Felix Oertel <*****@*****.**>
  */
 public function render($maxCharacters, $append = '...', $respectWordBoundaries = TRUE, $respectHtml = TRUE)
 {
     $stringToTruncate = $this->renderChildren();
     if (TYPO3_MODE === 'BE') {
         $this->simulateFrontendEnvironment();
     }
     if ($respectHtml) {
         $content = $this->contentObject->cropHTML($stringToTruncate, $maxCharacters . '|' . $append . '|' . $respectWordBoundaries);
     } else {
         $content = $this->contentObject->crop($stringToTruncate, $maxCharacters . '|' . $append . '|' . $respectWordBoundaries);
     }
     if (TYPO3_MODE === 'BE') {
         $this->resetFrontendEnvironment();
     }
     return $content;
 }
 /**
  * Render the cropped text
  *
  * @param integer $maxCharacters Place where to truncate the string
  * @param string $append What to append, if truncation happened
  * @param boolean $respectBoundaries If TRUE and division is in the middle of a word, the remains of that word is removed. This is currently ignored in backend mode!
  * @return string cropped text
  * @author Andreas Pattynama <*****@*****.**>
  * @author Sebastian Kurfürst <*****@*****.**>
  * @author Bastian Waidelich <*****@*****.**>
  * @author Felix Oertel <*****@*****.**>
  */
 public function render($maxCharacters, $append = '...', $respectWordBoundaries = TRUE)
 {
     $stringToTruncate = $this->renderChildren();
     if (TYPO3_MODE === 'BE') {
         if (strlen($stringToTruncate) > $maxCharacters) {
             $stringToTruncate = substr($stringToTruncate, 0, $maxCharacters - strlen($append)) . $append;
         }
         return $stringToTruncate;
     } else {
         if (strip_tags($stringToTruncate) != $stringToTruncate) {
             return $this->contentObject->cropHTML($stringToTruncate, $maxCharacters . '|' . $append . '|' . $respectWordBoundaries);
         } else {
             return $this->contentObject->crop($stringToTruncate, $maxCharacters . '|' . $append . '|' . $respectWordBoundaries);
         }
     }
 }
    /**
     * Checks if stdWrap.cropHTML works with a complex content with many tags. Currently cropHTML
     * counts multiple invisible characters not as one (as the browser will output the content).
     *
     * @test
     */
    public function cropHtmlWorksWithComplexContent()
    {
        $GLOBALS['TSFE']->renderCharset = 'iso-8859-1';
        $subject = '
<h1>Blog Example</h1>
<hr>
<div class="csc-header csc-header-n1">
	<h2 class="csc-firstHeader">Welcome to Blog #1</h2>
</div>
<p class="bodytext">
	A blog about TYPO3 extension development. In order to start blogging, read the <a href="#">Help section</a>. If you have any further questions, feel free to contact the administrator John Doe (<a href="mailto:john.doe@example.com">john.doe@example.com)</a>.
</p>
<div class="tx-blogexample-list-container">
	<p class="bodytext">
		Below are the most recent posts:
	</p>
	<ul>
		<li>
			<h3>
				<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog]=&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=003b0131ed">The Post #1</a>
			</h3>
			<p class="bodytext">
				Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut...
			</p>
			<p class="metadata">
				Published on 26.08.2009 by Jochen Rau
			</p>
			<p>
				Tags: [MVC]&nbsp;[Domain Driven Design]&nbsp;<br>
				<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=f982643bc3">read more &gt;&gt;</a><br>
				<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=edit&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=5b481bc8f0">Edit</a>&nbsp;<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=delete&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=4e52879656">Delete</a>
			</p>
		</li>
	</ul>
	<p>
		<a href="index.php?id=99&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=new&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=2718a4b1a0">Create a new Post</a>
	</p>
</div>
<hr>
<p>
	? TYPO3 Association
</p>
';
        $result = $this->cObj->cropHTML($subject, '300');
        $expected = '
<h1>Blog Example</h1>
<hr>
<div class="csc-header csc-header-n1">
	<h2 class="csc-firstHeader">Welcome to Blog #1</h2>
</div>
<p class="bodytext">
	A blog about TYPO3 extension development. In order to start blogging, read the <a href="#">Help section</a>. If you have any further questions, feel free to contact the administrator John Doe (<a href="mailto:john.doe@example.com">john.doe@example.com)</a>.
</p>
<div class="tx-blogexample-list-container">
	<p class="bodytext">
		Below are the most recent posts:
	</p>
	<ul>
		<li>
			<h3>
				<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog]=&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=003b0131ed">The Pos</a></h3></li></ul></div>';
        $this->assertEquals($expected, $result);
        $result = $this->cObj->cropHTML($subject, '-100');
        $expected = '<div class="tx-blogexample-list-container"><ul><li><p>Design]&nbsp;<br>
				<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=f982643bc3">read more &gt;&gt;</a><br>
				<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=edit&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=5b481bc8f0">Edit</a>&nbsp;<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=delete&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=4e52879656">Delete</a>
			</p>
		</li>
	</ul>
	<p>
		<a href="index.php?id=99&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=new&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=2718a4b1a0">Create a new Post</a>
	</p>
</div>
<hr>
<p>
	? TYPO3 Association
</p>
';
        $this->assertEquals($expected, $result);
    }
 /**
  * Highlighting of terms within a text
  * 
  * @param string $text											Text
  * @param string|\Zend_Search_Lucene_Search_Query $search		Terms to be highlighted (string or lucene search query)
  * @param int $crop												Max. number of characters length
  * @param string $append		 								Suffix in case of text being cropped at the end
  * @param string $prepend		 								Prefix in case of text being cropped at the beginning
  * @param string $field			 								Lucene document field to be used (if the search terms have to be found retroactively)
  * @return string												Text with highlighting
  * @see http://www.mail-archive.com/fw-general@lists.zend.com/msg09013.html
  */
 public function render($text = null, $search = null, $crop = null, $append = ' ...', $prepend = ' ... ', $field = 'bodytext')
 {
     $text = trim(strlen(trim($text)) ? $text : $this->renderChildren());
     $terms = array();
     // If there is a reasonable text given
     if (strlen($text)) {
         // If a list with search terms have been given ...
         if (is_array($search)) {
             $terms = $search;
             usort($terms, array($this, 'sortByLengthDesc'));
             // Else: If query hits have been given ...
         } elseif ($search instanceof \Tollwerk\TwLucenesearch\Domain\Model\QueryHits) {
             $terms = (array) $search->getHighlight($field);
             usort($terms, array($this, 'sortByLengthDesc'));
             // Else: If a lucene search query or a literal search term has been given
         } elseif ($search instanceof \Zend_Search_Lucene_Search_Query || strlen($search)) {
             // Instanciation of the lucene index service
             /* @var $indexerService \Tollwerk\TwLucenesearch\Service\Lucene */
             $indexerService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstanceService('index', 'lucene');
             if ($indexerService instanceof \TYPO3\CMS\Core\Service\AbstractService) {
                 // Converting search term to lucene search query if necessary
                 if (!$search instanceof \Zend_Search_Lucene_Search_Query) {
                     $search = $indexerService->query($search);
                 }
                 // If there is a valid lucene search query available
                 if ($search instanceof \Zend_Search_Lucene_Search_Query) {
                     $searchHash = md5("{$search}");
                     if (!array_key_exists($searchHash, self::$_queryTermCache)) {
                         self::$_queryTermCache[$searchHash] = array();
                         foreach ($indexerService->getQueryTerms($search) as $termField => $fieldTerms) {
                             usort($fieldTerms, array($this, 'sortByLengthDesc'));
                             self::$_queryTermCache[$searchHash][$termField] = $fieldTerms;
                         }
                     }
                     $terms = self::$_queryTermCache[$searchHash];
                     $field = trim($field);
                     $terms = strlen($field) && array_key_exists($field, $terms) ? $terms[$field] : array();
                 }
             }
         }
     }
     // Check if the text has to be cropped ...
     $crop = $crop !== null && intval($crop) && strlen($text) > $crop ? intval($crop) : false;
     // If the text is more than 33% too long and highlighting has to be applied: Cropping also at the beginning of the text
     if ($crop && strlen($text) / $crop > 1.5 && count($terms)) {
         // Find the first highlighting in the text ...
         $firstHighlight = $this->firstMatch($terms, $text);
         // If there is at least one highlighting ...
         if ($firstHighlight !== false) {
             $beforeHighlight = strrev(trim(substr($text, 0, $firstHighlight)));
             // Keep the last 3 words before the highlighting ...
             $words = preg_split("%\\s+%", $beforeHighlight, 4);
             if (count($words) > 3) {
                 $beforeHighlight = strrev(implode(' ', array_slice($words, 0, 3)));
                 $text = $prepend . $beforeHighlight . ' ' . substr($text, $firstHighlight);
             }
         }
     }
     // If there are search terms to be highlighted in the text ...
     if (count($terms)) {
         $text = $this->highlight($terms, $text, $crop);
     }
     // If the text has to be cropped ...
     if ($crop) {
         if (TYPO3_MODE === 'BE') {
             $this->simulateFrontendEnvironment();
         }
         $respectHtml = true;
         $text = $respectHtml ? $this->contentObject->cropHTML($text, $crop . '|' . $append . '|1') : $this->contentObject->crop($text, $crop . '|' . $append . '|1');
         if (TYPO3_MODE === 'BE') {
             $this->resetFrontendEnvironment();
         }
     }
     return $text;
 }