Get images from article in Joomla with php - php

I'm trying edit a plugin which I use to add meta open graph tags to the header. The problem with it is that it would only let me choose one picture for the whole site.. this is what I've done:
preg_match_all('/<img .*?(?=src)src=\"([^\"]+)\"/si', $hdog_base, $image);
if (strlen($hdog_base) <= 25)
{
if (substr($image[0], 0, 4) != 'http')
{
$image[0] = JURI::base().$image[0];
}
$hdog_image_tmp = $image[0];
}
else
{
if (substr($image[1], 0, 4) != 'http')
{
$image[1] = JURI::base().$image[1];
}
$hdog_image_tmp = $image[1];
}
$hdog_image = '<meta property="og:image" content="'.$hdog_image_tmp.'" />
';
$hdog_base is the current webpage I'm on.
The first if-statement would show the very first picture, which is the logo (used for ex. homepage), and the else would show the second picture (which would be different on each page), but the result only comes out like this, no matter if I'm on the homepage or anywhere else on the site:
<meta property="og:image" content="http://mysite.com/Array" />
Any suggestions?
Thanks in advance,
Update:
The biggest fault I'm making is that I am trying to find the images in a url, not the actual webpage. But just the link. So how would I go on to get the contents of the current page in a string? Instead of $hdog_base, which is nothing but a link.
UPDATE, SOLVED:
I used
$buffer = JResponse::getBody();
to get the webpage in HTML
and then DOM for the rest
$doc = new DOMDocument();
#$doc->loadHTML($buffer);
$images = $doc->getElementsByTagName('img');
if (strlen($hdog_base) <= 26)
{
$image = $images->item(0)->getAttribute('src');
}
else
{
$image = $images->item(1)->getAttribute('src');
}
if (substr($image, 0, 4) != 'http') $image = JURI::base().$image;
$hdog_image = '<meta property="og:image" content="'.$image.'" />
';
Thanks a lot cpilko for your help! :)

Using preg_match_all with more than one subpattern in the regular expression will return a multidimensional array. In your code $image[n] is an array. If you cast an array as a string in php, as you are doing it returns the text Array.
EDIT: Using a regex to parse HTML isn't ideal. You are better off doing it with DOMDocument:
$doc = new DOMDocument();
#$doc->loadHTML($hdog_base);
$images = $doc->getElementsByTagName('img');
if (strlen($hdog_base) <= 25) {
$image = $images->item(0)->getAttribute('src');
} else {
$image = $images->item(1)->getAttribute('src');
}
if (substr($image[0], 0, 4) != 'http') $image .= JURI::base();
$hdog_image = '<meta property="og:image" content="'.$hdog_image_tmp.'" />
';

Related

Append to start of href tag

I'm looking to turn
Some page to
Some page
using PHP. I'll have the HTML code of a random website so it's not as simple as using str_replace()
I've tried Replacing anchor href value with regex but that seems to just erase my entire page and I get a blank, white screen. Can anyone offer any help?
My code:
$html = file_get_contents(htmlentities($_GET['q'])); // Takes contents of website entered by user
$arr = array(); // Defines array
$html2 = ""; // Defines variable to write to later
$dom = new DOMDocument();
$dom->loadHTML($html); // Loads the HTML code displayed earlier
$domcss = $dom->getElementsByTagName('link');
foreach($domcss as $links) {
if( strtolower($links->getAttribute('rel')) == "stylesheet" ) {
$x = $links->getAttribute('href');
$html2 .= '<link rel="stylesheet" type="text/css" href="'.htmlentities($_GET['q']) . "/" . $x.'">';
}
} // This replaces all stylesheets from "./style.css", to "http://example.com/style.css"
echo $html2 . $html // Echos the entire webpage, with stylesheet links edited
To manipulate this with DOM, find the <a> tags and then if there is a href attribute, add the prefix in. The end of this code just echos out the resultant HTML...
$dom = new DOMDocument();
$dom->loadHTML($html); // Loads the HTML code displayed earlier
$aTags = $dom->getElementsByTagName('a');
$prefix = "http://example.com?q=";
foreach($aTags as $links) {
$href = $links->getAttribute('href');
if( !empty($href)) {
$links->setAttribute("href", $prefix.$href);
}
}
echo $dom->saveHTML();
$prefix contains the bit you want to add the the URL.

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.

