<?php

/**
 * Plugin Name: PinnerPress - Customizable Pin Buttons for Pinterest Creators
 * Plugin URI: https://pinnerpress.com/
 * Description: The Ultimate Pinterest Plugin for WordPress. Boost your Pinterest traffic and engagement with powerful tools designed specifically for content creators.
 * Version: 1.1.10
 * Author: Tony Hill
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: pinnerpress
 * Domain Path: /languages
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
// If this file is called directly, abort.
if ( !defined( 'WPINC' ) ) {
    die;
}
// Ensure server variables are never null
if ( !isset( $_SERVER['REQUEST_URI'] ) ) {
    $_SERVER['REQUEST_URI'] = '';
}
if ( !isset( $_SERVER['HTTP_HOST'] ) ) {
    $_SERVER['HTTP_HOST'] = '';
}
if ( !isset( $_SERVER['SERVER_NAME'] ) ) {
    $_SERVER['SERVER_NAME'] = '';
}
if ( !isset( $_SERVER['SCRIPT_FILENAME'] ) ) {
    $_SERVER['SCRIPT_FILENAME'] = '';
}
if ( !isset( $_SERVER['PHP_SELF'] ) ) {
    $_SERVER['PHP_SELF'] = '';
}
// Override PHP string functions to handle null values
if ( !function_exists( 'wp_strpos' ) ) {
    function wp_strpos(  $haystack, $needle, $offset = 0  ) {
        if ( is_null( $haystack ) || $haystack === false ) {
            return false;
        }
        return strpos( (string) $haystack, $needle, $offset );
    }

}
if ( !function_exists( 'wp_str_replace' ) ) {
    function wp_str_replace(
        $search,
        $replace,
        $subject,
        &$count = null
    ) {
        if ( is_null( $subject ) || $subject === false ) {
            return '';
        }
        return str_replace(
            $search,
            $replace,
            (string) $subject,
            $count
        );
    }

}
if ( !function_exists( 'wp_strip_tags' ) ) {
    function wp_strip_tags(  $string, $allowed_tags = null  ) {
        if ( is_null( $string ) || $string === false ) {
            return '';
        }
        return strip_tags( (string) $string, $allowed_tags );
    }

}
// Temporary: Trace deprecation warnings about null passed to string functions to locate source
if ( !function_exists( 'pinnerpress_register_deprecation_tracer' ) ) {
    function pinnerpress_register_deprecation_tracer() {
        // Only enable in debug/dev environments to avoid overhead in production
        // Check if in debug mode or local environment
        $is_debug = defined( 'WP_DEBUG' ) && WP_DEBUG;
        if ( !$is_debug && isset( $_SERVER['HTTP_HOST'] ) ) {
            $http_host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) );
            $is_debug = strpos( $http_host, 'localhost' ) !== false || strpos( $http_host, '.local' ) !== false;
        }
        if ( !$is_debug ) {
            return;
        }
        // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler -- Only used in debug mode
        set_error_handler( function (
            $errno,
            $errstr,
            $errfile,
            $errline
        ) {
            $is_target = ($errno === E_DEPRECATED || $errno === E_WARNING) && (strpos( (string) $errstr, 'strpos(): Passing null' ) !== false && strpos( (string) $errfile, '/wp-includes/functions.php' ) !== false || strpos( (string) $errstr, 'str_replace(): Passing null' ) !== false && strpos( (string) $errfile, '/wp-includes/functions.php' ) !== false);
            if ( $is_target ) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace -- Only used in debug mode
                $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
                $lines = [];
                foreach ( $trace as $frame ) {
                    $file = ( isset( $frame['file'] ) ? $frame['file'] : '[internal]' );
                    $line = ( isset( $frame['line'] ) ? $frame['line'] : '' );
                    $func = ( isset( $frame['function'] ) ? $frame['function'] : '' );
                    $lines[] = $file . ':' . $line . ' ' . $func;
                }
                $log = '[' . gmdate( 'c' ) . "] " . $errstr . ' in ' . $errfile . ':' . $errline . "\n";
                $log .= implode( "\n", $lines ) . "\n\n";
                $log_file = dirname( __FILE__ ) . '/test-results/deprecations.log';
                @file_put_contents( $log_file, $log, FILE_APPEND );
            }
            // Suppress these specific deprecations to avoid noisy output in dev
            if ( $is_target ) {
                return true;
            }
            return false;
        }, E_DEPRECATED | E_WARNING );
    }

}
add_action( 'plugins_loaded', 'pinnerpress_register_deprecation_tracer', 0 );
// Hook very early to catch all option filters
add_filter(
    'pre_option',
    function ( $pre_option, $option, $default ) {
        // For any option that returns null, convert to empty string or default
        if ( $pre_option !== false ) {
            return $pre_option;
        }
        // Add a filter to sanitize the actual option value
        add_filter( "option_{$option}", function ( $value ) use($default) {
            if ( is_null( $value ) ) {
                // Return default if provided, otherwise empty string for string-like options
                if ( !is_null( $default ) ) {
                    return $default;
                }
                // Check if this looks like a string option based on its name
                if ( preg_match( '/(url|uri|path|name|title|description|text|slug|string)/i', $option ) ) {
                    return '';
                }
            }
            return $value;
        }, 1 );
        return $pre_option;
    },
    1,
    3
);
// Also hook default_option to ensure defaults are never null
add_filter(
    'default_option',
    function ( $default, $option, $passed_default ) {
        if ( is_null( $default ) && preg_match( '/(url|uri|path|name|title|description|text|slug|string)/i', $option ) ) {
            return '';
        }
        return $default;
    },
    1,
    3
);
// Prevent conflicts between free and premium versions
if ( defined( 'PINNERPRESS_PLUGIN_LOADED' ) ) {
    add_action( 'admin_notices', function () {
        echo '<div class="notice notice-error"><p><strong>PinnerPress:</strong> Multiple versions detected. Please deactivate the free version to prevent conflicts.</p></div>';
    } );
    return;
    // Stop execution to prevent conflicts
}
define( 'PINNERPRESS_PLUGIN_LOADED', true );
/**
 * Current plugin version.
 */
