PHP/MySQL Limit Characters - php

Below is a preview of what I am dealing with:
The heading, the text, and the image is all dynamically created based on the user. They can choose if they want to add a picture, and they can choose what text to put in the heading and the main content.
There cannot be any scrolling, so it has to be visible and cannot go past the bottom of that white.
My question is... how can I limit the text of the body?
If the heading is large and goes down to two lines, and there is a picture, then in order to stay in the lines and not go past the white it has to be limited to a certain amount of characters.
But another user could decide to not have a picture and keep the heading in one line, so that user will have more text to write so the limit should be different.
I guess the confusing part for me is like.. what if a user has no picture and has a short heading, and creates some really long text to fit the size, but then later on decides to add an image.. then that long text will now no longer fit. So now.. I can't limit the text because it's already there.
I hope that makes sense. If anyone could help me through this and give me some ideas I would really appreciate it.

Use this for whatever the user input is for adding text. It could limit the characters they use just change the 250 value.
<script>
function countChar(val){
var len = val.value.length;
if (len >= 250) {
val.value = val.value.substring(0, 250);
}else {
$('#charNum').text(250 - len);
}
};
</script
<textarea id="field" name="description" onKeyUp="countChar(this)"></textarea>

its not only the text you need to limit but also the image thumbnail so that affect the style of your webpage
To limit the number of string .. i would you use a script form here php trim a string
function trim_word($str, $length, $suffix = '...')
{
$len = strlen($str);
if ($len < $length) return $str;
$pattern = sprintf('/^(.{%d,}?)\b.*$/', $length);
$str = preg_replace($pattern, '$1', $str);
$str = trim($str);
$str .= $suffix;
return $str;
}
it trim the text and makes sure it always ends with a word ...
You can use http://phpthumb.sourceforge.net/ to generate thumbnail of fixed size all you need to do it set your desired height and width

There are a few different options to consider. You may want to limit the amount of text the user can enter for starters, to ensure it doesn't overflow.
One thing I would probably do is find the maximum amount of characters you're comfortable with on the page, and use substr on the output from the database to ensure that it never displays more.
http://php.net/manual/en/function.substr.php
You could have a "more" link that way the visitor could read more if they want, but it doesn't break the layout. I would use basic if statements for the logic (if picture exists, trim text to this, if not etc).
Hope that helps.

Surround the entire thing with a container div of the fixed height which you desire with no padding, and inside that place another inner div with no margin and no fixed height, then as the user changes the content create a javascript function to check if the inner div is < the container div; and if not then do not allow the user to make that change - this way you are attacking the problem directly.
<script>
function checkDivs() {
if(inner.style.height >= container.style.height) {
//prevent change
}
}
</script>
<div id='container'>
<div id='inner'>
//User-defined content
</div>
</div>
This function would be attached to whatever GUI the user would edit the content through, as for how to prevent the change, I'd have to know more about your program.

Related

Zend PDF wysiwyg editor output