PHP Image not showing in HTML using img element

Hello there i have a php file with the included:
The image shows properly when i access the PHP file, however when I try to show it in the HTML template, it shows as the little img with a crack in it, so basically saying "image not found"
<img src="http://konvictgaming.com/status.php?channel=blindsniper47">
is what i'm using to display it in the HTML template, however it just doesn't seem to want to show, I've tried searching with next to no results for my specific issue, although I'm certain I've probably searched the wrong title
adding code from the OP below
$clientId = ''; // Register your application and get a client ID at http://www.twitch.tv/settings?section=applications
$online = 'online.png'; // Set online image here
$offline = 'offline.png'; // Set offline image here
$json_array = json_decode(file_get_contents('https://api.twitch.tv/kraken/streams/'.strtolower($channelName).'?client_id='.$clientId), true);
if ($json_array['stream'] != NULL) {
$channelTitle = $json_array['stream']['channel']['display_name'];
$streamTitle = $json_array['stream']['channel']['status'];
$currentGame = $json_array['stream']['channel']['game'];
echo "<img src='$online' />";
} else {
echo "<img src='$offline' />";
}
The url is not an image, it is a webpage with the following content
<img src='offline.png' alt='Offline' />
Webpages cannot be displayed as images. You will need to edit the page to only transmit the actual image, with the correct http-headers.
You can probably find some help on this by googling for "php dynamic image".
Specify in the HTTP header that it's a PNG (or whatever) image!
(By default they are interpreted as text/html)
in your status.php file, where you output the markup of <img src=... change it to read as follows
$image = file_get_contents("offline.png");
header("Content-Type: image/png");
echo $image;
Which will send an actual image for the request instead of sending markup. markup is not valid src for an img tag.
UPDATE your code modified below.
$clientId = ''; // Register your application and get a client ID at http://www.twitch.tv/settings?section=applications
$online = 'online.png'; // Set online image here
$offline = 'offline.png'; // Set offline image here
$json_array = json_decode(file_get_contents('https://api.twitch.tv/kraken/streams/'.strtolower($channelName).'?client_id='.$clientId), true);
header("Content-Type: image/png");
$image = null;
if ($json_array['stream'] != NULL) {
$channelTitle = $json_array['stream']['channel']['display_name'];
$streamTitle = $json_array['stream']['channel']['status'];
$currentGame = $json_array['stream']['channel']['game'];
$image = file_get_contents($online);
} else {
$image = file_get_contents($offline);
}
echo $image;
I suppose you change the picture dynmaclly on this page.
Easiest way with least changes will just be using an iframe:
<iframe src="http://konvictgaming.com/status.php?channel=blindsniper47"> </iframe>

Why is this foreach failing?

