Exempting pdf, doc, and xls from screen grab utility - php

I'm using the following code and an open service provided by wordpress to grab a screenshot thumbnail of a number of webpages on the fly
<img alt="<?php the_title(); ?>" src="http://s.wordpress.com/mshots/v1/<?php echo urlencode( get_post_meta(get_the_ID(), 'mjwlink-url', true )); ?>?w=300">
Problem is some of the links go to PDF, DOC or XLS files, in those cases I'd like to display a single alternative image.
I have absolutely no idea how to go about using the url in this way + given the fact I'm using urlencode I'm not sure it's even possible - any tips/advice/code appreciated.
Example outputs:
http://s.wordpress.com/mshots/v1/http%3A%2F%2Fwww.reform.co.uk%2Fportals%2F0%2Fdocuments%2Fitcanbedonesingle.pdf?w=300
http://s.wordpress.com/mshots/v1/http%3A%2F%2Fwww.outoftrouble.org.uk%2F?w=300

The thing to do would be to check the file type, even by simply checking what comes after the dot.
You can check this before your statement like this:
$types = array('.pdf', '.doc', '.xls');
if(0 < count(array_intersect(array_map('strtolower', $filename, $types)))) {
//go get the image
} else {
//do whatever else you want to
}
where $types can include any types that you want to process differently, and $filename is the name of the file, obviously.
Taken from here, but slightly modified in your case.

$types = array('pdf', 'doc', 'xls');
$path_parts = pathinfo($filename);
if(!in_array($path_parts['extension'], $types)) {
//go get the image
} else {
//do whatever else you want to
}

Related

Rotate an image on same page

I want to rotate an uploaded and retrieved image from one location. Yes i am almost done. But the problem is, due to header("content-type: image/jpeg") the page redirected to another/or image format. I want to display it in same page as original image in. Here my code..
$imgnames="upload/".$_SESSION["img"];
header("content-type: image/jpeg");
$source=imagecreatefromjpeg($imgnames);
$rotate=imagerotate($source,$degree,0);
imagejpeg($rotate);
i also did with css property.
echo "<img src='$imgnames' style='image-orientation:".$degree."deg;' />";
But anyway my task is to done only with php. Please guide me, or give any reference you have
thanks advance.
<?php
// Okay, so in your upload page
$imgName = "upload/".$_SESSION["img"];
$source=imagecreatefromjpeg($imgName);
$rotate=imagerotate($source, $degree,0);
// you generate a PHP uniqid,
$uniqid = uniqid();
// and use it to store the image
$rotImage = "upload/".$uniqid.".jpg";
// using imagejpeg to save to a file;
imagejpeg($rotate, $rotImage, $quality = 75);
// then just output a html containing ` <img src="UniqueId.000.jpg" />`
// and another img tag with the other file.
print <<<IMAGES
<img src="$imgName" />
<img src="$rotName" />
IMAGES;
// The browser will do the rest.
?>
UPDATE
Actually, while uniqid() usually works, we want to use uniqid() to create a file. That's a specialized usage for which there exists a better function, tempnam().
Yet, tempnam() does not allow a custom extension to be specified, and many browsers would balk at downloading a JPEG file called "foo" instead of "foo.jpg".
To be more sure that there will not be two identical unique names we can use
$uniqid = uniqid('', true);
adding the "true" parameter to have a longer name with more entropy.
Otherwise we need a more flexible function that will check if a unique name already exists and, if so, generate another: instead of
$uniqid = uniqid();
$rotImage = "upload/".$uniqid.".jpg";
we use
$rotImage = uniqueFile("upload/*.jpg");
where uniqueFile() is
function uniqueFile($template, $more = false) {
for ($retries = 0; $retries < 3; $retries++) {
$testfile = preg_replace_callback(
'#\\*#', // replace asterisks
function() use($more) {
return uniqid('', $more); // with unique strings
},
$template // throughout the template
);
if (file_exists($testfile)) {
continue;
}
// We don't want to return a filename if it has few chances of being usable
if (!is_writeable($dir = dirname($testfile))) {
trigger_error("Cannot create unique files in {$dir}", E_USER_ERROR);
}
return $testfile;
}
// If it doesn't work after three retries, something is seriously broken.
trigger_error("Cannot create unique file {$template}", E_USER_ERROR);
}
You need to generate the image separately - something like <img src="path/to/image.php?id=123">. Trying to use it as a variable like that isn't going to work.

How to handle php generated images (without extension)?

