Shorten Text from Object in PHP

The following method renders text:
	/*
		Function: renderPosition
			Render position output.

		Parameters:
			$position - Position name.
			$args - Arguments to be passed to into the position scope.

		Returns:
			Void
	*/
	public function renderPosition($position, $args = array()) {

		// init vars
		$elements = array();
		$output   = array();
		$user	  = $this->app->user->get();

		// get style
		$style = isset($args['style']) ? $args['style'] : 'default';

		// store layout
		$layout = $this->_layout;

		// render elements
		foreach ($this->_getConfigPosition($position) as $data) {
            if ($element = $this->_item->getElement($data['element'])) {

				if (!$element->canAccess()) {
					continue;
				}

                // set params
                $params = array_merge($data, $args);

                // check value
                if ($element->hasValue($params)) {
                    $elements[] = compact('element', 'params');
                }
            }
        }

        foreach ($elements as $i => $data) {
            $params  = array_merge(array('first' => ($i == 0), 'last' => ($i == count($elements)-1)), $data['params']);

			// trigger elements beforedisplay event
			$render = true;
			$this->app->event->dispatcher->notify($this->app->event->create($this->_item, 'element:beforedisplay', array('render' => &$render, 'element' => $data['element'], 'params' => $params)));

			if ($render) {
				$output[$i] = parent::render("element.$style", array('element' => $data['element'], 'params' => $params));

				// trigger elements afterdisplay event
				$this->app->event->dispatcher->notify($this->app->event->create($this->_item, 'element:afterdisplay', array('html' => &$output[$i], 'element' => $data['element'], 'params' => $params)));
			}
        }

		// restore layout
		$this->_layout = $layout;

		return implode("\n", $output);
	}

Open in new window

It is called with this script:
<?php echo $this->renderPosition('description', array('style' => 'block')); ?>

Open in new window

It generates the following HTML:
<div class="element element-textarea first last">
<p></p>
<p>Presteligence has been top-notch in customer service. Anytime we have had to call they have been quick to respond and are totally dedicated to our needs. They go above and beyond the call in making sure our production process is as smooth as possible. We have truly found a partnership for our future growth.</p>
<p></p>
</div>

Open in new window

I want to shorten (limit) the text to like 200 characters and then put a "..." at the end.  How can I do this?  The end result should be like this:
<div class="element element-textarea first last">
<p></p>
<p>Presteligence has been top-notch in customer service. Anytime we have had to call they have been quick to respond and are totally dedicated to our needs. They go above and beyond the call in making su...</p>
<p></p>
</div>

Open in new window

LVL 14
EMB01Asked:
Who is Participating?
 
xtermCommented:
Change this line:

  echo '<p>'.substr($var,0,125).' (continued)</p>';

to

  echo '<p>'.substr($var,0,200).' ...</p>';

That should get it done.
0
 
xtermCommented:
here you go:
$newtext=substr($text,0,200)."...";

Open in new window

0
 
EMB01Author Commented:
Yes, I understand how to do it on a regular variable, but I don't see how to change it in this OOP design...
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
EMB01Author Commented:
Or, if it's easier you can do some sort of preg function to turn this:

<div class="element element-textarea first last">
<p></p>
<p>Presteligence has been top-notch in customer service. Anytime we have had to call they have been quick to respond and are totally dedicated to our needs. They go above and beyond the call in making sure our production process is as smooth as possible. We have truly found a partnership for our future growth.</p>
<p></p>
</div>

Into this (limit text inside <p> element to 200 characters and add "..." at the end):

<div class="element element-textarea first last">
<p></p>
<p>Presteligence has been top-notch in customer service. Anytime we have had to call they have been quick to respond and are totally dedicated to our needs. They go above and beyond the call in making su...</p>
<p></p>
</div>
0
 
Lukasz ChmielewskiCommented:
Is the <p></p> paragraphs always present before and after the content ?
0
 
xtermCommented:
Sorry, I didn't read your original question closely enough.  Try this instead:
$newtext="";
$text="<div class=\"element element-textarea first last\">
<p></p>
<p>Presteligence has been top-notch in customer service. Anytime we have had to call they have been quick to respond and are totally dedicated to our needs. They go above and beyond the call in making sure our production process is as smooth as possible.  We have truly found a partnership for our future growth.</p>
<p></p>
</div>";

$lines=explode("\n",$text);
$lines[2]=substr($lines[2],0,203)."...</p>";

for($i=0; $i<count($lines); $i++) {
  $newtext.="$lines[$i]\n";
}

echo "$newtext\n";

Open in new window

0
 