I'm currently building a PDF editor. I have a problemen with implementing the processing of the tags.
I want to allow the following tags:
[h1],[h2],[h3],[h4],[h4],[h5],[h6],[strong]
I've build an class with a method called drawText(code below).
The [h1] tag will change the font size and the font weight. As you can see in the code I'm outputting lines of text.
Example text line:
This is your [strong]boarding pass[/strong], please save this PDF file on your smartphone or tablet and [strong]show it at the gate[/strong].
I'd like to make the text between the [strong] bold. To do this with Zend_PDF I need to set the TTF file with the bold text and then find the current X-coordinate and call $this->pdf()->drawText(text, X-coordinate, Y-coordinate, charset). I've been thinking and trying for hours to write the code which makes this possible(tried using explode, preg_match_all, etc), but I can't get it to work...
I believe I'm not the only one with this problem, and I hope someone has thought about this and can help a little by telling how he or she did it...
Hope to hear from someone and thanks in advance!
/**
* drawSplittedText()
*
* #param array $text
* #return object Application_Plugin_PdfPlugin
*/
public function drawSplittedText(Array $text)
{
// Count the number of rows.
$textRowCount = count($text);
$i = 0;
foreach ($text as $row)
{
// Replace tabs, because they're not outputted properly.
$row = str_replace("\t", ' ', $row);
// If the character encoding of the currrent row not is UTF-8, convert the row characters to UTF-8.
if (($rowEncoding = mb_detect_encoding($row)) != 'UTF-8') {
$row = iconv($rowEncoding, 'UTF-8', $row);
}
// Output row on PDF
$this->pdf()->drawText($row, $this->_defaultMarginleft, $this->currentY, 'UTF-8');
$this->newLine();
++$i;
}
return $this;
}
The code above is probably where most people start when rendering text with Zend_Pdf, but unfortunately you are going to have to develop something a litte more complex to achieve your goals.
Firstly, you are going to need to keep track of the current x and y location, along with the current font type and size.
Then you'll need a helper function/method to calculate how much space a chunk of text is going to need when rendered in the current font and size.
I would then suggest breaking up your rendering code as follows:
function writeParagraph( $text )
{
// Looks for the next tag and sends all text before that tag to the
// writeText() function. When it gets to a tag it changes the current
// font/size accordingly, then continues sending text until it runs out
// of text or reaches another tag. If you need to deal with nested tags
// then this function may have to call itself recursively.
}
function writeText( $text )
{
// The first thing this function needs to do is call getStringWidth() to
// determine the width of the text that it is being asked to render and if
// the line is too long, shorten it. In practice, a better approach is to
// split the words into an array based on the space between each word and
// then use a while() loop to start building the string to be rendered
// (start with first word, then add second word, then add third word, etc),
// in each iteration testing the length of the current string concatenated
// with the next word to see if the resulting string will still fit. If you
// end up with a situation where adding the next word to the current string
// will result in a string that is too long, render the current string and
// a line feed then start the process again, using the next word as the first
// word in the new string. You will probably want to write a bonus line feed
// at the end as well (unless, of course, you just wrote one!).
}
function getStringWidth( $str )
{
// This needs to return the width of $str
}
I have a sample class (https://github.com/jamesggordon/Wrap_Pdf) that implements the writeText() and getStringWidth() functions/methods, plus includes all of the other stuff, like current location, current style, etc. If you can't figure out the code for the writeParagraph() function let me know and I'll include it in Wrap_Pdf.

substr and strlen explanation

Ok guys, this question is related to my previous one.
If I have set $textlimit = 500; that will limit my text to 500 characters.
Is there any way to "avoid" text limit, and then onclick function load rest of it?
For example, if I set:
$textpart = substr($fulltext, 0, 400);
$textpart will only contain 400 characters of string.
My question is, how to declare variable, which will contain the rest of the text which is much longer than 500 characters?
Example of variables:
$fulltext //Contains full text, but is limited to 500 characters.
$textpart //Contains part of the text, substr 400 characters out of 500.
$textrest //This variable to "hold" rest of the text, after 400 characters of $textpart.
Like I've asked in previous question, I wanted to make expand and collapse button, I now know how to do that, but I don't know how to divide text.
Form would go like this:
Random text here(400 characters long)
Random image for expand
After declared onclick function I, load rest of the text (Over 500 characters).
Random image for collapse
After declared onclick function collapse and return to previous state - citation 1.
I hope I explained my question the right way. I would really appreciate any kind of help, if I can choose, I would like just basic explanation on how to that, because I want to learn that, not copy/paste solution (it is easier, but I will not learn much).
Thanks in advance.
$textrest = substr($fulltext, 400)
$fulltext = substr($fulltext, 0, 500);
$textpart = substr($fulltext, 0, 400);
$textrest = substr($fulltext,400,strlen ( $fulltext ));
If I understand you correctly you want to show the user an initial page that shows only the first X characters and then show all the characters when the users clicks on the text.
There are three strategies to do this. From easy to hard:
Output the shortened text and include a link that will reload the whole page but with the whole text
Output all the text and use css and JavaScript to hide/show any overflow
Output the shortened text and perform an Ajax call to load the extra characters and append
Options 2 and 3 require the use of client side JavaScript and are therefore not pure PHP solutions.
Option 1 is a matter of adding a $_GET variable, e.g. ?expand=para1, to your url and expanding the text identified in PHP by $_GET['expand'].
Do not make the mistake of thinking PHP is still running on the page in the browser. Only JavaScript can run in the browser on the web page. (Not strictly true I know, but true enough in reality.)

Determing div layout dimensions php

I have three div's which are being filled with dynamic text from a database. The div #container is a fixed height and width where the text inside wraps. The three divs are different font sizes. Any of the three div's could have enough text to exceed the container size. I need to determine if the text exceeds the container size and at which letter in which div it occurs. The extraneous text will then be wrapped in something like <span class=hide">text here</span>
<div id="container">
<div id="first"><?php echo $arr['first'] ?></div>
<div id="mid"><?php echo $arr['mid'] ?></div>
<div id="last"><?php echo $arr['last'] ?></div>
</div>
I'm thinking this is impossible to do in PHP as the styling is done client side. Maybe there is a way to fake it? Though that could get ugly really fast.
I'm trying really hard not to do it in javascript because this calculation will be done about 10 times per page viewed. Please don't tell me it's impossible to do in PHP, there's always a way.
Any ideas?
Just in case you decide that client-side makes more sense for you I put together a fiddle. I realize you want to avoid client-side, but you mentioned this would be happening ten times which honestly is very little these days with how much js speed has increased in browsers. It is also a much simpler problem client side.
http://jsfiddle.net/JSRtk/
Basically you detect if the container is overflown. If so you display a 'read more' button. When clicked it will expand the container to show all text and go away.
$('#container > div').each( function() {
if (checkOverflow(this)) {
console.log('overflow detected in ' + $(this).attr('id'));
$(this).after('<p>Read more...</p>');
}
});
$('p').live('click', function() {
$(this).prev('div').css('height', 'auto');
$(this).hide();
});
function checkOverflow(el)
{
var curOverflow = el.style.overflow;
if ( !curOverflow || curOverflow === "visible" )
el.style.overflow = "hidden";
var isOverflowing = el.clientWidth < el.scrollWidth
|| el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
}
Do you have to wrap it in a span for a purpose (i.e. crawlers/seo)? If not you could either set the CSS on the div with a fixed width to have overflow hidden, alternatively, you could figure out how many characters roughly fit in that width (count them) then use strlen() and substr() like so
<?php
$string = "This is a string thats too long to fit";
if(strlen($string) > 20)
echo substr($string,0,20);
else
echo $string;
?>
There is no way for you to calculate the size of a display element in PHP since it is run on the server and not on the client, and it's the client that renders the HTML.
If you have the same container size every time and the same font and font size and styles and everything, you could probably estimate a number of character and cut it off in PHP at that number of characters using substr. But even then, unless you build a table of character sizes or use a monospaced font, there is no way to reliably do what you want.

String replace the contents of a div

What I want to do:
I have a div with an id. Whenever ">" occurs I want to replace it with ">>". I also want to prefix the div with "You are here: ".
Example:
<div id="bbp-breadcrumb">Home > About > Contact</div>
Context:
My div contains breadcrumb links for bbPress but I'm trying to match its format to a site-wode bread crumb plugin that I'm using for WordPress. The div is called as function in PHP and outputted as HTML.
My question:
Do I use PHP of Javascript to replace the symbols and how do I go about calling the contents of the div in the first place?
Find the code that's generating the <, and either set the appropriate option (breadcrumb_separator or so) or modify the php code to change the separator.
Modifying supposedly static text with JavaScript is not only a maintenance nightmare, extremely brittle, and might lead to a strange rendering (as users see your site being modified if their system is slow), but will also not work in browsers without (or with disabled) JavaScript support.
You could use CSS to add the you are here text:
#bbp-breadcrumb:before {
content: "You are here: ";
}
Browser support:
http://www.quirksmode.org/css/beforeafter_content.html
You could change the > to >> with javascript:
var htmlElement = document.getElementById('bbp-breadcrumb');
htmlElement.innerHTML = htmlElement.innerHTML.split('>').join('>>').split('>').join('>>')
I don't recommend altering content like this, this is really hacky. You'd better change the ouput rendering of the breadcrumb plugin if possible. Within Wordpress this should be doable.
you can use a regex to match the breadcrumb content.. make the changes on it.. and put it back in the context..
check if this helps you:
$the_existing_html = 'somethis before<div id="bbp-breadcrumb">Home > About > Contact</div>something after'; // let's say this is your curreny html.. just added some context
echo $the_existing_html, '<hr />'; // output.. so that you can see the difference at the end
$pattern ='|<div(.*)bbp-breadcrumb(.*)>(.*)<\/div>|sU'; // find some text that is in a div that has "bbp-breadcrumb" somewhere in its atributes list
$all = preg_match_all($pattern, $the_existing_html, $matches); // match that pattern
$current_bc = $matches[3][0]; // get the text inside that div
$new_bc = 'You are here: ' . str_replace('>', '>>', $current_bc);// replace entity for > with the same thing repeated twice
$the_final_html = str_replace($current_bc, $new_bc, $the_existing_html); // replace the initial breadcrumb with the new one
echo $the_final_html; // output to see where we got