The script I am using 'gets' a html page and parses is showing only the .jpg images within, but I need to make some modifications and when i do it simply fails...
This works:
include('simple_html_dom.php');
function getUrlAddress() {
$url = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
return $url .'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
$html = file_get_html($url);
foreach($html->find('img[src$=jpg]') as $e)
echo '<img src='.$e->src .'><br>';
However, there are some problems... I only want to show images over a certain size, plus some site do not display full URL in the img tag and so need to try to get around that too... so I have done the following:
include('simple_html_dom.php');
function getUrlAddress() {
$url = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
return $url .'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
$html = file_get_html($url);
foreach($html->find('img[src$=jpg]') as $e)
$image = $e->src;
// check to see if src has domain
if (preg_match("/http/", $e->src)) {
$image = $image;
} else {
$parts = explode("/",$url);
$image = $parts['0']."//".$parts[1].$parts[2].$e->src;
}
$size = getimagesize($image);
echo "<br /><br />size is {$size[0]}";
echo '<img src='.$image.'><br>';
This works, but only returns the first image.
On the example link below there are 5 images, which the first code shows but does not display them as the src is without the leading domain
Example link as mentioned above
Is there a better way to do this? And why does the loop fail?
You seem to be missing a {:
foreach($html->find('img[src$=jpg]') as $e) {
You forgot your brackets:
foreach($html->find('img[src$=jpg]') as $e){
$image = $e->src;
// check to see if src has domain
if (preg_match("/http/", $e->src)) { $image = $image; }
else {
$parts = explode("/",$url);
$image = $parts['0']."//".$parts[1].$parts[2].$e->src;
}
$size = getimagesize($image);
echo "<br /><br />size is {$size[0]}";
echo '<img src='.$image.'><br>';
}

PHP file_get_contents

I'm looking to create a PHP script where, a user will provide a link to a webpage, and it will get the contents of that webpage and based on it's contents, parse the contents.
For example, if a user provides a YouTube link:
http://www.youtube.com/watch?v=xxxxxxxxxxx
Then, it will grab the basic information about that video (thumbnail, embed code?)
Or they might provide a vimeo link:
http://www.vimeo.com/xxxxxx
Or even if they were to provide any link, without a video attached, such as:
http://www.google.com/
And it could grab just the page Title or some meta content.
I'm thinking I'd have to use file_get_contents, but I'm not exactly sure how to use it in this context.
I'm not looking for someone to write the entire code, but perhaps provide me with some tools so that I can accomplish this.
You can use either the curl or the http library. You send a http request, and can use the library to get the information from the http response.
I know this question is quite old, but I'll answer just in case someone hits it looking for the same thing.
Use oEmbed (http://oembed.com/) for YouTube, Vimeo, Wordpress, Slideshare, Hulu, Flickr and many other services. If not in the list or you want to make it more precise, you can use this:
http://simplehtmldom.sourceforge.net/
It's a sort of jQuery for PHP, meaning you can use HTML selectors to get portions of the code (i.e.: all the images, get the contents of a div, return only text (no HTML) contents of a node, etc).
You could do something like this (could be done more elegantly but this is just an example):
require_once("simple_html_dom.php");
function getContent ($item, $contentLength)
{
$raw;
$content = "";
$html;
$images = "";
if (isset ($item->content) && $item->content != "")
{
$raw = $item->content;
$html = str_get_html ($raw);
$content = str_replace("\n", "<BR /><BR />\n\n", trim($html->plaintext));
try
{
foreach($html->find('img') as $image) {
if ($image->width != "1")
{
// Don't include images smaller than 100px height
$include = false;
$height = $image->width;
if ($height != "" && $height >= 100)
{
$include = true;
}
/*else
{
list($width, $height, $type, $attr) = getimagesize($image->src);
if ($height != "" && $height >= 100)
$include = true;
}*/
if ($include == true)
{
$images = $images . '<div class="theImage"><img src="'.$image->src.'" alt="'.$image->alt.'" class="postImage" border="0" /></div>';
}
}
}
}
catch (Exception $e) {
// Do nothing
}
$images = '<div id="images">'.$images.'</div>';
}
else
{
$raw = $item->summary;
$content = str_get_html ($raw)->plaintext;
}
return (substr($content, 0 , $contentLength) . (strlen ($content) > $contentLength ? "..." : "") . $images);
}
file_get_contents() would work in this case assuming that you have allow_fopen_url set to true in your php.ini. What you would do is something like:
$pageContent = #file_get_contents($url);
if ($pageContent) {
preg_match_all('#<embed.*</embed>#', $pageContent, $matches);
$embedStrings = $matches[0];
}
That said, file_get_contents() won't give you much in the way of error handling other receiving the content on success or false on failure. If you would like to have more rich control over the request and access the HTTP response codes, use the curl functions and in particular, curl_get_info, to look at the response codes, mime types, encoding, etc. Once you get the content via either curl or file_get_contents() your code for parsing it to look for the HTML of interest will be the same.
Maybe Thumbshots or Snap already have some of the functionality you want?
I know that's not exactly what you are looking for, but at least for the embedded stuff that might be handy. Also txwikinger already answered your other question. But maybe that helps ypu anyway.

Categories