I'm rendering a PDF in Symfony with dompdf.
allow_url_fopen is deactivated on my server. So I insert every image as base64-encoded.
$imagesPath = "/var/www/project/web/print/img/";
$images = array(
"###FRONTPAGE###" => $imagesPath . "company_frontpage_2016.svg",
"###LOGO###" => $imagesPath . "company_logo.svg"
);
foreach( $images as $image => $imageFile ) {
if ( is_readable( $imageFile ) ) {
$base64String = base64_encode( fread( fopen( $imageFile, "r" ), filesize( $imageFile ) ) );
$html = str_replace( $image, "data:image/svg+xml;base64," . $base64String, $html );
} else {
$html = str_replace( $image, "File nicht lesbar", $html );
}
}
The absolute server path didn't work for me. Does anyone know a better solution for this?
I'm happy that I see the SVG in the PDF now. But they aren't rendered correctly. Any idea why?
Related
I need to integrate a react application inside a wordpress website. I created a custom plugin and a shortcode but the shortcode renders an empty div. It's my first wordpress plugin so I might be missing something.
My plugin directory looks like this:
/public_html/wp-content/plugins/PatSearch
- PatSearch.php
/public_html/wp-content/plugins/PatSearch/includes
- enqueue.php
- shortcode.php
/public_html/wp-content/plugins/PatSearch/widget
- Contains the root of the react application. It has been build and works when I visit the build directory
PatSearch.php
<?php
/**
* #wordpress-plugin
* Plugin Name: Ajout d'un app React pour la recherche
*/
defined( 'ABSPATH' ) or die( 'Direct script access diallowed.' );
define( 'PAT_WIDGET_PATH', plugin_dir_path( __FILE__ ) . '/widget' );
define( 'PAT_ASSET_MANIFEST', PAT_WIDGET_PATH . '/build/asset-manifest.json' );
define( 'PAT_INCLUDES', plugin_dir_path( __FILE__ ) . '/includes' );
require_once( PAT_INCLUDES . '/enqueue.php' );
require_once( PAT_INCLUDES . '/shortcode.php' );
enqueue.php
<?php
// This file enqueues scripts and styles
defined( 'ABSPATH' ) or die( 'Direct script access disallowed.' );
add_action( 'init', function() {
add_filter( 'script_loader_tag', function( $tag, $handle ) {
if ( ! preg_match( '/^pat-/', $handle ) ) { return $tag; }
return str_replace( ' src', ' async defer src', $tag );
}, 10, 2 );
add_action( 'wp_enqueue_scripts', function() {
$asset_manifest = json_decode( file_get_contents( PAT_ASSET_MANIFEST ), true )['files'];
if ( isset( $asset_manifest[ 'main.css' ] ) ) {
wp_enqueue_style( 'pat', get_site_url() . $asset_manifest[ 'main.css' ] );
}
wp_enqueue_script( 'pat-runtime', get_site_url() . $asset_manifest[ 'runtime~main.js' ], array(), null, true );
wp_enqueue_script( 'pat-main', get_site_url() . $asset_manifest[ 'main.js' ], array('pat-runtime'), null, true );
foreach ( $asset_manifest as $key => $value ) {
if ( preg_match( '#static/js/(.*)\.chunk\.js#', $key, $matches ) ) {
if ( $matches && is_array( $matches ) && count( $matches ) === 2 ) {
$name = "pat-" . preg_replace( '/[^A-Za-z0-9_]/', '-', $matches[1] );
wp_enqueue_script( $name, get_site_url() . $value, array( 'pat-main' ), null, true );
}
}
if ( preg_match( '#static/css/(.*)\.chunk\.css#', $key, $matches ) ) {
if ( $matches && is_array( $matches ) && count( $matches ) == 2 ) {
$name = "pat-" . preg_replace( '/[^A-Za-z0-9_]/', '-', $matches[1] );
wp_enqueue_style( $name, get_site_url() . $value, array( 'pat' ), null );
}
}
}
});
});
shortcode.php
<?php
// This file enqueues a shortcode.
defined( 'ABSPATH' ) or die( 'Direct script access disallowed.' );
add_shortcode( 'pat_widget', function( $atts ) {
$default_atts = array();
$args = shortcode_atts( $default_atts, $atts );
return "<div id='pat-root'></div>";
});
I created a page and added the shortcode [pat_widget] saved it and visited the page but the react application located at /wp-content/plugins/PatSearch/widget/build/ was not embed like I thought ... When I look at the source code of the page, I can only see an empty <div id='pat-root'></div>
I found what the problem was. The wordpress side of things was working fine ... I had to modify the React index.js file that was generated in the build.
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
// Commented this line
// ReactDOM.render(<App />, document.getElementById("root"));
// Added this to match my shortcode requirements
const target = document.getElementById('pat-root');
if (target) { ReactDOM.render(<App />, target); }
I have the following lines of code to replace a little content my a static html file:
$ = cheerio.load( fs.readFileSync( path_Url ) );
$('a').each( ( idx , _e ) => {
let guidId = $(_e).attr('href').split('/').pop().split('.')[0],
keyMessage = guidIdsMaper.get(guidId);
keyMessage = ( keyMessage !== undefined ) ? keyMessage : ' ( please enter respective keyMessage ) ';
$(_e)
.attr('href' , '#')
.attr( 'onclick' , `document.location = 'veeva:gotoSlide(${keyMessage}.zip)'` )
});
let inner_content = $.html();
fs.writeFileSync( path_Url , inner_content , 'utf8');
So initially in my html file my anchor looks like this:
<a href="melt://navigatetoitem/RHEU-1218304-0000_html_0002.html">
<div id="item91263" class="pageItem" alt="Rectangle"> </div>
</a>
And as you can see , using the below line of code:
$(_e).attr('href' , '#')
.attr( 'onclick' , `document.location = 'veeva:gotoSlide(${keyMessage}.zip)'` )
But using the replacement code i get a couple of special characters for the single quote ' , so below is the output:
<a href="#" onclick="document.location = 'veeva:gotoSlide(RHEU-1218304-0000_html_0002.zip)'">
<div id="item91263" class="pageItem" alt="Rectangle"> </div>
</a>
So how do i avoid getting this ' and get ' instead ? would it be necessary to use htmlparser2 or something like that , i have tried it and so far have no luck.
You can hack by replace method:
$ = cheerio.load( fs.readFileSync( path_Url ) );
const SPECIAL_CHAR = '_XXX_'; // define you special string
$('a').each( ( idx , _e ) => {
let guidId = $(_e).attr('href').split('/').pop().split('.')[0],
keyMessage = guidIdsMaper.get(guidId);
keyMessage = ( keyMessage !== undefined ) ? keyMessage : ' ( please enter respective keyMessage ) ';
$(_e)
.attr('href' , '#')
.attr( 'onclick' , `document.location =${SPECIAL_CHAR}veeva:gotoSlide(${keyMessage}.zip)${SPECIAL_CHAR}` )
});
let inner_content = $.html().replace(new RegExp(SPECIAL_CHAR, 'g'), `'`); // hack you charactors
fs.writeFileSync( path_Url , inner_content , 'utf8');
In the past few days I was trying to create a search.php template for results that contain my CPT. As long as the search works itself, pagination not. Every link in pagination redirect to 404. I was trying a lot of possibility solutions from Stack, FB and others but with no results. Instead of showing to you my code wich is obviously not working correctly, I thought how great woultd be when someone could paste here a tested by himself a simple search.php template wchich contain CPT in results and with working pagination? Then I could compare with my code and find a solution for this annoying popular issue :)
Thanks!
edit:
If somoeone is curious, this is my current search.php:
<div class="center">
<?php
// Define custom query parameters
$custom_query_args = array(
'post_type' => array('drzewa_formowane', 'pre_bonsai'),
'post_status' => 'publish',
'order' => 'asc',
's' => $s,
'paged' => $paged
);
// Get current page and append to custom query parameters array
$custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
// Instantiate custom query
$custom_query = new WP_Query( $custom_query_args );
// Pagination fix
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $custom_query;
// Output custom query loop
if ( $custom_query->have_posts() ) :
while ( $custom_query->have_posts() ) :
$custom_query->the_post(); ?>
<?php include 'product.php' ?>
<? endwhile;
endif;
// Reset postdata
wp_reset_postdata(); ?>
<nav class="pagination">
<?php
$big = 999999999; // need an unlikely integer
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_next' => true,
'prev_text' => __(' « '),
'next_text' => __(' » '),
'type' => 'plain',
) ); ?>
</nav>
<?php
// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;
?>
</div>
I was also trying with simple
if ( have_posts() ) : while ( have_posts() ) : the_post();
without WP_Query and I was trying include CPT to search results via "pre_get_posts" but then was no results from my CPT...
I have created custom post type called campaign, then I have create custom action button using post_row_actions filter like this.
function hipwee_add_action_button($actions, $post){
if(get_post_type() === 'campaign'){
$actions['export'] = 'Export Result';
}
return $actions;
}
add_filter( 'post_row_actions', 'hipwee_add_action_button', 10, 2 );
as you can see above, I added new action button called "Export Result",
but now, how to add a function to handle the export, is there available wordpress filter to put my custom action handler?
Try this code:
function hipwee_add_action_button($actions, $post){
if(get_post_type() === 'campaign'){
$url = add_query_arg(
array(
'post_id' => $post->ID,
'my_action' => 'custom_export_post',
)
);
$actions['export'] = '<a href="' . esc_url( $url ) . '" target="_blank" >Export Result</a>';
}
return $actions;
}
add_filter( 'post_row_actions', 'hipwee_add_action_button', 10, 2 );
add_action( 'admin_init', 'custom_export_function' );
function custom_export_function(){
if ( isset( $_REQUEST['my_action'] ) &&
'custom_export_post' == $_REQUEST['my_action'] ) {
$data = array(
'hello' => 'world'
);
header('Content-Type: application/json');
header('Content-Disposition: attachment; filename="sample.json"');
echo json_encode($data);
exit;
}
}
What it does:
When Export Result button is clicked, it opens new window with parameter my_action with value custom_export_post. Now another function custom_export_function is hooked to admin_init. This function acts as the main exporter. In the example a sample array is exported to JSON file. You can now customize function as you require.
I have to use wordpress with .html extension, and i am using plugin to make .html extension at end of URL, that is working fine, but my pagination becoming failed, it makes URL as /page-url.html/page/2 that goes on Page not found, how can I enable .html in pagination ?
Thanks in advance.
By the way, i did some work like
add_filter('get_pagenum_link', function($url) {
$html = strrpos( $url, '.html' );
if( $html > 0 ){
$base_link = substr( $url, 0, strrpos( $url, '/page' ) );
$page_number = basename($url);
$new_url = $base_link.'/?iter='.$page_number;
return $new_url;
}
else{
return $url;
}
});
but how can i tell wordpress the page link of pagination should follow this ? i mean active and inactive links of pagination
I have done this task by adding filter for URL of pagination, and it works fine with .html extension. Following is code to run pagination with .html extension.
add_filter('get_pagenum_link', function($url) {
$current_url_arr = explode("?", $_SERVER['REQUEST_URI']);
$current_url = $current_url_arr[0];
$html = strrpos( $url, '.html' );
$page_number = 1;
//$page_number = $_GET['iter'] + 1;
if( $html > 0 ){
$basename = basename($url);
$page_number = substr( $basename, 0, strrpos( $basename , '?') );
$new_url = $current_url.'/?iter='.$page_number;
return $new_url;
}
else{
return $url;
}
});
and on above the query parameter, write the following code
if( $_GET['iter'] > 0 ){
$paged = $_GET['iter'];
}
Enjoy!!!