image in OpenTBS not changing - php

I'm trying to show a series of pictures and comments in a document with OpenTBS. The pictures are hosted on a local webserver. The data is in an array.
In the resulting document the text lines are rendered as expected, but the sample image is not changed.
When I copy paste the url location in my browser it shows a picture without problem.
With setting "$NoErr = false;" there is no error message.
What am I doing wrong?
My template:
[imgs; block=begin]
<a sample image>[imgs.url;ope=changepic]
Location: [imgs.url]
Description: [imgs.txt]
[imgs; block=end]
In my PHP code (a.o.):
$imgs = array();
$imgs[] = array('url'=>'http://192.168.0...', 'txt'=>'Sample 1');
$imgs[] = array('url'=>'http://192.168.0...', 'txt'=>'Sample 2');
$OOo->MergeBlock('imgs', $imgs);
$OOo->Show(OPENTBS_DOWNLOAD, 'file.docx');
Update: same problem when I change the url to some public available images on the web.

OpenTBS uses the following 3 functions in order to instert a picture into the current document :
file_exists()
filesize()
file_get_contents()
While the function file_get_contents() usually works for an URL, the tow other functions file_exists() and filesize() return false despite the PHP documentation says they can supports http protocol.
So the behavior you have probably come from file_exists() returning false for you url.
The workaround I suggest is to download the file as a temporary file, then insert it into the document.

Related

How to use FPDI SetSourceFile with a URL that redirects?

I've got a PDF file on my server, and I want to use it as parameter for this function:
$fpdi->setSourceFile()
The problem is that the link used as a source redirects to another URL and I don't know the final URL.
It seems that setSourceFile needs the real PDF filename.
Is there a way to get the final URL, and then pass it as parameter?
I edited your question according to the explanation you gave in the comments. This is not related to a rewrite, it's related to URL redirection.
Solution 1: open a stream manually
I looked at the source code for this specific function and it expects to receive either a filename or a Stream. You could fetch the PDF link manually, process the redirects and pass the final Stream to this function:
$stream = fopen('https://example.com/12/PDF', 'rb', false, stream_context_create());
$fpdi->setSourceFile($stream);
You can tweak the headers and other parameters such as cookies in the stream_context_create function if needed. It's likely that the remote server requires a cookie or something before redirect to the final URL.
Solution 2: download the file
If you pass a link to this function it will recognize it as a String and try to open it as a file. Since you stated that passing a link that doesn't redirect works, your server is allowing the function fopen() to open external links. If that's the case, you could simply use ordinary file functions to download the PDF to a local folder temporarily:
// saves the file locally
file_put_contents('localFile.pdf', file_get_contents('https://example.com/12/PDF'));
// do what you need to do with it
$fpdi->setSourceFile('localFile.pdf');
// deletes the file after using it
unlink('localFile.pdf');

Extract PDF metadata field using PHP

I have a series of PDF files on my shared hosting webserver which I'm writing a PHP script for to catalogue them on the screen. I've added metadata to the PDF files - Document Title, Author and Subject. The filename is composed of the Author and Title so I can construct the catalogue text from that. However, I want to display the contents of the 'Subject' metadata field as well.
Because I'm using shared hosting, I cannot install any extra PHP extensions. They have the free version of PDFLib but this doesn't include any functions to load the PDF file or to extract metadata.
This is the script so far which just displays a list of the filenames...
function catalogue($folder){
$files = preg_grep('/^([^.])/', scandir($folder));
foreach($files as $file){
echo($file.'<br/>');
}
}
So, I've not made much progress :(
I've tried PDF_open_pdi_document() but this is not part of the installed PDFLib extension. I've tried PDF_pcos_get_string() but all I get with...
PDF_pcos_get_string($file,0,'author');
...is...
pdf_pcos_get_string(): supplied resource is not a valid pdf object resource
...and I can find literally ZERO help on the web for this function. Literally nothing!
I am running PHP 7.4 on the shared hosting.
Metadata aren't encrypted like the PDF, so you can use file_get_contents, find the pattern for the subject (<</Subject) and extract it using either a regex or a simple combination of strpos/substr.
Thank you #drdlp. I've used file_get_contents() to load in the PDF and extract and display the metadata.
function catalogue($folder){
$files = preg_grep('/^([^.])/', scandir($folder));
foreach($files as $file){
$page = file_get_contents($file);
$metadata = preg_match_all('/\/[^\(]*\(([^\/\)]*)/',$page,$matches);
$author = $matches[1][0];
$subject = $matches[1][4];
$title = $matches[1][5];
echo($title.'/'.$subject.'/'.$author.'<br>');
}
}
/
However, this is very slow for 40 odd PDF articles in a folder.
How can I speed this up?
I've begun experimenting with pdf.js for which I can load all the basic details from files first (filename etc) and then update them with Javascript after the page has loaded.
However, I clearly don't know enough about Javascript to make this work. This is what I have so far and I am very stuck. I've imported pdf.js from mozilla.github.io/pdf.js/build/pdf.js...
function pdf_metadata(file_url,id){
var pdfjsLib = window['pdfjs-dist/build/pdf'];
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';
var loadingTask = pdfjsLib.getDocument(file_url);
loadingTask.promise.then(function(pdf) {
pdf.getMetadata().then(function(details) {
console.log(details);
document.getElementById(id).innerHTML=details;
}).catch(function(err) {
console.log('Error getting meta data');
console.log(err);
});
});
}
The line console.log(details); outputs an object to the console. From there I have no idea how to extract any data at all. Therefore document.getElementById(id).innerHTML=details; displays nothing.
This is the object which is output to the console.