define( 'PINNERPRESS_VERSION', '1.1.10' );
/**
 * Define Freemius constants to prevent fatal errors.
 */
if ( !defined( 'WP_FS__SLUG' ) ) {
    define( 'WP_FS__SLUG', 'pinnerpress' );
}
if ( !defined( 'WP_FS__DEBUG_SDK' ) ) {
    define( 'WP_FS__DEBUG_SDK', false );
}
if ( !defined( 'WP_FS__ECHO_DEBUG_SDK' ) ) {
    define( 'WP_FS__ECHO_DEBUG_SDK', false );
}
// Global flag to track conflicts
$pinnerpress_has_conflict = false;
// Composer autoloader - load Freemius SDK with error handling
if ( !function_exists( 'fs_dynamic_init' ) ) {
    $autoloader_file = dirname( __FILE__ ) . '/vendor/autoload.php';
    if ( file_exists( $autoloader_file ) ) {
        try {
            // Try to load the autoloader
            require_once $autoloader_file;
        } catch ( Error $e ) {
            // Catch autoloader conflicts (class already declared errors)
            $error_message = $e->getMessage();
            if ( strpos( $error_message, 'Cannot declare class' ) !== false || strpos( $error_message, 'ComposerAutoloaderInit' ) !== false ) {
                $pinnerpress_has_conflict = true;
                add_action( 'admin_notices', function () use($error_message) {
                    echo '<div class="notice notice-error is-dismissible">';
                    echo '<p><strong>PinnerPress Plugin Conflict Detected!</strong></p>';
                    echo '<p>Both free and premium versions of PinnerPress are active, causing a conflict.</p>';
                    echo '<p><strong>To fix this:</strong></p>';
                    echo '<ol>';
                    echo '<li>Go to <strong>Plugins</strong> in your WordPress admin</li>';
                    echo '<li>Deactivate the <strong>free version</strong> of PinnerPress</li>';
                    echo '<li>Keep only the <strong>premium version</strong> active</li>';
                    echo '</ol>';
                    echo '<p>The premium version includes all free features plus additional premium functionality.</p>';
                    if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                        echo '<p><small><strong>Debug info:</strong> ' . esc_html( $error_message ) . '</small></p>';
                    }
                    echo '</div>';
                } );
            } else {
                // Re-throw other errors
                throw $e;
            }
        }
    }
}
// Stop execution if there's a conflict
if ( $pinnerpress_has_conflict ) {
    return;
}
// Check if Freemius SDK is available after loading autoloader
if ( !function_exists( 'fs_dynamic_init' ) ) {
    // Show admin notice that Freemius SDK is missing or failed to load
    add_action( 'admin_notices', function () {
        echo '<div class="notice notice-error"><p><strong>PinnerPress:</strong> Freemius SDK failed to load. Please ensure only one version of PinnerPress is active, or reinstall the plugin.</p></div>';
    } );
    return;
    // Stop plugin execution
}
// WordPress compatibility fixes - removed problematic esc_js_e function as it causes i18n issues
// Freemius SDK Integration
if ( !function_exists( 'pin_fs' ) ) {
    // Include Freemius SDK start file if not already loaded
    if ( !function_exists( 'fs_dynamic_init' ) ) {
        require_once dirname( __FILE__ ) . '/vendor/freemius/wordpress-sdk/start.php';
    }
    // Create a helper function for easy SDK access.
    function pin_fs() {
        global $pin_fs;
        if ( !isset( $pin_fs ) ) {
            // Include Freemius SDK.
            $pin_fs = fs_dynamic_init( array(
                'id'               => '19457',
                'slug'             => 'pinnerpress',
                'type'             => 'plugin',
                'public_key'       => 'pk_00f492a324d8135d9a19c7cd43439',
                'is_premium'       => false,
                'has_addons'       => false,
                'has_paid_plans'   => true,
                'trial'            => array(
                    'days'               => 7,
                    'is_require_payment' => false,
                ),
                'menu'             => array(
                    'slug'    => 'pinnerpress',
                    'contact' => false,
                    'support' => false,
                ),
                'is_live'          => true,
                'is_org_compliant' => true,
            ) );
        }
        return $pin_fs;
    }

    // Init Freemius.
    pin_fs();
    // Signal that SDK was initiated.
    do_action( 'pin_fs_loaded' );
}
if ( function_exists( 'pin_fs' ) ) {
    // Customize Freemius opt-in messages
    pinnerpress_customize_freemius_opt_in();
    // Hook uninstall cleanup to Freemius
    pin_fs()->add_action( 'after_uninstall', 'pin_fs_uninstall_cleanup' );
}
/**
 * Ensure the Freemius dashboard icon is cached locally so the SDK can use it.
 * The SDK automatically looks for `assets/img/pinnerpress.(png|svg|jpg)`.
 */
