wp_handle_upload() from the backend - wordpress

I've used wp_handle_upload from the front end and it works fine.
Now I want to receive base64 string (jpg) from API POST store in metabox then turn it in to jpg(until here it works fine). Then I need to upload it in the media library and attach it to a post.
when I pass the file with file_get_contents or fopen it does not work. Any ideas?
function base64ToImage($base64){
$img = base64_decode($base64);
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
// wp_handle_upload( $_POST['img'], 0 );
$fp = fopen(get_template_directory()."/xxxxxxxxxxxxxxxxxxxxxxxxx.jpg", "w+");
// write the data in image file
fwrite($fp, base64_decode($base64));
// close an open file pointer
fclose($fp);
wp_handle_upload( file_get_contents("../" ."/xxxxxxxxxxxxxxxxxxxxxxxxx.jpg"), 0 );
return 0;
}

So to my past self and to anyone that might find this useful.
I used the wp_upload_bits function instead, subsequently I used
-wp_insert_attachment
-wp_generate_attachment_metadata
-wp_update_attachment_metadata
-set_post_thumbnail in order to associate the image with a specific parent post.

Related

PHP mailer not Working with wordpress 5.5

I have a website on wordpress 5.4 and recently it was updated to version 5.5 and now i am unable to send emails using PHPMailer. The Error i get is "There has been a critical error on your website" . The below code will work perfectly for previous wordpress Versions.
include_once( ABSPATH . WPINC . '/class-phpmailer.php' );
include_once( ABSPATH . WPINC . '/includes/PHPMailer/PHPMailerAutoload.php' );
$mailserver_url = "[mailserver_url]";
$mailserver_login = "[mailserver_login]";
$mailserver_pass = '[mailserver_pass]';
$mailserver_port = '[mailserver_port]';
$email = '[email]';
$mail = new PHPMailer;
$mail->ClearAttachments();
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => false
)
);
$mail->Host = $mailserver_url;
$mail->Port = $mailserver_port;
$mail->Username = $mailserver_login;
$mail->Password = $mailserver_pass;
$mail->setFrom( $email );
$mail->addReplyTo( $mailserver_login );
$mail->addAddress( $email );
$mail->Subject = 'The Subject';
$mail->isHTML();
$mail->Body = '<p>Helloo</p>';
if ( $mail->Send() ) {
echo 'sent';
}
I looked into the below article but i wasnt able to fix it https://wordpress.org/support/topic/fatal-error-after-updating-to-wp-5-5/
If you want to use it in a plugin and keep PHP Mailer compatible for older WordPress version, this is the complete solution.
global $wp_version;
if( $wp_version < '5.5') {
require_once(ABSPATH . WPINC . '/class-phpmailer.php');
require_once(ABSPATH . WPINC . '/class-smtp.php');
$mail = new PHPMailer( true );
}
else {
require_once(ABSPATH . WPINC . '/PHPMailer/PHPMailer.php');
require_once(ABSPATH . WPINC . '/PHPMailer/SMTP.php');
require_once(ABSPATH . WPINC . '/PHPMailer/Exception.php');
$mail = new PHPMailer\PHPMailer\PHPMailer( true );
}
It’s because you are attempting to load an old version of PHPMailer that no longer exists in WordPress, and getting a fatal error as a result. You should not have to load PHPMailer yourself because WordPress supplies it as standard, so refer to their docs for how to send messages, and how to create a hook to inject a custom configuration.
You can still load it yourself, but by doing so you bypass all that WP is doing for you and become liable for everything that goes with it, including loading the classes properly. To help update your code to work with PHPMailer 6.x, read the upgrade guide, or this question.
With WordPress upgrade to version 5.5 it may be necessary to include the PHPMailer SMPT.php file.
include_once (ABSPATH . WPINC . '/class-phpmailer.php');
include_once (ABSPATH . WPINC . '/PHPMailer/SMTP.php');
$mail = new PHPMailer ();
WordPress has now moved PHP mailer into a subdirecotry, you need to update your code as follows:
At the top of your function add:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
The update your code further down to:
require_once(\ABSPATH . \WPINC . "/PHPMailer/PHPMailer.php");
require_once(\ABSPATH . \WPINC . "/PHPMailer/Exception.php");
require_once(\ABSPATH . \WPINC . "/PHPMailer/SMTP.php");
$mail = new PHPMailer();

Triggering wp_update_plugins cron to automatically update plugins in WordPress

I am trying to force plugin updates with WordPress, but it doesn't seem to be working. I need to force these updates within a custom plugin itself.
I added the following filter into my plugin:
add_filter( 'auto_update_plugin', '__return_true' );
I made sure that nothing in the wp_config file disallows auto-updates. Even though I didn't need to, to be safe I also set:
define( 'FS_METHOD', 'direct' );
and define( 'WP_AUTO_UPDATE_CORE', true );
I then installed the Advanced Cron Manager plugin to trigger the wp_update_plugins event, but this did not update any plugins.
I decided to simply call the wp_maybe_auto_update() function within my plugin on init... and it worked and updated my plugin - but also disabled it!
I am wondering if anyone knows why running the wp_update_plugins cron event wouldn't be updating any plugins? There must be a really simple solution here that I'm missing! Your help would be much appreciated!
You could use the following function to update a plugin programatically:
function upgrade_plugin( $plugin_slug ) {
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
wp_cache_flush();
$upgrader = new Plugin_Upgrader();
$upgraded = $upgrader->upgrade( $plugin_slug );
return $upgraded;
}
& you could use that in conjunction with get_plugins
// Check if get_plugins() function exists. This is required on the front end of the
// site, since it is in a file that is normally only loaded in the admin.
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$all_plugins = get_plugins();
and then loop over it to update the plugins
foreach ( $all_plugins as $key => $value ) {
upgrade_plugin( $key );
}
I found this article useful when putting together this answer: https://wpreset.com/programmatically-automatically-download-install-activate-wordpress-plugins/
From the answer above I got this to work, you just need to remove the extra / from include_once ABSPATH . '/wp-admin/includes/class-wp-upgrader-skin.php';
to make it: include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
When I am relying on a cron event (Testing with WP Crontrol plugin) to take care of plugin update, following code seems to be working with given required files:
include_once ABSPATH . 'wp-admin/includes/file.php';
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
include_once ABSPATH . 'wp-admin/includes/misc.php';
$upgrader = new Plugin_Upgrader();
$result = $upgrader->upgrade($plugin_slug);
if (is_wp_error($result) || !$result) {
// Check if error, else updated successfully
}