Programmatically (PHP) save image with no extension

I am trying to save to disk an image that is served to me via a JSON result. The returned JSON result property that I am interested in is this:
https://i.scdn.co/image/6cd03f58ddf30a1393f06d6469973ba16ac908df
Which is the correct image. The problem is that, while the above URL does display the image, it does not allow me to download it, yet I can download it by right-clicking on it.
What I need to be able to do is, using my PHP code, save it to disk.
I have no issues saving results from other sites that give results that link to a direct image extension (.jpg, .gif or .png). But I have not been able to figure out how to programmatically download the image from the above URL.
Is it possible?
This is the code that I use, which works correctly on results that give a URL that has a correct image extension. The URL returned is loaded into the $largeimg variable.
$input = $largeimg;
$output = 'image.jpg';
file_put_contents($output, file_get_contents($input));
How do I achieve this?
file_get_contents() is able to accept raw URI arguments. Your code works perfectly for me, if modified in the way:
$input = 'https://i.scdn.co/image/6cd03f58ddf30a1393f06d6469973ba16ac908df';
So, file_get_contents() can download the image directly. I think, the problem is your $largeimg variable.

PHP: How to output image files?

I would like to add images to a dynamically generated page (I use my own template system) with PHP.
NOTE: I regulate image access for security reason.
The folder that contains the images is above the site root, therefore not accessible by HTML links.
I believe there is a method in which PHP returns a file as a resource, specifying the type in a header, and (correct me if I am wrong) a function specifically designed for that imagejpeg().
Please advise, and if possible write a simple example.
What you need to do to output image files is in order:
PHP loads the image from the file, this is file_get_contents or otherwise fopen to open and access the file itself. If the file is a specific image file you can open the file with imagecreatefromjpeg() which will do just that, generate an image file from a JPEG source.
Then, once the file is loaded from anywhere on your filesystem, including directories outside of your web root, PHP can output the data caught in point 1, above, with some HTTP Headers and direct reference to the loaded image.
NOTE: this means that the sole output of this PHP file is the image,
so file.php === image.jpg in this case.
So a brief example:
image is stored in /home/images/image1.jpg
PHP file runs from /home/site/imagecall.php
PHP file says:
<?php
if (file_exists('/home/images/image1.jpg')){
$image = imagecreatefromjpeg('/home/images/image1.jpg');
if ($image){
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
}
else {
die("Image could not be loaded");
}
}
This is a starting point for you and by no means an absolute guide. Explore.
Useful references:
http://php.net/manual/en/function.imagecreatefromjpeg.php
http://php.net/manual/en/function.file-get-contents.php

Trouble with imagepng

I am struggling with PHP's GD library.
I have written a script called foo.php which outputs a png:
header('Content-type:image/png');
$img = imagecreatefrompng($url) or die('bad url:'.$url);
imagepng($img);
imagedestroy($img);
It works fine. Its purpose is to accept a GET parameter and then spit out the appropriate graph:
(e.g.) foo.php?id=2 puts a nice graph in any browser.
Here's my problem:
In another script (baz.php), I'd like to use readfile or something similar to take the image created by foo.php and have baz.php send it to the browser. But no matter what I try, it won't seem to work when I call baz.php
Example from baz.php:
switch($id) {
case '1':
readfile('foo.php?id=1');
break;
case '2':
readfile('foo.php?id=2');
break;
// and so on...
}
I get an error saying:
failed to open stream: No such file or directory...
If I put in the full url or the path:
readfile('http://localhost/dev/foo.php?id=1');
readfile('C:/xampp/htdocs/dev/foo.php?id=1');
...I get the same error.
If I add the header to baz.php:
header('Content-type:image/png');
readfile($url);
In firefox I get "The image "http://localhost/dev/baz.php" cannot be displayed, because it contains errors. In Chrome it shows a broken image 27.82kb in size with dimensions of 0x0
allow_url_fopen is on, and as I mentioned, foo.php is producing pngs without any problems; I just can't seem to get in out of baz.php, which I need to.
I can, for instance just put:
header("Location: foo.php?id=1");
and it will redirect and output the image, but I don't want to do a 302 redirect, I need baz.php to push the image out to the browser. If I save the file as a static file, it will load that fine as well. It just doesn't seem to want to handle the dynamic file.
Any help is very much appreciated. Thanks in advance.
Figured it out:
Issue #1:
You cannot use php's readfile() to include a png that is generated dynamically by php if it is on the same server.
Why? Because readfile will include the raw php code rather than rendering that php code into an image. If you want to call it from another server, readfile works fine.
So, you can include/require the file instead (so it will be rendered into a png), however...
Issue #2:
You cannot include a file with parameters / query string directly (e.g. the following code will error that it cannot open the file:
include('baz.php?id=1'); //this won't work
Solution:
Set the parameter manually in the GET string (e.g. $_GET['id'] = 1;)
Include the file: include('baz.php');
Also note: Apache's virtual() command will also not work with GET because only QUERY_STRING is passed along ($_GET is copied from the parent script):
PHP.net's description of virtual()
this should work http://theserverpages.com/php/manual/en/function.imagecreatefrompng.php

Categories