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(); 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> <!-- <script>
// $.noConflict(); // $.noConflict();
jQuery(document).ready(function(){ jQuery(document).ready(function(){

View file

@ -1,33 +1,136 @@
<?php <?php
/**
* GeneratePress child theme functions and definitions.
*
*/
/** /* Add Dashicons in WordPress Front-end */
* Basic logging function for debugging. Allows passing of an object or array for the $data paramater add_action('wp_enqueue_scripts', 'load_dashicons_front_end');
* function load_dashicons_front_end()
* Set the CUSTOM_DEBUG_LOG file in wp-config.php {
* wp_enqueue_style('dashicons');
*/
/*
function log_to_file($message = false, $data = false){
if ($message) {
$log_File = CUSTOM_DEBUG_LOG;
$date = new DateTime();
$date = $date->format("Y/m/d h:i:s");
// 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;
}
error_log("[$date] " . $message ."\r\n",3,$log_File);
}
} }
*/
/**
* Convert uploaded images to WebP with adjustable image compression quality
*/
// Register the settings on the Media Settings page
function add_optimize_images_settings()
{
register_setting('media', 'optimize_images');
register_setting('media', 'image_compression_quality');
add_settings_field(
'optimize_images',
__('Optimize Images', 'textdomain'),
'display_optimize_images_checkbox',
'media',
'default'
);
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;
}
$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. 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(); ?> 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_email = get_user_meta($current_user_id, 'cloudflare_api_email', true);
$cloudflare_key = get_user_meta($current_user_id, 'cloudflare_api_key', true); $cloudflare_key = get_user_meta($current_user_id, 'cloudflare_api_key', true);
$onboard_steps = [ false, false, false, false ]; $onboard_steps = [ false, false, false, false ];
// $message = "This is the notification area";
if (! ($cloudflare_email || $cloudflare_key) ) { 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>'; $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([ $domain_count = count(get_posts([
'post_type' => 'domain', 'post_type' => 'domain',
'posts_per_page' => -1, 'posts_per_page' => -1,
'status' => 'publish',
'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]] 'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]]
])); ]));
$campaign_count = count(get_posts([ $campaign_count = count(get_posts([
'post_type' => 'campaign', 'post_type' => 'campaign',
'posts_per_page' => -1, 'posts_per_page' => -1,
'status' => 'publish',
'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]] 'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]]
])); ]));
$email_count = count(get_posts([ $email_account_count = count(get_posts([
'post_type' => 'email-account', 'post_type' => 'email-account',
'posts_per_page' => -1, 'posts_per_page' => -1,
'status' => 'publish',
'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]] 'meta_query' => [['key' => 'owner_id', 'value' => $current_user_id]]
])); ]));
@ -44,7 +48,7 @@ if ($domain_count > 0) {
$onboard_steps[1] = true; $onboard_steps[1] = true;
} }
if ($email_count > 0) { if ($email_account_count > 0) {
$onboard_steps[2] = true; $onboard_steps[2] = true;
} }
@ -103,7 +107,14 @@ get_header(); ?>
?> ?>
<div class="dash_summary"> <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"> <table class="summary-table">
<tr> <tr>
<th><a href="/dashboard/domains">Total Domains</a></th> <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> <th><a href="/dashboard/email-accounts">Total Email Accounts</a></th>
</tr> </tr>
<tr> <tr>
<td><a href="/dashboard/domains"><?php echo $domain_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/campaigns"><?php //echo $campaign_count; ?></a></td>
<td><a href="/dashboard/email-accounts"><?php echo $email_count; ?></a></td> <td><a href="/dashboard/email-accounts"><?php //echo $email_count; ?></a></td>
</tr> </tr>
</table> </table>
</div> </div> -->
<?php if (isset($message) ) : ?>
<div class="message_area_wrapper">
<div class="message_area">
<?php echo $message; ?>
</div>
</div>
<?php endif; ?>
</div> </div>
<?php <?php
@ -167,9 +171,24 @@ get_header(); ?>
'after' => '</div>', 'after' => '</div>',
) )
); );
if ( ($onboard_steps[0] || $onboard_steps[1] || $onboard_steps[2] || $onboard_steps[3]) ) :
?> ?>
<div id="onboarding_frame"> <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>
<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> <h2>Get Started:</h2>
<ol class="onboarding_list"> <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[0] ?'finished': ''; ?>" ><a href="/membership-account/your-profile/">Save your CloudFlare API Credentials</a></li>
@ -177,9 +196,20 @@ get_header(); ?>
<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[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> <li class="<?php echo $onboard_steps[3] ?'finished': ''; ?>" ><a href="/dashboard/campaigns/edit-campaign/">Create a Campaign</a></li>
</ol> </ol>
</div>
<?php endif; ?> <?php endif; ?>
</div> </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 <?php
/** /**

View file

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly. 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(); ?> get_header(); ?>

View file

@ -11,8 +11,10 @@ if (!defined('ABSPATH')) {
// log_to_file("Campaign Edit template - Loaded"); // log_to_file("Campaign Edit template - Loaded");
$current_user_id = get_current_user_id(); $current_user_id = get_current_user_id();
$calculate_timeline = true;
$message = false; $message = false;
$new_post = true; $new_post = true;
$campaign_enabled = true;
$professions = []; $professions = [];
@ -30,6 +32,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
'post_type' => 'campaign', 'post_type' => 'campaign',
'post_status' => 'publish' 'post_status' => 'publish'
); );
$calculate_timeline = isset($_POST['calculate_timeline']) ? true : false;
if (isset($_POST['post_id']) && !empty($_POST['post_id'])) { 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); $post_id = wp_update_post($post_data);
$new_post = false; $new_post = false;
$message = ['status' => 'success', 'message' => 'Campaign updated successfully.']; $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 { } else {
// log_to_file("Campaign Edit template - Creating new campaign"); // log_to_file("Campaign Edit template - Creating new campaign");
$post_id = wp_insert_post($post_data); $post_id = wp_insert_post($post_data);
RL_MailWarmer_Campaign_Helper::generate_campaign_tracking_id($post_id);
$message = ['status' => 'success', 'message' => 'Campaign added successfully.']; $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!"); // 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 = [ $acf_fields = [
'domain_id', 'domain_id',
// 'enabled',
'email_accounts', 'email_accounts',
// 'num_additional_emails', // 'num_additional_emails',
'start_date', 'start_date',
'warmup_period', 'warmup_period',
'starting_volume', 'starting_volume',
'target_volume', 'target_volume',
'weekend_reduction_factor',
'target_profession', 'target_profession',
'target_profession_other', 'target_profession_other',
'campaign_conversation_topics' 'campaign_conversation_topics'
@ -66,8 +82,30 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['campaign_submit'])) {
// log_to_file("Campaign Edit template - Checking for $field in POST: ", $_POST[$field]); // log_to_file("Campaign Edit template - Checking for $field in POST: ", $_POST[$field]);
switch ($field) { switch ($field) {
case 'email_accounts': case 'email_accounts':
// log_to_file("Campaign Edit template - Found email_accounts in POST", $_POST[$field]); $campaign_email_accounts = $_POST[$field];
update_field($field, $_POST[$field], $post_id); $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; break;
case 'domain_id': case '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"); // log_to_file("Campaign Edit template - Setting campaign owner_id to $current_user_id");
update_post_meta($post_id, 'owner_id', $current_user_id); update_post_meta($post_id, 'owner_id', $current_user_id);
// Run a domain health check // Calculate a timeline
$campaign_timeline = RL_MailWarmer_Campaign_Helper::calculate_campaign_timeline($post_id); 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 { } else {
$message = ['status' => 'error', 'message' => 'Error: ' . $post_id->get_error_message()]; $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'])) { if (isset($_GET['edit'])) {
$post_id = intval($_GET['edit']); $post_id = intval($_GET['edit']);
$new_post = false; $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 { } else {
$post_id = 0; $post_id = 0;
} }
$campaign_data = [ $campaign_data = [
'campaign_name' => '', 'campaign_name' => '',
// 'enabled' => '',
'domain_id' => '', 'domain_id' => '',
'email_accounts' => [], 'email_accounts' => [],
'num_additional_emails' => '', 'num_additional_emails' => '',
@ -125,6 +174,7 @@ $campaign_data = [
'warmup_period' => '8', 'warmup_period' => '8',
'starting_volume' => '5', 'starting_volume' => '5',
'target_volume' => '50', 'target_volume' => '50',
'weekend_reduction_factor' => 25,
'target_profession' => '', 'target_profession' => '',
'target_profession_other' => '', 'target_profession_other' => '',
'campaign_conversation_topics' => '' 'campaign_conversation_topics' => ''
@ -139,18 +189,20 @@ if ($post_id > 0) {
switch ($key) { switch ($key) {
case 'domain_id': case 'domain_id':
$domain_id = get_field('domain', $post_id); $domain_id = get_field('domain', $post_id) ? get_field('domain', $post_id) : '';
if ($domain_id) {
$campaign_data[$key] = $domain_id->ID; $campaign_data[$key] = $domain_id->ID;
}
break; break;
case 'email_accounts': 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); // log_to_file("Campaign Edit template - Email accounts: ", $email_accounts);
$campaign_data[$key] = $email_accounts; $campaign_data[$key] = $email_accounts;
break; break;
case 'start_date': 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)); $campaign_data[$key] = date('Y-m-d', strtotime($start_date));
break; break;
@ -170,6 +222,8 @@ if ($post_id > 0) {
} }
} }
log_to_file("Campaign Edit template - Campaign data: ", $campaign_data);
// Get domains for current user // Get domains for current user
$domains = get_posts([ $domains = get_posts([
'orderby' => 'title', 'orderby' => 'title',
@ -189,8 +243,14 @@ $domains = get_posts([
$professions = rl_get_textarea_meta_as_array('option', 'default_profession_pool'); $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 - Professions: ", $professions);
// log_to_file("Campaign Edit template - 3 Campaign Enabled: {$campaign_enabled} New Post: {$new_post}");
get_header(); ?> get_header(); ?>
<div <?php generate_do_attr('content'); ?>> <div <?php generate_do_attr('content'); ?>>
<main <?php generate_do_attr('main'); ?>> <main <?php generate_do_attr('main'); ?>>
<?php do_action('generate_before_main_content'); <?php do_action('generate_before_main_content');
@ -213,7 +273,11 @@ get_header(); ?>
<div class="entry-content"> <div class="entry-content">
<div class="wrap"> <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"> <form method="post" action="" class="mf-dashboard-form">
<?php wp_nonce_field('campaign_form_nonce', 'campaign_nonce'); ?> <?php wp_nonce_field('campaign_form_nonce', 'campaign_nonce'); ?>
@ -232,6 +296,18 @@ get_header(); ?>
class="regular-text" required> class="regular-text" required>
</td> </td>
</tr> </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> <tr>
<th><label for="domain_id">Domain</label></th> <th><label for="domain_id">Domain</label></th>
<td> <td>
@ -248,7 +324,8 @@ get_header(); ?>
<td> <td>
<select id="email_accounts" name="email_accounts[]" multiple required class="email-accounts-select"> <select id="email_accounts" name="email_accounts[]" multiple required class="email-accounts-select">
<?php <?php
$email_accounts = get_posts([ $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', 'post_type' => 'email-account',
'posts_per_page' => -1, 'posts_per_page' => -1,
'meta_query' => [ '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) : // 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_id = $account->ID;
$account_name = $account->post_title; ?> $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> <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 endforeach; ?>
<?php endif; ?>
</select> </select>
</td> </td>
</tr> </tr>
@ -281,8 +361,14 @@ get_header(); ?>
<tr> <tr>
<th><label for="start_date">Start Date</label></th> <th><label for="start_date">Start Date</label></th>
<td> <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" <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> </td>
</tr> </tr>
<tr> <tr>
@ -309,6 +395,15 @@ get_header(); ?>
class="small-text" min="10" max="1000" placeholder="50" required> class="small-text" min="10" max="1000" placeholder="50" required>
</td> </td>
</tr> </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> <tr>
<th><label for="target_profession">Target Profession</label></th> <th><label for="target_profession">Target Profession</label></th>
<td> <td>
@ -336,6 +431,18 @@ get_header(); ?>
class="regular-text" rows="5"><?php echo esc_textarea($campaign_data['campaign_conversation_topics']); ?></textarea> class="regular-text" rows="5"><?php echo esc_textarea($campaign_data['campaign_conversation_topics']); ?></textarea>
</td> </td>
</tr> </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> </table>
</div> </div>
@ -344,7 +451,8 @@ get_header(); ?>
value="<?php echo $post_id ? 'Update Campaign' : 'Add Campaign'; ?>"> value="<?php echo $post_id ? 'Update Campaign' : 'Add Campaign'; ?>">
</p> </p>
<?php if ($new_post) : ?> <?php //if ($new_post) : ?>
<?php if (true) : ?>
<div class="mf-form-field-block"> <div class="mf-form-field-block">
<label for="stay_on_page">Stay on this page to create another?</label> <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 // Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['domain_submit'])) { 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_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']) : ''; $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'] : ''; $domain_in_use = isset($_POST['domain_in_use']) ? $_POST['domain_in_use'] : '';
@ -33,10 +33,24 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['domain_submit'])) {
$new_post = false; $new_post = false;
$message = ['status' => 'success', 'message' => 'Domain updated successfully.']; $message = ['status' => 'success', 'message' => 'Domain updated successfully.'];
} else { } else {
$post_id = wp_insert_post($post_data); // Prepare WP_Query to check for an existing post with the same title
$message = ['status' => 'success', 'message' => 'Domain added successfully.']; $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 ($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)) { if (!is_wp_error($post_id)) {
update_post_meta($post_id, 'cloudflare_api_email', $cloudflare_email); 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, 'cloudflare_api_key', $cloudflare_key);
@ -60,9 +74,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['domain_submit'])) {
} }
if ($domain_in_use) { if ($domain_in_use) {
log_to_file("Domain Edit template - Domain in use: $post_title"); log_to_file("Domain Edit template - Domain in use: {$post_title}. Not modifying MX records");
} else { } else {
log_to_file("Domain Edit template - Domain not in use: $post_title"); 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')) ) { if ( !(isset($_POST['stay_on_page']) && ($_POST['stay_on_page'] === 'on')) ) {
@ -70,6 +89,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['domain_submit'])) {
wp_redirect( get_permalink( $post_id ) ); wp_redirect( get_permalink( $post_id ) );
exit; exit;
} }
}
// Reset post data
wp_reset_postdata();
}
} }
// Get existing post data if editing // 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 // Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email_submit']) && isset($_POST['email_address'])) { 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_data = array(
'post_title' => sanitize_email($_POST['email_address']), 'post_title' => $post_title,
'post_type' => 'email-account', 'post_type' => 'email-account',
'post_status' => 'publish' 'post_status' => 'publish'
); );
@ -36,10 +37,24 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email_submit']) && is
$new_post = false; $new_post = false;
$message = ['status' => 'success', 'message' => 'Email account updated successfully.']; $message = ['status' => 'success', 'message' => 'Email account updated successfully.'];
} else { } else {
$post_id = wp_insert_post($post_data); // Prepare WP_Query to check for an existing post with the same title
$message = ['status' => 'success', 'message' => 'Email account added successfully.']; $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 ($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)) { if (!is_wp_error($post_id)) {
foreach ($meta_fields as $field) { foreach ($meta_fields as $field) {
if (isset($_POST[$field])) { if (isset($_POST[$field])) {
@ -61,6 +76,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email_submit']) && is
wp_redirect( get_permalink( $post_id ) ); wp_redirect( get_permalink( $post_id ) );
exit; exit;
} }
}
}
} }
// Get existing post data if editing // Get existing post data if editing

View file

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly. 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(); ?> get_header(); ?>

View file

@ -25,6 +25,7 @@ get_header(); ?>
while ( have_posts() ) : while ( have_posts() ) :
the_post(); the_post();
$post_id = get_the_ID();
?> ?>
@ -53,8 +54,14 @@ get_header(); ?>
if ( generate_show_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 * @hooked generate_post_meta - 10
*/ */
do_action( 'generate_after_entry_title' ); 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> </header>
<?php <?php
endif; endif;

View file

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