How to send an email with inline images using zend framework? - php

The documentation specifies how to add inline attachement, but what is the correct way of referencing it from the html part? Is it possible to include images automatically as it is in other libraries?
Maybe someone has written a little snippet and is willing to share?

That's not exactly a trivial thing, lucky for you someone has subclassed Zend_Mail (Demo_Zend_Mail_InlineImages) to do that, see here:
http://davidnussio.wordpress.com/2008/09/21/inline-images-into-html-email-with-zend-framework/

i write wrapper for mail class
private function _processHtmlBody($I_html, $I_mailer, $I_data) {
$html = $I_html;
$mail = $I_mailer;
$xmlBody = new DomDocument();
$xmlBody->loadHTML($html);
$imgs = $xmlBody->getElementsByTagName('img');
$I_data['atts'] = array();
$imgCount = 0;
foreach ($imgs as $img) {
$imgCount++;
$imgUrlRel = $img->getAttribute('src');
$imgId = sha1(time() . $imgCount . $imgUrlRel);
$html = str_replace($imgUrlRel, 'cid:' . $imgId, $html);
$imgUrlFull = 'http://' . $_SERVER['HTTP_HOST'] . $imgUrlRel;
$imgBinary = file_get_contents($imgUrlFull);
$imgPart = $mail->createAttachment($imgBinary);
$imgPart->filename = 'image' . $imgCount . '.jpg';
$imgPart->id = $imgId;
$I_data['atts'][] = $imgPart;
}
$mail->setBodyHtml($html);
return $html;
}

Instead of extending Zend_Mail you can directly embed your image in base64 using html.
Here is an example image that I included in my email template:
<img src="data:image/jpg;base64,<?= base64_encode(file_get_contents("/local/path/to/image.png")) ?>" />

Related

How to show image element from XML with php