WordPress replace header.php from a plugin

I have searched and cant find any answer.
How can I replace the themes header.php template from a custom plugin?
Everywhere I look it seems like it cant be done, and you can only change template parts from a theme/child theme.
But how does plugins like Elementor page builder do it then in their theme builder?
Thanks,
Daniel
I also needed to include a custom header.php from my plugin. Because you can register templates like page.php, post.php or archive.php from a plugin via the ${type}_template hook, I thought it shouldn't be that difficult to do the same for the header.php, but you can't load a custom header.php from directories other than parent or child theme's one.
When traversing down the get_header function you'll see the locate_template function being invoked to load the header template. But there is no way to hook into that function and to replace the path for the loaded header template:
function locate_template( $template_names, $load = false, $require_once = true, $args = array() ) {
$located = '';
foreach ( (array) $template_names as $template_name ) {
if ( ! $template_name ) {
continue;
}
if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {
$located = STYLESHEETPATH . '/' . $template_name;
break;
} elseif ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {
$located = TEMPLATEPATH . '/' . $template_name;
break;
} elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
$located = ABSPATH . WPINC . '/theme-compat/' . $template_name;
break;
}
}
if ( $load && '' !== $located ) {
load_template( $located, $require_once, $args );
}
return $located;
}
One solution to bypass this limitation would be to get rid of the get_header function within your plugin's templates and to include the plugin's header.php via require or require_once statement from within the plugin's templates. But than you will have to implement your own get_header hook and locate_template functionality to enable replacement from the parent or child theme. See this answer for more information on limitations when omitting the get_header function:
https://wordpress.stackexchange.com/a/5195/80177
I have experience using a similar page-builder to elementor called site origin.
To the best of my knowledge wordpress page-builders don't manipulate or replace the themes template files. Instead, a lot of the page-builder content is displayed in the front end with the_content() found in your template file. In addition, it appends a bunch of css and js scripts to the web page in order to handle the styling of the elements and interactivity.
As for your original question... If I understand correctly, there's no need for this plugin because the header.php file can be freely edited/replaced in the theme editor!
In the admin section, go to 'appearance' > 'editor'. Then under "theme files", select the template for header.php.
I used this solution
add_action('get_header', 'wpbet_replace_theme_header');
function wpbet_replace_theme_header(){
require plugin_dir_path( __FILE__ ) . 'templates/headers/header-padrao.php';
$templates = [];
$templates[] = 'header.php';
remove_all_actions( 'wp_head' );
ob_start();
locate_template( $templates, true );
ob_get_clean();
}
Elementor does not replace the header.php. It adopts whatever header.php the active theme has. It simply takes over the_content() part.
header.php is essential part & asset of a theme.
You may build a page template with a different header (not different header.php)

upload PNG using set_post_thumbnail in WordPress

It works fine for JPG but for PNG.
I wonder which part am I gonna change to make this work for PNG as well.
Here is my code
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
$pid = wp_insert_post( $my_post ); //retrieves the last inserted post id
$attachment_id = media_handle_upload( 'my_image_upload', $pid );
if ( is_wp_error( $attachment_id ) ) {
$mine_msg = "There was an error uploading the image.";
} else {
$mine_msg = "The image was uploaded successfully!";
set_post_thumbnail( $pid , $attachment_id );
}
Please suggest me if this question needs to be changed or removed, instead of voting down my question.
Thanks :)
Found solution. Posting here for future reference.
After trying the comments/suggestions by Punit Gajjar and Ash Patel for hours I came to know that it was a virus in my client's desktop. The virus prevented him from uploading images.
Both mine and Ash Patel's code (link in comment above) works.

error on wordpress front-end submission file upload

I have a function working for wordpress front-end forms except for one thing. I can upload images from the front-end form but if I opt NOT to add a file, I get the following error:
Object of class WP_Error could not be converted to int in wp-includes/post.php on line 4365
Here is the code that handles the image upload part:
if ($_FILES) {
foreach ($_FILES as $file => $array) {
$newupload = insert_attachment($file, $pid);
}
}
function insert_attachment($file_handler,$post_id,$setthumb='false') {
if ($_FILES[$file_handler]['error'] !== UPLOAD_ERR_OK) __return_false();
require_once(ABSPATH . "wp-admin" . '/includes/image.php');
require_once(ABSPATH . "wp-admin" . '/includes/file.php');
require_once(ABSPATH . "wp-admin" . '/includes/media.php');
$attach_id = media_handle_upload( $file_handler, $post_id );
if ($setthumb) update_post_meta($post_id,'_thumbnail_id',$attach_id);
return $attach_id;
}
Note: This only happens when file is not uploaded. Seems like it's expecting an integer and throws an error if there is not file id or integer. How do I fix this? Thanks.
I discovered that when I went from my local server to a staging server, the error disappeared. Guessing that it might be a wp-config or htaccess file difference that caused the error, not sure, but anyway it's no longer an issue.

Resources