<?php
/**
* QR Code Footer Widget
*
* A dynamic WordPress widget for displaying a QR code in the footer
*
* Usage: Add this code to your theme's functions.php file or create a custom plugin
*/
class QR_Code_Footer_Widget extends WP_Widget
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
'qr_code_footer_widget',
__('QR Code Footer', 'bearing'),
array(
'description' => __('Display a QR code with custom title and image', 'bearing'),
'classname' => 'qr-code-footer-widget'
)
);
// Enqueue admin scripts
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
add_action('admin_footer', array($this, 'media_selector_script'));
}
/**
* Enqueue admin scripts
*/
public function enqueue_admin_scripts($hook)
{
if ('widgets.php' !== $hook && 'customize.php' !== $hook) {
return;
}
wp_enqueue_media();
wp_enqueue_script('jquery');
}
/**
* Media selector script
*/
public function media_selector_script()
{
$screen = get_current_screen();
if ('widgets' !== $screen->id && 'customize' !== $screen->id) {
return;
}
?>
<script>
jQuery(document).ready(function($) {
function initMediaUploader() {
var frame;
$(document).off('click', '.qr-image-upload-btn');
$(document).on('click', '.qr-image-upload-btn', function(e) {
e.preventDefault();
var button = $(this);
var widget = button.closest('.widget-content');
var imageIdInput = widget.find('.qr-image-id-input');
var preview = widget.find('.qr-image-preview-container');
var removeBtn = widget.find('.qr-image-remove-btn');
// Create frame if it doesn't exist
if (frame) {
frame.open();
return;
}
frame = wp.media({
title: '<?php echo esc_js(__('Select QR Code Image', 'bearing')); ?>',
button: {
text: '<?php echo esc_js(__('Use this image', 'bearing')); ?>'
},
multiple: false,
library: {
type: 'image'
}
});
frame.on('select', function() {
var attachment = frame.state().get('selection').first().toJSON();
imageIdInput.val(attachment.id);
preview.html('<img src="' + attachment.url + '" style="max-width: 100%; height: auto; display: block;">');
removeBtn.show();
// Trigger change event to enable Save button
imageIdInput.trigger('change');
widget.find('input, select, textarea').trigger('change');
});
frame.open();
});
$(document).off('click', '.qr-image-remove-btn');
$(document).on('click', '.qr-image-remove-btn', function(e) {
e.preventDefault();
var button = $(this);
var widget = button.closest('.widget-content');
var imageIdInput = widget.find('.qr-image-id-input');
var preview = widget.find('.qr-image-preview-container');
imageIdInput.val('');
preview.html('');
button.hide();
// Trigger change event to enable Save button
imageIdInput.trigger('change');
widget.find('input, select, textarea').trigger('change');
});
}
// Initialize on page load
initMediaUploader();
// Re-initialize when widget is added or updated
$(document).on('widget-added widget-updated', function() {
initMediaUploader();
});
// For customizer
if (wp.customize) {
wp.customize.bind('ready', function() {
initMediaUploader();
});
}
});
</script>
<?php
}
/**
* Front-end display of widget
*/
public function widget($args, $instance)
{
$title = !empty($instance['title']) ? $instance['title'] : __('QR Code', 'bearing');
$image_id = !empty($instance['image_id']) ? $instance['image_id'] : '';
$image_width = !empty($instance['image_width']) ? intval($instance['image_width']) : 180;
$image_height = !empty($instance['image_height']) ? intval($instance['image_height']) : 180;
$alt_text = !empty($instance['alt_text']) ? $instance['alt_text'] : $title;
// Get image URL
$image_url = '';
if ($image_id) {
$image_url = wp_get_attachment_image_url($image_id, 'full');
}
// Only display if we have an image
if ($image_url) {
echo $args['before_widget'];
?>
<div class="foot-item foot-code">
<div class="foot-title"><?php echo esc_html($title); ?></div>
<div class="foot-qrimg">
<img src="<?php echo esc_url($image_url); ?>"
width="<?php echo esc_attr($image_width); ?>"
height="<?php echo esc_attr($image_height); ?>"
loading="lazy"
class="ErWeiImg"
alt="<?php echo esc_attr($alt_text); ?>">
</div>
</div>
<?php
echo $args['after_widget'];
}
}
/**
* Back-end widget form
*/
public function form($instance)
{
$title = !empty($instance['title']) ? $instance['title'] : __('QR Code', 'bearing');
$image_id = !empty($instance['image_id']) ? $instance['image_id'] : '';
$image_width = !empty($instance['image_width']) ? intval($instance['image_width']) : 180;
$image_height = !empty($instance['image_height']) ? intval($instance['image_height']) : 180;
$alt_text = !empty($instance['alt_text']) ? $instance['alt_text'] : '';
$image_url = $image_id ? wp_get_attachment_image_url($image_id, 'thumbnail') : '';
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>">
<?php _e('Title:', 'bearing'); ?>
</label>
<input class="widefat"
id="<?php echo esc_attr($this->get_field_id('title')); ?>"
name="<?php echo esc_attr($this->get_field_name('title')); ?>"
type="text"
value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label><?php _e('QR Code Image:', 'bearing'); ?></label><br>
<input type="hidden"
class="qr-image-id-input"
id="<?php echo esc_attr($this->get_field_id('image_id')); ?>"
name="<?php echo esc_attr($this->get_field_name('image_id')); ?>"
value="<?php echo esc_attr($image_id); ?>">
<div class="qr-image-preview-container" style="margin: 10px 0;">
<?php if ($image_url): ?>
<img src="<?php echo esc_url($image_url); ?>" style="max-width: 100%; height: auto; display: block;">
<?php endif; ?>
</div>
<button type="button" class="button qr-image-upload-btn">
<?php _e('Select Image', 'bearing'); ?>
</button>
<button type="button" class="button qr-image-remove-btn" <?php echo $image_id ? '' : 'style="display:none;"'; ?>>
<?php _e('Remove Image', 'bearing'); ?>
</button>
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('image_width')); ?>">
<?php _e('Image Width (px):', 'bearing'); ?>
</label>
<input class="widefat"
id="<?php echo esc_attr($this->get_field_id('image_width')); ?>"
name="<?php echo esc_attr($this->get_field_name('image_width')); ?>"
type="number"
value="<?php echo esc_attr($image_width); ?>"
min="1">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('image_height')); ?>">
<?php _e('Image Height (px):', 'bearing'); ?>
</label>
<input class="widefat"
id="<?php echo esc_attr($this->get_field_id('image_height')); ?>"
name="<?php echo esc_attr($this->get_field_name('image_height')); ?>"
type="number"
value="<?php echo esc_attr($image_height); ?>"
min="1">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('alt_text')); ?>">
<?php _e('Alt Text:', 'bearing'); ?>
</label>
<input class="widefat"
id="<?php echo esc_attr($this->get_field_id('alt_text')); ?>"
name="<?php echo esc_attr($this->get_field_name('alt_text')); ?>"
type="text"
value="<?php echo esc_attr($alt_text); ?>"
placeholder="<?php echo esc_attr($title); ?>">
</p>
<?php
}
/**
* Sanitize widget form values as they are saved
*/
public function update($new_instance, $old_instance)
{
$instance = array();
$instance['title'] = !empty($new_instance['title']) ? sanitize_text_field($new_instance['title']) : '';
$instance['image_id'] = !empty($new_instance['image_id']) ? absint($new_instance['image_id']) : '';
$instance['image_width'] = !empty($new_instance['image_width']) ? absint($new_instance['image_width']) : 180;
$instance['image_height'] = !empty($new_instance['image_height']) ? absint($new_instance['image_height']) : 180;
$instance['alt_text'] = !empty($new_instance['alt_text']) ? sanitize_text_field($new_instance['alt_text']) : '';
return $instance;
}
}
/**
* Register the widget
*/
function register_qr_code_footer_widget()
{
register_widget('QR_Code_Footer_Widget');
}
add_action('widgets_init', 'register_qr_code_footer_widget');