I've tried what others have posted on stack overflow but it doesn't seem to work for me. So could anyone help please.
I have this xml document with a structure of:
<surveys>
<survey>
<section>
<page>
<reference>P1</reference>
<image><! [CDATA[<img src="imagepath">]]></image>
</page>
<page>
<reference>P2</reference>
<image><! [CDATA[<img src="imagepath">]]></image>
</page>
</section>
</survey>
</surveys>
Then this is my PHP code to get the image to show up:
function xml($survey){
$result = "<surveys></surveys>";
$xml_surveys = new SimpleXMLExtended($result);
$xml_survey = $xml_surveys->addChild('survey');
if ("" != $survey[id]){
$xml_survey_>addChildData($survey['image']);
}
This is my other file:
$image = “”;
if(“” != $image){
$image = <div class=“image_holder”> $image </div>
echo $image;
}
I'm not sure how to progress forward with this. so any help would be appreciated
It looks like you would like to fetch the image for a specific survey id. Well you can use DOM+Xpath To fetch this directly:
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$expression = 'string(
/surveys/survey/section/page[reference="P1"]/image
)';
$imageForSurvey = $xpath->evaluate($expression);
var_dump($imageForSurvey);
Output:
string(22) "<img src="imagepath1">"
The content of the CDATA section inside the image element is a separate HTML fragment. You can use it directly if you trust the source of the XML or you parse it as HTML.
$htmlFragment = new DOMDocument();
$htmlFragment->loadHTML($imageForSurvey);
$htmlXpath= new DOMXpath($htmlFragment);
var_dump(
$htmlXpath->evaluate('string(//img/#src)')
);
Output:
string(10) "imagepath"
Your example-logic is trying to create XML, not load it ;-)
First you need to find the path and/or address to the XML file, like:
$filePath = __DIR__ . '/my-file.xml';
Then load XML:
<?php
$filePath = __DIR__ . '/my-file.xml';
$document = simplexml_load_file($filePath);
$surveyCount = 0;
foreach($document->survey as $survey)
{
$surveyCount = $surveyCount + 1;
echo '<h1>Survey #' . $surveyCount . '</h1>';
foreach($survey->section->page as $page)
{
echo 'Page reference: ' . $page->reference . '<br>';
// Decode your image.
$imageHtml = $page->image;
$dom = new DOMDocument();
$dom->loadHTML($imageHtml);
$xpath= new DOMXpath($dom);
$image = $xpath->evaluate('string(//img/#src)');
if(!empty($image)) {
echo '<div class=“image_holder”>' . $image . '</div>';
}
echo "<br>";
}
}
?>
Note that you should replace <! [CDATA[ with <![CDATA[ (without space),
else you will get StartTag: invalid element name error probably.

Fetching image from google using dom

I want to fetch image from google using PHP. so I tried to get help from net I got a script as I needed but it is showing this fatal error
Fatal error: Call to a member function find() on a non-object in C:\wamp\www\nq\qimages.php on line 7**
Here is my script:
<?php
include "simple_html_dom.php";
$search_query = "car";
$search_query = urlencode( $search_query );
$html = file_get_html( "https://www.google.com/search?q=$search_query&tbm=isch" );
$image_container = $html->find('div#rcnt', 0);
$images = $image_container->find('img');
$image_count = 10; //Enter the amount of images to be shown
$i = 0;
foreach($images as $image){
if($i == $image_count) break;
$i++;
// DO with the image whatever you want here (the image element is '$image'):
echo $image;
}
?>
I am also using Simple html dom.
Look at my example that works and gets first image from google results:
<?php
$url = "https://www.google.hr/search?q=aaaa&biw=1517&bih=714&source=lnms&tbm=isch&sa=X&ved=0CAYQ_AUoAWoVChMIyKnjyrjQyAIVylwaCh06nAIE&dpr=0.9";
$content = file_get_contents($url);
libxml_use_internal_errors(true);
$dom = new DOMDocument;
#$dom->loadHTML($content);
$images_dom = $dom->getElementsByTagName('img');
foreach ($images_dom as $img) {
if($img->hasAttribute('src')){
$image_url = $img->getAttribute('src');
}
break;
}
//this is first image on url
echo $image_url;
This error usually means that $html isn't an object.
It's odd that you say this seems to work. What happens if you output $html? I'd imagine that the url isn't available and that $html is null.
Edit: Looks like this may be an error in the parser. Someone has submitted a bug and added a check in his code as a workaround.

Scraping html with urls from website

I'm scraping some html from a webite using php simple html dom, which include several images. However the images is not pointing correctly to the website. For example below is a example of one of the images where you can see it is no pointing to the website. Is it possible to dynamically change the urls to point to the website for instance
http://www.url.com/bilder/flags_long/United States.gif
html example
<img src="/bilder/flags_long/United States.gif" align="absmiddle" title="United States" alt="United States" border="0">
sample code:
include('simple_html_dom.php');
$sum_gosu = file_get_html("http://www.gosugamers.net/counterstrike/news/30995-starladder-is-back-with-the-thirteenth-edition-of-starseries");
$gosu_full = $sum_gosu->find("//div[#class='content light']/div[#class='text clearfix']/div", 0);
How about concatenating the actual URL you fetched the document from and the relative image paths. Just to give an idea (this is not tested and you should definitely do some checks whether the image src attribute is relative or maybe absolute in some cases):
<?php
$url = 'http://www.url.com/';
$html = file_get_html($url);
$images = array();
foreach($html->find('img') as $img) {
// Option 1: Fill your images array (in case you only need the images)
$images[] = rtrim($url, '/') . '/' . ltrim($img->src, '/');
// Option 2: Update $img->src inside your $html document
$img->src = rtrim($url, '/') . '/' . ltrim($img->src, '/');
}
?>
UPDATE According your sample code my example could look like follows:
<?php
include('simple_html_dom.php');
$sum_gosu_url = "http://www.gosugamers.net/counterstrike/news/30995-starladder-is-back-with-the-thirteenth-edition-of-starseries";
$sum_gosu = file_get_html($sum_gosu_url);
$gosu_full = $sum_gosu->find("//div[#class='content light']/div[#class='text clearfix']/div", 0);
foreach($gosu_full->find('img') as $img) {
$img->src = $sum_gosu_url . $img->src;
}
?>
After that the img src attributes inside your $gosu_full document should be fixed and resolvable (downloadable by a client). Hope that helps and that I'm actually understanding your problem :)
$url="http://www.url.com";
$Chtml = file_get_html($url);
$imgurl=Chtml->find("img",0)->src;
echo $url.$imgurl;

Getting media:thumbnail from XML

I just can't seem to be able to solve this. I want to get the media:thumbnail from an RSS file (http://feeds.bbci.co.uk/news/rss.xml).
I did some research and tried to incorporate insights from
https://stackoverflow.com/questions/6707315/getting-xml-attribute-from-mediathumbnail-in-bbc-rss-feed
and from other sources.
This is what I got:
$source_link = "http://feeds.bbci.co.uk/news/rss.xml";
$source_xml = simplexml_load_file($source_link);
$namespace = "http://search.yahoo.com/mrss/";
foreach ($source_xml->channel->item as $rss) {
$title = $rss->title;
$description = $rss->description;
$link = $rss->link;
$date_raw = $rss->pubDate;
$date = date("Y-m-j G:i:s", strtotime($date_raw));
$image = $rss->attributes($namespace);
print_r($image);
}
When I run the script, all I see is a white page. If I echo or print_r any of the other variables, then it works like a charm. It's just the $image one which poses problems. Why isn't this working? Thx for any help!
OK, it works now. I replaced
$image = $rss->attributes($namespace);
with
$image = $rss->children($namespace)->thumbnail[1]->attributes();
$image_link = $image['url'];
and it works like a charm now.
Base from this blog, with post title Processing media:thumbnail in RSS feeds with php.
The solution that I found works best simply loads the xml file as a string, then find and replace 'media:thumbnail' with a correctly formatted 'thumbnail' and lastly convert it back to xml with simplexml_load_string:
$xSource = 'http://feeds.bbci.co.uk/news/rss.xml';
$xsourcefile = file_get_contents( $xSource );
$xsourcefile = str_replace("media:thumbnail","thumbnail",$xsourcefile);
$xml = simplexml_load_string( $xsourcefile );
echo $row['xtitle'] . '<BR>';
foreach ($xml->channel->item as $item) {
echo ':' . $item->title . '<BR>';
echo ':' . $item->thumbnail['url'] . '<BR>';
}
$image = $rss->attributes($namespace);
This says "Give me all attributes of this <item> element which are in the media namespace". There are no attributes on the item element (much less any in the media namespace), so this returns nothing.
You want this:
$firstimage = $rss->children($namespace)->thumbnail[0];
BTW, when you use SimpleXML you need to be careful to cast your SimpleXMLElements to string when you need the text value of the element. Something like $rss->title is a SimpleXMLElement, not a string.

Replace the content of a tag with a certain class

I am looking for suitable replacement code that allows me replace the content inside of any HTML tag that has a certain class e.g.
$class = "blah";
$content = "new content";
$html = '<div class="blah">hello world</div>';
// code to replace, $html now looks like:
// <div class="blah">new content</div>
Bare in mind that:
It wont necessarily be a div, it could be <h2 class="blah">
The class can have more than one class and still needs to be replaced e.g. <div class="foo blah green">hello world</div>
I am thinking regular expressions should be able to do this, if not I am open to other suggestions such as using the DOM class (although I would rather avoid this if possible because it has to be PHP4 compatible).
Do not use regular expressions to parse HTML. You can use the built in DOMDocument, or something like simple_html_dom:
require_once("simple_html_dom.php");
$class = "blah";
$content = "new content";
$html = '<div class="blah">hello world</div>';
$doc = new simple_html_dom();
$doc->load($html);
foreach ( $doc->find("." . $class) as $node ) {
$node->innertext = $content;
}
Sorry, I didn't see the PHP4 requirement. Here's a solution using the standard DOMDocument as mentioned above.
function DOM_getElementByClassName($referenceNode, $className, $index=false) {
$className = strtolower($className);
$response = array();
foreach ( $referenceNode->getElementsByTagName("*") as $node ) {
$nodeClass = strtolower($node->getAttribute("class"));
if (
$nodeClass == $className ||
preg_match("/\b" . $className . "\b/", $nodeClass)
) {
$response[] = $node;
}
}
if ( $index !== false ) {
return isset($response[$index]) ? $response[$index] : false;
}
return $response;
}
$doc = new DOMDocument();
$doc->loadHTML($html);
foreach ( DOM_getElementByClassName($doc, $class) as $node ) {
$node->nodeValue = $content;
}
echo $doc->saveHTML();
If you are sure that $html is valid HTML code, you could use a HTML parser or even XML parser if it's valid XML code.
But the quick and dirty way in Regex would be something like:
$html = preg_replace('/(<[^>]+ class="[^>]*' . $class . '[^"]*"[^>]*>)[^<]+(<\/[^>]+>)/siU', '$1' . $content . '$2', $html);
Didn't test it too much, but it should work. Tell me if you find cases where it doesn't. ;)
Edit: Added "and dirty"... ;)
Edit 2: New version of the RegEx:
<?php
$class = "blah";
$content = "new content";
$html = '<div class="blah test"><h1><span>hello</span> world</h1></div><div class="other">other content</div><h2 class="blah">remove this</h2>';
$html = preg_replace('/<([\w]+)(\s[^>]*class="[^"]*' . $class . '[^"]*"[^>]*>).+(<\/\\1>)/siU', '<$1$2' . $content . '$3', $html);
echo $html;
?>
The last problem left is if theres a class that only has "blah" in its name, like "tooMuchBlahNow". Let's see how we can address that. Btw: Is it obvious already that I love playing with RegEx? ;)
There is no need to use the DOM class, this would probably be done quickest using jQuery, as Khnle said, or you could use the preg_replace() function. Give me some time, I may write a quick regex for you.
But I would recommend using something like jQuery, this way you can serve the page up to the user quickly and allow their computer to do the processing instead of your server.

Categories