character-based pagination - inserting page breaks on text, not punctuation or code

I'm writing code to generate character-based pagination. I have articles in my site that I want to split up based on length.
The code I have so far is working albeit two issues:
It's splitting pages in the middle of words and HTML tags; I want it to
only split after a complete word, tag, or a punctuation mark.
In the pagination bar, it's generating the wrong number of pages.
In the
pagination bar, it's generating the
wrong number of pages.
Need help addressing these two issues. Code follows:
$text = file_get_contents($View);
$ArticleLength = strlen($text);
$CharsPerPage = 5000;
$NoOfPages = round((double)$ArticleLength / (double)$CharsPerPage);
$CurrentPage = $this->ReturnNeededObject('pagenumber');
$Page = (isset($CurrentPage) && '' !== $CurrentPage) ? $CurrentPage : '1';
$PageText = substr($text, $CharsPerPage*($Page-1), $CharsPerPage);
echo $PageText, '<p>';
for ($i=1; $i<$NoOfPages+1; $i++)
{
if ($i == $CurrentPage)
{
echo '<strong>', $i, '</strong>';
}
else
{
echo '', $i, '';
}
echo ' | ';
}
echo '</p>';
What am I doing wrong?
Thanks, guys. I put in the fix for the 1st point and it worked beautifully.
Hm. I guess it is messy to do the second point. I've found some regex on-line. Will think, write, and get back to you when I make some progress.
Thanks again.
$NoOfPages = round((double)$ArticleLength / (double)$CharsPerPage);
That should use ceil instead of round - if you use round, 4.2 pages will only show 1-4 - you need a 5th page to show the last .2 of a page.
The other part is harder ... its common to use some sort of marker in the file to indicate where the page breaks go as no matter how clever your code, it can't appreciate where is a good break in then same way a human can.
If you insist on doing it suggest some logic that first works forwards/backwards to the nearest space when a page break is created, which isn't too tricky. More tricky is deciding when you are within a tag or not .... think you'll either need some fairly heavy regex, or else an HTML parsing tool.
You're calculating the number of pages wrong... you should be using ceil() not round() (for example 4.1 pages worth of text is still 5 pages to display).
To fix the other issue, you're going to have big problems if there's arbitrary HTML in there. For example, you need to know that <div>s and <p>s are OK to split, but <table>s aren't (unless you want to get really fancy)!
To do it properly you should use an HTML library to build a tree of elements and then go from there.
Based on your first statement,
It's splitting pages in the middle of words and HTML tags
it appears that your character count is being done after markup is inserted. That would imply that e.g. long URLs in links would be counted against the page length you're trying to achieve. However, you didn't say how the articles were being created initially.
I'd suggest looking for a point in the process of creating the article where you could examine the raw text. By regarding the actual content (without markup) as a set of paragraphs, and estimating the vertical length of each paragraph based on typical number of characters per line, you can come up with a more consistent sizing.
I would also consider only breaking between paragraphs, to keep units of thought together on the same page. Speaking as a reader, I really hate going to sites that force me to pause, hit a button or link, and wait for a page reload, all in the middle of a single thought.

Categories