EMB01Author Commented:
Thanks, I ended up just stripping tags and rewriting them (I only need the <p> tags, don't need the div):

$var = strip_tags($this->renderPosition('description', array('style' => 'block')));
                  echo '<p>'.substr($var,0,125).' (continued)</p>';

But, I would like to figure out how to modify the renderPosition method, instead of changing the data after the fact.  Can you help me with this?
0
 
EMB01Author Commented:
I understand how to change that code, I understand PHP quite well; but not well enough to change the OOP design.

I don't want to change the script part:

<?php echo $this->renderPosition('description', array('style' => 'block')); ?>

I already know how to solve the problem doing that.  I want to know how to solve the problem by changing the method part:


/*
		Function: renderPosition
			Render position output.

		Parameters:
			$position - Position name.
			$args - Arguments to be passed to into the position scope.

		Returns:
			Void
	*/
	public function renderPosition($position, $args = array()) {

		// init vars
		$elements = array();
		$output   = array();
		$user	  = $this->app->user->get();

		// get style
		$style = isset($args['style']) ? $args['style'] : 'default';

		// store layout
		$layout = $this->_layout;

		// render elements
		foreach ($this->_getConfigPosition($position) as $data) {
            if ($element = $this->_item->getElement($data['element'])) {

				if (!$element->canAccess()) {
					continue;
				}

                // set params
                $params = array_merge($data, $args);

                // check value
                if ($element->hasValue($params)) {
                    $elements[] = compact('element', 'params');
                }
            }
        }

        foreach ($elements as $i => $data) {
            $params  = array_merge(array('first' => ($i == 0), 'last' => ($i == count($elements)-1)), $data['params']);

			// trigger elements beforedisplay event
			$render = true;
			$this->app->event->dispatcher->notify($this->app->event->create($this->_item, 'element:beforedisplay', array('render' => &$render, 'element' => $data['element'], 'params' => $params)));

			if ($render) {
				$output[$i] = parent::render("element.$style", array('element' => $data['element'], 'params' => $params));

				// trigger elements afterdisplay event
				$this->app->event->dispatcher->notify($this->app->event->create($this->_item, 'element:afterdisplay', array('html' => &$output[$i], 'element' => $data['element'], 'params' => $params)));
			}
        }

		// restore layout
		$this->_layout = $layout;

		return implode("\n", $output);
	}

Open in new window

0
 
Ray PaseurCommented:
This is just a guess, because the code is so generalized that it does not have specific handlers for the "description" and so it might not work.

Looking at the OOP code, it looks like somewhere around line32 you might put something like this:

if ($position == "description")
{
    ?? = teaser_fragment(??, 200);
}

Unfortunately from the code posted here, it is impossible to figure out what the ?? values should be.
<?php // RAY_teaser_fragment.php
error_reporting(E_ALL);


// CREATE A TEASER FRAGMENT HEADLINE
// RETURN FIRST FEW WHOLE WORDS FOLLOWED BY ELLIPSES
// WITH A LINK TO THE FULL ARTICLE
// $length IS MINIMUM TRUNCATION CHARACTER COUNT


function teaser_fragment($text, $length=32, $url='/', $delim='|||')
{
    // IF TRUNCATION IS NEEDED
    if (strlen($text) > $length)
    {
        // IF TRUNCATION IS NEEDED, BREAK STRING APART
        $t = wordwrap($text, $length, $delim);
        $a = explode($delim, $t);
        $z = '...';
    }
    // IF TRUNCATION IS NOT NEEDED
    else
    {
        $a[0] = $text;
        $z = NULL;
    }

    // CONSTRUCT THE FRAGMENT WITH THE LINK AND ADD ELLIPSIS (LINK) TO THE END
    $teaser
    = '<a target="_blank" href="'
    . $url
    . '">'
    . $a[0]
    . $z
    . '</a>'
    ;
    return $teaser;
}



// USE CASES
echo "<pre>";
echo PHP_EOL;
echo "1...5...10...15...20...25...30...35...40...45..." . PHP_EOL;
echo teaser_fragment('Now is the time for all good men to come to the aid of their party');

echo PHP_EOL;
echo teaser_fragment('Now is the time for all good men to come to the aid of their party', 300);

echo PHP_EOL;
echo teaser_fragment('Now is the time for all good men to come to the aid of their party', 15, 'http://en.wikipedia.org/wiki/Filler_text');

Open in new window

0
 
EMB01Author Commented:
I'm not able to understand the solution.  Do you need to see more code, i.e. the entire class to which renderPosition belongs?
0
 
Ray PaseurCommented:
That might help, and some test data that shows us where to find the "description" would be useful, for sure.  The renderPosition method appears to be generalized to work on lots of different things, so any solution we might posit will require a lot of testing.
0
 
EMB01Author Commented:
just going to except because I can't look into this anytime soon, but I would be interested in learning the best way to work with these scripts where there are bunch of $class inherits $class2, etc. and it's hard to follow since the code is hard to understand.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.