Is it possible to work with following kind of image urls?
http://product-images.barneys.com/is/image/Barneys/503230930_product_1
Currently I'm using following code to determine remote image formats. But I don't know how to handle the above mentioned example. Thats one example. Normally they do it for dynamic image resizing.
if($source['extension'] == 'png') {
$type = 'image/png';
}
<?php
$f = tempnam("./", "TMP0");
file_put_contents($f,file_get_contents("http://product-images.barneys.com/is/image/Barneys/503230930_product_1"));
if(getimagesize($f)){
$type = 'image/png';
}
$f file has now the image do whatever you want or delete it using unlink($f);
You could make use of finfo::file extension. You don't need to use cURL for this context.
<?php
$remoteImgTempName = 'someimg';
file_put_contents($remoteImgTempName,file_get_contents('http://product-images.barneys.com/is/image/Barneys/503230930_product_1'));
echo finfo_file(finfo_open(FILEINFO_MIME_TYPE), $remoteImgTempName);
OUTPUT :
image/jpeg

Check if file exists before displaying in Magento PHP?

I am able to get the web path to the file like so:
$filename = 'elephant.jpg';
$path_to_file = $this->getSkinUrl('manufacturertab');
$full_path = $path_to_file . '/' . $filename;
But if the file doesn't exist, then I end up with a broken image link.
I tried this:
if(!file_exists($full_path)) {
Mage::log('File doesn\'t exist.');
} else {
?><img src="<?php echo $full_path ?>" /><?php
}
Of course that didn't work because file_exists does not work on urls.
How do I solve this?
1.)
Can I translate between system paths and web urls in Magento?
e.g. something like (pseudocode):
$system_path = $this->getSystemPath('manufacturertab');
That looks symmetrical and portable.
or
2.)
Is there some PHP or Magento function for checking remote resource existence? But that seems a waste, since the resource is really local. It would be stupid for PHP to use an http method to check a local file, wouldn't it be?
Solution I am currently using:
$system_path = Mage::getBaseDir('skin') . '/frontend/default/mytheme/manufacturertab'; // portable, but not pretty
$file_path = $system_path . '/' . $filename;
I then check if file_exists and if it does, I display the img. But I don't like the asymmetry between having to hard-code part of the path for the system path, and using a method for the url path. It would be nice to have a method for both.
Function
$localPath = Mage::getSingleton( 'core/design_package' )->getFilename( 'manufacturertab/' . $filename, array( '_type' => 'skin', '_default' => false ) );
will return the same path as
$urlPath = $this->getSkinUrl( 'manufacturertab/' . $filename );
but on your local file system. You can omit the '_default' => false parameter and it will stil work (I left it there just because getSkinUrl also sets it internaly).
Note that the parameter for getSkinUrl and getFilename can be either a file or a directory but you should always use the entire path (with file name) so that the fallback mechanism will work correctly.
Consider the situation
skin/default/default/manufacturertab/a.jpg
skin/yourtheme/default/manufacturertab/b.jpg
In this case the call to getSkinUrl or getFilename would return the path to a.jpg and b.jpg in both cases if file name is provided as a parameter but for your case where you only set the folder name it would return skin/yourtheme/default/manufacturertab/ for both cases and when you would attach the file name and check for a.jpg the check would fail. That's why you shold always provide the entire path as the parameter.
You will still have to use your own function to check if the file exists as getFilename function returns default path if file doesn't exist (returns skin/default/default/manufacturertab/foo.jpg if manufacturertab/foo.jpg doesn't exist).
it help me:
$url = getimagesize($imagepath); //print_r($url); returns an array
if (!is_array($url))
{
//if file does not exists
$imagepath=Mage::getDesign()->getSkinUrl('default path to image');
}
$fileUrl = $this->getSkinUrl('images/elephant.jpg');
$filePath = str_replace( Mage::getBaseUrl(), Mage::getBaseDir() . '/', $fileUrl);
if (file_exists($filePath)) {
// display image ($fileUrl)
}
you can use
$thumb_image = file_get_contents($full_path) //if full path is url
//then check for empty
if (#$http_response_header == NULL) {
// run check
}
you can also use curl or try this link http://junal.wordpress.com/2008/07/22/checking-if-an-image-url-exist/
Mage::getBaseDir() is what you're asking for. For your scenario, getSkinBaseDir() will perform a better job.
$filename = 'elephant.jpg';
$full_path = Mage::getDesign()->getSkinBaseDir().'/manufacturertab/'.$filename;
$full_URL=$this->getSkinUrl('manufacturertab/').$filename;
if(!is_file($full_path)) {
Mage::log('File doesn\'t exist.');
} else {
?><img src="<?php echo $full_URL ?>" /><?php
}
Note that for the <img src> you'll need the URL, not the system path. ...
is_file(), rather than file_exists(), in this case, might be a good option if you're sure you're checking a file, not a dir.
You could use the following:
$file = 'http://mysite.co.za/files/image.jpg';
$file_exists = (#fopen($file, "r")) ? true : false;
Worked for me when trying to check if an image exists on the URL

echoing thumbnails that link to the larger image

I have a script that scans a directory of thumbnails and echoes them to the page. It works nicely, but the thumbnails are not clickable, and i would really like this to be the case. echo "<img src='$thumbnail' class='resizesmall'>"; is the line where the thumbnails are echoed. I'm not sure how to write the path to the larger image inside the php without breaking it. Maybe this should be done inside the foreach statement? thanks for your help?
$dir = "../mysite/thumbnails/";
$dh = opendir($dir);
// echo "$dh";
$gallery = array();
while($filename = readdir($dh))
{
$filepath = $dir.$filename;
//pregmatch used to be ereg
if (is_file($filepath) and preg_match("/\.png/",$filename))
{
$gallery[] = $filepath;
}
}
sort($gallery);
foreach($gallery as $thumbnail)
{
echo "<img src='$thumbnail' class='resizesmall'>";
}
?>
</div>
<??>
The easiest way would be to setup a situation where your thumbs and your full size images were named the same. So you may have thumbs/image1.png and full/image1.png. Then instead of using $thumbnail use a variable $image, or something similar just so the code reads better. You'll also want to leave the $filepath out of the mix so that $image ends up as just the file name.
foreach($gallery as $image)
{
echo "<a href='full/$image'><img src='thumb/$image' class='resizesmall'></a>";
}
You may want to throw in some checks to make sure there is a matching image just to prevent errors or bad UX. However, the code above should work.

Check if the image is a JPEG

I need to check whether a given image is a JPEG.
if ($_FILES["fname"]["error"] > 0) {
$imgData = "hyperlink/holder.jpg";
} else {
$imgData ="hyperlink/" . $_FILES["fname"]["name"];
}
// Only accept jpg images
// pjpeg is for Internet Explorer should be jpeg
if (!($_FILES["fname"]["type"] == "image/pjpeg") ) {
print "I only accept jpg files!";
exit(0);
}
When it goes to first statement in the first if statement it always gives I only accept jpg files!
How can I fix it?
Try the exif_imagetype image function.
Example:
if(exif_imagetype($filepath) != IMAGETYPE_JPEG){
echo 'Not a JPEG image';
}
PHP has such good image-type support, i wonder why you are restricting your app. In just a couple lines of code you can deal with any input format and convert to jpeg, if that is a requirement...
$im = imagecreatefrompng(input_filename)
imagejpeg($im, output_filename);
I believe the following works:
Also note that:
(exif_imagetype($ImagePathAndName) == IMAGETYPE_JPEG)
only reads the first few bytes looking for an image header so isn't really good enough to confirm if an image is corrupt.
Below I have it in a logical “and” statement i.e. both of these tests must be passed in order for the image to qualify as being valid and non-corrupt etc:
if ((exif_imagetype($ImagePathAndName) == IMAGETYPE_JPEG) && (imagecreatefromjpeg( $ImagePathAndName ) !== false ))
{
echo 'The picture is a valid jpg<br>';
}
Note: You need to place this line of code at the top of the php code in order to avoid seeing the warning messages from imagecreatefromjpeg( $ImagePathAndName ) when it encounters a fake/corrupt image file.
ini_set(‘gd.jpeg_ignore_warning’, 1);
Why don't you try creating an array of exceptions (the files you want the user to be able to upload).
// Hyperlink for your website
$hyperlink = "http://www.yourwebsitehere.com";
if($_FILES['fname']['error'] > 0)
{
$image= $hyperlink . "/holder.jpg";
}
else
{
$image = $hyperlink . "/" . $_FILES['fname']['name'];
}
// Only accept files of jpeg format
$exceptions = array("image/jpg", "image/jpeg", "image/pjpeg");
foreach($exceptions as $value)
{
if($_FILES['fname']['type'] != $value)
{
echo "I only accept jpeg images!";
break; // Or exit();
}
}
When using $_FILES, you are relying on informations sent by the client, which is not the best thing to do (you've seen it's not always the same, and, if I remember correctly, $_FILES['...']['type'] can be faked).
If you are using PHP >= 5.3 (or can install PECL packages), maybe you can give a look to the extension Fileinfo. If you are using an older version, what about mime_content_type?
And, as said by Scott, why allow only jpeg?
Looking about the code better : when you are in the first case (error > 0), you are assigning a default file to $imgData? Why the spaces around "hyperlink"?
And why do you always use to check the content-type, even if there was an error a couple of lines before?
To finish, did you have a look at the manual (Handling file uploads)?
Check the mime (Multipurpose Internet Mail Extensions) type of file with this code. And verify your desired type. You can also detect png,gif with this code.
if($_FILES["fname"]["type"] == "image/jpeg")
{
echo "File type is JPEG";
}

Categories