function pinnerpress_ensure_freemius_icon_cached() {
    if ( !function_exists( 'pin_fs' ) ) {
        return;
    }
    $assets_dir = plugin_dir_path( __FILE__ ) . 'assets/img';
    if ( !is_dir( $assets_dir ) ) {
        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_mkdir
        wp_mkdir_p( $assets_dir );
    }
    // If an icon already exists, nothing to do.
    $existing = glob( $assets_dir . '/pinnerpress.*' );
    if ( is_array( $existing ) && count( $existing ) > 0 ) {
        return;
    }
    if ( method_exists( pin_fs(), 'fetch_remote_icon_url' ) ) {
        $url = pin_fs()->fetch_remote_icon_url();
        if ( !empty( $url ) ) {
            if ( 0 !== strpos( $url, 'http' ) ) {
                $url = 'https:' . $url;
            }
            $response = wp_remote_get( $url, array(
                'timeout' => 15,
            ) );
            if ( !is_wp_error( $response ) && 200 === (int) wp_remote_retrieve_response_code( $response ) ) {
                $body = wp_remote_retrieve_body( $response );
                $path = wp_parse_url( $url, PHP_URL_PATH );
                $ext = pathinfo( $path, PATHINFO_EXTENSION );
                if ( empty( $ext ) ) {
                    $ext = 'png';
                }
                $target = $assets_dir . '/pinnerpress.' . $ext;
                // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
                @file_put_contents( $target, $body );
            }
        }
    }
}

