| Server IP : 13.126.101.145 / Your IP : 216.73.217.47 Web Server : Apache/2.4.52 (Ubuntu) System : Linux ip-11-115-0-196 6.8.0-1039-aws #41~22.04.1-Ubuntu SMP Thu Sep 11 10:54:48 UTC 2025 x86_64 User : www-data ( 33) PHP Version : 8.3.17 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /opt/rms/wp-content/plugins/contract-renewal-list/ |
Upload File : |
<?php
/**
* Plugin Name: Contract Renewal Orders
* Description: Adds orders with end dates within the next 15 days to a contract renewal list.
* Version: 1.1
* Author: Your Name
*/
// Prevent direct access to the file
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
include plugin_dir_path(__FILE__) . "contracts-for-myaccount.php";
// Hook into WordPress Admin Menu to add a page for displaying renewal orders
add_action('admin_menu', 'contract_renewal_menu');
function contract_renewal_menu() {
add_menu_page(
'Contract Renewal Orders', // Page Title
'Renew Contracts', // Menu Title
'manage_options', // Capability
'contract-renewal-orders', // Menu Slug
'show_contract_renewal_orders', // Callback function to display content
'dashicons-update', // Icon
999// Position
);
}
// Display the orders with end dates within the next 15 days
function show_contract_renewal_orders() {
global $wpdb;
// Fetch today's date and the date 15 days from now
$today = date('d-m-Y');
$next_15_days = date('d-m-Y', strtotime('+15 days'));
// Fetch orders where the end date is within the next 15 days
$query = "
SELECT p.*,
pm1.meta_value AS end_date,
cr.reminder_sent
FROM {$wpdb->prefix}posts p
INNER JOIN {$wpdb->prefix}postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = 'end_date'
LEFT JOIN {$wpdb->prefix}contract_renewal cr ON p.ID = cr.contract_id
WHERE p.post_type = 'shop_order'
AND p.post_status IN ('wc-work_order', 'wc-renewal_status')
AND pm1.meta_value BETWEEN '$today' AND '$next_15_days'
";
$orders = $wpdb->get_results($query);
?>
<div class="wrap contract-renewal-wrap">
<h1 style="font-weight:bold;"><?php esc_html_e('Contracts Due For Renewal', 'contract-renewal-orders'); ?></h1><br><br>
<button id="exportbutton" style="margin-top: -11px; padding: 5px 20px; background-color: #000; color: #FFBD2B; border-radius: 5px;flex-shrink: 0;">Export</button><br><br>
<table class="wp-list-table widefat striped table-view-list posts" id="contract-renewal-table">
<thead>
<tr>
<th><?php esc_html_e('Order ID', 'contract-renewal-orders'); ?></th>
<th><?php esc_html_e('Start Date', 'contract-renewal-orders'); ?></th>
<th><?php esc_html_e('End Date', 'contract-renewal-orders'); ?></th>
<th><?php esc_html_e('Days Remaining', 'contract-renewal-orders'); ?></th>
<th><?php esc_html_e('Customer', 'contract-renewal-orders'); ?></th>
<th><?php esc_html_e('Actions', 'contract-renewal-orders'); ?></th>
</tr>
</thead>
<tbody>
<?php if (!empty($orders)) : ?>
<?php foreach ($orders as $order) : ?>
<?php
// Fetch start date, end date, and reminder_sent status
$start_date = get_post_meta($order->ID, 'start_date', true);
$end_date = get_post_meta($order->ID, 'end_date', true);
$reminder_sent = $order->reminder_sent;
// Calculate days remaining until the end date
$end_date_obj = new DateTime($end_date);
$today_obj = new DateTime($today);
$days_remaining = $today_obj->diff($end_date_obj)->days;
// Fetch customer information
$order_data = wc_get_order($order->ID);
$customer = $order_data->get_billing_first_name() . ' ' . $order_data->get_billing_last_name();
$customer_email = $order_data->get_billing_email();
// Check if there's an extended date by user
global $wpdb;
$extended_date = $wpdb->get_var($wpdb->prepare(
"SELECT extended_date_by_user FROM wp_contract_renewal WHERE contract_id = %d",
$order->ID
));
// Validate if extended_date is not '00-00-00'
$is_valid_extended_date = ($extended_date && $extended_date !== '0000-00-00');
?>
<tr>
<td>
<?php echo esc_html($order->ID); ?>
<div class="row-actions">
<?php if ($is_valid_extended_date) : // Check if extended_date_by_user exists ?>
<span class="renew">
<a href="#" class="renew-link" data-order-id="<?php echo esc_attr($order->ID); ?>">
<?php esc_html_e('Renew', 'contract-renewal-orders'); ?>
</a>
</span>
<?php endif; ?>
</div>
</td>
<td><?php echo esc_html($start_date); ?></td>
<td><?php echo esc_html($end_date); ?></td>
<td><?php echo esc_html($days_remaining . ' days'); ?></td>
<td><?php echo esc_html($customer); ?></td>
<td>
<button class="send-email-button button"
data-order-id="<?php echo esc_attr($order->ID); ?>"
data-customer-email="<?php echo esc_attr($customer_email); ?>"
<?php echo $reminder_sent ? 'disabled' : ''; ?>>
<?php esc_html_e($reminder_sent ? 'Reminder Sent' : 'Send Reminder', 'contract-renewal-orders'); ?>
</button>
<a href="<?php echo esc_url(admin_url('post.php?post=' . $order->ID . '&action=edit')); ?>" class="button button-primary">
<?php esc_html_e('View Current Contract', 'contract-renewal-orders'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
<?php else : ?>
<!-- <tr>
<td colspan="6"><?php esc_html_e('No orders found with contract renewals in the next 15 days.', 'contract-renewal-orders'); ?></td>
</tr> -->
<?php endif; ?>
</tbody>
</table>
<!-- Modal HTML structure -->
<div id="renew-modal" style="display: none;">
<div class="modal-content">
<span class="close-modal">×</span>
<p id="modal-content-text"><?php esc_html_e('Fetching date...', 'contract-renewal-orders'); ?></p>
<div class="datepicker-container">
<input type="date" id="extended-date-picker" placeholder="<?php esc_html_e('Select or enter a date', 'contract-renewal-orders'); ?>" />
</div>
<!-- Button to update the extended date -->
<button id="update-extended-date" class="button button-primary" style="margin-top: 10px;"><?php esc_html_e('Renew Now', 'contract-renewal-orders'); ?></button>
</div>
</div>
<style>
/* Modal CSS */
#renew-modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-content {
background-color: #fff;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 30%;
text-align: center;
}
#extended-date-picker {
width: 100%; /* Full width of the modal */
padding: 8px; /* Padding for input */
margin-top: 10px; /* Space between text and input */
font-size: 16px; /* Font size for readability */
}
.close-modal {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close-modal:hover, .close-modal:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
.contract-renewal-wrap {
padding:20px;
}
#contract-renewal-table_filter {
margin-bottom:20px;
}
#contract-renewal-table tbody tr:nth-child(even) {
background-color: #ffbd2b30 ;
}
</style>
<!-- Include DataTables CSS -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
<!-- Include jQuery and DataTables JS -->
<script type="text/javascript" charset="utf8" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
var table = $('#contract-renewal-table').DataTable({
"ordering": true,
"paging": true,
"lengthChange": true,
"pageLength": 10,
"columnDefs": [
{
"targets": [1],
}
]
});
function exportTableToCSV(filename) {
var csv = [];
var rows = document.querySelectorAll("#contract-renewal-table tbody tr");
// Get table headers (column names)
var headers = [];
var headerCols = document.querySelectorAll("#contract-renewal-table thead th");
for (var k = 0; k < headerCols.length; k++) { // Include all headers
headers.push(headerCols[k].innerText);
}
csv.push(headers.join(",")); // Push headers to CSV
// Get table rows data
for (var i = 0; i < rows.length; i++) {
var row = [];
var cols = rows[i].querySelectorAll("td");
for (var j = 0; j < cols.length; j++) { // Include all columns
row.push(cols[j].innerText);
}
csv.push(row.join(","));
}
// Create a timestamp for the filename
var date = new Date();
var timestamp = date.toISOString().slice(0, 10).split("-").reverse().join("-");
// Add timestamp to filename if needed
var fullFilename = `RenewalContract__${timestamp}.csv`;
// Trigger CSV download
downloadCSV(csv.join("\n"), fullFilename);
}
// Function to download CSV file
function downloadCSV(csv, filename) {
var csvFile;
var downloadLink;
// Create a Blob from the CSV data
csvFile = new Blob([csv], { type: "text/csv" });
// Create a download link for the file
downloadLink = document.createElement("a");
// Set the file name for download
downloadLink.download = filename;
// Create a URL for the Blob and assign it to the download link
downloadLink.href = window.URL.createObjectURL(csvFile);
// Hide the download link from the page
downloadLink.style.display = "none";
// Append the download link to the document body
document.body.appendChild(downloadLink);
// Simulate a click on the download link to trigger the download
downloadLink.click();
// Remove the download link from the document body after download
document.body.removeChild(downloadLink);
}
// Attach event listener to the export button
document.getElementById("exportbutton").addEventListener("click", function() {
exportTableToCSV("agreement-table.csv");
});
// Open modal when "Renew" link is clicked
$('.renew-link').click(function(e) {
e.preventDefault();
// Get the order ID from the data attribute
var orderId = $(this).data('order-id');
// Show fetching message
$('#modal-content-text').text('<?php esc_html_e("Fetching date...", "contract-renewal-orders"); ?>');
$('#renew-modal').show();
// AJAX request to fetch the extended date
$.ajax({
url: ajaxurl, // Ensure ajaxurl is defined correctly
method: 'POST',
data: {
action: 'fetch_extended_date', // WordPress action hook
order_id: orderId // Send the order ID
},
success: function(response) {
console.log(response); // For debugging
if (response.success) {
// Log the extended date to the console
console.log('Extended Date:', response.data.extended_date);
// Set the value of the datepicker input field
$('#extended-date-picker').val(response.data.extended_date);
// Update modal text (optional)
$('#modal-content-text').html(
'<?php esc_html_e("Extended Date By Customer: ", "contract-renewal-orders"); ?>' +
'<span style="color: red; font-weight: bold;">' + response.data.extended_date + '</span>'
);
} else {
// Handle error where no extended date is found
$('#modal-content-text').text('<?php esc_html_e("No extended date found.", "contract-renewal-orders"); ?>');
}
},
error: function(xhr, status, error) {
console.error('AJAX Error:', status, error); // Log any errors
$('#modal-content-text').text('<?php esc_html_e("Error fetching the date.", "contract-renewal-orders"); ?>');
}
});
});
// Close modal when "x" is clicked
$('.close-modal').click(function() {
$('#renew-modal').hide();
});
// Close modal when clicking outside the modal content
$(window).click(function(e) {
if ($(e.target).is('#renew-modal')) {
$('#renew-modal').hide();
}
});
// Handle the update extended date button click
$('#update-extended-date').click(function() {
var newExtendedDate = $('#extended-date-picker').val();
var orderId = $('.renew-link').data('order-id'); // Get the order ID
// AJAX request to update the extended date
$.ajax({
url: ajaxurl, // Ensure ajaxurl is defined correctly
method: 'POST',
data: {
action: 'update_extended_date', // WordPress action hook
order_id: orderId, // Send the order ID
extended_date_by_admin: newExtendedDate // New extended date from the input
},
success: function(response) {
console.log(response); // For debugging
if (response.success) {
// Show the success message in the modal
$('#modal-content-text').html(
'<?php esc_html_e("You have updated the end date from ", "contract-renewal-orders"); ?>' +
'<span style="color: red; font-weight: bold;">' + response.data.previous_date + '</span>' +
'<?php esc_html_e(" to ", "contract-renewal-orders"); ?>' +
'<span style="color: red; font-weight: bold;">' + response.data.new_date + '</span>.'
);
setTimeout(() => {
$('#renew-modal').hide(); // Hide the modal
location.reload(); // Reload the page to reflect changes
}, 2000);
} else {
$('#modal-content-text').text('<?php esc_html_e("Error updating end date.", "contract-renewal-orders"); ?>');
}
},
error: function(xhr, status, error) {
console.error('AJAX Error:', status, error); // Log any errors
$('#modal-content-text').text('<?php esc_html_e("Error updating the end date.", "contract-renewal-orders"); ?>');
}
});
});
});
</script>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('.send-email-button').click(function() {
var orderId = $(this).data('order-id');
var customerEmail = $(this).data('customer-email');
var button = $(this); // Reference to the button
// Change the button text to indicate an action is in progress
button.text('<?php esc_html_e("Sending...", "contract-renewal-orders"); ?>').prop('disabled', true);
$.ajax({
url: ajaxurl, // ajaxurl is already defined in the admin
type: 'POST',
data: {
action: 'send_contract_renewal_email',
order_id: orderId,
customer_email: customerEmail,
},
success: function(response) {
alert(response.data.message);
// Change the button text and disable it after sending the email
button.text('<?php esc_html_e("Reminder Sent", "contract-renewal-orders"); ?>').prop('disabled', true);
},
error: function() {
alert('<?php esc_html_e("Failed to send email.", "contract-renewal-orders"); ?>');
// Enable the button if there's an error
button.text('<?php esc_html_e("Send Reminder", "contract-renewal-orders"); ?>').prop('disabled', false);
}
});
});
// Handle test email button click
$('.test-email-button').click(function() {
var customerEmail = $(this).data('customer-email');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'send_test_email',
customer_email: customerEmail,
},
success: function(response) {
alert(response.data.message);
},
error: function() {
alert('<?php esc_html_e("Failed to send test email.", "contract-renewal-orders"); ?>');
}
});
});
});
</script>
<?php
}
// Hook into wp_ajax to handle the AJAX request for sending emails
add_action('wp_ajax_send_contract_renewal_email', 'send_contract_renewal_email');
function send_contract_renewal_email() {
// Verify that the necessary data was sent
if (isset($_POST['order_id']) && isset($_POST['customer_email'])) {
$order_id = intval($_POST['order_id']);
$customer_email = sanitize_email($_POST['customer_email']);
// Get the customer ID using the email
$user = get_user_by('email', $customer_email);
if ($user) {
// Get the end date from the order's meta
$end_date = get_post_meta($order_id, 'end_date', true);
// Check if the end date is in a valid format
if (!$end_date || !DateTime::createFromFormat('d-m-Y', $end_date)) {
wp_send_json_error(array('message' => __('Invalid end date format.', 'contract-renewal-orders')));
wp_die();
}
// Set today and the end date to midnight to avoid time differences
$today_obj = new DateTime();
$today_obj->setTime(0, 0); // Set time to 00:00:00 (midnight)
$end_date_obj = new DateTime($end_date);
$end_date_obj->setTime(0, 0); // Set end date time to 00:00:00
// Calculate the number of remaining days
$interval = $today_obj->diff($end_date_obj);
$days_remaining = $interval->format('%r%a'); // %r accounts for negative differences
// Ensure the difference is positive (only future dates)
if ($days_remaining >= 0) {
// Store the message with order ID in user meta and add a "View Contracts" button
$contract_message = 'Order ID: ' . $order_id . ' - Your contract is due for renewal in ' . $days_remaining . ' days. Please get in touch with GMMCO for renewal.';
update_user_meta($user->ID, 'contract_renewal_message', wp_kses_post($contract_message));
// Insert into the wp_contract_renewal table
global $wpdb; // Use the global $wpdb object
$data = array(
'contract_id' => $order_id, // Store the order ID in contract_id
'reminder_sent' => 1, // Set reminder_sent to 1
'user_id' => $user->ID // Store the user ID
);
// Insert into the database
$wpdb->insert($wpdb->prefix . 'contract_renewal', $data);
// Return a success response
wp_send_json_success(array('message' => __('Message sent to customer dashboard.', 'contract-renewal-orders')));
} else {
wp_send_json_error(array('message' => __('The contract has already expired.', 'contract-renewal-orders')));
}
} else {
wp_send_json_error(array('message' => __('Customer not found.', 'contract-renewal-orders')));
}
} else {
wp_send_json_error(array('message' => __('Invalid data received.', 'contract-renewal-orders')));
}
// Always die after handling an AJAX request in WordPress
wp_die();
}
// Hook into the WooCommerce My Account dashboard
add_action('woocommerce_account_notification_endpoint', 'display_contract_renewal_message');
function display_contract_renewal_message() {
global $wpdb;
// Ensure the user is logged in
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$contract_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT contract_id FROM {$wpdb->prefix}contract_renewal
WHERE user_id = %d AND reminder_sent = 1 AND extended_date_by_user IS NULL
ORDER BY updated_at DESC
LIMIT 1",
$user_id
)
);
$contract_renewal = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM wp_contract_renewal WHERE user_id = %d AND extended_date_by_admin IS NOT NULL
ORDER BY updated_at DESC LIMIT 1",
$user_id
)
);
$contract_message = '';
// if (!empty($contract_ids) || !empty($contract_renewal))
if (!empty($contract_renewal)) {
$contract_message = "Gmmco extended your contract renewal date.";
echo '<div class="woocommerce-info">
<span>' . esc_html($contract_message) . '</span>
<a href="' . esc_url(home_url('/my-account/contracts')) . '" class="button wc-forward" style="display: inline-block; background-color:#000;padding:5px 10px;border-radius:5px;font-size:13px;">
View Contracts
</a>
</div>';
}
// Check if contract IDs exist
if (!empty($contract_ids)) {
$contract_message = "Gmmco sends reminder to extend your contract.";
echo '<div class="woocommerce-info">
<span>' . esc_html($contract_message) . '</span>
<a href="' . esc_url(home_url('/my-account/contracts')) . '" class="button wc-forward" style="display: inline-block; background-color:#000;padding:5px 10px;border-radius:5px;font-size:13px;">
View Contracts
</a>
</div>';
}
}
}
add_action('wp_ajax_fetch_extended_date', 'fetch_extended_date');
function fetch_extended_date() {
global $wpdb;
// Validate order ID
$order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0;
if ($order_id) {
// Fetch the extended_date_by_user and user_id from the database
$result = $wpdb->get_row($wpdb->prepare(
"SELECT extended_date_by_user, user_id FROM wp_contract_renewal WHERE contract_id = %d",
$order_id
));
// Check if the result exists
if ($result) {
$extended_date = $result->extended_date_by_user;
$user_id = $result->user_id;
// Format the extended date if it's valid
if ($extended_date && $extended_date !== '0000-00-00') {
$formatted_date = date('d-m-Y', strtotime($extended_date)); // Format to YYYY-MM-DD
wp_send_json_success(['extended_date' => $formatted_date, 'user_id' => $user_id]);
} else {
wp_send_json_error(['message' => 'No extended date found.']);
}
} else {
wp_send_json_error(['message' => 'No contract found.']);
}
} else {
wp_send_json_error(['message' => 'Invalid order ID.']);
}
wp_die(); // Properly terminate the AJAX request
}
add_action('wp_ajax_update_extended_date', 'update_extended_date_callback');
function update_extended_date_callback() {
global $wpdb;
// Check for required POST data
$order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0;
$extended_date_by_admin = isset($_POST['extended_date_by_admin']) ? sanitize_text_field($_POST['extended_date_by_admin']) : '';
if ($order_id && $extended_date_by_admin) {
// Get the previous end date before updating
$previous_end_date = get_post_meta($order_id, 'end_date', true);
// Update the post meta with the new end date
$updated_meta = update_post_meta($order_id, 'end_date', $extended_date_by_admin);
$updated_db = $wpdb->update(
'wp_contract_renewal',
['extended_date_by_admin' => $extended_date_by_admin],
['contract_id' => $order_id],
['%s'],
['%d']
);
if ($updated_meta || $updated_db !== false) {
$order = wc_get_order($order_id);
if ($order) {
$order->update_status('wc-contract-renewed', __('Contract renewed.', 'contract-renewal-orders'));
}
// Return success response with old and new dates
wp_send_json_success([
'previous_date' => $previous_end_date,
'new_date' => $extended_date_by_admin,
]);
} else {
wp_send_json_error('Database update failed.'); // Return error response
}
} else {
wp_send_json_error('Invalid order ID or date.'); // Return error response
}
}
function hide_screen_options_for_contract_renew() {
?>
<style>
<?php if (isset($_GET['page']) && ($_GET['page'] === 'contract-renewal-orders')) : ?>
#screen-meta-links {
display: none !important;
}
<?php endif; ?>
</style>
<?php
}
add_action('admin_head', 'hide_screen_options_for_contract_renew');