Modifying content of web page on the fly

Scenario:
Users enter content which goes on a web site using Movable Type. Users are non-technical, but I need to enable a couple of things without requiring users to enter html, code etc. Specifically:
(1) catch any email addresses entered and print them in a format not readable by spambots
(2) allow easy insertion of images within the text

Planned solution:
Movable Type will output a static file for each entry based on a predefined template. This template will contain PHP code to provide the functionality I require. Use ob_start to route all output to a function which
(1) routes any email addresses found to a function (already written and working, uses javascript to 'mangle' addresses in a non machine readable format)
(2) looks for any instances of {image=file.jpg} and replaces with the relevant IMG html

The code I have so far is as follows:-
<?
//load email() function
require("dev/inc/email.inc");

function image($command) {
      //convert {image=[image filename] align=[left|right|center] caption=[caption in quotes]} to correct html
      preg_match("/image=([^\s}]*)/i",$command,$image);
      preg_match("/align=([^\s}]*)/i",$command,$align);
      preg_match('/caption.*"([^"]*)"/i',$command,$caption);
      $caption=stripslashes($caption[1]);
      //output correct html for IMG (or dummy text for testing)
      echo("IMAGE=$image[1] ALIGN=$align[1] CAPTION=$caption");
}

function callback($buffer) {
      //regexp for replacing emails with email() function
      $search[0]="/[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+/ie";
      $replace[0]="email('\\0','\\0');";

      //regexp for replacing {image} with IMG html code by calling image() function
      $search[1]="/{image[^}]*}/ie";
      $replace[1]="image('\\0');";

      $buffer = preg_replace($search,$replace,$buffer);

      return($buffer);
}
?>

<html>
<body>
<p><b>Callback function called directly</b></p>
<?echo(callback('<p>An image might go here {image=img.jpg caption="hello there" align=right}</p><p>Just email me at email@somewhere.com</p>'));?>

<p><b>Callback function called through ob_start</b></p>
<?ob_start("callback");?>
<p>Just email me at email@somewhere.com</p>
<p>An image might go here {image=img.jpg align=right caption=hello there}</p>
<? ob_end_flush();?>
</body>
</html>

Problems:
(1) when calling the callback function directly (ie not through ob_start), the results of the replacements are output first, then the rest of the text.
(2) when calling through ob_start, no replacement results are output, just the buffer less the bits that matched.

Requirement:
Either help me to get this code working correctly, or suggest a better way to achieve the same. Note that over time I will probably add more replacements, so it needs to be flexible enough to accept an arbitrary number of replacements.

Thanks

mark.
markaukAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

abuzzuzCommented:
What the hell is Moveable Type?
0
abuzzuzCommented:
I'd like to help you but, as I said before, cant figure out exaclty what you are trying to achieve with this movable type and static html stuff.
0
markaukAuthor Commented:
MovableType is a blog/content management system (www.movabletype.org). The fact that I am using Movable Type doesn't really matter except to explain why I have individual pages which have content in them which needs modified on the fly (rather than having the pages done correctly when originally authored). As far as I know, I can't achieve what I want directly within Movable Type, hence needing separate php code to do it.
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

waygoodCommented:
why dont you use BBcode (bulletin board)

eg [b]bold text[/b] [img=pic.jpg] some other normal text then [email=email@domain.com]email me[/email] the < character doesnt interfere with bbcode.

you then convert the code to html and store it for when you display the page. pointless converting on the fly. forums like phpBB use it.
You can also convert email addresses to code values, which bot dont pick up.

$encoded_email="";
for ($i = 0; $i < strlen($email); $i++) {
   $encoded_email.='&#'.ord(substr($email,$i,1));
}
0
markaukAuthor Commented:
Not sure I follow. BBcode is just html, but with [] instead of <>, right? I'd still have to parse through and convert [] to <>. phpBB presumably does this every time it outputs a page, and its pages are always generated dynamically on the fly. Also, the image insertion will be more complex than just inserting <img=pic.jpg> as I will also be inserting styles and other stuff I need to hide from the user.

I need to convert on the fly, because otherwise how do I change something that is sitting in a php file generated by moveable type to the code I want? (assuming movable type can't do the conversion itself, and I don't think it can)
0
FenricCommented:
Hi, markauk.

I don't know enough about PHP and I know next to nothing about Movable Type (I know what it is) and BBCode, but I used this question as an opportunity to learn a couple of new PHP functions. So thanks for the inspiration. :-)

The simplest answer to your question appears to be your echo statement at the end of the "image()" function. If you replace this with a return(), it appears to work fine, as far as I can tell without access to your email() function.

Without making this change, I was able to at least get some output from the buffered stream by using an ob_get_contents() call. I added the following two lines:

$buffer=ob_get_contents();
callback($buffer);

before the ob_end_flush(). It worked, except that the replaced strings were at the end of the buffer rather than in place. (Interesting, as the direct call output the replacements first, before the rest of the buffer string.) Again, replacing the echo with a return fixed the problem and allowed me to remove the extra two lines.

My final code read as follows:

[CODE]

<?
//load email() function
//require("dev/inc/email.inc");

function imgo($command) {
     //convert {image=[image filename] align=[left|right|center] caption=[caption in quotes]} to correct html
     preg_match("/image=([^\s}]*)/i",$command,$image);
     preg_match("/align=([^\s}]*)/i",$command,$align);
     preg_match('/caption.*"([^"]*)"/i',$command,$caption);
     $caption=stripslashes($caption[1]);
     //output correct html for IMG (or dummy text for testing)
     return("IMAGE=$image[1] ALIGN=$align[1] CAPTION=$caption");
}

function callback($buffer) {
     //regexp for replacing emails with email() function
     $search[0]="/[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+/ie";
     $replace[0]="email";

     //regexp for replacing {image} with IMG html code by calling image() function
     $search[1]="/{image[^}]*}/ie";
     $replace[1]="imgo('\\0');";

     $buffer = preg_replace($search,$replace,$buffer);
     return($buffer);
}

?>

<html>
<body>
<p><b>Callback function called directly</b></p>
<?echo(callback('<p>An image might go here {image=img.jpg caption="hello there" align=right}</p><p>Just email me at email@somewhere.com</p><p>And another image goes here. {image=img2.jpg align=right caption="hello again"}'));?>

<p><b>Callback function called through ob_start</b></p>
<?ob_start("callback");?>
<p>Just email me at email@somewhere.com</p>
<p>An image might go here {image=img.jpg align=right caption="hello there"}
<p>And another image goes here. {image=img2.jpg align=right caption="hello again"}
<?

ob_end_flush();?>
</p></body>
</html>

[/CODE]


Thanks for the opportunity to stretch my knowledge of PHP... now I just have to start using a few of these functions in my own code. :-)

Cheers
Fenric!
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
markaukAuthor Commented:
Thanks Fenric. That does the trick perfectly.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

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.