Add PSR HTTP Message Interfaces and Dependencies
- Implemented StreamInterface, UploadedFileInterface, and UriInterface as per PSR standards. - Added getallheaders function to retrieve HTTP headers in a compatible manner. - Included LICENSE files for ralouphie/getallheaders and symfony/deprecation-contracts. - Introduced function for triggering deprecation notices in Symfony.
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' )) exit;
|
||||
|
||||
class CPFM_Feedback_Notice {
|
||||
|
||||
private static $registered_notices = [];
|
||||
|
||||
public function __construct() {
|
||||
|
||||
add_action('admin_init', [ $this, 'cpfm_listen_for_external_notice_registration' ]);
|
||||
add_action('admin_enqueue_scripts', [ $this, 'cpfm_enqueue_assets' ]);
|
||||
add_action('wp_ajax_cpfm_handle_opt_in', [ $this, 'cpfm_handle_opt_in_choice' ]);
|
||||
add_action('admin_footer', [ $this, 'cpfm_render_notice_panel' ]);
|
||||
|
||||
}
|
||||
|
||||
public static function cpfm_register_notice($key, $args) {
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset(self::$registered_notices[$key])) {
|
||||
self::$registered_notices[$key] = wp_parse_args($args, [
|
||||
'title' => '',
|
||||
'message' => '',
|
||||
'pages' => [],
|
||||
'always_show_on' => [],
|
||||
]);
|
||||
}
|
||||
self::$registered_notices[$key][] = $args;
|
||||
}
|
||||
|
||||
public function cpfm_listen_for_external_notice_registration() {
|
||||
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow other plugins to register notices dynamically.
|
||||
* Example usage in other plugins:
|
||||
* do_action('cpf_cpfm_register_notice', 'crypto', [
|
||||
* 'title' => 'Crypto Plugin Notice',
|
||||
* 'message' => 'This is a crypto dashboard setup notice.',
|
||||
* 'pages' => ['dashboard', 'cpfm_'],
|
||||
* ]);
|
||||
*/
|
||||
do_action('cpfm_register_notice');
|
||||
}
|
||||
|
||||
public function cpfm_enqueue_assets() {
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
$screen = get_current_screen();
|
||||
$current_page = isset($_GET['page'])? sanitize_key($_GET['page']):'';
|
||||
|
||||
// Gather all unique pages from registered notices
|
||||
$allowed_pages = [];
|
||||
|
||||
foreach (self::$registered_notices as $notice) {
|
||||
if (!empty($notice['pages']) && is_array($notice['pages'])) {
|
||||
$allowed_pages = array_merge($allowed_pages, $notice['pages']);
|
||||
}
|
||||
}
|
||||
|
||||
// Early return if not needed
|
||||
if (!in_array($current_page, array_unique($allowed_pages))) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_style('cpfm-common-review-style', ATFPP_URL . 'admin/cpfm-feedback/css/cpfm-admin-feedback.css');
|
||||
wp_enqueue_script(
|
||||
'cpfm-common-review-script',
|
||||
ATFPP_URL . 'admin/cpfm-feedback/js/cpfm-admin-feedback.js',
|
||||
['jquery'],
|
||||
ATFPP_V,
|
||||
true
|
||||
|
||||
);
|
||||
wp_localize_script('cpfm-common-review-script', 'adminNotice', [
|
||||
'ajaxurl' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('dismiss_admin_notice'),
|
||||
'autoShowPages' => array_unique(
|
||||
array_merge(
|
||||
[],
|
||||
...array_filter(
|
||||
array_column(self::$registered_notices, 'always_show_on'),
|
||||
function($pages) { return !empty($pages); }
|
||||
)
|
||||
)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function cpfm_handle_opt_in_choice() {
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
|
||||
wp_send_json_error('Unauthorized access.');
|
||||
}
|
||||
|
||||
check_ajax_referer('dismiss_admin_notice', 'nonce');
|
||||
|
||||
$category = isset($_POST['category']) ? sanitize_text_field( wp_unslash( $_POST['category'] ) ): '';
|
||||
$opt_in_raw = isset($_POST['opt_in']) ? sanitize_text_field( wp_unslash( $_POST['opt_in'] ) ) : '';
|
||||
$opt_in = ($opt_in_raw === 'yes') ? 'yes' : 'no';
|
||||
$category_notices = self::$registered_notices;
|
||||
$registered_notices = isset($GLOBALS['cool_plugins_feedback'])? $GLOBALS['cool_plugins_feedback']:$category_notices;
|
||||
|
||||
if (!$category || !isset(self::$registered_notices[$category])) {
|
||||
|
||||
wp_send_json_error('Invalid notice category.');
|
||||
}
|
||||
|
||||
update_option("cpfm_opt_in_choice_{$category}", $opt_in);
|
||||
|
||||
$review_option = get_option("cpfm_opt_in_choice_{$category}");
|
||||
|
||||
|
||||
if ($review_option === 'yes') {
|
||||
|
||||
foreach (self::$registered_notices[$category] as $notice) {
|
||||
|
||||
$plugin_name = isset($notice['plugin_name'])?sanitize_key($notice['plugin_name']):'';
|
||||
|
||||
if($plugin_name){
|
||||
|
||||
do_action('cpfm_after_opt_in_' . $plugin_name, $category);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
public function cpfm_render_notice_panel() {
|
||||
|
||||
if (!current_user_can('manage_options') || !function_exists('get_current_screen')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
$current_page = isset($_GET['page']) ? sanitize_key($_GET['page']) : '';
|
||||
|
||||
|
||||
$unread_count = 0;
|
||||
$auto_show = false;
|
||||
|
||||
foreach (self::$registered_notices as $notice) {
|
||||
|
||||
if (!empty($notice['always_show_on']) && in_array($current_page, (array) $notice['always_show_on'])) {
|
||||
$auto_show = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$output = '';
|
||||
$output .= '<div id="cpfNoticePanel" class="notice-panel"' . ($auto_show ? ' data-auto-show="true"' : '') . '>';
|
||||
$output .= '<div class="notice-panel-header">' . esc_html__('Help Improve Plugins', 'ccpw') . ' <span class="dashicons dashicons-no" id="cpfm_remove_notice"></span></div>';
|
||||
$output .= '<div class="notice-panel-content">';
|
||||
|
||||
foreach (self::$registered_notices as $key => $notice) {
|
||||
|
||||
$choice = get_option("cpfm_opt_in_choice_{$key}");
|
||||
|
||||
if ($choice !== false) continue;
|
||||
|
||||
$should_show = false;
|
||||
foreach ($notice['pages'] as $match) {
|
||||
|
||||
if ($current_page === $match || strpos($current_page, $match) === 0) {
|
||||
|
||||
$should_show = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$should_show) continue;
|
||||
$unread_count++;
|
||||
|
||||
$output .= '<div class="notice-item unread" data-notice-id="' . esc_attr($key) . '">';
|
||||
$output .= '<strong>' . esc_html($notice['title']) . '</strong>';
|
||||
|
||||
$output .= '<div class="notice-message-with-toggle">';
|
||||
$output .= '<p>' . esc_html($notice['message']) . '<a href="#" class="cpf-toggle-extra">' . esc_html__(' More info', 'ccpw') . '</a></p>';
|
||||
$output .= '</div>';
|
||||
|
||||
$output .= '<div class="cpf-extra-info">';
|
||||
$output .= '<p>' . esc_html__('Opt in to receive email updates about security improvements, new features, helpful tutorials, and occasional special offers. We\'ll collect:', 'ccpw') . '</p>';
|
||||
$output .= '<ul>';
|
||||
$output .= '<li>' . esc_html__('Your website home URL and WordPress admin email.', 'ccpw') . '</li>';
|
||||
$output .= '<li>' . esc_html__('To check plugin compatibility, we will collect the following: list of active plugins and themes, server type, MySQL version, WordPress version, memory limit, site language and database prefix.', 'ccpw') . '</li>';
|
||||
$output .= '</ul>';
|
||||
|
||||
$output .= '</div>';
|
||||
|
||||
$output .= '<div class="notice-actions">';
|
||||
$output .= '<button class="button button-primary opt-in-yes" data-category="' . esc_attr($key) . '" id="yes-share-data" value="yes">' . esc_html__("Yes, I Agree", 'ccpw') . '</button>';
|
||||
$output .= '<button class="button opt-in-no" data-category="' . esc_attr($key) . '" id="no-share-data" value="no">' . esc_html__('No, Thanks', 'ccpw') . '</button>';
|
||||
$output .= '</div>';
|
||||
|
||||
$output .= '</div>';
|
||||
}
|
||||
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
|
||||
if ($unread_count > 0) {
|
||||
echo $output;
|
||||
}
|
||||
}
|
||||
}
|
||||
new CPFM_Feedback_Notice();
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!class_exists('ATFPP_cronjob')) {
|
||||
class ATFPP_cronjob
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function atfpp_cron_init_hooks()
|
||||
{
|
||||
|
||||
//initialize Cron Jobs
|
||||
add_filter('cron_schedules', array($this, 'atfpp_cron_schedules'));
|
||||
add_action('atfpp_extra_data_update', array($this, 'atfpp_cron_extra_data_autoupdater'));
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| cron custom schedules
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function atfpp_cron_schedules($schedules)
|
||||
{
|
||||
|
||||
if (!isset($schedules['every_30_days'])) {
|
||||
|
||||
$schedules['every_30_days'] = array(
|
||||
'interval' => 30 * 24 * 60 * 60, // 2,592,000 seconds
|
||||
'display' => __('Once every 30 days'),
|
||||
);
|
||||
}
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| cron extra data autoupdater
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
function atfpp_cron_extra_data_autoupdater() {
|
||||
$opt_in = get_option('atfp_feedback_opt_in');
|
||||
$opt_in = is_string($opt_in) ? strtolower($opt_in) : 'no';
|
||||
|
||||
if ($opt_in === 'yes' || $opt_in === true || $opt_in === '1') {
|
||||
|
||||
if (class_exists('ATFPP_cronjob')) {
|
||||
|
||||
ATFPP_cronjob::atfpp_send_data();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| cron send data
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static public function atfpp_send_data() {
|
||||
|
||||
$feedback_url = ATFPP_FEEDBACK_API.'wp-json/coolplugins-feedback/v1/site';
|
||||
|
||||
$extra_data_details = AutoPolyPro::atfpp_get_user_info();
|
||||
$server_info = $extra_data_details['server_info'];
|
||||
$extra_details = $extra_data_details['extra_details'];
|
||||
$site_url = get_site_url();
|
||||
$install_date = get_option('atfpp-install-date');
|
||||
$unique_key = '42'; // Ensure this key is unique per plugin to prevent collisions when site URL and install date are the same across plugins
|
||||
$site_id = $site_url . '-' . $install_date . '-' . $unique_key;
|
||||
$initial_version = get_option('atfpp_initial_save_version');
|
||||
$initial_version = is_string($initial_version) ? sanitize_text_field($initial_version) : 'N/A';
|
||||
$plugin_version = ATFPP_V;
|
||||
$admin_email = sanitize_email(get_option('admin_email') ?: 'N/A');
|
||||
$post_data = array(
|
||||
|
||||
'site_id' => md5($site_id),
|
||||
'plugin_version' => $plugin_version,
|
||||
'plugin_name' => 'AutoPoly - AI Translation For Polylang (Pro)',
|
||||
'plugin_initial' => $initial_version,
|
||||
'email' => $admin_email,
|
||||
'site_url' => esc_url_raw($site_url),
|
||||
'server_info' => $server_info,
|
||||
'extra_details' => $extra_details,
|
||||
);
|
||||
|
||||
$response = wp_remote_post($feedback_url, array(
|
||||
'method' => 'POST',
|
||||
'timeout' => 30,
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'body' => wp_json_encode($post_data),
|
||||
));
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
defined('WP_DEBUG') && WP_DEBUG && error_log('ATFPP Feedback Send Failed: ' . sanitize_text_field($response->get_error_message()));
|
||||
return;
|
||||
}
|
||||
|
||||
$response_body = wp_remote_retrieve_body($response);
|
||||
$decoded = json_decode($response_body, true);
|
||||
|
||||
if (!wp_next_scheduled('atfpp_extra_data_update')) {
|
||||
wp_schedule_event(time(), 'every_30_days', 'atfpp_extra_data_update');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#cpfNoticePanel{display:none;position:fixed;z-index:999999;right:0;top:32px;width:380px;background:#fff;box-shadow:0 4px 15px rgba(0,0,0,.1);border-radius:8px;margin:10px}#cpfNoticePanel .notice-panel-header{padding:16px 20px;background:#f6f7f7;border-bottom:1px solid #e1e1e1;font-weight:600;font-size:15px;color:#1d2327;display:flex;justify-content:space-between;border-radius:8px 8px 8px 0}#cpfNoticePanel .notice-panel-content{padding:15px 20px;max-height:400px;overflow-y:auto}#cpfNoticePanel .notice-item{background:#fefefe;border:1px solid #e0e0e0;border-radius:6px;padding:15px;margin-bottom:20px;transition:.3s}#cpfNoticePanel .notice-item:hover{box-shadow:0 2px 8px rgba(0,0,0,.06)}#cpfNoticePanel .notice-item strong{font-size:14px;font-weight:600;color:#1d2327;margin-bottom:10px;display:block}#cpfNoticePanel .opt-in-text{font-size:13px;color:#50575e;margin-bottom:15px;line-height:1.6}#cpfNoticePanel .notice-actions{display:flex;justify-content:space-between;gap:10px}#cpfNoticePanel .notice-actions .button{flex:1;padding:8px 10px;font-size:13px;border-radius:4px;text-align:center;line-height:1.4;transition:.2s ease-in-out}#cpfNoticePanel .opt-in-yes{background-color:#2271b1;border:1px solid #2271b1;color:#fff}#cpfNoticePanel .opt-in-yes:hover{background-color:#135e96;border-color:#135e96}#cpfNoticePanel .opt-in-no{background-color:#fff;border:1px solid #2271b1;color:#2271b1}#cpfNoticePanel .opt-in-no:hover{background-color:#f0f0f1}#wpadminbar .cpf-notice-admin-button>.ab-item{position:relative;padding-left:10px!important;font-weight:600;color:#fff!important;display:flex;align-items:center;gap:6px}#wpadminbar .cpf-notice-admin-button .notice-count{background-color:#f44336;color:#fff;border-radius:12px;padding:2px 7px;font-size:11px;line-height:1;font-weight:700;display:inline-block;min-width:20px;text-align:center}span#cpfm_remove_notice{cursor:pointer}.cpf-extra-info{display:none;font-size:12px;color:#999}.cpf-extra-info ul{list-style-type:auto;padding-left:20px;margin-top:10px}
|
||||
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function ($) { const noticePanel = $('#cpfNoticePanel');let isPanelVisible = !1; var urlParams = new URLSearchParams(window.location.search); var currentPage = urlParams.get('page'); if (noticePanel.data('auto-show') && adminNotice.autoShowPages.includes(currentPage)) { setTimeout(function () { noticePanel.fadeIn(300); isPanelVisible = !0 }, 500) } $(document).on('click', '#wp-admin-bar-cpf-notice-admin-button > a', function (e) { e.preventDefault(); isPanelVisible ? noticePanel.fadeOut(300) : noticePanel.fadeIn(300); isPanelVisible = !isPanelVisible }); $(document).on('click', '#cpfm_remove_notice', function (e) { e.preventDefault(); noticePanel.fadeOut(300); isPanelVisible = false; }); $(document).on('click', '.opt-in-yes, .opt-in-no', function (e) { e.preventDefault(); const button = $(this); const category = button.data('category'); const optIn = button.val(); const noticeItem = button.closest('.notice-item'); $.post(adminNotice.ajaxurl, { action: 'cpfm_handle_opt_in', nonce: adminNotice.nonce, category: category, opt_in: optIn }, function (response) { if (response.success) { noticeItem.slideUp(300, function () { noticeItem.remove(); const remainingNotices = $('#cpfNoticePanel .notice-item.unread'); const count = remainingNotices.length; $('.cpf-notice-admin-button .notice-count').text(count); if (count === 0) { $('#cpfNoticePanel').fadeOut(300); $('#wp-admin-bar-cpf-notice-admin-button').fadeOut(300, function () { $(this).remove() }) }}) } }) }); $('.cpf-toggle-extra').on('click', function () { $(this).closest('.notice-item').find('.cpf-extra-info').slideToggle() }) })
|
||||
Reference in New Issue
Block a user