I am getting errors when I tried to include image in dompdf. I am using version 1.2.1
I tried with base4 encoded image as well from one of the solutions mentioned in forums, that also not working.
<?php
namespace Dompdf;
require_once 'dompdf/autoload.inc.php';
$_dompdf_show_warnings = true;
$_dompdf_warnings = [];
$path="http://localhost/dompdf/assets/images/logo.png";
$data = file_get_contents($path);
$image = 'data:image/' . $type . ';base64,' . base64_encode($data);
$htmldata = '<!DOCTYPE html>
<html>
<head>
<title>Results</title>
<style>
body {
background-color: lightblue;
}
.container {
width: 90%;
max-width: 600px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<h1>test pdf</h1>
<img src="/assets/images/logo.png" alt="image">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer egestas elementum justo, eget maximus odio ultricies eu. Aenean faucibus varius massa, sit amet sagittis neque vulputate luctus.</p>
<img src="'.$image.'" alt="base64">
</div>
</body>
</html>';
$options = new Options();
$options->getChroot($_SERVER['DOCUMENT_ROOT']."/dompdf/");;
$options->setisRemoteEnabled(true);
$options->setIsHtml5ParserEnabled(true);
$dompdf = new Dompdf($options);
$dompdf->loadHtml($htmldata);
$dompdf->render();
$dompdf->stream("",array("Attachment" => false));
exit(0);
?>
Getting these errors, first is when I include the image path and second for base64 encoded one. I tried to enable remote, added chroot path and tried several solutions found on internet. Nothing helped.
Permission denied on /assets/images/logo.png. The file could not be found under the paths specified by Options::chroot. /assets/images/logo.png
Unable to create temporary image in /var/folders/bc/tnbzrzvd1k370wftgbm5lnqh0000gn/T data:image/;base64,iVBORw0KGgoAAAANSUhEUgA
EDIT:
Tried with file_exists() from the same directory and it works.
Can anyone suggest a solution for this?
Related
Capture the image in the background and save it in a folder in PHP.
I have created a PHP page in which we capture the image of an HTML using html2canvas() and via ajax save that image in a folder.
When I run the code from the browser it shows an HTML and saves the image in a given folder. (Here it is working fine).
The issue is when I run the same file using cmd like via PHP cmd or via CRON (php test.php) then that is not generating an image just render HTML in the terminal.
How I run the same code in the background and save in the generated image in a folder?
test.php
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<button type="button" id="capture">Capture & Save</button>
<div class="parent-wrapper">
<div class="wrapper-box" id="canvas" width="1080" height="1080">
<div class="heading">
Lorem Ipsum
</div>
<div class="sub-heading">
Lorem ipsum , Lorem
</div>
<div class="paragraph">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="bottom-heading">
#Lorem
</div>
</div>
</div>
<script type="text/javascript">
function truncate(source, size) {
return source.length > size ? source.slice(0, size - 1) + "..." : source;
}
var para = document.querySelector('.paragraph');
var res = truncate(para.innerHTML, 280);
para.innerHTML = res;
</script>
<script src="jquery-3.5.1.min.js"></script>
<script src="html2canvas.min.js"></script>
<script type="text/javascript">
$(function(){
$('.movable_div').on('contextmenu', function(){
return false;
});
$('#capture').click(function(){
div_content = document.querySelector("#canvas");
html2canvas(div_content, {
dpi: 96,
width: 1080,
height: 1080,
}).then(canvas => {
data = canvas.toDataURL('image/jpeg', 1);
save_img(data);
});
});
// Onload Click capture
$('#capture').click();
});
//to save the canvas image
function save_img(data){
//ajax method.
$.post('save_jpg1.php', {data: data}, function(res){
});
}
</script>
</body>
</html>
save_jpg1.php
<?php
//just a random name for the image file
$random = rand(100, 1000);
$savefile = #file_put_contents("output/$random.jpg", base64_decode(explode(",", $_POST['data'])[1]));
//if the file saved properly, print the file name
if($savefile){
echo $random;
}
?>
Thanks in advance.
Tried below code also but not work for me:
setTimeout(function(){
div_content = document.querySelector("#canvas");
html2canvas(div_content, {
dpi: 96,
width: 1080,
height: 1080,
}).then(canvas => {
data = canvas.toDataURL('image/jpeg', 1);
save_img(data);
});
}, 5000);
You can achieve this by using below library.
Source: https://github.com/stil/gd-text
Wrote the script in PHP and run via terminal to create image in background.
The terminal doesn't know how to render an html file like a browser does - the terminal will simply output the html as a text file. I think there may be a way to programmatically trigger such a rendering, and you could update the javascript to trigger the html2canvas when the page loads rather than after a click. In that way, you could trigger it from the command line, it would render, and fire the save function with the image.
Looks like this might have some ideas for how to run an html file from the terminal:
How can I run a html file from terminal?
Specifically, you may want to try serving the html file locally, and triggering a browser view
A client of mine wants a "project of the month" feature on his Wordpress site. But with a archive page.
My idea was to create a custom post type and call it projects. In here the client can manage projects and make new ones.
With this piece of code i can take the content from the latest project post, and put that content on the main "project of the month" page, while all the past projects are on the archive page.
$latest_cpt = get_posts("post_type=projects&numberposts=1");
$my_postid = $latest_cpt[0]->ID; //This is page id or post id
$content_post = get_post($my_postid);
$content = $content_post->post_content;
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
echo $content;
This works ... but not really.
The project pages are build using visual composer. And some of the elements have background colors or padding. Visual composer gives these elements unique classes like
.vc_custom_1516702624245
And adds the custom style tag when the page loads. Something like this
<style type="text/css" data-type="vc_shortcodes-custom-css">
.vc_custom_1516711125312 {
padding-top: 75px !important;
padding-bottom: 75px !important;
background-color: #f3f5f6 !important;
}
.vc_custom_1516702624245 {
background-color: #f3f5f6 !important;
}
.vc_custom_1516711013808 {
margin-top: -106px !important;
}
.vc_custom_1516702490896 {
padding-left: 50px !important;
}
.vc_custom_1516703325534 {
margin-top: -15px !important;
}
.vc_custom_1516702744160 {
background-position: center !important;
background-repeat: no-repeat !important;
background-size: cover !important;
}
.vc_custom_1516702987431 {
padding-right: 65px !important;
}
.vc_custom_1516709810401 {
border-radius: 3px !important;
}
</style>
The problem with my approach is that visual composer does not create the style tag for the post content that is being loaded.
So therefore a lot of minor styling details are lost.
Image: Page content on archive page (how it should look)
Image: Page content on "project of the month" page
TL:DR visual composer style not generating post_content
You can use part of the addShortcodesCustomCss function of Vc_base:
$shortcodes_custom_css = get_post_meta( $id, '_wpb_shortcodes_custom_css', true );
if ( ! empty( $shortcodes_custom_css ) ) {
$shortcodes_custom_css = strip_tags( $shortcodes_custom_css );
echo '<style type="text/css" data-type="vc_shortcodes-custom-css">';
echo $shortcodes_custom_css;
echo '</style>';
}
replacing $id with yours $my_postid and, if needed, the echo with $content .=
Heres a function combining what i've seen across various stack overflow topics.
If you are using WPBakery for a page builder and want to use the WP_JSON api to serve your content to the frontend such as Angular or React you need to do a few things.
Tell wordpress to render the WP Bakery shortodes into actual HTML
Tell wordpress to include the dynamically generated css classes in the API response.
To do this I simply did the following:
add_action( 'rest_api_init', function ()
{
register_rest_field(
'page',
'content',
array(
'get_callback' => 'compasshb_do_shortcodes',
'update_callback' => null,
'schema' => null,
)
);
});
function compasshb_do_shortcodes( $object, $field_name, $request )
{
WPBMap::addAllMappedShortcodes(); // This does all the work
global $post;
$post = get_post ($object['id']);
$output['rendered'] = apply_filters( 'the_content', $post->post_content );
$output['css'] = '';
$shortcodes_custom_css = get_post_meta( $object['id'], '_wpb_shortcodes_custom_css', true );
if ( ! empty( $shortcodes_custom_css ) ) {
$shortcodes_custom_css = strip_tags( $shortcodes_custom_css );
$output['css'] .= $shortcodes_custom_css;
}
return $output;
}
This basically returns the following:
"content": {
"rendered": "<div class=\"row\"><div class=\"col-sm-12\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div></div><div class=\"row\"><div class=\"col-sm-6\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div><div class=\"col-sm-6\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div></div><div class=\"row\"><div class=\"col-sm-4\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div><div class=\"col-sm-4 vc_col-has-fill\"><div class=\"vc_column-inner vc_custom_1631795792357\"><div class=\"wpb_wrapper\"><h2 style=\"text-align: left;font-family:Abril Fatface;font-weight:400;font-style:normal\" class=\"vc_custom_heading\" >This is custom heading element</h2>\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div><div class=\"col-sm-4\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"></div></div></div></div><div class=\"row\"><div class=\"col-sm-12\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><div style='color:#FF0000;' data-foo='something'></div></div></div></div></div>\n",
"css": ".vc_custom_1631795792357{background-color: #afafaf !important;}"
},
You can then use the html on your frontend for example using angular by creating a dynamic route that feeds the slug in as a parameter, then simply connect a resolver service to it to hit the api for that page, if it's found, render the page, if not redirect to a 404.
The css can then be added in on component load by appending to the head.
And hey presto, you get WpBakery powered Angular.
Also for SEO, you can use SSR and WP Yoast to control and append meta tags from the WP Admin.
Any questions or improvement suggestions let me know.
function usp_modify_post_type($post_type) {
return 'post,footer,header,page,product,'; // Edit post type as needed
}
add_filter('usp_post_type', 'usp_modify_post_type');
Im busy with an school command, and i need to play display and text on a page when you have fill in 2 forms on 2 different pages.
First page is kies_merk.html where you have to choose the merk (brand)
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8" />
<title>Kies merk</title>
</head>
<body>
<h3>Auto selectie (Deel 1 van 3)</h3>
<p>Kies een automerk...</p>
<form name="form" action="kies_type.php" method="get">
<select name="merk">
<option value="Volvo">Volvo</option>
<option value="Peugeot">Peugeot</option>
<option value="Volkswagen">Volkswagen</option>
<option value="Opel">Opel</option>
</select>
<input type="submit" value="ok"/>
</form>
</body>
</html>
Second page is where you have to choose the type of the car:
<?php
$formulier = '<p>Welk type wil je bekijken?</p><form name="form2" action="type_informatie.php" method="get"><select name="type"><option value="S40">S40</option><option value="S60">S60</option><option value="C70">C70</option><option value="S80">S80</option></select><input type="hidden" name="Merk" value="Volvo"><input type="submit" value="ok"/></form>'
?>
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8" />
<title>Kies merk</title>
</head>
<body>
<h3>Auto selectie (Deel 2 van 3)</h3>
<p>Kies een type...</p>
<?php
$merk = ($_GET['merk']);
if ($merk === Volvo) {
echo $formulier;
} else {
echo "<p>Dit merk zit helaas nog niet in het 'systeem'...</p><a href='kies_merk.html'>Maak een andere keuze a.u.b</a>";
}
?>
</body>
</html>
On the third page is the output, but there it goes wrong. It doesnt show the image, it only takes the first number out of the array. If i go to my browser to the image URL, it says for e.g. /S (not even .png extension). I think it goes wrong at the $type = $_GET['type'] part, but i dont know for sure. I hope someone can help me.
type_informatie.php:
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8" />
<title>Kies merk</title>
<style>
img {
height: 200px;
width: auto;
}
</style>
</head>
<body>
<h3>Auto selectie (Deel 3 van 3)</h3>
<p>Je koos de volgende auto: <?php echo ($_GET['Merk']) . " " . ($_GET['type']) ?> </p>
<?php
$S40 = array('/S40.png', 'De S40: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut malesuada tincidunt est ut faucibus.');
$S60 = array('/S60.png', 'De S60: Fusce eget quam in purus interdum tincidunt ultricies sit amet velit. Nulla pulvinar cursus malesuada.');
$C70 = array('/C70.png', 'De C70: Aenean aliquam varius eros. Nam dictum, lorem a maximus gravida, odio risus pretium mi, vel convallis neque dui eget nisl. Quisque vestibulum vel lacus id congue.');
$S80 = array('/S80.png', 'De S80: Nullam rutrum metus nec iaculis facilisis. Maecenas vitae hendrerit orci. Nulla sit amet dolor risus. Fusce accumsan augue nec leo congue, nec porta tellus semper.');
$type = $_GET['type'];
echo "<div>" . "<img src='$type[0]' alt='' />" . "</div>";
echo "<p>$type[1]</p>"
?>
</body>
</html>
$type = $_GET['type']; is going to hold the value of the selected option in your select named type
<select name="type"><option value="S40">
$type[0] is an array reference in <img src='$type[0]' alt='' /> which is referencing the first character in the string, which happens to be S from S40
so you need to echo the whole thing, and probably add the .png extension since that's not in your form.
echo "<div>" . "<img src='$type.png' alt='' />" . "</div>";
if you look at your error logs, then you might also notice a notice
Notice: Use of undefined constant Volvo - assumed 'Volvo' in thispage.php on line 6,000,042
You should clean up that assumption by explicitly changing if ($merk === Volvo) which uses a constant, to if ($merk === 'Volvo') which uses a string.
I am trying to create a paragraph and next to that paragraph are images that are generated randomly from a database table. The main container is called ".container" and this includes every element. .container is set to width: 90%. The paragraph (.header) floats to the left and has a width of 70%. The generated images (.recommend) floats to the right and has a width of 30%. Everything works out fine, but the only problem is that when I set the images to take up the whole space of the .recommend div (width: 100%), but it doesn't do that. Instead, the width of the images are 30%. How do I make the images take up the whole space of the .recommend div?
<!DOCTYPE html>
<html>
<head><link type="text/css" rel="stylesheet" href="/science/template.css"></head>
<body>
<div class="container">
<div class="header">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="recommend">
<?php
$numArray = array();
for ($i = 1; $i <=10; $i++)
{
$numArray[$i] = $i;
}
shuffle($numArray);
$resultSet = $db->query("SELECT * FROM table");
if ($resultSet->num_rows != 0)
{
while ($rows = $resultSet->fetch_assoc())
{
$id = $rows["id"];
$image1 = $rows["image1"];
$image2 = $rows["image2"];
$image3 = $rows["image3"];
$title = $rows["title"];
$title2 = $rows["title2"];
$title3 = $rows["title3"];
echo "<div class=row>";
if ($id == $numArray[0])
{
echo "<div class=col-md-4 id=left><img src=$image1><p>$title</p></div>";
}
if ($id == $numArray[1])
{
echo "<div class=col-md-4 id=left><img src=$image1><p>$title</p></div>";
}
if ($id == $numArray[2])
{
echo "<div class=col-md-4 id=left><img src=$image1><p>$title</p></div>";
}
echo "</div>";
}
}
?>
</div>
</div>
</body>
</html>
CSS
.container{
background--color: green;
width: 90%;
height: auto;
}
.header{
background-color: blue;
float: left;
width: 70%;
}
.recommend{
background-color: red;
width: 30%;
float: right;
}
.recommend img{
width: 100%;
}
It would be FAR more useful to see the rendered HTML than the PHP that generates the html.
The image is taking the full width of the containing div - which is set to 30% width. This markup: <div class=col-md-4 id=left> is using a Bootstrap grid class. And, col-md-4 tells the div to be 4/12 (or 30%) of the width of the parent. Since the parent is .recommend, then the div is 30%, and the image inside is 100% of THAT (which means it is 30% of the .recommend div)
So, you can either remove the col-md-4 class from the divs, or you can try and resolve it another way.
According to the CSS provided .recommend div is set to width:30%
All the child elements that have width:100% (images) will only take up as much space as .recommend div, which is 30%
I have a really small webpage written in php (approx. 5 pages + blog entries). All pages are located in php files on the server side (no database is used). So far I managed to search inside my 'blog entries' - because these are just plain textfiles with HTML markup (I strip the tags & performing a search operation):
$file_name=array();
$search_string="";
if(isSet($_GET["query"])){
$search_string=$_GET["query"];
}
$search_result="";
$files="";
$phpfilename="";
$i=0;
if (!$search_string){
echo 'No query entered<br />';
}else{
if ($handle = opendir('content/')) {
while (false !== ($file = readdir($handle))){
if(strrchr($file, '.') === ".txt"){
$filename[]= $file;
}
}
closedir($handle);
}
foreach($filename as $value){
$files="content/$value";
$fp = strip_tags(file_get_contents($files));
if(stripos($fp, $search_string)) {
$search_result.=preg_replace('/<[^>]*>[^<]*<[^>]*>/', '', substr($fp,0,255)); // append a preview to search results
}
if($search_result!=""){
echo $search_result;
}else{
echo "No Results<br />";
}
}
}
Of course that works just because the files are plain text. But I've got also pages that are real 'php' files and want to perform a search operation on them too. But I don't want to search inside the 'php code' of course. I figured out, that I would need the preparsed files that the browser gets from the webserver - I thought about using file_get_contents() with http requests to all my pages (ok, 'just' about 5 pages but still)...
I've read here on SO that it's considered bad practice to do so and it feels like I'm taking the wrong approach.
Any ideas & suggestions would be highly appreciated.
Edit: A example for a regular page that I want to be able to search in
index.php
<?php ob_start(); require_once("./include/common.php"); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?php echo $lang['WEBSITE_TITLE']; ?></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="keywords" content="keyword, keyword, keyword" />
<link href="css/main.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div id="page">
<!-- Header Area -->
<?php include("./include/header.php"); ?>
<?php include("./include/banner.php"); ?>
<div id="content">
<?php
$page = '';
if(isSet($_GET["page"])){
$page=$_GET["page"];
}
switch($page){
case 'category_1':
include("./include/category_1.php");
break;
case 'about':
include("./include/category_2.php");
break;
case 'contact':
include("./include/contact.php");
break;
default:
include("./include/home.php");
}
?>
<!-- /content --></div>
<!-- /page --></div>
<br />
<br /><br /><br />
<!-- Footer Area -->
<?php include("./include/footer.php"); ob_end_flush(); ?>
</body>
</html>
/include/category_1.php
<?php echo '<h2>'.$lang['NAVI_CAT_1'].'</h2>'; ?>
<div id="entry">
<br/>
<?php echo $lang['CAT_1_TEXT']; ?>
</div>
language file
<?php
$lang = array();
$lang['NAVI_CAT_1'] = 'Category 1';
$lang['CAT_1_TEXT'] = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.';
?>
Why not include into a buffer and then search the buffer's contents?
ob_start();
include ('index.php');
$contents = ob_get_clean();
//the $contents now includes whatever the php file outputs
I actually use this method in production code for all kinds of things, but mainly previewing site-generated emails before users send them. The nice thing is, you can use this on all the files, not just the php files.
this is failed by design.
consider not using plain mixed html sides. try to use xml files or wathever.
the alternative is crawling your own side. take a look at http://symfony.com/doc/current/components/dom_crawler.html