add_action( 'admin_init', 'pinnerpress_ensure_freemius_icon_cached' );
/**
 * Fix Freemius icon URL when the plugin is symlinked outside wp-content.
 * Forces a path under WP_PLUGIN_DIR so fs_asset_url builds a valid URL.
 */
function pinnerpress_fix_freemius_icon_url() {
    if ( !function_exists( 'pin_fs' ) ) {
        return;
    }
    $plugin_dirname = dirname( plugin_basename( __FILE__ ) );
    $preferred = trailingslashit( WP_PLUGIN_DIR ) . $plugin_dirname . '/assets/img/pinnerpress.png';
    $fallback = trailingslashit( WP_PLUGIN_DIR ) . $plugin_dirname . '/admin/images/pinnerpress-icon.svg';
    pin_fs()->add_filter( 'plugin_icon', function ( $icon_path ) use($preferred, $fallback) {
        if ( file_exists( $preferred ) ) {
            return $preferred;
        }
        if ( file_exists( $fallback ) ) {
            return $fallback;
        }
        return $icon_path;
    } );
}

add_action( 'plugins_loaded', 'pinnerpress_fix_freemius_icon_url', 20 );
/**
 * Customize Freemius opt-in messages to recommend opting in.
 */
function pinnerpress_customize_freemius_opt_in() {
    if ( function_exists( 'pin_fs' ) ) {
        // Custom header for new users
        pin_fs()->add_filter( 'connect_header', 'pinnerpress_custom_connect_header' );
        // Custom message for new users
        pin_fs()->add_filter(
            'connect_message',
            'pinnerpress_custom_connect_message',
            10,
            6
        );
        // Custom header for existing users (on update)
        pin_fs()->add_filter( 'connect_header_on_update', 'pinnerpress_custom_connect_header_on_update' );
        // Custom message for existing users (on update)
        pin_fs()->add_filter(
            'connect_message_on_update',
            'pinnerpress_custom_connect_message_on_update',
            10,
            6
        );
    }
}

/**
 * Custom opt-in header for new users.
 */
function pinnerpress_custom_connect_header(  $header  ) {
    return __( 'Welcome to PinnerPress! 🚀', 'pinnerpress' );
}

/**
 * Custom opt-in message for new users.
 */
function pinnerpress_custom_connect_message(
    $message,
    $user_first_name,
    $product_title,
    $user_login,
    $site_link,
    $freemius_link
) {
    return __( 'Get exclusive discounts, Pinterest SEO tips, security & feature updates by clicking allow & continue.', 'pinnerpress' );
}

/**
 * Custom opt-in header for existing users (on update).
 */
function pinnerpress_custom_connect_header_on_update(  $header  ) {
    $user = wp_get_current_user();
    return sprintf( 
        /* translators: %s: User's first name or display name */
        __( 'Thanks %s for updating PinnerPress! 🎉', 'pinnerpress' ),
        ( !empty( $user->user_firstname ) ? $user->user_firstname : $user->display_name )
     );
}

/**
 * Custom opt-in message for existing users (on update).
 */
function pinnerpress_custom_connect_message_on_update(
    $message,
    $user_first_name,
    $product_title,
    $user_login,
    $site_link,
    $freemius_link
) {
    return __( 'Get exclusive discounts, Pinterest SEO tips, security & feature updates by clicking allow & continue.', 'pinnerpress' );
}

/**
 * Plugin activation hook.
 */
if ( !function_exists( 'activate_pinnerpress' ) ) {
    function activate_pinnerpress() {
        require_once plugin_dir_path( __FILE__ ) . 'includes/class-pinnerpress-activator.php';
        PinnerPress_Activator::activate();
    }

}
/**
 * Plugin deactivation hook.
 */
if ( !function_exists( 'deactivate_pinnerpress' ) ) {
    function deactivate_pinnerpress() {
        require_once plugin_dir_path( __FILE__ ) . 'includes/class-pinnerpress-deactivator.php';
        PinnerPress_Deactivator::deactivate();
    }

}
register_activation_hook( __FILE__, 'activate_pinnerpress' );
register_deactivation_hook( __FILE__, 'deactivate_pinnerpress' );
/**
 * The core plugin class (hardened include with graceful fail + bail).
 */
