File: /var/www/laracopilot.stgviitor.com/laracopilot-wp/wp-content/themes/laracopilot-v2/functions.php
<?php
/**
* LaraCopilot V2 functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package LaraCopilot_V2
*/
if (! defined('_S_VERSION')) {
// Replace the version number of the theme on each release.
define('_S_VERSION', '1.0.7');
}
/**
* Sets up theme defaults and registers support for various WordPress features.
*
* Note that this function is hooked into the after_setup_theme hook, which
* runs before the init hook. The init hook is too late for some features, such
* as indicating support for post thumbnails.
*/
function laracopilot_v2_setup()
{
/*
* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on LaraCopilot V2, use a find and replace
* to change 'laracopilot-v2' to the name of your theme in all the template files.
*/
load_theme_textdomain('laracopilot-v2', get_template_directory() . '/languages');
// Add default posts and comments RSS feed links to head.
add_theme_support('automatic-feed-links');
/*
* Let WordPress manage the document title.
* By adding theme support, we declare that this theme does not use a
* hard-coded <title> tag in the document head, and expect WordPress to
* provide it for us.
*/
add_theme_support('title-tag');
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support('post-thumbnails');
// This theme uses wp_nav_menu() in multiple locations.
register_nav_menus(
array(
'menu-1' => esc_html__('Primary', 'laracopilot-v2'),
'footer-product' => esc_html__('Footer: Product', 'laracopilot-v2'),
'footer-grow-with-us' => esc_html__('Footer: Grow with us', 'laracopilot-v2'),
'footer-resources' => esc_html__('Footer: Resources', 'laracopilot-v2'),
'footer-company' => esc_html__('Footer: Company', 'laracopilot-v2'),
)
);
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'style',
'script',
)
);
// Set up the WordPress core custom background feature.
add_theme_support(
'custom-background',
apply_filters(
'laracopilot_v2_custom_background_args',
array(
'default-color' => 'ffffff',
'default-image' => '',
)
)
);
// Add theme support for selective refresh for widgets.
add_theme_support('customize-selective-refresh-widgets');
/**
* Add support for core custom logo.
*
* @link https://codex.wordpress.org/Theme_Logo
*/
add_theme_support(
'custom-logo',
array(
'height' => 250,
'width' => 250,
'flex-width' => true,
'flex-height' => true,
)
);
}
add_action('after_setup_theme', 'laracopilot_v2_setup');
/**
* Set the content width in pixels, based on the theme's design and stylesheet.
*
* Priority 0 to make it available to lower priority callbacks.
*
* @global int $content_width
*/
function laracopilot_v2_content_width()
{
$GLOBALS['content_width'] = apply_filters('laracopilot_v2_content_width', 640);
}
add_action('after_setup_theme', 'laracopilot_v2_content_width', 0);
/**
* Register widget area.
*
* @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar
*/
function laracopilot_v2_widgets_init()
{
register_sidebar(
array(
'name' => esc_html__('Sidebar', 'laracopilot-v2'),
'id' => 'sidebar-1',
'description' => esc_html__('Add widgets here.', 'laracopilot-v2'),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
}
add_action('widgets_init', 'laracopilot_v2_widgets_init');
/**
* Enqueue scripts and styles.
*/
function laracopilot_v2_scripts()
{
// Common Assets
wp_enqueue_style('laracopilot-v2-common', get_template_directory_uri() . '/assets/css/common.css', array(), _S_VERSION);
wp_enqueue_script('laracopilot-v2-common-js', get_template_directory_uri() . '/assets/js/common.js', array(), _S_VERSION, true);
wp_enqueue_script('laracopilot-prompt-examples', get_template_directory_uri() . '/assets/js/prompt-examples.js', array('laracopilot-v2-common-js'), _S_VERSION, true);
if (is_page_template('templates/template-blog.php')) {
wp_enqueue_script('laracopilot-blog', get_template_directory_uri() . '/assets/js/pages/template-blog.js', array(), '1.0', true);
}
wp_localize_script('laracopilot-v2-common-js', 'laracopilot_data', array(
'home_url' => home_url('/'),
));
// Theme Style
wp_enqueue_style('laracopilot-v2-style', get_stylesheet_uri(), array(), _S_VERSION);
wp_style_add_data('laracopilot-v2-style', 'rtl', 'replace');
// Page-Specific Assets
$template_slug = get_page_template_slug();
$page_name = '';
if (is_front_page()) {
$page_name = 'home';
} elseif ($template_slug) {
// e.g., templates/template-blog.php -> template-blog
$page_name = str_replace(array('templates/', '.php'), '', $template_slug);
}
// Consolidation: If this is a product template (legacy or new), load the unified builder CSS
if (strpos($page_name, 'template-product-') === 0 && $page_name !== 'template-product-builder') {
$page_name = 'template-product-builder';
}
// Consolidation: Use Cases Builder
if ($page_name === 'template-use-cases-single') {
$page_name = 'template-use-case-builder';
}
// Consolidation: Roles Builder
if ($page_name === 'template-roles') {
$page_name = 'template-roles-builder';
}
if ($page_name === 'template-role-single') {
$page_name = 'template-role-single-builder';
}
// CMS Pages Detection (Privacy, Terms, Security)
$cms_slugs = array('privacy-policy', 'terms', 'security', 'cookie-policy');
if (is_page($cms_slugs)) {
$page_name = 'cms-content';
}
if ($page_name) {
$css_path = '/assets/css/pages/' . $page_name . '.css';
$js_path = '/assets/js/pages/' . $page_name . '.js';
if (file_exists(get_template_directory() . $css_path)) {
wp_enqueue_style('laracopilot-v2-page-' . $page_name, get_template_directory_uri() . $css_path, array('laracopilot-v2-common'), _S_VERSION);
}
if (file_exists(get_template_directory() . $js_path)) {
wp_enqueue_script('laracopilot-v2-page-js-' . $page_name, get_template_directory_uri() . $js_path, array('laracopilot-v2-common-js'), _S_VERSION, true);
}
}
// Single Blog Post Styles
if (is_singular('post')) {
wp_enqueue_style('laracopilot-v2-blog-detail', get_template_directory_uri() . '/assets/css/pages/blog-detail.css', array('laracopilot-v2-common'), _S_VERSION);
}
if (is_singular() && comments_open() && get_option('thread_comments')) {
wp_enqueue_script('comment-reply');
}
}
add_action('wp_enqueue_scripts', 'laracopilot_v2_scripts');
/**
* Implement the Custom Header feature.
*/
require get_template_directory() . '/inc/custom-header.php';
/**
* Custom template tags for this theme.
*/
require get_template_directory() . '/inc/template-tags.php';
/**
* Functions which enhance the theme by hooking into WordPress.
*/
require get_template_directory() . '/inc/template-functions.php';
/**
* Customizer additions.
*/
require get_template_directory() . '/inc/customizer.php';
/**
* Load Jetpack compatibility file.
*/
if (defined('JETPACK__VERSION')) {
require get_template_directory() . '/inc/jetpack.php';
}
function mailtrap($phpmailer)
{
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = true;
$phpmailer->Port = SMTP_PORT;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = SMTP_SECURE;
$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_FROM_NAME;
}
add_action('phpmailer_init', 'mailtrap');
// Add SVG support to WordPress
function add_file_types_to_uploads($file_types)
{
$new_filetypes = array();
$new_filetypes['svg'] = 'image/svg+xml';
$file_types = array_merge($file_types, $new_filetypes);
return $file_types;
}
add_filter('upload_mimes', 'add_file_types_to_uploads');
/*
* ACF Options Page Setup
*/
if (function_exists('acf_add_options_page')) {
// Main Theme Options Page (optional)
acf_add_options_page(array(
'page_title' => 'Theme Settings',
'menu_title' => 'Theme Settings',
'menu_slug' => 'theme-settings',
'capability' => 'edit_posts',
'redirect' => true
));
// Header Settings Sub Page
acf_add_options_sub_page(array(
'page_title' => 'Header Settings',
'menu_title' => 'Header',
'menu_slug' => 'header-settings',
'parent_slug' => 'theme-settings',
));
// Footer Settings Sub Page
acf_add_options_sub_page(array(
'page_title' => 'Footer Settings',
'menu_title' => 'Footer',
'menu_slug' => 'footer-settings',
'parent_slug' => 'theme-settings',
));
// Hero Settings Sub Page
acf_add_options_sub_page(array(
'page_title' => 'Hero Settings',
'menu_title' => 'Hero',
'menu_slug' => 'hero-settings',
'parent_slug' => 'theme-settings',
));
}
/**
* Helper to render footer menus as plain <a> tags
*/
function laracopilot_v2_footer_menu($location)
{
global $wp;
$current_url = trailingslashit(home_url($wp->request));
$locations = get_nav_menu_locations();
if (isset($locations[$location])) {
$menu = wp_get_nav_menu_object($locations[$location]);
if ($menu) {
$menu_items = wp_get_nav_menu_items($menu->term_id);
if ($menu_items) {
foreach ($menu_items as $item) {
$item_url = trailingslashit(esc_url($item->url));
$active_class = ($current_url === $item_url) ? 'active' : '';
$target = !empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : '';
$rel = ($item->target === '_blank') ? ' rel="noopener"' : '';
echo '<a href="' . esc_url($item->url) . '" class="' . $active_class . '"' . $target . $rel . '>' . esc_html($item->title) . '</a>';
}
}
}
}
}
/**
* ACF JSON synchronization
*/
add_filter('acf/settings/save_json', function ($path) {
return get_template_directory() . '/acf-json';
});
add_filter('acf/settings/load_json', function ($paths) {
unset($paths[0]);
$paths[] = get_template_directory() . '/acf-json';
return $paths;
});
/**
* AJAX Load More for Blog
*/
function laracopilot_v2_load_more()
{
$paged = isset($_POST['paged']) ? intval($_POST['paged']) : 1;
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : 'all';
$args = array(
'post_type' => 'post',
'posts_per_page' => 12,
'paged' => $paged,
'post_status' => 'publish',
);
if ($category !== 'all') {
$args['category_name'] = $category;
} else {
// Exclude the very latest post if it's the featured one
// Offset = (page - 1) * posts_per_page + 1 (for featured)
$args['offset'] = (($paged - 1) * 12) + 1;
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
get_template_part('template-parts/content', 'post-card');
}
// Send max pages info to JS
echo '<span id="ajax-max-pages" data-max="' . $query->max_num_pages . '" style="display:none;"></span>';
} else {
if ($paged === 1) {
echo '<div class="no-posts">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1-2.5-2.5z"/><path d="M8 6h10"/><path d="M8 10h10"/><path d="M8 14h10"/></svg>
<h3>No articles found</h3>
<p>We haven\'t published anything in this category yet. Check back soon!</p>
</div>';
}
}
wp_reset_postdata();
die();
}
add_action('wp_ajax_laracopilot_load_more', 'laracopilot_v2_load_more');
add_action('wp_ajax_nopriv_laracopilot_load_more', 'laracopilot_v2_load_more');
/**
* Estimate reading time for content
*/
function laracopilot_v2_estimate_reading_time($content)
{
$word_count = str_word_count(strip_tags($content));
$reading_time = ceil($word_count / 200); // Average 200 words per minute
return $reading_time;
}
/**
* Automatically add data-reveal attribute to top-level content tags in single posts
*/
function laracopilot_v2_add_reveal_to_content($content)
{
if (is_singular('post')) {
// Add data-reveal to top-level tags like p, h2, h3, ul, ol, blockquote
$content = preg_replace('/<(p|h2|h3|ul|ol|blockquote)([^>]*)>/i', '<$1$2 data-reveal>', $content);
}
return $content;
}
add_filter('the_content', 'laracopilot_v2_add_reveal_to_content', 20);
function disable_gutenberg_editor_except_posts($use_block_editor, $post_type)
{
// Disable block editor for all post types except 'post'
if ($post_type !== 'post') {
return false;
}
return true;
}
add_filter('use_block_editor_for_post_type', 'disable_gutenberg_editor_except_posts', 10, 2);
/**
* Generate a secure token for LaraCopilot API
*/
function laracopilot_generate_token($identifier = 'wordpress')
{
$timestamp = time();
$nonce = bin2hex(random_bytes(16));
$payload = $identifier . '|' . $timestamp . '|' . $nonce;
$signature = hash_hmac(
'sha512',
$payload,
LARACOPILOT_API_SECRET
);
$token_data = [
'identifier' => $identifier,
'timestamp' => $timestamp,
'nonce' => $nonce,
'signature' => $signature
];
return base64_encode(json_encode($token_data));
}
/**
* Fetch plans from LaraCopilot API
*/
function laracopilot_get_plans()
{
$token = laracopilot_generate_token();
$api_url = defined('LARACOPILOT_API_URL') ? LARACOPILOT_API_URL : 'https://builder.laracopilot.com/api/v1/';
$response = wp_remote_get(
$api_url . 'subscription-plans',
[
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json'
],
'timeout' => 20
]
);
if (is_wp_error($response)) {
return false;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (!empty($data) && isset($data['data'])) {
return $data;
}
return false;
}
/**
* Map API plans to V2 template format
*/
function laracopilot_get_mapped_plans()
{
$api_data = laracopilot_get_plans();
if (!$api_data || empty($api_data['data'])) {
return ['regular' => [], 'enterprise' => null];
}
$regular_plans = [];
$enterprise_plan = null;
foreach ($api_data['data'] as $plan) {
// Skip inactive plans
if (isset($plan['is_active']) && !$plan['is_active']) {
continue;
}
$is_free = (float)$plan['price'] === 0.0 && empty($plan['is_custom']);
$is_custom = !empty($plan['is_custom']);
// Map features
$features_list = [];
// Credits
if (!empty($plan['credits_per_month'])) {
$features_list[] = [
'is_included' => true,
'feature_text' => number_format($plan['credits_per_month']) . ' credits' . ($is_free ? '' : '/mo')
];
}
// Projects
if (array_key_exists('max_projects', $plan)) {
$projects = $plan['max_projects'];
$features_list[] = [
'is_included' => true,
'feature_text' => ($projects === null || $projects === '') ? 'Unlimited projects' : $projects . ' project' . ($projects != 1 ? 's' : '')
];
}
// Team Seats
if (array_key_exists('max_team_seats', $plan)) {
$seats = $plan['max_team_seats'];
$features_list[] = [
'is_included' => true,
'feature_text' => ($seats === null || $seats === '') ? 'Unlimited team seats' : $seats . ' team seat' . ($seats != 1 ? 's' : '')
];
}
// Custom Features
if (!empty($plan['features']) && is_array($plan['features'])) {
foreach ($plan['features'] as $feat) {
$features_list[] = [
'is_included' => true,
'feature_text' => $feat
];
}
}
// Clean up price displays for template
$price_m = $plan['price_display'];
$price_y = $plan['yearly_discounted_price_display'];
$price_y_total = $plan['yearly_price_display'];
// Extract parts (e.g. "$29.00/mo" -> ["$29.00", "/mo"])
$m_parts = explode('/', $price_m);
$y_parts = explode('/', $price_y); // Use discounted monthly price instead of yearly total
$mapped = [
'plan_name' => $plan['name'],
'plan_slug' => $plan['slug'],
'plan_description' => $is_custom ? 'Custom credit allocation, unlimited projects & seats, private deployments, dedicated support, SLA, and custom integrations.' : ($is_free ? 'For individuals and small projects.' : 'Advanced features for scaling.'),
'is_popular' => !empty($plan['is_featured']),
'price_m_amt' => trim($m_parts[0]),
'price_m_per' => isset($m_parts[1]) ? '/' . trim($m_parts[1]) : '',
'price_y_amt' => trim($y_parts[0]),
'price_y_per' => isset($y_parts[1]) ? '/' . trim($y_parts[1]) : '',
'sub_y' => 'billed annually',
'features_list' => $features_list,
'credits_val' => !empty($plan['credits_per_month']) ? number_format($plan['credits_per_month']) : '0',
'projects_val' => array_key_exists('max_projects', $plan) ? ($plan['max_projects'] === null ? 'Unlimited' : $plan['max_projects']) : '—',
'seats_val' => array_key_exists('max_team_seats', $plan) ? ($plan['max_team_seats'] === null ? 'Unlimited' : $plan['max_team_seats']) : '—',
'raw_features' => !empty($plan['features']) ? $plan['features'] : [],
'is_red_button' => !empty($plan['is_featured']),
'button_url' => $is_custom ? 'mailto:support@laracopilot.com' : lc_plan_url($plan['slug'], 'month'),
'button_text' => $is_custom ? 'Talk to Sales' : ($is_free ? 'Get Started' : 'Subscribe'),
'is_custom' => $is_custom
];
if ($is_custom) {
$enterprise_plan = $mapped;
} else {
$regular_plans[] = $mapped;
}
}
return [
'regular' => $regular_plans,
'enterprise' => $enterprise_plan
];
}
/**
* Generate plan subscription URL with parameters
*/
function lc_plan_url($plan_slug, $interval = 'month')
{
$base_url = defined('LARACOPILOT_APP_URL') ? LARACOPILOT_APP_URL : 'https://app.laracopilot.com/plan-start';
return add_query_arg([
'plan_slug' => $plan_slug,
'interval' => $interval
], $base_url);
}
/**
* Fetch roles from LaraCopilot API
*/
function laracopilot_get_roles()
{
$token = laracopilot_generate_token();
$api_url = defined('LARACOPILOT_ROLES_API_URL') ? LARACOPILOT_ROLES_API_URL : 'https://builder.laracopilot.com/api/v1/roles';
$response = wp_remote_get(
$api_url,
[
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json'
],
'timeout' => 20
]
);
if (is_wp_error($response)) {
return false;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (!empty($data) && isset($data['data'])) {
return $data;
}
return false;
}
/**
* Get mapped plans for a specific role
*/
function laracopilot_get_mapped_role_plans($role_slug = '')
{
if (empty($role_slug)) {
// Try to get current post slug if on single role page
$role_slug = get_post_field('post_name', get_the_ID());
}
$roles_data = laracopilot_get_roles();
if (!$roles_data || empty($roles_data['data'])) {
return [];
}
$target_role = null;
foreach ($roles_data['data'] as $role) {
if ($role['slug'] === $role_slug) {
$target_role = $role;
break;
}
}
if (!$target_role || empty($target_role['plans'])) {
return [];
}
$mapped_plans = [];
foreach ($target_role['plans'] as $plan) {
// Skip inactive plans
if (isset($plan['is_active']) && !$plan['is_active']) {
continue;
}
$monthly_price = (float)$plan['price'];
$is_free = $monthly_price === 0.0;
$is_custom = !empty($plan['is_custom']);
$mapped_plans[] = [
'name' => $plan['name'],
'slug' => $plan['slug'],
'price' => $is_custom ? 'Custom' : ($is_free ? 'Free' : '$' . (int)$monthly_price),
'desc' => !empty($plan['pivot']['description']) ? $plan['pivot']['description'] : ($is_free ? 'For individuals.' : 'Advanced features.'),
'featured' => !empty($plan['pivot']['is_featured']),
'url' => $is_custom ? 'mailto:support@laracopilot.com' : lc_plan_url($plan['slug'], 'month')
];
}
return $mapped_plans;
}
/**
* CF7 Spam Protection
* - Rate limit by IP
* - Validate real email domains using MX records
*/
add_filter('wpcf7_spam', function ($spam) {
$form_id = 1906;
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$form = $submission->get_contact_form();
// Apply only to specific form
if ($form->id() !== $form_id) {
return $spam;
}
}
// Get visitor IP (Cloudflare compatible)
$headers = [
'HTTP_CF_CONNECTING_IP',
'HTTP_X_REAL_IP',
'HTTP_X_FORWARDED_FOR',
'REMOTE_ADDR',
];
$ip = '0.0.0.0';
foreach ($headers as $header) {
if (!empty($_SERVER[$header])) {
$ip = trim(explode(',', $_SERVER[$header])[0]);
break;
}
}
$ip = sanitize_text_field($ip);
/**
* Rate Limiting
* Max 3 submissions per minute
*/
$transient_key = 'cf7_submit_' . md5($ip);
$count = (int) get_transient($transient_key);
if ($count >= 3) {
return true; // Mark as spam
}
set_transient($transient_key, $count + 1, 60);
return $spam;
});
/**
* Validate Email Domain (MX Record Check)
*/
add_filter('wpcf7_validate_email*', 'validate_real_email_domain', 20, 2);
add_filter('wpcf7_validate_email', 'validate_real_email_domain', 20, 2);
function validate_real_email_domain($result, $tag)
{
$form_id = 1906;
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$form = $submission->get_contact_form();
// Apply only to specific form
if ($form->id() !== $form_id) {
return $result;
}
}
// Replace with your actual CF7 email field name
$field_name = 'work_email';
if ($tag->name !== $field_name) {
return $result;
}
$email = isset($_POST[$field_name])
? sanitize_email($_POST[$field_name])
: '';
if (empty($email)) {
return $result;
}
/**
* Basic email validation
*/
if (!is_email($email)) {
$result->invalidate(
$tag,
'Please enter a valid email address.'
);
return $result;
}
/**
* Extract domain
*/
$domain = substr(strrchr($email, "@"), 1);
if (!$domain) {
$result->invalidate(
$tag,
'Invalid email domain.'
);
return $result;
}
/**
* MX / DNS Validation
*/
if (
!checkdnsrr($domain, 'MX') &&
!checkdnsrr($domain, 'A')
) {
$result->invalidate(
$tag,
'Please enter a real email address.'
);
}
return $result;
}
add_action('wp_footer', function () {
?>
<script>
window.addEventListener('load', function() {
setTimeout(function() {
(function(w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({
'gtm.start': new Date().getTime(),
event: 'gtm.js'
});
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-P5RK8Z5X');
}, 2000);
document.body.classList.add('bg-ready');
});
</script>
<?php
}, 99);
function get_user_ip()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
}
return $_SERVER['REMOTE_ADDR'];
}
function get_ip_location()
{
$ip = get_user_ip();
$response = wp_remote_get("https://ipapi.co/{$ip}/json/");
if (is_wp_error($response)) {
return false;
}
$data = json_decode(wp_remote_retrieve_body($response), true);
return [
'ip' => $ip,
'country' => $data['country_name'] ?? '',
'state' => $data['region'] ?? '',
'city' => $data['city'] ?? '',
];
}
add_filter('wpcf7_special_mail_tags', function ($output, $name) {
if (!in_array($name, [
'server-ip',
'server-country',
'server-state',
'server-city'
])) {
return $output;
}
$location = get_ip_location();
if (!$location) return '';
switch ($name) {
case 'server-ip':
return esc_html($location['ip']);
case 'server-country':
return esc_html($location['country']);
case 'server-state':
return esc_html($location['state']);
case 'server-city':
return esc_html($location['city']);
}
return $output;
}, 10, 2);
add_action('wp_head', function () {
if (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] === 'laracopilot.com') {
echo '<meta name="google-site-verification" content="xlCZ_Ifzh1AwR2USHv2L287qWcrRtmw5WUgODFKZ8pw" />' . "\n";
}
});
/**
* Add custom user contact methods
*/
function laracopilot_v2_user_contact_methods($methods)
{
$methods['twitter'] = 'Twitter URL';
$methods['linkedin'] = 'LinkedIn URL';
$methods['upload_profile_picture'] = 'Profile Picture';
return $methods;
}
add_filter('user_contactmethods', 'laracopilot_v2_user_contact_methods');
/**
* Transform Profile Picture Input to Media Uploader via JS
*/
function laracopilot_v2_transform_profile_field()
{
$screen = get_current_screen();
if (!in_array($screen->id, ['profile', 'user-edit'])) {
return;
}
?>
<script>
jQuery(document).ready(function($) {
var $input = $('#upload_profile_picture');
if ($input.length === 0) return;
var frame;
var currentVal = $input.val();
// Create UI
var $preview = $('<div class="profile-pic-preview" style="margin-bottom: 10px;">' +
'<img id="profile_pic_img" src="' + currentVal + '" style="max-width: 150px; height: auto; display: ' + (currentVal ? 'block' : 'none') + '; border: 1px solid #ddd; border-radius: 8px;" />' +
'</div>');
var $uploadBtn = $('<button type="button" class="button" id="upload_profile_pic_button" style="margin-right: 5px;">Upload/Select Image</button>');
var $removeBtn = $('<button type="button" class="button" id="remove_profile_pic_button" style="display: ' + (currentVal ? 'inline-block' : 'none') + ';">Remove</button>');
// Hide original input and append new UI
$input.css({
'visibility': 'hidden',
'position': 'absolute',
'width': '1px',
'height': '1px'
}).after($removeBtn).after($uploadBtn).after($preview);
$('#upload_profile_pic_button').on('click', function(e) {
e.preventDefault();
if (frame) {
frame.open();
return;
}
frame = wp.media({
title: 'Select Profile Picture',
button: {
text: 'Use this image'
},
multiple: false
});
frame.on('select', function() {
var attachment = frame.state().get('selection').first().toJSON();
$input.val(attachment.url);
$('#profile_pic_img').attr('src', attachment.url).show();
$removeBtn.show();
});
frame.open();
});
$('#remove_profile_pic_button').on('click', function(e) {
e.preventDefault();
$input.val('');
$('#profile_pic_img').hide();
$(this).hide();
});
});
</script>
<?php
}
add_action('admin_footer', 'laracopilot_v2_transform_profile_field');
/**
* Enqueue Media Scripts for User Profile
*/
function laracopilot_v2_enqueue_user_media($hook)
{
if ('profile.php' !== $hook && 'user-edit.php' !== $hook) {
return;
}
wp_enqueue_media();
}
add_action('admin_enqueue_scripts', 'laracopilot_v2_enqueue_user_media');