Implement Mailferno theme enhancements

- Added image optimization with WebP conversion
- Updated Dashboard UI with card layout
- Fixed duplicate domain/email detection
- Increased default items per page to 25
- Added campaign weekend reduction factor field
- Added ember animation effect in footer

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ruben Ramirez 2025-02-25 23:57:08 -06:00
parent d5f41acd10
commit dc42392180
13 changed files with 530 additions and 136 deletions

32
CLAUDE.md Normal file
View file

@ -0,0 +1,32 @@
# Mailferno WordPress Theme - Development Guidelines
## Development Environment
- This is a WordPress theme that appears to be a child theme of GeneratePress
- Project includes custom templates for a SaaS email service (Mailferno)
- WordPress core functions and AJAX are used extensively
## Code Style Guidelines
- Indentation: 4 spaces (not tabs)
- Function/variable naming: snake_case (e.g., my_function_name)
- Constants/globals: UPPERCASE_WITH_UNDERSCORES
- Opening braces on separate lines for functions and control structures
- Add spaces after control keywords (if, for, while)
## WordPress Patterns
- Use WordPress coding standards for hook naming
- Prefix custom functions with theme prefix to avoid conflicts
- Use WordPress sanitization functions for user input
- Validate data with WordPress validation functions
- Follow WordPress nonce verification practices for forms
## Error Handling
- Use try/catch blocks for operations that may fail
- Check return values with is_wp_error() for WP operations
- Return early from functions when conditions aren't met
- Use log_to_file() for debug logging
## Common Tasks
- Testing: Manual testing in WordPress admin and frontend
- Development: Use WP_DEBUG=true in wp-config.php for development
- Code organization: Group related functions together
- JavaScript: Include at bottom of template files or enqueue properly

View file