$pinnerpress_core_file = plugin_dir_path( __FILE__ ) . 'includes/class-pinnerpress.php';
if ( file_exists( $pinnerpress_core_file ) && is_readable( $pinnerpress_core_file ) ) {
    require_once $pinnerpress_core_file;
} else {
    add_action( 'admin_notices', function () use($pinnerpress_core_file) {
        echo '<div class="notice notice-error"><p><strong>PinnerPress:</strong> Missing or unreadable file: ' . esc_html( $pinnerpress_core_file ) . '</p></div>';
    } );
    return;
    // Stop loading the plugin to avoid fatals
}
/**
 * Include the helper functions file (hardened include).
 */
$pinnerpress_helpers_file = plugin_dir_path( __FILE__ ) . 'includes/pinnerpress-helper-functions.php';
if ( file_exists( $pinnerpress_helpers_file ) && is_readable( $pinnerpress_helpers_file ) ) {
    require_once $pinnerpress_helpers_file;
} else {
    add_action( 'admin_notices', function () use($pinnerpress_helpers_file) {
        echo '<div class="notice notice-error"><p><strong>PinnerPress:</strong> Missing or unreadable file: ' . esc_html( $pinnerpress_helpers_file ) . '</p></div>';
    } );
    return;
}
/**
 * Include the default options file (hardened include).
 */
$pinnerpress_defaults_file = plugin_dir_path( __FILE__ ) . 'includes/pinnerpress-default-options.php';
if ( file_exists( $pinnerpress_defaults_file ) && is_readable( $pinnerpress_defaults_file ) ) {
    require_once $pinnerpress_defaults_file;
} else {
    add_action( 'admin_notices', function () use($pinnerpress_defaults_file) {
        echo '<div class="notice notice-error"><p><strong>PinnerPress:</strong> Missing or unreadable file: ' . esc_html( $pinnerpress_defaults_file ) . '</p></div>';
    } );
    return;
}
/**
 * Include the premium functionality file (hardened include).
 */
$pinnerpress_premium_file = plugin_dir_path( __FILE__ ) . 'includes/pinnerpress-premium.php';
if ( file_exists( $pinnerpress_premium_file ) && is_readable( $pinnerpress_premium_file ) ) {
    require_once $pinnerpress_premium_file;
} else {
    add_action( 'admin_notices', function () use($pinnerpress_premium_file) {
        echo '<div class="notice notice-error"><p><strong>PinnerPress:</strong> Missing or unreadable file: ' . esc_html( $pinnerpress_premium_file ) . '</p></div>';
    } );
    return;
}
/**
 * Cleanup function called after Freemius uninstall event is reported.
 * This ensures user feedback is sent before cleanup occurs.
 * Note: We intentionally do NOT remove any database data on uninstall.
 */
function pin_fs_uninstall_cleanup() {
    // No database cleanup - preserve all user data and settings
    // This allows users to reinstall without losing their configuration
}

/**
 * Begins execution of the plugin.
 */
if ( !function_exists( 'run_pinnerpress' ) ) {
    function run_pinnerpress() {
        try {
            $plugin = new PinnerPress();
            $plugin->run();
        } catch ( Error $e ) {
            // Catch any remaining fatal errors during plugin initialization
            $error_message = $e->getMessage();
            if ( strpos( $error_message, 'ComposerAutoloaderInit' ) !== false ) {
                add_action( 'admin_notices', function () use($error_message) {
                    echo '<div class="notice notice-error is-dismissible">';
                    echo '<p><strong>PinnerPress Plugin Conflict!</strong></p>';
                    echo '<p>Multiple versions of PinnerPress are causing conflicts. Please deactivate the free version and keep only the premium version active.</p>';
                    if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                        echo '<p><small><strong>Debug info:</strong> ' . esc_html( $error_message ) . '</small></p>';
                    }
                    echo '</div>';
                } );
            } else {
                // Re-throw other errors
                throw $e;
            }
        }
    }

}
// Only run the plugin if there are no conflicts
if ( !$pinnerpress_has_conflict ) {
    run_pinnerpress();
}