@ -60,6 +60,70 @@ do_action( 'generate_after_footer' );
wp_footer();
?>
<script>
class Ember {
constructor() {
this.element = document.createElement('div');
this.element.className = 'ember';
this.reset();
document.body.appendChild(this.element);
}
getRandomColor() {
const colors = [
// { inner: 'rgb(255, 0, 0)', outer: 'rgb(255, 50, 0)' }, // Red
{ inner: 'rgb(255, 150, 50)', outer: 'rgb(255, 50, 0)' }, // Red-Orange
{ inner: 'rgb(255, 200, 50)', outer: 'rgb(255, 100, 0)' }, // Orange
{ inner: 'rgb(255, 255, 100)', outer: 'rgb(255, 200, 50)' } // Yellow
];
return colors[Math.floor(Math.random() * colors.length)];
}
reset() {
this.x = Math.random() * 100;
this.y = 100;
this.size = Math.random() * 4 + 2;
this.speedY = -(Math.random() * 0.25 + 0.125);
this.speedX = (Math.random() - 0.25) * 0.125;
this.opacity = Math.random() * 0.5 + 0.5;
this.life = Math.random() * 100 * this.size;
this.color = this.getRandomColor();
}
update() {
this.x += this.speedX;
this.y += this.speedY;
this.life -= 1;
this.opacity *= 0.99;
this.element.style.left = `${this.x}%`;
this.element.style.top = `${this.y}%`;
this.element.style.width = `${this.size}px`;
this.element.style.height = `${this.size}px`;
this.element.style.opacity = this.opacity;
this.element.style.background = `radial-gradient(circle at center, ${this.color.inner}, ${this.color.outer})`;
this.element.style.boxShadow = `0 0 4px ${this.color.inner}`;
if (this.life <= 0) {
this.reset();
}
}
}
const minCeiled = Math.ceil(50);
const maxFloored = Math.floor(100);
// const emberCount = Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
const emberCount = 100;
const embers = Array.from({ length: emberCount }, () => new Ember());
console.log("Created " + emberCount + "embers");
function animate() {
embers.forEach(ember => ember.update());
requestAnimationFrame(animate);
}
// animate();
</script>
<!-- <script>
// $.noConflict();
jQuery(document).ready(function(){

View file

@ -1,33 +1,136 @@
<?php
/**
* GeneratePress child theme functions and definitions.
*
*/
/* Add Dashicons in WordPress Front-end */
add_action('wp_enqueue_scripts', 'load_dashicons_front_end');
function load_dashicons_front_end()
{
wp_enqueue_style('dashicons');
}
/**
* Basic logging function for debugging. Allows passing of an object or array for the $data paramater
*
* Set the CUSTOM_DEBUG_LOG file in wp-config.php
*
* Convert uploaded images to WebP with adjustable image compression quality
*/
/*
function log_to_file($message = false, $data = false){
if ($message) {
$log_File = CUSTOM_DEBUG_LOG;
// Register the settings on the Media Settings page
function add_optimize_images_settings()
{
register_setting('media', 'optimize_images');
register_setting('media', 'image_compression_quality');
$date = new DateTime();
$date = $date->format("Y/m/d h:i:s");
add_settings_field(
'optimize_images',
__('Optimize Images', 'textdomain'),
'display_optimize_images_checkbox',
'media',
'default'
);
// Convert arrays and objects to JSON format
if (is_array($data) || is_object($data)) {
$data = json_encode($data);
$message = $message . " " . $data;
} else if ($data) {
$message = $message . " " . $data;
add_settings_field(
'image_compression_quality',
__('Image Compression Quality', 'textdomain'),
'display_image_compression_quality_input',
'media',
'default'
);
}
function display_optimize_images_checkbox()
{
$option = get_option('optimize_images');
?>
<input type="checkbox" name="optimize_images" value="1" <?php checked(1, $option, true); ?> />
<label for="optimize_images"><?php esc_html_e('Convert images to WebP format upon upload.', 'textdomain'); ?></label>
<?php
}
function display_image_compression_quality_input()
{
$quality = get_option('image_compression_quality', 80);
?>
<input type="number" name="image_compression_quality"
value="<?php echo esc_attr($quality); ?>" min="1" max="100" />
<label for="image_compression_quality"><?php esc_html_e('Set compression quality for WebP images (1-100).', 'textdomain'); ?></label>
<?php
}
add_action('admin_init', 'add_optimize_images_settings');
function convert_images_to_webp($file)
{
$optimize_images = get_option('optimize_images');
if (!$optimize_images) {
return $file;
}
if (!class_exists('Imagick')) {
return $file;
}
$supported_types = ['image/jpeg', 'image/jpg', 'image/png'];
if (!in_array($file['type'], $supported_types)) {
return $file;
}
$wp_upload_dir = wp_upload_dir();
$original_file_path = $file['file'];
$file_name = pathinfo($original_file_path, PATHINFO_FILENAME);
$webp_file_path = $wp_upload_dir['path'] . '/' . $file_name . '.webp';
if (pathinfo($original_file_path, PATHINFO_EXTENSION) === 'webp') {
return $file;
}
$compression_quality = get_option('image_compression_quality', 75);
try {
$image = new Imagick($original_file_path);
$hasTransparency = $image->getImageAlphaChannel();
if ($hasTransparency) {
return $file;
}
error_log("[$date] " . $message ."\r\n",3,$log_File);
$image->setImageFormat('webp');
$image->setImageCompressionQuality($compression_quality);
$image->stripImage();
$image->writeImage($webp_file_path);
$image->clear();
$image->destroy();
} catch (Exception $e) {
return $file;
}
$backup_dir = $wp_upload_dir['path'] . '/backup';
if (!file_exists($backup_dir)) {
mkdir($backup_dir, 0755, true);
}
$backup_file_path = $backup_dir . '/' . basename($original_file_path);
rename($original_file_path, $backup_file_path);
$metadata = wp_generate_attachment_metadata(attachment_url_to_postid($file['url']), $webp_file_path);
wp_update_attachment_metadata(attachment_url_to_postid($file['url']), $metadata);
return [
'file' => $webp_file_path,
'url' => $wp_upload_dir['url'] . '/' . basename($webp_file_path),
'type' => 'image/webp',
];
}
*/
add_filter('wp_handle_upload', 'convert_images_to_webp');
// function rl_before_update( $upgrader_object, $options ) {
// log_to_file("rl_before_update - Options: ", $options);
// }
// function rl_after_update( $upgrader_object, $options ) {
// log_to_file("rl_after_update - Options: ", $options);
// }
// add_action( 'upgrader_pre_install', 'rl_before_update', 10, 2 );
// add_action( 'upgrader_process_complete', 'rl_after_update', 10, 2 );

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
$items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 10;
$items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 25;
get_header(); ?>

View file

@ -13,6 +13,7 @@ $current_user_id = get_current_user_id();
$cloudflare_email = get_user_meta($current_user_id, 'cloudflare_api_email', true);
$cloudflare_key = get_user_meta($current_user_id, 'cloudflare_api_key', true);
$onboard_steps = [ false, false, false, false ];
// $message = "This is the notification area";
if (! ($cloudflare_email || $cloudflare_key) ) {
$message = '<a href="/membership-account/your-profile/">It looks like you haven\'t set up your CloudFlare API info yet. Click here to save that in your profile and get started!</a>';
@ -21,18 +22,21 @@ if (! ($cloudflare_email || $cloudflare_key) ) {
$domain_count = count(get_posts([
'post_type' => 'domain',
'posts_per_page' => -1,
'status' => 'publish',
'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]]
]));
$campaign_count = count(get_posts([
'post_type' => 'campaign',
'posts_per_page' => -1,
'status' => 'publish',
'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]]
]));
$email_count = count(get_posts([
$email_account_count = count(get_posts([
'post_type' => 'email-account',
'posts_per_page' => -1,
'status' => 'publish',
'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]]
]));
@ -44,7 +48,7 @@ if ($domain_count > 0) {
$onboard_steps[1] = true;
}
if ($email_count > 0) {
if ($email_account_count > 0) {
$onboard_steps[2] = true;
}
@ -103,7 +107,14 @@ get_header(); ?>
?>
<div class="dash_summary">
<div class="summary_table_wrapper">
<?php if (isset($message) ) : ?>
<div class="message_area_wrapper">
<div class="message_area notice notice-success">
<?php echo $message; ?>
</div>
</div>
<?php endif; ?>
<!-- <div class="summary_table_wrapper dash-card">
<table class="summary-table">
<tr>
<th><a href="/dashboard/domains">Total Domains</a></th>
@ -111,19 +122,12 @@ get_header(); ?>
<th><a href="/dashboard/email-accounts">Total Email Accounts</a></th>
</tr>
<tr>
<td><a href="/dashboard/domains"><?php echo $domain_count; ?></a></td>
<td><a href="/dashboard/campaigns"><?php echo $campaign_count; ?></a></td>
<td><a href="/dashboard/email-accounts"><?php echo $email_count; ?></a></td>
<td><a href="/dashboard/domains"><?php //echo $domain_count; ?></a></td>
<td><a href="/dashboard/campaigns"><?php //echo $campaign_count; ?></a></td>
<td><a href="/dashboard/email-accounts"><?php //echo $email_count; ?></a></td>
</tr>
</table>
</div>
<?php if (isset($message) ) : ?>
<div class="message_area_wrapper">
<div class="message_area">
<?php echo $message; ?>
</div>
</div>
<?php endif; ?>
</div> -->
</div>
<?php
@ -167,18 +171,44 @@ get_header(); ?>
'after' => '</div>',
)
);
if ( ($onboard_steps[0] || $onboard_steps[1] || $onboard_steps[2] || $onboard_steps[3]) ) :
?>
<div id="onboarding_frame">
<h2>Get Started:</h2>
<ol class="onboarding_list">
<li class="<?php echo $onboard_steps[0] ?'finished': ''; ?>" ><a href="/membership-account/your-profile/">Save your CloudFlare API Credentials</a></li>
<li class="<?php echo $onboard_steps[1] ?'finished': ''; ?>" ><a href="/dashboard/domains/edit-domain/">Add a Domain and verify DNS records</a></li>
<li class="<?php echo $onboard_steps[2] ?'finished': ''; ?>" ><a href="/dashboard/email-accounts/edit-email-account/">Add one or more Email Accounts</a></li>
<li class="<?php echo $onboard_steps[3] ?'finished': ''; ?>" ><a href="/dashboard/campaigns/edit-campaign/">Create a Campaign</a></li>
</ol>
<div class="dash-row-wrapper">
<div class="dash-card header-card"><h3>Campaigns</h3><span class="card_data"><?php echo $campaign_count; ?></span></div>
<div class="dash-card header-card"><h3>Email Accounts</h3><span class="card_data"><?php echo $email_account_count; ?></span></div>
<div class="dash-card header-card"><h3>Domains</h3><span class="card_data"><?php echo $domain_count; ?></span></div>
<div class="dash-card header-card"><h3>Messages Scheduled</h3><span class="card_data"><?php ///echo ; ?></span></div>
<div class="dash-card header-card"><h3>Delivery Rate</h3><span class="card_data"><?php ///echo ; ?></span></div>
<div class="dash-card header-card"><h3>Delivery Errors</h3><span class="card_data"><?php ///echo ; ?></span></div>
<!-- <div class="dash-card header-card"></div>
<div class="dash-card header-card"></div> -->
</div>
<?php endif; ?>
<div class="dash-row-wrapper">
<div class="dash-card">
<?php
if ( ($onboard_steps[0] = false || $onboard_steps[1] = false || $onboard_steps[2] = false || $onboard_steps[3] = false) ) :
?>
<h2>Get Started:</h2>
<ol class="onboarding_list">
<li class="<?php echo $onboard_steps[0] ?'finished': ''; ?>" ><a href="/membership-account/your-profile/">Save your CloudFlare API Credentials</a></li>
<li class="<?php echo $onboard_steps[1] ?'finished': ''; ?>" ><a href="/dashboard/domains/edit-domain/">Add a Domain and verify DNS records</a></li>
<li class="<?php echo $onboard_steps[2] ?'finished': ''; ?>" ><a href="/dashboard/email-accounts/edit-email-account/">Add one or more Email Accounts</a></li>
<li class="<?php echo $onboard_steps[3] ?'finished': ''; ?>" ><a href="/dashboard/campaigns/edit-campaign/">Create a Campaign</a></li>
</ol>
<?php endif; ?>
</div>
<!-- <div class="dash-card"></div> -->
</div>
<!-- <div class="dash-row-wrapper">
<div class="dash-card"></div>
<div class="dash-card"></div>
<div class="dash-card"></div>
</div> -->
<!-- <div id="onboarding_frame" class="dash-card">
</div> -->
</div>
<?php

View file

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
$items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 10;
$items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 25;
get_header(); ?>

View file

@ -11,8 +11,10 @@ if (!defined('ABSPATH')) {
// log_to_file("Campaign Edit template - Loaded");
$current_user_id = get_current_user_id();
$calculate_timeline = true;
$message = false;
$new_post = true;
$campaign_enabled = true;
$professions = [];
@ -30,6 +32,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
'post_type' => 'campaign',
'post_status' => 'publish'
);
$calculate_timeline = isset($_POST['calculate_timeline']) ? true : false;
if (isset($_POST['post_id']) && !empty($_POST['post_id'])) {
@ -38,9 +41,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
$post_id = wp_update_post($post_data);
$new_post = false;
$message = ['status' => 'success', 'message' => 'Campaign updated successfully.'];
$campaign_tracking_id = get_post_meta($post_id, 'campaign_tracking_id', true);
// log_to_file("Campaign Edit template - Campaign Tracking ID: $campaign_tracking_id");
if ($campaign_tracking_id == '') {
RL_MailWarmer_Campaign_Helper::generate_campaign_tracking_id($post_id);
}
} else {
// log_to_file("Campaign Edit template - Creating new campaign");
$post_id = wp_insert_post($post_data);
RL_MailWarmer_Campaign_Helper::generate_campaign_tracking_id($post_id);
$message = ['status' => 'success', 'message' => 'Campaign added successfully.'];
}
@ -48,14 +57,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
// log_to_file("Campaign Edit template - Create/update successful!");
$campaign_enabled = isset($_POST['enabled']) ? true : false;
// log_to_file("Campaign Edit template - 1 Campaign Enabled: {$campaign_enabled} New Post: {$new_post}");
// var_dump($campaign_enabled);
update_post_meta($post_id, 'enabled', $campaign_enabled);
$acf_fields = [
'domain_id',
// 'enabled',
'email_accounts',
// 'num_additional_emails',
'start_date',
'warmup_period',
'starting_volume',
'target_volume',
'weekend_reduction_factor',
'target_profession',
'target_profession_other',
'campaign_conversation_topics'
@ -66,9 +82,31 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
// log_to_file("Campaign Edit template - Checking for $field in POST: ", $_POST[$field]);
switch ($field) {
case 'email_accounts':
// log_to_file("Campaign Edit template - Found email_accounts in POST", $_POST[$field]);
update_field($field, $_POST[$field], $post_id);
break;
$campaign_email_accounts = $_POST[$field];
$is_limited = false;
// Iterate through each email account ID
foreach ($campaign_email_accounts as $account_id) {
// Retrieve the 'limited_access' meta value for the current account ID
$limited_access = get_post_meta($account_id, 'limited_access', true);
// Check if 'limited_access' is true
if ($limited_access === true || $limited_access === '1') {
$is_limited = true;
break; // Exit the loop early as we only need one true value
}
}
// Update 'campaign_limited' for $post_id if any account is limited
if ($is_limited) {
update_post_meta($post_id, 'campaign_limited', true);
} else {
update_post_meta($post_id, 'campaign_limited', false);
}
// Update the field as usual
update_field($field, $campaign_email_accounts, $post_id);
break;
case 'domain_id':
// log_to_file("Campaign Edit template - Found domain in POST", $_POST['domain_id']);
@ -87,13 +125,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
}
}
// log_to_file("Campaign Edit template - Setting campaign owner_id to $current_user_id");
update_post_meta($post_id, 'owner_id', $current_user_id);
// Run a domain health check
$campaign_timeline = RL_MailWarmer_Campaign_Helper::calculate_campaign_timeline($post_id);
// Calculate a timeline
if ($new_post || $calculate_timeline) {
RL_MailWarmer_DB_Helper::delete_all_conversations_messages($post_id);
RL_MailWarmer_Campaign_Helper::calculate_campaign_timeline($post_id);
RL_MailWarmer_Campaign_Helper::fill_campaign_timeline($post_id);
// log_to_file("Campaign Edit template - Campaign timeline: ", $campaign_timeline);
}
log_to_file("Campaign Edit template - Campaign timeline: ", $campaign_timeline);
} else {
$message = ['status' => 'error', 'message' => 'Error: ' . $post_id->get_error_message()];
@ -113,11 +157,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
if (isset($_GET['edit'])) {
$post_id = intval($_GET['edit']);
$new_post = false;
$campaign_enabled = get_post_meta($post_id, 'enabled') ? get_post_meta($post_id, 'enabled', true) : false;
// log_to_file("Campaign Edit template - 2 Campaign Enabled: {$campaign_enabled} New Post: {$new_post}");
// var_dump($campaign_enabled);
// update_post_meta($post_id, 'enabled', $campaign_enabled);
} else {
$post_id = 0;
}
$campaign_data = [
'campaign_name' => '',
// 'enabled' => '',
'domain_id' => '',
'email_accounts' => [],
'num_additional_emails' => '',
@ -125,6 +174,7 @@ $campaign_data = [
'warmup_period' => '8',
'starting_volume' => '5',
'target_volume' => '50',
'weekend_reduction_factor' => 25,
'target_profession' => '',
'target_profession_other' => '',
'campaign_conversation_topics' => ''
@ -139,18 +189,20 @@ if ($post_id > 0) {
switch ($key) {
case 'domain_id':
$domain_id = get_field('domain', $post_id);
$campaign_data[$key] = $domain_id->ID;
$domain_id = get_field('domain', $post_id) ? get_field('domain', $post_id) : '';
if ($domain_id) {
$campaign_data[$key] = $domain_id->ID;
}
break;
case 'email_accounts':
$email_accounts = get_field($key, $post_id);
$email_accounts = get_field($key, $post_id) ? get_field($key, $post_id) : '';
// log_to_file("Campaign Edit template - Email accounts: ", $email_accounts);
$campaign_data[$key] = $email_accounts;
break;
case 'start_date':
$start_date = get_field($key, $post_id);
$start_date = get_field($key, $post_id) ? get_field($key, $post_id) : '';
$campaign_data[$key] = date('Y-m-d', strtotime($start_date));
break;
@ -170,6 +222,8 @@ if ($post_id > 0) {
}
}
log_to_file("Campaign Edit template - Campaign data: ", $campaign_data);
// Get domains for current user
$domains = get_posts([
'orderby' => 'title',
@ -189,8 +243,14 @@ $domains = get_posts([
$professions = rl_get_textarea_meta_as_array('option', 'default_profession_pool');
// log_to_file("Campaign Edit template - Professions: ", $professions);
// log_to_file("Campaign Edit template - 3 Campaign Enabled: {$campaign_enabled} New Post: {$new_post}");
get_header(); ?>
<div <?php generate_do_attr('content'); ?>>
<main <?php generate_do_attr('main'); ?>>
<?php do_action('generate_before_main_content');
@ -213,7 +273,11 @@ get_header(); ?>
<div class="entry-content">
<div class="wrap">
<h1><?php echo $post_id ? 'Edit Campaign' : 'Add New Campaign'; ?></h1>
<h1 style="display:inline-block;"><?php echo $post_id ? 'Edit Campaign' : 'Add New Campaign'; ?></h1>
<?php if ($post_id) : ?>
<span id="view_post_link"><a href="<?php echo get_the_permalink($post_id); ?>">View Campaign</a></span>
<?php endif; ?>
<form method="post" action="" class="mf-dashboard-form">
<?php wp_nonce_field('campaign_form_nonce', 'campaign_nonce'); ?>
@ -232,6 +296,18 @@ get_header(); ?>
class="regular-text" required>
</td>
</tr>
<tr>
<th><label for="enabled">Enable this campaign?</label></th>
<td>
<input type="checkbox"
id="enabled"
name="enabled"
<?php echo $campaign_enabled || $new_post ? 'checked' : ''; ?>
class="">
<span>Disabled campaigns will not send any mail until they are re-enabled</span>
</td>
</tr>
<tr>
<th><label for="domain_id">Domain</label></th>
<td>
@ -247,8 +323,9 @@ get_header(); ?>
<th><label for="email_accounts">Email Accounts</label></th>
<td>
<select id="email_accounts" name="email_accounts[]" multiple required class="email-accounts-select">
<?php
$email_accounts = get_posts([
<?php
$selected_accounts = get_post_meta($post_id, 'email_accounts') ? get_post_meta($post_id, 'email_accounts', true) : [];
$user_email_accounts = get_posts([
'post_type' => 'email-account',
'posts_per_page' => -1,
'meta_query' => [
@ -259,14 +336,17 @@ get_header(); ?>
]
]);
$selected_accounts = isset($campaign_data['email_accounts']) ? $campaign_data['email_accounts'] : [];
// log_to_file("Selected email accounts: ", $selected_accounts);
foreach ($email_accounts as $account) :
$account_id = $account->ID;
$account_name = $account->post_title; ?>
<option value="<?php echo esc_attr($account_id); ?>"<?php echo in_array($account_id, $selected_accounts) ? 'selected' : ''; ?>><?php echo esc_html($account_name); ?></option>
<?php endforeach; ?>
// log_to_file("Selected email accounts: ", $selected_accounts );
// log_to_file("User email accounts: ", $user_email_accounts);
if ($user_email_accounts) :
foreach ($user_email_accounts as $account) :
$account_id = $account->ID;
$account_name = $account->post_title; ?>
<option value="<?php echo esc_attr($account_id); ?>"<?php echo in_array($account_id, $selected_accounts) ? 'selected' : ''; ?>><?php echo esc_html($account_name); ?></option>
<?php endforeach; ?>
<?php endif; ?>
</select>
</td>
</tr>
@ -281,8 +361,14 @@ get_header(); ?>
<tr>
<th><label for="start_date">Start Date</label></th>
<td>
<?php
$start_date = isset($campaign_data['start_date']) && !empty($campaign_data['start_date'])
? $campaign_data['start_date']
: date('Y-m-d');
?>
<input type="date" id="start_date" name="start_date"
value="<?php echo esc_attr($campaign_data['start_date']); ?>" required>
value="<?php echo esc_attr($start_date); ?>" required>
</td>
</tr>
<tr>
@ -309,6 +395,15 @@ get_header(); ?>
class="small-text" min="10" max="1000" placeholder="50" required>
</td>
</tr>
<tr>
<th><label for="weekend_reduction_factor">Weekend Reduction Factor</label></th>
<td>
<input type="number" id="weekend_reduction_factor" name="weekend_reduction_factor"
value="<?php echo esc_attr($campaign_data['weekend_reduction_factor']); ?>"
class="small-text" min="10" max="90" placeholder="25" step="5">%
<span>Reduce traffic on weekend & holidays by this percentage</span>
</td>
</tr>
<tr>
<th><label for="target_profession">Target Profession</label></th>
<td>
@ -336,6 +431,18 @@ get_header(); ?>
class="regular-text" rows="5"><?php echo esc_textarea($campaign_data['campaign_conversation_topics']); ?></textarea>
</td>
</tr>
<tr>
<th><label for="calculate_timeline">Calculate the campaign timeline?</label></th>
<td>
<input type="checkbox"
id="calculate_timeline"
name="calculate_timeline"
<?php echo $new_post ? 'checked' : ''; ?>
class="">
<span>This will delete any pending messages and recreate the timeline based on the above fields</span>
</td>
</tr>
</table>
</div>
@ -344,7 +451,8 @@ get_header(); ?>
value="<?php echo $post_id ? 'Update Campaign' : 'Add Campaign'; ?>">
</p>
<?php if ($new_post) : ?>
<?php //if ($new_post) : ?>
<?php if (true) : ?>
<div class="mf-form-field-block">
<label for="stay_on_page">Stay on this page to create another?</label>

View file

@ -15,7 +15,7 @@ $new_post = true;
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['domain_submit'])) {
$post_title = sanitize_text_field($_POST['domain_name']);
$post_title = strtolower(sanitize_text_field($_POST['domain_name']));
$cloudflare_email = isset($_POST['cloudflare_api_email']) ? sanitize_email($_POST['cloudflare_api_email']) : '';
$cloudflare_key = isset($_POST['cloudflare_api_key']) ? sanitize_text_field($_POST['cloudflare_api_key']) : '';
$domain_in_use = isset($_POST['domain_in_use']) ? $_POST['domain_in_use'] : '';
@ -26,50 +26,76 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['domain_submit'])) {
'post_status' => 'publish'
);
// Check if editing existing post
if (isset($_POST['post_id']) && !empty($_POST['post_id'])) {
$post_data['ID'] = intval($_POST['post_id']);
$post_id = wp_update_post($post_data);
$new_post = false;
$message = ['status' => 'success', 'message' => 'Domain updated successfully.'];
} else {
$post_id = wp_insert_post($post_data);
$message = ['status' => 'success', 'message' => 'Domain added successfully.'];
}
// Check if editing existing post
if (isset($_POST['post_id']) && !empty($_POST['post_id'])) {
$post_data['ID'] = intval($_POST['post_id']);
$post_id = wp_update_post($post_data);
$new_post = false;
$message = ['status' => 'success', 'message' => 'Domain updated successfully.'];
} else {
// Prepare WP_Query to check for an existing post with the same title
$args = [
'post_type' => 'domain', // Replace with your post type
'post_status' => 'any',
'title' => $post_title,
'fields' => 'id',
'posts_per_page' => 1
];
$query = new WP_Query($args);
if (!is_wp_error($post_id)) {
update_post_meta($post_id, 'cloudflare_api_email', $cloudflare_email);
update_post_meta($post_id, 'cloudflare_api_key', $cloudflare_key);
update_post_meta($post_id, 'domain_in_use', $domain_in_use);
if ($new_post) {
// set the owner_id to the creator of the post if this is a new domain
update_post_meta($post_id, 'owner_id', $current_user_id);
if ($query->have_posts()) {
log_to_file("Domain Edit template - Domain {$post_title} already exists: ");
$message = ['status' => 'error', 'message' => 'Domain already exists.'];
} else {
$post_id = wp_insert_post($post_data);
$new_post = true;
$message = ['status' => 'success', 'message' => 'Domain added successfully.'];
if (!is_wp_error($post_id)) {
update_post_meta($post_id, 'cloudflare_api_email', $cloudflare_email);
update_post_meta($post_id, 'cloudflare_api_key', $cloudflare_key);
update_post_meta($post_id, 'domain_in_use', $domain_in_use);
if ($new_post) {
// set the owner_id to the creator of the post if this is a new domain
update_post_meta($post_id, 'owner_id', $current_user_id);
// Run a domain health check
$domain_report_id = RL_MailWarmer_Domain_Helper::save_domain_health_report($post_id);
}
} else {
$message = ['status' => 'error', 'message' => 'Error: ' . $post_id->get_error_message()];
// $message = 'Error: ' . $post_id->get_error_message();
}
// Run a domain health check
$domain_report_id = RL_MailWarmer_Domain_Helper::save_domain_health_report($post_id);
}
} else {
$message = ['status' => 'error', 'message' => 'Error: ' . $post_id->get_error_message()];
// $message = 'Error: ' . $post_id->get_error_message();
}
if (isset($_POST['update_dns']) && !empty($_POST['update_dns'])) {
log_to_file("Domain Edit template - Running Fix Domain");
$results = RL_MailWarmer_Domain_Helper::fix_deliverability_dns_issues($post_id);
log_to_file("Domain Edit template - Results: ", $results);
}
if (isset($_POST['update_dns']) && !empty($_POST['update_dns'])) {
log_to_file("Domain Edit template - Running Fix Domain");
$results = RL_MailWarmer_Domain_Helper::fix_deliverability_dns_issues($post_id);
log_to_file("Domain Edit template - Results: ", $results);
}
if ($domain_in_use) {
log_to_file("Domain Edit template - Domain in use: $post_title");
} else {
log_to_file("Domain Edit template - Domain not in use: $post_title");
}
if ($domain_in_use) {
log_to_file("Domain Edit template - Domain in use: {$post_title}. Not modifying MX records");
} else {
log_to_file("Domain Edit template - Domain not in use: {$post_title}. Setting MX to Mailferno server ");
// Set MX to 'server' of $post_id
$server = get_field('defaut_mailferno_mx', 'option');
log_to_file("Domain Edit template - Default Mailferno MX Server: ", $server);
$update_MX_result = RL_MailWarmer_Domain_Helper::update_mx_record($post_id, $server->post_title, 0, $ttl = 3600);
log_to_file("Domain Edit template - CloudFlare Response: {$update_MX_result}");
}
if ( !(isset($_POST['stay_on_page']) && ($_POST['stay_on_page'] === 'on')) ) {
// log_to_file("Domain Edit template - stay_on_page not set; redirecting!");
wp_redirect( get_permalink( $post_id ) );
exit;
}
if ( !(isset($_POST['stay_on_page']) && ($_POST['stay_on_page'] === 'on')) ) {
// log_to_file("Domain Edit template - stay_on_page not set; redirecting!");
wp_redirect( get_permalink( $post_id ) );
exit;
}
}
// Reset post data
wp_reset_postdata();
}
}
// Get existing post data if editing

View file

@ -18,8 +18,9 @@ log_to_file("Email Account Edit template - Post Data: ", $_POST);
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email_submit']) && isset($_POST['email_address'])) {
$post_title = strtolower(sanitize_email($_POST['email_address']));
$post_data = array(
'post_title' => sanitize_email($_POST['email_address']),
'post_title' => $post_title,
'post_type' => 'email-account',
'post_status' => 'publish'
);
@ -36,31 +37,47 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email_submit']) && is
$new_post = false;
$message = ['status' => 'success', 'message' => 'Email account updated successfully.'];
} else {
$post_id = wp_insert_post($post_data);
$message = ['status' => 'success', 'message' => 'Email account added successfully.'];
}
// Prepare WP_Query to check for an existing post with the same title
$args = [
'post_type' => 'email-account', // Replace with your post type
'post_status' => 'any',
'title' => $post_title,
'fields' => 'id',
'posts_per_page' => 1
];
$query = new WP_Query($args);
if (!is_wp_error($post_id)) {
foreach ($meta_fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
if ($query->have_posts()) {
log_to_file("Email Account Edit template - email account {$post_title} already exists: ");
$message = ['status' => 'error', 'message' => 'Email account already exists.'];
} else {
$post_id = wp_insert_post($post_data);
$new_post = true;
$message = ['status' => 'success', 'message' => 'Email account added successfully.'];
if (!is_wp_error($post_id)) {
foreach ($meta_fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
}
}
// include new accounts in the warmup pool and set the owner_id to the creator of the post
if ($new_post) {
update_post_meta($post_id, 'owner_id', $current_user_id);
update_post_meta($post_id, 'include_in_warmup_pool', $current_user_id);
}
} else {
$message = ['status' => 'error', 'message' => 'Error: ' . $post_id->get_error_message()];
}
if ( !(isset($_POST['stay_on_page']) && ($_POST['stay_on_page'] === 'on')) ) {
// log_to_file("Email Account Edit template - stay_on_page not set; redirecting!");
wp_redirect( get_permalink( $post_id ) );
exit;
}
}
// include new accounts in the warmup pool and set the owner_id to the creator of the post
if ($new_post) {
update_post_meta($post_id, 'owner_id', $current_user_id);
update_post_meta($post_id, 'include_in_warmup_pool', $current_user_id);
}
} else {
$message = ['status' => 'error', 'message' => 'Error: ' . $post_id->get_error_message()];
}
if ( !(isset($_POST['stay_on_page']) && ($_POST['stay_on_page'] === 'on')) ) {
// log_to_file("Email Account Edit template - stay_on_page not set; redirecting!");
wp_redirect( get_permalink( $post_id ) );
exit;
}
}
}
// Get existing post data if editing

View file

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
$items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 10;
$items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 25;
get_header(); ?>

View file

@ -25,6 +25,7 @@ get_header(); ?>
while ( have_posts() ) :
the_post();
$post_id = get_the_ID();
?>
@ -52,9 +53,15 @@ get_header(); ?>
do_action( 'generate_before_entry_title' );
if ( generate_show_title() ) {
$params = generate_get_the_title_parameters();
$params = generate_get_the_title_parameters();
$post_id = get_the_ID(); // Get the current post ID
$edit_url = "/dashboard/campaigns/edit-campaign?edit={$post_id}"; // Construct the edit URL
the_title( $params['before'], $params['after'] );
echo $params['before']; // Output the title before markup
echo '<a href="' . esc_url( $edit_url ) . '">'; // Begin the link
the_title(); // Display the title
echo '</a>'; // Close the link
echo $params['after']; // Output the title after markup
}
/**
@ -65,7 +72,9 @@ get_header(); ?>
* @hooked generate_post_meta - 10
*/
do_action( 'generate_after_entry_title' );
$campaign_tracking_id = get_field('campaign_tracking_id', $post_id);
?>
<span class="tracking_id"><?php echo $campaign_tracking_id; ?></span>
</header>
<?php
endif;

View file

@ -8,3 +8,8 @@
Version: 0.1
*/
:root {
--lotus_red: #ab0000;
}