File manager - Edit - /home/aresglob/public_html/wp/wp-includes/images/smilies/includes.zip
Back
PK �g[���2 �2 functions.phpnu �[��� <?php /* * CookieAdmin * https://cookieadmin.net * (c) Softaculous Team */ // Are we being accessed directly ? if(!defined('COOKIEADMIN_PRO_VERSION')) { exit('Hacking Attempt !'); } function cookieadmin_pro_activation(){ update_option('cookieadmin_pro_version', COOKIEADMIN_PRO_VERSION); include_once(COOKIEADMIN_PRO_DIR . 'includes/database.php'); \CookieAdminPro\Database::activate(); } function cookieadmin_pro_is_network_active($plugin_name){ $is_network_wide = false; // Handling network site if(!is_multisite()){ return $is_network_wide; } $_tmp_plugins = get_site_option('active_sitewide_plugins'); if(!empty($_tmp_plugins) && preg_grep('/.*\/'.$plugin_name.'\.php$/', array_keys($_tmp_plugins))){ $is_network_wide = true; } return $is_network_wide; } function cookieadmin_pro_update_checker(){ $current_version = get_option('cookieadmin_pro_version', '0.0'); $version = (int) str_replace('.', '', $current_version); // No update required if($current_version == COOKIEADMIN_PRO_VERSION){ return true; } $is_network_wide = cookieadmin_pro_is_network_active('cookieadmin'); if($is_network_wide){ $free_ins = get_site_option('cookieadmin_free_installed'); }else{ $free_ins = get_option('cookieadmin_free_installed'); } // If plugin runing reached here it means CookieAdmin free installed if(empty($free_ins)){ if($is_network_wide){ update_site_option('cookieadmin_free_installed', time()); }else{ update_option('cookieadmin_free_installed', time()); } } update_option('cookieadmin_version_pro_nag', time()); update_option('cookieadmin_version_free_nag', time()); update_option('cookieadmin_pro_version', COOKIEADMIN_PRO_VERSION); } // Load license data function cookieadmin_pro_load_license($parent = 0){ global $cookieadmin, $lic_resp; $license_field = 'cookieadmin_license'; $license_api_url = COOKIEADMIN_API; // Save license if(!empty($parent) && is_string($parent) && strlen($parent) > 5){ $lic['license'] = $parent; // Load license of Soft Pro }elseif(!empty($parent)){ $license_field = 'softaculous_pro_license'; $lic = get_option('softaculous_pro_license', []); // My license }else{ $lic = get_option($license_field, []); } // Loaded license is a Soft Pro if(!empty($lic['license']) && preg_match('/^softwp/is', $lic['license'])){ $license_field = 'softaculous_pro_license'; $license_api_url = 'https://a.softaculous.com/softwp/'; $prods = apply_filters('softaculous_pro_products', []); }else{ $prods = []; } if(empty($lic['last_update'])){ $lic['last_update'] = time() - 86600; } // Update license details as well if(!empty($lic) && !empty($lic['license']) && (time() - @$lic['last_update']) >= 86400){ $url = $license_api_url.'/license.php?license='.$lic['license'].'&prods='.implode(',', $prods).'&url='.rawurlencode(site_url()); $resp = wp_remote_get($url); $lic_resp = $resp; //Did we get a response ? if(is_array($resp)){ $tosave = json_decode($resp['body'], true); //Is it the license ? if(!empty($tosave['license'])){ $tosave['last_update'] = time(); update_option($license_field, $tosave); $lic = $tosave; } } } // If the license is Free or Expired check for Softaculous Pro license if(empty($lic) || empty($lic['active'])){ if(function_exists('softaculous_pro_load_license')){ $softaculous_license = softaculous_pro_load_license(); if(!empty($softaculous_license['license']) && (!empty($softaculous_license['active']) || empty($lic['license'])) ){ $lic = $softaculous_license; } }elseif(empty($parent)){ $soft_lic = get_option('softaculous_pro_license', []); if(!empty($soft_lic)){ return cookieadmin_pro_load_license(1); } } } if(!empty($lic['license'])){ $cookieadmin['license'] = $lic; } } add_filter('softaculous_pro_products', 'cookieadmin_pro_softaculous_pro_products', 10, 1); function cookieadmin_pro_softaculous_pro_products($r = []){ $r['cookieadmin'] = 'cookieadmin'; return $r; } // Add our license key if ANY function cookieadmin_pro_updater_filter_args($queryArgs){ global $cookieadmin; if (!empty($cookieadmin['license']['license'])){ $queryArgs['license'] = $cookieadmin['license']['license']; } $queryArgs['url'] = rawurlencode(site_url()); return $queryArgs; } function cookieadmin_pro_ajax_handler(){ $cookieadmin_fn = (!empty($_REQUEST['cookieadmin_act']) ? sanitize_text_field(wp_unslash($_REQUEST['cookieadmin_act'])) : ''); if(empty($cookieadmin_fn)){ wp_send_json_error(array('message' => 'Action not posted')); } // Define a whitelist of allowed functions $user_allowed_actions = array( 'save_consent' => 'save_consent' ); $admin_allowed_actions = array( 'export_logs' => 'export_logs', 'get_consent_logs' => 'get_consent_logs', 'dismiss_expired_licenses' => 'dismiss_expired_licenses', 'version_notice' => 'version_notice' ); if(array_key_exists($cookieadmin_fn, $user_allowed_actions)){ check_ajax_referer('cookieadmin_pro_js_nonce', 'cookieadmin_pro_security'); header_remove('Set-Cookie'); call_user_func('\CookieAdminPro\Enduser::'.$user_allowed_actions[$cookieadmin_fn]); }elseif(array_key_exists($cookieadmin_fn, $admin_allowed_actions)){ check_ajax_referer('cookieadmin_pro_admin_js_nonce', 'cookieadmin_pro_security'); if(!current_user_can('administrator')){ wp_send_json_error(array('message' => 'Sorry, but you do not have permissions to perform this action')); } call_user_func('\CookieAdminPro\Admin::'.$admin_allowed_actions[$cookieadmin_fn]); }else{ wp_send_json_error(array('message' => 'Unauthorized action')); } } // Handle the Check for update link and ask to install license key function cookieadmin_pro_updater_check_link($final_link){ global $cookieadmin; if(empty($cookieadmin['license']['license'])){ return '<a href="'.admin_url('admin.php?page=cookieadmin-license').'">'.esc_html__('Install CookieAdmin Pro License Key', 'cookieadmin-pro').'</a>'; } return $final_link; } // Prevent update of cookieadmin free function cookieadmin_pro_get_free_version_num(){ if(defined('COOKIEADMIN_VERSION')){ return COOKIEADMIN_VERSION; } // In case of cookieadmin deactive return cookieadmin_pro_file_get_version_num('cookieadmin/cookieadmin.php'); } // Prevent update of cookieadmin free function cookieadmin_pro_file_get_version_num($plugin){ // In case of cookieadmin deactive include_once(ABSPATH . 'wp-admin/includes/plugin.php'); $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/'.$plugin); if(empty($plugin_data)){ return false; } return $plugin_data['Version']; } // Prevent update of cookieadmin free function cookieadmin_pro_disable_manual_update_for_plugin($transient){ $plugin = 'cookieadmin/cookieadmin.php'; // Is update available? if(!isset($transient->response) || !isset($transient->response[$plugin])){ return $transient; } $free_version = cookieadmin_pro_get_free_version_num(); $pro_version = COOKIEADMIN_PRO_VERSION; if(!empty($GLOBALS['cookieadmin_pro_is_upgraded'])){ $pro_version = cookieadmin_pro_file_get_version_num('cookieadmin-pro/cookieadmin-pro.php'); } // Update the cookieadmin version to the equivalent of Pro version if(!empty($pro_version) && version_compare($free_version, $pro_version, '<')){ $transient->response[$plugin]->new_version = $pro_version; $transient->response[$plugin]->package = 'https://downloads.wordpress.org/plugin/cookieadmin.'.$pro_version.'.zip'; }else{ unset($transient->response[$plugin]); } return $transient; } // Auto update free version after update pro version function cookieadmin_pro_update_free_after_pro($upgrader_object, $options){ // Check if the action is an update for the plugins if($options['action'] != 'update' || $options['type'] != 'plugin'){ return; } // Define the slugs for the free and pro plugins $free_slug = 'cookieadmin/cookieadmin.php'; $pro_slug = 'cookieadmin-pro/cookieadmin-pro.php'; // Check if the pro plugin is in the list of updated plugins if( (isset($options['plugins']) && in_array($pro_slug, $options['plugins']) && !in_array($free_slug, $options['plugins'])) || (isset($options['plugin']) && $pro_slug == $options['plugin']) ){ // Trigger the update for the free plugin $current_version = cookieadmin_pro_get_free_version_num(); if(empty($current_version)){ return; } $GLOBALS['cookieadmin_pro_is_upgraded'] = true; // This will set the 'update_plugins' transient again wp_update_plugins(); // Check for updates for the free plugin $update_plugins = get_site_transient('update_plugins'); if(empty($update_plugins) || !isset($update_plugins->response[$free_slug]) || version_compare($update_plugins->response[$free_slug]->new_version, $current_version, '<=')){ return; } require_once(ABSPATH . 'wp-admin/includes/plugin.php'); require_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); $skin = wp_doing_ajax()? new WP_Ajax_Upgrader_Skin() : null; $upgrader = new Plugin_Upgrader($skin); $upgraded = $upgrader->upgrade($free_slug); if(!is_wp_error($upgraded) && $upgraded){ // Re-active free plugins if( file_exists( WP_PLUGIN_DIR . '/'. $free_slug ) && is_plugin_inactive($free_slug) ){ activate_plugin($free_slug); // TODO for network } // Re-active pro plugins if( file_exists( WP_PLUGIN_DIR . '/'. $pro_slug ) && is_plugin_inactive($pro_slug) ){ activate_plugin($pro_slug); // TODO for network } } } } function cookieadmin_pro_api_url($main_server = 0, $suffix = 'cookieadmin'){ global $cookieadmin; $r = array( 'https://s0.softaculous.com/a/softwp/', 'https://s1.softaculous.com/a/softwp/', 'https://s2.softaculous.com/a/softwp/', 'https://s3.softaculous.com/a/softwp/', 'https://s4.softaculous.com/a/softwp/', 'https://s5.softaculous.com/a/softwp/', 'https://s7.softaculous.com/a/softwp/', 'https://s8.softaculous.com/a/softwp/' ); $mirror = $r[array_rand($r)]; if(!empty($main_server) && $main_server < 0){ return $mirror; } // If the license is newly issued, we need to fetch from API only if(!empty($main_server) || empty($cookieadmin['license']['last_edit']) || (!empty($cookieadmin['license']['last_edit']) && (time() - 3600) < $cookieadmin['license']['last_edit']) ){ $mirror = COOKIEADMIN_API; } if(!empty($suffix)){ $mirror = str_replace('/softwp', '/'.$suffix, $mirror); } return $mirror; } function cookieadmin_pro_plugins_expired($plugins){ $plugins[] = 'CookieAdmin'; return $plugins; } function cookieadmin_pro_expiry_notice(){ global $cookieadmin; // The combined notice for all Softaculous plugin to show that the license has expired $dismissed_at = get_option('softaculous_expired_licenses', 0); $expired_plugins = apply_filters('softaculous_expired_licenses', []); if( !empty($expired_plugins) && is_array($expired_plugins) && !defined('SOFTACULOUS_EXPIRY_LICENSES') && (empty($dismissed_at) || ($dismissed_at + WEEK_IN_SECONDS) < time()) ){ define('SOFTACULOUS_EXPIRY_LICENSES', true); // To make sure other plugins don't return a Notice echo '<div class="notice notice-error is-dismissible" id="cookieadmin-pro-expiry-notice"> <p>'.sprintf(__('Your SoftWP license has %1$sexpired%2$s. Please renew it to continue receiving uninterrupted updates and support for %3$s.', 'cookieadmin-pro'), '<font style="color:red;"><b>', '</b></font>', esc_html(implode(', ', $expired_plugins)) ). '</p> </div>'; wp_register_script('cookieadmin-pro-expiry-notice', '', ['jquery'], COOKIEADMIN_PRO_VERSION, true); wp_enqueue_script('cookieadmin-pro-expiry-notice'); wp_add_inline_script('cookieadmin-pro-expiry-notice', ' jQuery(document).ready(function(){ jQuery("#cookieadmin-pro-expiry-notice").on("click", ".notice-dismiss", function(e){ e.preventDefault(); let target = jQuery(e.target); let jEle = target.closest("#cookieadmin-pro-expiry-notice"); jEle.slideUp(); jQuery.post("'.admin_url('admin-ajax.php').'", { cookieadmin_pro_security : "'.wp_create_nonce('cookieadmin_pro_admin_js_nonce').'", action: "cookieadmin_pro_ajax_handler", cookieadmin_act: "dismiss_expired_licenses", }, function(res){ if(!res["success"]){ alert(res["data"]); } }).fail(function(data){ alert("There seems to be some issue dismissing this alert"); }); }); })'); } } function cookieadmin_pro_human_readable_time($timestamp){ $now = time(); $today_start = strtotime('today'); $yesterday_start = strtotime('yesterday'); if ($timestamp >= $today_start) { return 'Today ' . wp_date('g:i A T', $timestamp); } elseif ($timestamp >= $yesterday_start) { return 'Yesterday ' . wp_date('g:i A T', $timestamp); } else { return wp_date('M j Y g:i A T', $timestamp); // e.g., Dec 6 2024 6:00 AM UTC } }PK �g[G �3 3 license.phpnu �[��� <?php /* * CookieAdmin Pro * https://cookieadmin.net * (c) Softaculous Team */ namespace CookieAdminPro; if(!defined('ABSPATH')){ die('Hacking Attempt!'); } class License{ static function cookieadmin_pro_license(){ global $lic_resp, $cookieadmin_lang, $cookieadmin_error, $cookieadmin_msg; if(empty($_POST['cookieadmin_pro_license_nonce']) || !wp_verify_nonce($_POST['cookieadmin_pro_license_nonce'], 'cookieadmin_pro_license')){ $cookieadmin_error = __('Security Check Failed', 'cookieadmin-pro'); return; } $license = !empty($_POST['cookieadmin_pro_license']) ? sanitize_key(wp_unslash($_POST['cookieadmin_pro_license'])) : ''; if(empty($license)){ $cookieadmin_error = __('The license key was not submitted', 'cookieadmin-pro'); return; } cookieadmin_pro_load_license($license); if(!is_array($lic_resp)){ $cookieadmin_error = __('The response was malformed<br>'.var_export($lic_resp, true), 'cookieadmin-pro'); return; } $json = json_decode($lic_resp['body'], true); if(empty($json['license'])){ $cookieadmin_error = __('The license key is invalid', 'cookieadmin-pro'); return; } $cookieadmin_msg = __('Successfully updated the license key', 'cookieadmin-pro'); } static function cookieadmin_show_license(){ global $cookieadmin; if(isset($_REQUEST['save_cookieadmin_pro_license'])){ \CookieAdminPro\License::cookieadmin_pro_license(); } ?> <?php \CookieAdmin\Admin::header_theme(__('License', 'cookieadmin-pro')); ?> <div class="cookieadmin-pro-license-content wrap" > <div class="cookieadmin-pro-tab-group" style=" width:100% ;background:white; padding:20px;"> <table class="wp-list-table fixed striped users cookieadmin-pro-license-table" cellspacing="1" border="0" width="100%" cellpadding="10" align="center"> <tbody> <tr> <th align="left" width="25%"><?php esc_html_e('CookieAdmin Version', 'cookieadmin-pro'); ?></th> <td><?php echo COOKIEADMIN_PRO_VERSION.' ('.esc_html__('Pro Version', 'cookieadmin-pro').')'; ?> </td> </tr> <tr> <th align="left" valign="top"><?php esc_html_e('CookieAdmin License', 'cookieadmin-pro'); ?></th> <td align="left"> <form method="post" action=""> <?php echo (defined('COOKIEADMIN_PREMIUM') && empty($cookieadmin['license']['license']) ? '<span style="color:red">'.esc_html__('Unlicensed', 'cookieadmin-pro').'</span> ' : '')?> <input type="hidden" name="cookieadmin_pro_license_nonce" value="<?php echo wp_create_nonce('cookieadmin_pro_license');?>"/> <input type="text" name="cookieadmin_pro_license" value="<?php echo (empty($cookieadmin['license']['license']) ? '': esc_html($cookieadmin['license']['license']))?>" size="30" placeholder="e.g. COOKA-11111-22222-33333-44444" style="width:300px;"> <input name="save_cookieadmin_pro_license" class="cookieadmin-btn cookieadmin-btn-primary dosmtp-sumbit-licence" value="Update License" type="submit"> </form> <?php if(!empty($cookieadmin['license']['license'])){ $expires = $cookieadmin['license']['expires']; $expires = substr($expires, 0, 4).'/'.substr($expires, 4, 2).'/'.substr($expires, 6); echo '<div style="margin-top:10px;">'.esc_html__('License Status', 'cookieadmin-pro').' : '.(empty($cookieadmin['license']['status_txt']) ? 'N.A.' : wp_kses_post($cookieadmin['license']['status_txt'])).' '.($cookieadmin['license']['expires'] <= date('Ymd') ? esc_html__('License Expires', 'cookieadmin-pro').' : <span style="color:red;">'.esc_attr($expires).'</span>' : (empty($cookieadmin['license']['has_plid']) ? esc_html__('License Expires', 'cookieadmin-pro').' : '.esc_html($expires) : '')).' </div>'; }?> </td> </tr> <tr> <th align="left">URL</th> <td><?php echo esc_url(get_site_url()); ?></td> </tr> <tr> <th align="left">Path</th> <td><?php echo ABSPATH; ?></td> </tr> <tr> <th align="left"><?php esc_html_e('Server\'s IP Address', 'cookieadmin-pro') ?></th> <td><?php echo esc_attr($_SERVER['SERVER_ADDR']); ?></td> </tr> </tbody> </table> </div> </div> <?php \CookieAdmin\Admin::footer_theme(); } }PK �g[߁a��� �� plugin-update-checker.phpnu �[��� <?php /** * Plugin Update Checker Library 3.2 * http://w-shadow.com/ * * Copyright 2016 Janis Elsts * Released under the MIT license. See license.txt for details. */ if ( !class_exists('CookieAdminUpdateChecker_3_2', false) ): /** * A custom plugin update checker. * * @author Janis Elsts * @copyright 2016 * @version 3.2 * @access public */ class CookieAdminUpdateChecker_3_2 { public $metadataUrl = ''; //The URL of the plugin's metadata file. public $pluginAbsolutePath = ''; //Full path of the main plugin file. public $pluginFile = ''; //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins. public $slug = ''; //Plugin slug. public $optionName = ''; //Where to store the update info. public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory. public $debugMode = false; //Set to TRUE to enable error reporting. Errors are raised using trigger_error() //and should be logged to the standard PHP error log. public $scheduler; protected $upgraderStatus; private $debugBarPlugin = null; private $cachedInstalledVersion = null; private $metadataHost = ''; //The host component of $metadataUrl. /** * Class constructor. * * @param string $metadataUrl The URL of the plugin's metadata file. * @param string $pluginFile Fully qualified path to the main plugin file. * @param string $slug The plugin's 'slug'. If not specified, the filename part of $pluginFile sans '.php' will be used as the slug. * @param integer $checkPeriod How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks. * @param string $optionName Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'. * @param string $muPluginFile Optional. The plugin filename relative to the mu-plugins directory. */ public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = ''){ $this->metadataUrl = $metadataUrl; $this->pluginAbsolutePath = $pluginFile; $this->pluginFile = plugin_basename($this->pluginAbsolutePath); $this->muPluginFile = $muPluginFile; $this->slug = $slug; $this->optionName = $optionName; $this->debugMode = (bool)(constant('WP_DEBUG')); //If no slug is specified, use the name of the main plugin file as the slug. //For example, 'my-cool-plugin/cool-plugin.php' becomes 'cool-plugin'. if ( empty($this->slug) ){ $this->slug = basename($this->pluginFile, '.php'); } //Plugin slugs must be unique. $slugCheckFilter = 'puc_is_slug_in_use-' . $this->slug; $slugUsedBy = apply_filters($slugCheckFilter, false); if ( $slugUsedBy ) { $this->triggerError(sprintf( 'Plugin slug "%s" is already in use by %s. Slugs must be unique.', htmlentities($this->slug), htmlentities($slugUsedBy) ), E_USER_ERROR); } add_filter($slugCheckFilter, array($this, 'getAbsolutePath')); if ( empty($this->optionName) ){ $this->optionName = 'external_updates-' . $this->slug; } //Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume //it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir). if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) { $this->muPluginFile = $this->pluginFile; } $this->scheduler = $this->createScheduler($checkPeriod); $this->upgraderStatus = new CookieAdmin_PucUpgraderStatus_3_2(); $this->installHooks(); } /** * Create an instance of the scheduler. * * This is implemented as a method to make it possible for plugins to subclass the update checker * and substitute their own scheduler. * * @param int $checkPeriod * @return CookieAdmin_PucScheduler_3_2 */ protected function createScheduler($checkPeriod) { return new CookieAdmin_PucScheduler_3_2($this, $checkPeriod); } /** * Install the hooks required to run periodic update checks and inject update info * into WP data structures. * * @return void */ protected function installHooks(){ //Override requests for plugin information add_filter('plugins_api', array($this, 'injectInfo'), 20, 3); //Insert our update info into the update array maintained by WP. add_filter('site_transient_update_plugins', array($this,'injectUpdate')); //WP 3.0+ add_filter('transient_update_plugins', array($this,'injectUpdate')); //WP 2.8+ add_filter('site_transient_update_plugins', array($this, 'injectTranslationUpdates')); add_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10, 2); add_action('admin_init', array($this, 'handleManualCheck')); add_action('all_admin_notices', array($this, 'displayManualCheckResult')); //Clear the version number cache when something - anything - is upgraded or WP clears the update cache. add_filter('upgrader_post_install', array($this, 'clearCachedVersion')); add_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion')); //Clear translation updates when WP clears the update cache. //This needs to be done directly because the library doesn't actually remove obsolete plugin updates, //it just hides them (see getUpdate()). We can't do that with translations - too much disk I/O. add_action('delete_site_transient_update_plugins', array($this, 'clearCachedTranslationUpdates')); if ( did_action('plugins_loaded') ) { $this->initDebugBarPanel(); } else { add_action('plugins_loaded', array($this, 'initDebugBarPanel')); } //Rename the update directory to be the same as the existing directory. add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3); //Enable language support (i18n). load_plugin_textdomain('plugin-update-checker', false, plugin_basename(dirname(__FILE__)) . '/languages'); //Allow HTTP requests to the metadata URL even if it's on a local host. $this->metadataHost = @parse_url($this->metadataUrl, PHP_URL_HOST); add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2); } /** * Explicitly allow HTTP requests to the metadata URL. * * WordPress has a security feature where the HTTP API will reject all requests that are sent to * another site hosted on the same server as the current site (IP match), a local host, or a local * IP, unless the host exactly matches the current site. * * This feature is opt-in (at least in WP 4.4). Apparently some people enable it. * * That can be a problem when you're developing your plugin and you decide to host the update information * on the same server as your test site. Update requests will mysteriously fail. * * We fix that by adding an exception for the metadata host. * * @param bool $allow * @param string $host * @return bool */ public function allowMetadataHost($allow, $host) { if ( strtolower($host) === strtolower($this->metadataHost) ) { return true; } return $allow; } /** * Retrieve plugin info from the configured API endpoint. * * @uses wp_remote_get() * * @param array $queryArgs Additional query arguments to append to the request. Optional. * @return CookieAdminInfo_3_2 */ public function requestInfo($queryArgs = array()){ //Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()). $installedVersion = $this->getInstalledVersion(); $queryArgs['installed_version'] = ($installedVersion !== null) ? $installedVersion : ''; $queryArgs = apply_filters('puc_request_info_query_args-'.$this->slug, $queryArgs); //Various options for the wp_remote_get() call. Plugins can filter these, too. $options = array( 'timeout' => 10, //seconds 'headers' => array( 'Accept' => 'application/json' ), ); $options = apply_filters('puc_request_info_options-'.$this->slug, $options); //The plugin info should be at 'http://your-api.com/url/here/$slug/info.json' $url = $this->metadataUrl; if ( !empty($queryArgs) ){ $url = add_query_arg($queryArgs, $url); } $result = wp_remote_get( $url, $options ); //Try to parse the response $status = $this->validateApiResponse($result); $pluginInfo = null; if ( !is_wp_error($status) ){ $pluginInfo = CookieAdminInfo_3_2::fromJson($result['body']); if ( $pluginInfo !== null ) { $pluginInfo->filename = $this->pluginFile; $pluginInfo->slug = $this->slug; } } else { $this->triggerError( sprintf('The URL %s does not point to a valid plugin metadata file. ', $url) . $status->get_error_message(), E_USER_WARNING ); } $pluginInfo = apply_filters('puc_request_info_result-'.$this->slug, $pluginInfo, $result); return $pluginInfo; } /** * Check if $result is a successful update API response. * * @param array|WP_Error $result * @return true|WP_Error */ private function validateApiResponse($result) { if ( is_wp_error($result) ) { /** @var WP_Error $result */ return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message()); } if ( !isset($result['response']['code']) ) { return new WP_Error('puc_no_response_code', 'wp_remote_get() returned an unexpected result.'); } if ( $result['response']['code'] !== 200 ) { return new WP_Error( 'puc_unexpected_response_code', 'HTTP response code is ' . $result['response']['code'] . ' (expected: 200)' ); } if ( empty($result['body']) ) { return new WP_Error('puc_empty_response', 'The metadata file appears to be empty.'); } return true; } /** * Retrieve the latest update (if any) from the configured API endpoint. * * @uses CookieAdminUpdateChecker::requestInfo() * * @return CookieAdminUpdate_3_2 An instance of CookieAdminUpdate, or NULL when no updates are available. */ public function requestUpdate(){ //For the sake of simplicity, this function just calls requestInfo() //and transforms the result accordingly. $pluginInfo = $this->requestInfo(array('checking_for_updates' => '1')); if ( $pluginInfo == null ){ return null; } $update = CookieAdminUpdate_3_2::fromCookieAdminInfo($pluginInfo); //Keep only those translation updates that apply to this site. $update->translations = $this->filterApplicableTranslations($update->translations); return $update; } /** * Filter a list of translation updates and return a new list that contains only updates * that apply to the current site. * * @param array $translations * @return array */ private function filterApplicableTranslations($translations) { $languages = array_flip(array_values(get_available_languages())); $installedTranslations = wp_get_installed_translations('plugins'); if ( isset($installedTranslations[$this->slug]) ) { $installedTranslations = $installedTranslations[$this->slug]; } else { $installedTranslations = array(); } $applicableTranslations = array(); foreach($translations as $translation) { //Does it match one of the available core languages? $isApplicable = array_key_exists($translation->language, $languages); //Is it more recent than an already-installed translation? if ( isset($installedTranslations[$translation->language]) ) { $updateTimestamp = strtotime($translation->updated); $installedTimestamp = strtotime($installedTranslations[$translation->language]['PO-Revision-Date']); $isApplicable = $updateTimestamp > $installedTimestamp; } if ( $isApplicable ) { $applicableTranslations[] = $translation; } } return $applicableTranslations; } /** * Get the currently installed version of the plugin. * * @return string Version number. */ public function getInstalledVersion(){ if ( isset($this->cachedInstalledVersion) ) { return $this->cachedInstalledVersion; } $pluginHeader = $this->getPluginHeader(); if ( isset($pluginHeader['Version']) ) { $this->cachedInstalledVersion = $pluginHeader['Version']; return $pluginHeader['Version']; } else { //This can happen if the filename points to something that is not a plugin. $this->triggerError( sprintf( "Can't to read the Version header for '%s'. The filename is incorrect or is not a plugin.", $this->pluginFile ), E_USER_WARNING ); return null; } } /** * Get plugin's metadata from its file header. * * @return array */ protected function getPluginHeader() { if ( !is_file($this->pluginAbsolutePath) ) { //This can happen if the plugin filename is wrong. $this->triggerError( sprintf( "Can't to read the plugin header for '%s'. The file does not exist.", $this->pluginFile ), E_USER_WARNING ); return array(); } if ( !function_exists('get_plugin_data') ){ /** @noinspection PhpIncludeInspection */ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); } return get_plugin_data($this->pluginAbsolutePath, false, false); } /** * Check for plugin updates. * The results are stored in the DB option specified in $optionName. * * @return CookieAdminUpdate_3_2|null */ public function checkForUpdates(){ $installedVersion = $this->getInstalledVersion(); //Fail silently if we can't find the plugin or read its header. if ( $installedVersion === null ) { $this->triggerError( sprintf('Skipping update check for %s - installed version unknown.', $this->pluginFile), E_USER_WARNING ); return null; } $state = $this->getUpdateState(); if ( empty($state) ){ $state = new stdClass; $state->lastCheck = 0; $state->checkedVersion = ''; $state->update = null; } $state->lastCheck = time(); $state->checkedVersion = $installedVersion; $this->setUpdateState($state); //Save before checking in case something goes wrong $state->update = $this->requestUpdate(); $this->setUpdateState($state); return $this->getUpdate(); } /** * Load the update checker state from the DB. * * @return stdClass|null */ public function getUpdateState() { $state = get_site_option($this->optionName, null); if ( empty($state) || !is_object($state)) { $state = null; } if ( isset($state, $state->update) && is_object($state->update) ) { $state->update = CookieAdminUpdate_3_2::fromObject($state->update); } return $state; } /** * Persist the update checker state to the DB. * * @param StdClass $state * @return void */ private function setUpdateState($state) { if ( isset($state->update) && is_object($state->update) && method_exists($state->update, 'toStdClass') ) { $update = $state->update; /** @var CookieAdminUpdate_3_2 $update */ $state->update = $update->toStdClass(); } update_site_option($this->optionName, $state); } /** * Reset update checker state - i.e. last check time, cached update data and so on. * * Call this when your plugin is being uninstalled, or if you want to * clear the update cache. */ public function resetUpdateState() { delete_site_option($this->optionName); } /** * Intercept plugins_api() calls that request information about our plugin and * use the configured API endpoint to satisfy them. * * @see plugins_api() * * @param mixed $result * @param string $action * @param array|object $args * @return mixed */ public function injectInfo($result, $action = null, $args = null){ $relevant = ($action == 'plugin_information') && isset($args->slug) && ( ($args->slug == $this->slug) || ($args->slug == dirname($this->pluginFile)) ); if ( !$relevant ) { return $result; } $pluginInfo = $this->requestInfo(); $pluginInfo = apply_filters('puc_pre_inject_info-' . $this->slug, $pluginInfo); if ( $pluginInfo ) { return $pluginInfo->toWpFormat(); } return $result; } /** * Insert the latest update (if any) into the update list maintained by WP. * * @param StdClass $updates Update list. * @return StdClass Modified update list. */ public function injectUpdate($updates){ //Is there an update to insert? $update = $this->getUpdate(); //No update notifications for mu-plugins unless explicitly enabled. The MU plugin file //is usually different from the main plugin file so the update wouldn't show up properly anyway. if ( $this->isUnknownMuPlugin() ) { $update = null; } if ( !empty($update) ) { //Let plugins filter the update info before it's passed on to WordPress. $update = apply_filters('puc_pre_inject_update-' . $this->slug, $update); $updates = $this->addUpdateToList($updates, $update); } else { //Clean up any stale update info. $updates = $this->removeUpdateFromList($updates); } return $updates; } /** * @param StdClass|null $updates * @param CookieAdminUpdate_3_2 $updateToAdd * @return StdClass */ private function addUpdateToList($updates, $updateToAdd) { if ( !is_object($updates) ) { $updates = new stdClass(); $updates->response = array(); } $wpUpdate = $updateToAdd->toWpFormat(); $pluginFile = $this->pluginFile; if ( $this->isMuPlugin() ) { //WP does not support automatic update installation for mu-plugins, but we can still display a notice. $wpUpdate->package = null; $pluginFile = $this->muPluginFile; } $updates->response[$pluginFile] = $wpUpdate; return $updates; } /** * @param stdClass|null $updates * @return stdClass|null */ private function removeUpdateFromList($updates) { if ( isset($updates, $updates->response) ) { unset($updates->response[$this->pluginFile]); if ( !empty($this->muPluginFile) ) { unset($updates->response[$this->muPluginFile]); } } return $updates; } /** * Insert translation updates into the list maintained by WordPress. * * @param stdClass $updates * @return stdClass */ public function injectTranslationUpdates($updates) { $translationUpdates = $this->getTranslationUpdates(); if ( empty($translationUpdates) ) { return $updates; } //Being defensive. if ( !is_object($updates) ) { $updates = new stdClass(); } if ( !isset($updates->translations) ) { $updates->translations = array(); } //In case there's a name collision with a plugin hosted on wordpress.org, //remove any preexisting updates that match our plugin. $translationType = 'plugin'; $filteredTranslations = array(); foreach($updates->translations as $translation) { if ( ($translation['type'] === $translationType) && ($translation['slug'] === $this->slug) ) { continue; } $filteredTranslations[] = $translation; } $updates->translations = $filteredTranslations; //Add our updates to the list. foreach($translationUpdates as $update) { $convertedUpdate = array_merge( array( 'type' => $translationType, 'slug' => $this->slug, 'autoupdate' => 0, //AFAICT, WordPress doesn't actually use the "version" field for anything. //But lets make sure it's there, just in case. 'version' => isset($update->version) ? $update->version : ('1.' . strtotime($update->updated)), ), (array)$update ); $updates->translations[] = $convertedUpdate; } return $updates; } /** * Rename the update directory to match the existing plugin directory. * * When WordPress installs a plugin or theme update, it assumes that the ZIP file will contain * exactly one directory, and that the directory name will be the same as the directory where * the plugin/theme is currently installed. * * GitHub and other repositories provide ZIP downloads, but they often use directory names like * "project-branch" or "project-tag-hash". We need to change the name to the actual plugin folder. * * This is a hook callback. Don't call it from a plugin. * * @param string $source The directory to copy to /wp-content/plugins. Usually a subdirectory of $remoteSource. * @param string $remoteSource WordPress has extracted the update to this directory. * @param WP_Upgrader $upgrader * @return string|WP_Error */ public function fixDirectoryName($source, $remoteSource, $upgrader) { global $wp_filesystem; /** @var WP_Filesystem_Base $wp_filesystem */ //Basic sanity checks. if ( !isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem) ) { return $source; } //If WordPress is upgrading anything other than our plugin, leave the directory name unchanged. if ( !$this->isPluginBeingUpgraded($upgrader) ) { return $source; } //Rename the source to match the existing plugin directory. $pluginDirectoryName = dirname($this->pluginFile); if ( $pluginDirectoryName === '.' ) { return $source; } $correctedSource = trailingslashit($remoteSource) . $pluginDirectoryName . '/'; if ( $source !== $correctedSource ) { //The update archive should contain a single directory that contains the rest of plugin files. Otherwise, //WordPress will try to copy the entire working directory ($source == $remoteSource). We can't rename //$remoteSource because that would break WordPress code that cleans up temporary files after update. if ( $this->isBadDirectoryStructure($remoteSource) ) { return new WP_Error( 'puc-incorrect-directory-structure', sprintf( 'The directory structure of the update is incorrect. All plugin files should be inside ' . 'a directory named <span class="code">%s</span>, not at the root of the ZIP file.', htmlentities($this->slug) ) ); } /** @var WP_Upgrader_Skin $upgrader->skin */ $upgrader->skin->feedback(sprintf( 'Renaming %s to %s…', '<span class="code">' . basename($source) . '</span>', '<span class="code">' . $pluginDirectoryName . '</span>' )); if ( $wp_filesystem->move($source, $correctedSource, true) ) { $upgrader->skin->feedback('Plugin directory successfully renamed.'); return $correctedSource; } else { return new WP_Error( 'puc-rename-failed', 'Unable to rename the update to match the existing plugin directory.' ); } } return $source; } /** * Check for incorrect update directory structure. An update must contain a single directory, * all other files should be inside that directory. * * @param string $remoteSource Directory path. * @return bool */ private function isBadDirectoryStructure($remoteSource) { global $wp_filesystem; /** @var WP_Filesystem_Base $wp_filesystem */ $sourceFiles = $wp_filesystem->dirlist($remoteSource); if ( is_array($sourceFiles) ) { $sourceFiles = array_keys($sourceFiles); $firstFilePath = trailingslashit($remoteSource) . $sourceFiles[0]; return (count($sourceFiles) > 1) || (!$wp_filesystem->is_dir($firstFilePath)); } //Assume it's fine. return false; } /** * Is there and update being installed RIGHT NOW, for this specific plugin? * * @param WP_Upgrader|null $upgrader The upgrader that's performing the current update. * @return bool */ public function isPluginBeingUpgraded($upgrader = null) { return $this->upgraderStatus->isPluginBeingUpgraded($this->pluginFile, $upgrader); } /** * Get the details of the currently available update, if any. * * If no updates are available, or if the last known update version is below or equal * to the currently installed version, this method will return NULL. * * Uses cached update data. To retrieve update information straight from * the metadata URL, call requestUpdate() instead. * * @return CookieAdminUpdate_3_2|null */ public function getUpdate() { $state = $this->getUpdateState(); /** @var StdClass $state */ //Is there an update available? if ( isset($state, $state->update) ) { $update = $state->update; //Check if the update is actually newer than the currently installed version. $installedVersion = $this->getInstalledVersion(); if ( ($installedVersion !== null) && version_compare($update->version, $installedVersion, '>') ){ $update->filename = $this->pluginFile; return $update; } } return null; } /** * Get a list of available translation updates. * * This method will return an empty array if there are no updates. * Uses cached update data. * * @return array */ public function getTranslationUpdates() { $state = $this->getUpdateState(); if ( isset($state, $state->update, $state->update->translations) ) { return $state->update->translations; } return array(); } /** * Remove all cached translation updates. * * @see wp_clean_update_cache */ public function clearCachedTranslationUpdates() { $state = $this->getUpdateState(); if ( isset($state, $state->update, $state->update->translations) ) { $state->update->translations = array(); $this->setUpdateState($state); } } /** * Add a "Check for updates" link to the plugin row in the "Plugins" page. By default, * the new link will appear after the "Visit plugin site" link. * * You can change the link text by using the "puc_manual_check_link-$slug" filter. * Returning an empty string from the filter will disable the link. * * @param array $pluginMeta Array of meta links. * @param string $pluginFile * @return array */ public function addCheckForUpdatesLink($pluginMeta, $pluginFile) { $isRelevant = ($pluginFile == $this->pluginFile) || (!empty($this->muPluginFile) && $pluginFile == $this->muPluginFile); if ( $isRelevant && current_user_can('update_plugins') ) { $linkUrl = wp_nonce_url( add_query_arg( array( 'puc_check_for_updates' => 1, 'puc_slug' => $this->slug, ), self_admin_url('plugins.php') ), 'puc_check_for_updates' ); $linkText = apply_filters('puc_manual_check_link-' . $this->slug, __('Check for updates', 'plugin-update-checker')); if ( !empty($linkText) ) { $final_link = sprintf('<a href="%s">%s</a>', esc_attr($linkUrl), $linkText); $pluginMeta[] = apply_filters('puc_manual_final_check_link-' . $this->slug, $final_link); } } return $pluginMeta; } /** * Check for updates when the user clicks the "Check for updates" link. * @see self::addCheckForUpdatesLink() * * @return void */ public function handleManualCheck() { $shouldCheck = isset($_GET['puc_check_for_updates'], $_GET['puc_slug']) && $_GET['puc_slug'] == $this->slug && current_user_can('update_plugins') && check_admin_referer('puc_check_for_updates'); if ( $shouldCheck ) { $update = $this->checkForUpdates(); $status = ($update === null) ? 'no_update' : 'update_available'; wp_redirect(add_query_arg( array( 'puc_update_check_result' => $status, 'puc_slug' => $this->slug, ), self_admin_url('plugins.php') )); } } /** * Display the results of a manual update check. * @see self::handleManualCheck() * * You can change the result message by using the "puc_manual_check_message-$slug" filter. */ public function displayManualCheckResult() { if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->slug) ) { $status = strval($_GET['puc_update_check_result']); if ( $status == 'no_update' ) { $message = __('This plugin is up to date.', 'plugin-update-checker'); } else if ( $status == 'update_available' ) { $message = __('A new version of this plugin is available.', 'plugin-update-checker'); } else { $message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), htmlentities($status)); } printf( '<div class="updated notice is-dismissible"><p>%s</p></div>', apply_filters('puc_manual_check_message-' . $this->slug, $message, $status) ); } } /** * Check if the plugin file is inside the mu-plugins directory. * * @return bool */ protected function isMuPlugin() { static $cachedResult = null; if ( $cachedResult === null ) { //Convert both paths to the canonical form before comparison. $muPluginDir = realpath(WPMU_PLUGIN_DIR); $pluginPath = realpath($this->pluginAbsolutePath); if(!empty($muPluginDir)){ $cachedResult = (strpos($pluginPath, $muPluginDir) === 0); }else{ $cachedResult = false; } } return $cachedResult; } /** * MU plugins are partially supported, but only when we know which file in mu-plugins * corresponds to this plugin. * * @return bool */ protected function isUnknownMuPlugin() { return empty($this->muPluginFile) && $this->isMuPlugin(); } /** * Clear the cached plugin version. This method can be set up as a filter (hook) and will * return the filter argument unmodified. * * @param mixed $filterArgument * @return mixed */ public function clearCachedVersion($filterArgument = null) { $this->cachedInstalledVersion = null; return $filterArgument; } /** * Get absolute path to the main plugin file. * * @return string */ public function getAbsolutePath() { return $this->pluginAbsolutePath; } /** * Register a callback for filtering query arguments. * * The callback function should take one argument - an associative array of query arguments. * It should return a modified array of query arguments. * * @uses add_filter() This method is a convenience wrapper for add_filter(). * * @param callable $callback * @return void */ public function addQueryArgFilter($callback){ add_filter('puc_request_info_query_args-'.$this->slug, $callback); } /** * Register a callback for filtering arguments passed to wp_remote_get(). * * The callback function should take one argument - an associative array of arguments - * and return a modified array or arguments. See the WP documentation on wp_remote_get() * for details on what arguments are available and how they work. * * @uses add_filter() This method is a convenience wrapper for add_filter(). * * @param callable $callback * @return void */ public function addHttpRequestArgFilter($callback){ add_filter('puc_request_info_options-'.$this->slug, $callback); } /** * Register a callback for filtering the plugin info retrieved from the external API. * * The callback function should take two arguments. If the plugin info was retrieved * successfully, the first argument passed will be an instance of CookieAdminInfo. Otherwise, * it will be NULL. The second argument will be the corresponding return value of * wp_remote_get (see WP docs for details). * * The callback function should return a new or modified instance of CookieAdminInfo or NULL. * * @uses add_filter() This method is a convenience wrapper for add_filter(). * * @param callable $callback * @return void */ public function addResultFilter($callback){ add_filter('puc_request_info_result-'.$this->slug, $callback, 10, 2); } /** * Register a callback for one of the update checker filters. * * Identical to add_filter(), except it automatically adds the "puc_" prefix * and the "-$plugin_slug" suffix to the filter name. For example, "request_info_result" * becomes "puc_request_info_result-your_plugin_slug". * * @param string $tag * @param callable $callback * @param int $priority * @param int $acceptedArgs */ public function addFilter($tag, $callback, $priority = 10, $acceptedArgs = 1) { add_filter('puc_' . $tag . '-' . $this->slug, $callback, $priority, $acceptedArgs); } /** * Initialize the update checker Debug Bar plugin/add-on thingy. */ public function initDebugBarPanel() { $debugBarPlugin = dirname(__FILE__) . '/debug-bar-plugin.php'; if ( class_exists('Debug_Bar', false) && file_exists($debugBarPlugin) ) { /** @noinspection PhpIncludeInspection */ require_once $debugBarPlugin; $this->debugBarPlugin = new CookieAdmin_PucDebugBarPlugin_3_2($this); } } /** * Trigger a PHP error, but only when $debugMode is enabled. * * @param string $message * @param int $errorType */ protected function triggerError($message, $errorType) { if ( $this->debugMode ) { trigger_error($message, $errorType); } } } endif; if ( !class_exists('CookieAdminInfo_3_2', false) ): /** * A container class for holding and transforming various plugin metadata. * * @author Janis Elsts * @copyright 2016 * @version 3.2 * @access public */ class CookieAdminInfo_3_2 { //Most fields map directly to the contents of the plugin's info.json file. //See the relevant docs for a description of their meaning. public $name; public $slug; public $version; public $homepage; public $sections = array(); public $banners; public $translations = array(); public $download_url; public $author; public $author_homepage; public $requires; public $tested; public $upgrade_notice; public $rating; public $num_ratings; public $downloaded; public $active_installs; public $last_updated; public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything. public $filename; //Plugin filename relative to the plugins directory. /** * Create a new instance of CookieAdminInfo from JSON-encoded plugin info * returned by an external update API. * * @param string $json Valid JSON string representing plugin info. * @return CookieAdminInfo_3_2|null New instance of CookieAdminInfo, or NULL on error. */ public static function fromJson($json){ /** @var StdClass $apiResponse */ $apiResponse = json_decode($json); if ( empty($apiResponse) || !is_object($apiResponse) ){ trigger_error( "Failed to parse plugin metadata. Try validating your .json file with http://jsonlint.com/", E_USER_NOTICE ); return null; } $valid = self::validateMetadata($apiResponse); if ( is_wp_error($valid) ){ trigger_error($valid->get_error_message(), E_USER_NOTICE); return null; } $info = new self(); foreach(get_object_vars($apiResponse) as $key => $value){ $info->$key = $value; } //json_decode decodes assoc. arrays as objects. We want it as an array. $info->sections = (array)$info->sections; return $info; } /** * Very, very basic validation. * * @param StdClass $apiResponse * @return bool|WP_Error */ protected static function validateMetadata($apiResponse) { if ( !isset($apiResponse->name, $apiResponse->version) || empty($apiResponse->name) || empty($apiResponse->version) ) { return new WP_Error( 'puc-invalid-metadata', "The plugin metadata file does not contain the required 'name' and/or 'version' keys." ); } return true; } /** * Transform plugin info into the format used by the native WordPress.org API * * @return object */ public function toWpFormat(){ $info = new stdClass; //The custom update API is built so that many fields have the same name and format //as those returned by the native WordPress.org API. These can be assigned directly. $sameFormat = array( 'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice', 'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated', ); foreach($sameFormat as $field){ if ( isset($this->$field) ) { $info->$field = $this->$field; } else { $info->$field = null; } } //Other fields need to be renamed and/or transformed. $info->download_link = $this->download_url; $info->author = $this->getFormattedAuthor(); $info->sections = array_merge(array('description' => ''), $this->sections); if ( !empty($this->banners) ) { //WP expects an array with two keys: "high" and "low". Both are optional. //Docs: https://wordpress.org/plugins/about/faq/#banners $info->banners = is_object($this->banners) ? get_object_vars($this->banners) : $this->banners; $info->banners = array_intersect_key($info->banners, array('high' => true, 'low' => true)); } return $info; } protected function getFormattedAuthor() { if ( !empty($this->author_homepage) ){ return sprintf('<a href="%s">%s</a>', $this->author_homepage, $this->author); } return $this->author; } } endif; if ( !class_exists('CookieAdminUpdate_3_2', false) ): /** * A simple container class for holding information about an available update. * * @author Janis Elsts * @copyright 2016 * @version 3.2 * @access public */ class CookieAdminUpdate_3_2 { public $id = 0; public $slug; public $version; public $homepage; public $download_url; public $upgrade_notice; public $tested; public $translations = array(); public $filename; //Plugin filename relative to the plugins directory. private static $fields = array( 'id', 'slug', 'version', 'homepage', 'tested', 'download_url', 'upgrade_notice', 'filename', 'translations' ); /** * Create a new instance of CookieAdminUpdate from its JSON-encoded representation. * * @param string $json * @return CookieAdminUpdate_3_2|null */ public static function fromJson($json){ //Since update-related information is simply a subset of the full plugin info, //we can parse the update JSON as if it was a plugin info string, then copy over //the parts that we care about. $pluginInfo = CookieAdminInfo_3_2::fromJson($json); if ( $pluginInfo != null ) { return self::fromCookieAdminInfo($pluginInfo); } else { return null; } } /** * Create a new instance of CookieAdminUpdate based on an instance of CookieAdminInfo. * Basically, this just copies a subset of fields from one object to another. * * @param CookieAdminInfo_3_2 $info * @return CookieAdminUpdate_3_2 */ public static function fromCookieAdminInfo($info){ return self::fromObject($info); } /** * Create a new instance of CookieAdminUpdate by copying the necessary fields from * another object. * * @param StdClass|CookieAdminInfo_3_2|CookieAdminUpdate_3_2 $object The source object. * @return CookieAdminUpdate_3_2 The new copy. */ public static function fromObject($object) { $update = new self(); $fields = self::$fields; if ( !empty($object->slug) ) { $fields = apply_filters('puc_retain_fields-' . $object->slug, $fields); } foreach($fields as $field){ if (property_exists($object, $field)) { $update->$field = $object->$field; } } return $update; } /** * Create an instance of StdClass that can later be converted back to * a CookieAdminUpdate. Useful for serialization and caching, as it avoids * the "incomplete object" problem if the cached value is loaded before * this class. * * @return StdClass */ public function toStdClass() { $object = new stdClass(); $fields = self::$fields; if ( !empty($this->slug) ) { $fields = apply_filters('puc_retain_fields-' . $this->slug, $fields); } foreach($fields as $field){ if (property_exists($this, $field)) { $object->$field = $this->$field; } } return $object; } /** * Transform the update into the format used by WordPress native plugin API. * * @return object */ public function toWpFormat(){ $update = new stdClass; $update->id = $this->id; $update->slug = $this->slug; $update->new_version = $this->version; $update->url = $this->homepage; $update->package = $this->download_url; $update->tested = $this->tested; $update->plugin = $this->filename; if ( !empty($this->upgrade_notice) ){ $update->upgrade_notice = $this->upgrade_notice; } return $update; } } endif; if ( !class_exists('CookieAdmin_PucScheduler_3_2', false) ): /** * The scheduler decides when and how often to check for updates. * It calls @see CookieAdminUpdateChecker::checkForUpdates() to perform the actual checks. * * @version 3.2 */ class CookieAdmin_PucScheduler_3_2 { public $checkPeriod = 12; //How often to check for updates (in hours). public $throttleRedundantChecks = false; //Check less often if we already know that an update is available. public $throttledCheckPeriod = 72; /** * @var CookieAdminUpdateChecker_3_2 */ protected $updateChecker; private $cronHook = null; /** * Scheduler constructor. * * @param CookieAdminUpdateChecker_3_2 $updateChecker * @param int $checkPeriod How often to check for updates (in hours). */ public function __construct($updateChecker, $checkPeriod) { $this->updateChecker = $updateChecker; $this->checkPeriod = $checkPeriod; //Set up the periodic update checks $this->cronHook = 'check_plugin_updates-' . $this->updateChecker->slug; if ( $this->checkPeriod > 0 ){ //Trigger the check via Cron. //Try to use one of the default schedules if possible as it's less likely to conflict //with other plugins and their custom schedules. $defaultSchedules = array( 1 => 'hourly', 12 => 'twicedaily', 24 => 'daily', ); if ( array_key_exists($this->checkPeriod, $defaultSchedules) ) { $scheduleName = $defaultSchedules[$this->checkPeriod]; } else { //Use a custom cron schedule. $scheduleName = 'every' . $this->checkPeriod . 'hours'; add_filter('cron_schedules', array($this, '_addCustomSchedule')); } if ( !wp_next_scheduled($this->cronHook) && !defined('WP_INSTALLING') ) { wp_schedule_event(time(), $scheduleName, $this->cronHook); } add_action($this->cronHook, array($this, 'maybeCheckForUpdates')); register_deactivation_hook($this->updateChecker->pluginFile, array($this, '_removeUpdaterCron')); //In case Cron is disabled or unreliable, we also manually trigger //the periodic checks while the user is browsing the Dashboard. add_action( 'admin_init', array($this, 'maybeCheckForUpdates') ); //Like WordPress itself, we check more often on certain pages. /** @see wp_update_plugins */ add_action('load-update-core.php', array($this, 'maybeCheckForUpdates')); add_action('load-plugins.php', array($this, 'maybeCheckForUpdates')); add_action('load-update.php', array($this, 'maybeCheckForUpdates')); //This hook fires after a bulk update is complete. add_action('upgrader_process_complete', array($this, 'maybeCheckForUpdates'), 11, 0); } else { //Periodic checks are disabled. wp_clear_scheduled_hook($this->cronHook); } } /** * Check for updates if the configured check interval has already elapsed. * Will use a shorter check interval on certain admin pages like "Dashboard -> Updates" or when doing cron. * * You can override the default behaviour by using the "puc_check_now-$slug" filter. * The filter callback will be passed three parameters: * - Current decision. TRUE = check updates now, FALSE = don't check now. * - Last check time as a Unix timestamp. * - Configured check period in hours. * Return TRUE to check for updates immediately, or FALSE to cancel. * * This method is declared public because it's a hook callback. Calling it directly is not recommended. */ public function maybeCheckForUpdates(){ if ( empty($this->checkPeriod) ){ return; } $state = $this->updateChecker->getUpdateState(); $shouldCheck = empty($state) || !isset($state->lastCheck) || ( (time() - $state->lastCheck) >= $this->getEffectiveCheckPeriod() ); //Let plugin authors substitute their own algorithm. $shouldCheck = apply_filters( 'puc_check_now-' . $this->updateChecker->slug, $shouldCheck, (!empty($state) && isset($state->lastCheck)) ? $state->lastCheck : 0, $this->checkPeriod ); if ( $shouldCheck ) { $this->updateChecker->checkForUpdates(); } } /** * Calculate the actual check period based on the current status and environment. * * @return int Check period in seconds. */ protected function getEffectiveCheckPeriod() { $currentFilter = current_filter(); if ( in_array($currentFilter, array('load-update-core.php', 'upgrader_process_complete')) ) { //Check more often when the user visits "Dashboard -> Updates" or does a bulk update. $period = 60; } else if ( in_array($currentFilter, array('load-plugins.php', 'load-update.php')) ) { //Also check more often on the "Plugins" page and /wp-admin/update.php. $period = 3600; } else if ( $this->throttleRedundantChecks && ($this->updateChecker->getUpdate() !== null) ) { //Check less frequently if it's already known that an update is available. $period = $this->throttledCheckPeriod * 3600; } else if ( defined('DOING_CRON') && constant('DOING_CRON') ) { //WordPress cron schedules are not exact, so lets do an update check even //if slightly less than $checkPeriod hours have elapsed since the last check. $cronFuzziness = 20 * 60; $period = $this->checkPeriod * 3600 - $cronFuzziness; } else { $period = $this->checkPeriod * 3600; } return $period; } /** * Add our custom schedule to the array of Cron schedules used by WP. * * @param array $schedules * @return array */ public function _addCustomSchedule($schedules){ if ( $this->checkPeriod && ($this->checkPeriod > 0) ){ $scheduleName = 'every' . $this->checkPeriod . 'hours'; $schedules[$scheduleName] = array( 'interval' => $this->checkPeriod * 3600, 'display' => sprintf('Every %d hours', $this->checkPeriod), ); } return $schedules; } /** * Remove the scheduled cron event that the library uses to check for updates. * * @return void */ public function _removeUpdaterCron(){ wp_clear_scheduled_hook($this->cronHook); } /** * Get the name of the update checker's WP-cron hook. Mostly useful for debugging. * * @return string */ public function getCronHookName() { return $this->cronHook; } } endif; if ( !class_exists('CookieAdmin_PucUpgraderStatus_3_2', false) ): /** * A utility class that helps figure out which plugin WordPress is upgrading. * * It may seem strange to have an separate class just for that, but the task is surprisingly complicated. * Core classes like Plugin_Upgrader don't expose the plugin file name during an in-progress update (AFAICT). * This class uses a few workarounds and heuristics to get the file name. */ class CookieAdmin_PucUpgraderStatus_3_2 { private $upgradedPluginFile = null; //The plugin that is currently being upgraded by WordPress. public function __construct() { //Keep track of which plugin WordPress is currently upgrading. add_filter('upgrader_pre_install', array($this, 'setUpgradedPlugin'), 10, 2); add_filter('upgrader_package_options', array($this, 'setUpgradedPluginFromOptions'), 10, 1); add_filter('upgrader_post_install', array($this, 'clearUpgradedPlugin'), 10, 1); add_action('upgrader_process_complete', array($this, 'clearUpgradedPlugin'), 10, 1); } /** * Is there and update being installed RIGHT NOW, for a specific plugin? * * Caution: This method is unreliable. WordPress doesn't make it easy to figure out what it is upgrading, * and upgrader implementations are liable to change without notice. * * @param string $pluginFile The plugin to check. * @param WP_Upgrader|null $upgrader The upgrader that's performing the current update. * @return bool True if the plugin identified by $pluginFile is being upgraded. */ public function isPluginBeingUpgraded($pluginFile, $upgrader = null) { if ( isset($upgrader) ) { $upgradedPluginFile = $this->getPluginBeingUpgradedBy($upgrader); if ( !empty($upgradedPluginFile) ) { $this->upgradedPluginFile = $upgradedPluginFile; } } return ( !empty($this->upgradedPluginFile) && ($this->upgradedPluginFile === $pluginFile) ); } /** * Get the file name of the plugin that's currently being upgraded. * * @param Plugin_Upgrader|WP_Upgrader $upgrader * @return string|null */ private function getPluginBeingUpgradedBy($upgrader) { if ( !isset($upgrader, $upgrader->skin) ) { return null; } //Figure out which plugin is being upgraded. $pluginFile = null; $skin = $upgrader->skin; if ( $skin instanceof Plugin_Upgrader_Skin ) { if ( isset($skin->plugin) && is_string($skin->plugin) && ($skin->plugin !== '') ) { $pluginFile = $skin->plugin; } } elseif ( isset($skin->plugin_info) && is_array($skin->plugin_info) ) { //This case is tricky because Bulk_Plugin_Upgrader_Skin (etc) doesn't actually store the plugin //filename anywhere. Instead, it has the plugin headers in $plugin_info. So the best we can //do is compare those headers to the headers of installed plugins. $pluginFile = $this->identifyPluginByHeaders($skin->plugin_info); } return $pluginFile; } /** * Identify an installed plugin based on its headers. * * @param array $searchHeaders The plugin file header to look for. * @return string|null Plugin basename ("foo/bar.php"), or NULL if we can't identify the plugin. */ private function identifyPluginByHeaders($searchHeaders) { if ( !function_exists('get_plugins') ){ /** @noinspection PhpIncludeInspection */ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); } $installedPlugins = get_plugins(); $matches = array(); foreach($installedPlugins as $pluginBasename => $headers) { $diff1 = array_diff_assoc($headers, $searchHeaders); $diff2 = array_diff_assoc($searchHeaders, $headers); if ( empty($diff1) && empty($diff2) ) { $matches[] = $pluginBasename; } } //It's possible (though very unlikely) that there could be two plugins with identical //headers. In that case, we can't unambiguously identify the plugin that's being upgraded. if ( count($matches) !== 1 ) { return null; } return reset($matches); } /** * @access private * * @param mixed $input * @param array $hookExtra * @return mixed Returns $input unaltered. */ public function setUpgradedPlugin($input, $hookExtra) { if (!empty($hookExtra['plugin']) && is_string($hookExtra['plugin'])) { $this->upgradedPluginFile = $hookExtra['plugin']; } else { $this->upgradedPluginFile = null; } return $input; } /** * @access private * * @param array $options * @return array */ public function setUpgradedPluginFromOptions($options) { if (isset($options['hook_extra']['plugin']) && is_string($options['hook_extra']['plugin'])) { $this->upgradedPluginFile = $options['hook_extra']['plugin']; } else { $this->upgradedPluginFile = null; } return $options; } /** * @access private * * @param mixed $input * @return mixed Returns $input unaltered. */ public function clearUpgradedPlugin($input = null) { $this->upgradedPluginFile = null; return $input; } } endif; if ( !class_exists('CookieAdmin_PucFactory', false) ): /** * A factory that builds instances of other classes from this library. * * When multiple versions of the same class have been loaded (e.g. CookieAdminUpdateChecker 1.2 * and 1.3), this factory will always use the latest available version. Register class * versions by calling {@link CookieAdmin_PucFactory::addVersion()}. * * At the moment it can only build instances of the CookieAdminUpdateChecker class. Other classes * are intended mainly for internal use and refer directly to specific implementations. If you * want to instantiate one of them anyway, you can use {@link CookieAdmin_PucFactory::getLatestClassVersion()} * to get the class name and then create it with <code>new $class(...)</code>. */ class CookieAdmin_PucFactory { protected static $classVersions = array(); protected static $sorted = false; /** * Create a new instance of CookieAdminUpdateChecker. * * @see CookieAdminUpdateChecker::__construct() * * @param $metadataUrl * @param $pluginFile * @param string $slug * @param int $checkPeriod * @param string $optionName * @param string $muPluginFile * @return CookieAdminUpdateChecker_3_2 */ public static function buildUpdateChecker($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') { $class = self::getLatestClassVersion('CookieAdminUpdateChecker'); return new $class($metadataUrl, $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile); } /** * Get the specific class name for the latest available version of a class. * * @param string $class * @return string|null */ public static function getLatestClassVersion($class) { if ( !self::$sorted ) { self::sortVersions(); } if ( isset(self::$classVersions[$class]) ) { return reset(self::$classVersions[$class]); } else { return null; } } /** * Sort available class versions in descending order (i.e. newest first). */ protected static function sortVersions() { foreach ( self::$classVersions as $class => $versions ) { uksort($versions, array(__CLASS__, 'compareVersions')); self::$classVersions[$class] = $versions; } self::$sorted = true; } protected static function compareVersions($a, $b) { return -version_compare($a, $b); } /** * Register a version of a class. * * @access private This method is only for internal use by the library. * * @param string $generalClass Class name without version numbers, e.g. 'CookieAdminUpdateChecker'. * @param string $versionedClass Actual class name, e.g. 'CookieAdminUpdateChecker_1_2'. * @param string $version Version number, e.g. '1.2'. */ public static function addVersion($generalClass, $versionedClass, $version) { if ( !isset(self::$classVersions[$generalClass]) ) { self::$classVersions[$generalClass] = array(); } self::$classVersions[$generalClass][$version] = $versionedClass; self::$sorted = false; } } endif; //Register classes defined in this file with the factory. CookieAdmin_PucFactory::addVersion('CookieAdminUpdateChecker', 'CookieAdminUpdateChecker_3_2', '3.2'); CookieAdmin_PucFactory::addVersion('CookieAdminUpdate', 'CookieAdminUpdate_3_2', '3.2'); CookieAdmin_PucFactory::addVersion('CookieAdminInfo', 'CookieAdminInfo_3_2', '3.2'); CookieAdmin_PucFactory::addVersion('CookieAdmin_PucGitHubChecker', 'CookieAdmin_PucGitHubChecker_3_2', '3.2'); PK �g[U�3#+ + database.phpnu �[��� <?php namespace CookieAdminPro; if(!defined('COOKIEADMIN_PRO_VERSION') || !defined('ABSPATH')){ die('Hacking Attempt'); } class Database{ static $wpdb = ''; static $consent_table = ''; static function activate(){ global $wpdb; self::$wpdb = $wpdb; self::$consent_table = esc_sql(self::$wpdb->prefix . 'cookieadmin_consents'); self::cookieadmin_create_tables(); } static function cookieadmin_create_tables() { $charset_collate = self::$wpdb->get_charset_collate(); require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); //Create Consent table $sql = "CREATE TABLE IF NOT EXISTS ".self::$consent_table." ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, consent_id VARCHAR(128) NOT NULL UNIQUE, -- Designed to store up to 128 characters for future expansion user_ip VARBINARY(16) DEFAULT NULL, -- For storing anonymized IP (IPv4 or IPv6) consent_time INT NOT NULL, country VARCHAR(150) DEFAULT NULL, -- Full country name browser TEXT DEFAULT NULL, -- Browser User agent string domain VARCHAR(255) DEFAULT NULL, -- Domain from which consent was submitted consent_status VARCHAR(50) NOT NULL -- Stores 'accepted', 'rejected', 'partially accepted', etc. ) {$charset_collate};"; dbDelta($sql); } } PK �g[̃�T T enduser.phpnu �[��� <?php namespace CookieAdminPro; if(!defined('COOKIEADMIN_PRO_VERSION') || !defined('ABSPATH')){ die('Hacking Attempt'); } class Enduser{ static $http_cookies; static function enqueue_scripts(){ wp_enqueue_script('cookieadmin_pro_js', COOKIEADMIN_PRO_PLUGIN_URL . 'assets/js/consent.js', [], COOKIEADMIN_PRO_VERSION, 'async'); $vars['ajax_url'] = admin_url('admin-ajax.php'); $vars['nonce'] = wp_create_nonce('cookieadmin_pro_js_nonce'); $vars['home_url'] = home_url(); // cookieadmin_r_print($policy);die(); wp_localize_script('cookieadmin_pro_js', 'cookieadmin_pro_vars', $vars); } // TODO static function cookieadmin_check_rate_limit($ip) { global $wpdb; //First Fetch stored rate limit for this IP $table_name = esc_sql($wpdb->prefix . 'cookie_consent_logs'); $rate_limit_count = $wpdb->get_var($wpdb->prepare( "SELECT rate_limit_count FROM $table_name WHERE user_ip = %s", $ip )); if (!$rate_limit_count) { return true; // No rate limit set, allow request } $time_window = 10; // Time window in seconds as of now we are checking for 10 seconds, we can pass this value as function's paramater as well. $transient_key = 'rate_limit_' . md5($ip); $requests = get_transient($transient_key); if (!$requests) { $requests = []; } $current_time = time(); $requests = array_filter($requests, function($timestamp) use ($current_time, $time_window) { return ($current_time - $timestamp) < $time_window; }); if (count($requests) >= $rate_limit_count) { return false; //Too many requests } $requests[] = $current_time; set_transient($transient_key, $requests, $time_window); return true; //Request allowed } // TODO static function get_location_details($ip){ global $cookieadmin; $return = array(); $api_url = cookieadmin_pro_api_url(-1, 'softwp'); $url = $api_url.'ipinfo.php?ip='.rawurlencode($ip).'&license='.$cookieadmin['license']['license'].'&url='.rawurlencode(site_url()); $response = wp_remote_get($url); if(is_wp_error($response)){ return $return; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if(empty($data)){ return $return; } return $data; } static function consent_exists($consent_id){ global $wpdb; $table_name = esc_sql($wpdb->prefix . 'cookieadmin_consents'); $result = $wpdb->get_var( $wpdb->prepare("SELECT id FROM $table_name WHERE consent_id = %s", $consent_id) ); return !empty($result); } static function anonymize_ip($ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { // Replace last octet with 0 return preg_replace('/\.\d+$/', '.0', $ip); } elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { // Replace last segment with :: return preg_replace('/:[0-9a-fA-F]+$/', '::', $ip); } return $ip; // fallback if invalid IP } static function generate_consent_id() { return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', wp_rand(0, 0xffff), wp_rand(0, 0xffff), wp_rand(0, 0xffff), wp_rand(0, 0x0fff) | 0x4000, // version 4 wp_rand(0, 0x3fff) | 0x8000, // variant wp_rand(0, 0xffff), wp_rand(0, 0xffff), wp_rand(0, 0xffff) ); } static function save_consent(){ global $wpdb; if(empty($_POST['cookieadmin_preference'])){ exit(1); } $default_prefrencs = array('accept', 'reject', 'functional', 'analytics', 'marketing'); $prefrnc = json_decode(sanitize_text_field(wp_unslash($_POST['cookieadmin_preference']))); foreach($prefrnc as $k => $preff){ if(!in_array($preff, $default_prefrencs)){ array_splice($prefrnc, $k, 1); } } $prefrnc = json_encode($prefrnc, true); $user_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : ''; $location = \CookieAdminPro\Enduser::get_location_details($user_ip); $masked_user_ip = \CookieAdminPro\Enduser::anonymize_ip($user_ip); $country = !empty($location['country']) ? sanitize_text_field($location['country']) : ''; $browser = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : ''; $domain = wp_parse_url(home_url())['host']; $table_name = esc_sql($wpdb->prefix . 'cookieadmin_consents'); $consent_id = !empty($_POST['cookieadmin_consent_id']) ? sanitize_text_field(wp_unslash($_POST['cookieadmin_consent_id'])) : ''; $data = array( 'user_ip' => inet_pton($masked_user_ip), 'consent_time' => time(), 'country' => $country, 'browser' => $browser, 'domain' => $domain, 'consent_status' => $prefrnc ); //Save consent in DB if(!empty($consent_id) && \CookieAdminPro\Enduser::consent_exists($consent_id)){ $format = array('%s', '%d', '%s', '%s', '%s', '%s'); $where = array('consent_id' => $consent_id); $where_format = array('%s'); $inserted = $wpdb->update($table_name, $data, $where, $format, $where_format); }else{ $consent_id = \CookieAdminPro\Enduser::generate_consent_id(); $data['consent_id'] = $consent_id; $format = array('%s', '%d', '%s', '%s', '%s', '%s', '%s'); $inserted = $wpdb->insert($table_name, $data, $format); } if (false === $inserted) { wp_send_json_error(array('response' => 'Error saving consent data.')); } else { wp_send_json_success(array('response' => $consent_id)); } } } PK �g[z�ZNL/ L/ admin.phpnu �[��� <?php namespace CookieAdminPro; if(!defined('COOKIEADMIN_PRO_VERSION') || !defined('ABSPATH')){ die('Hacking Attempt'); } class Admin{ static function enqueue_scripts(){ $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; $is_admin_page = basename(parse_url($request_uri, PHP_URL_PATH)); if(!is_admin() || empty($_GET['page']) || !in_array($_GET['page'], array('cookieadmin-consent-logs')) || $is_admin_page != 'admin.php'){ return false; } // Add condition to load only on our settings page //Consent Page Css wp_enqueue_style('cookieadmin-pro-style', COOKIEADMIN_PRO_PLUGIN_URL . 'assets/css/cookie.css', [], COOKIEADMIN_PRO_VERSION); wp_enqueue_script('cookieadmin_pro_js', COOKIEADMIN_PRO_PLUGIN_URL . 'assets/js/cookie.js', [], COOKIEADMIN_PRO_VERSION); $policy['admin_url'] = admin_url('admin-ajax.php'); $policy['cookieadmin_nonce'] = wp_create_nonce('cookieadmin_pro_admin_js_nonce'); //cookieadmin_r_print($policy);die(); wp_localize_script('cookieadmin_pro_js', 'cookieadmin_pro_policy', $policy); } //Add Main Menu static function plugin_menu(){ } static function show_settings($title = 'CookieAdmin Pro'){ } static function cookieadmin_pro_table_exists($table_name) { global $wpdb; $query = $wpdb->prepare("SHOW TABLES LIKE %s", $table_name); return $wpdb->get_var($query) === $table_name; } static function show_consent_logs(){ global $cookieadmin_lang, $cookieadmin_error, $cookieadmin_msg; \CookieAdmin\Admin::header_theme(__('Consent Logs', 'cookieadmin-pro')); $log_data = \CookieAdminPro\Admin::get_consent_logs(); $consent_logs = (!empty($log_data['logs']) ? $log_data['logs'] : array()); echo ' <div class="cookieadmin_pro_consent-wrap" style="max-width: 85vw;"> <form action="" method="post"> <div class="cookieadmin_consent-contents"> <div class="cookieadmin_consent"> <div class="contents cookieadmin_manager"> <div class="cookieadmin-setting cookieadmin-manager-consent-logs"> <label class="cookieadmin-title"></label> <div class="cookieadmin-setting-contents cookieadmin-consent-logs"> <input type="button" class="cookieadmin-btn cookieadmin-btn-primary cookieadmin-consent-logs-export" value="Export CSV"> </div> <div class="cookieadmin-manager-scan-result"> <table class="cookieadmin-table cookieadmin-consent-logs-result"> <thead> <tr> <th width="30%">'.esc_html__('Consent Id', 'cookieadmin-pro').'</th> <th width="20%">'.esc_html__('Status', 'cookieadmin-pro').'</th> <th>'.esc_html__('Country', 'cookieadmin-pro').'</th> <th>'.esc_html__('User IP (Anonymized)', 'cookieadmin-pro').'</th> <th>'.esc_html__('Time', 'cookieadmin-pro').'</th> </tr> </thead> <tbody>'; if(!empty($consent_logs)){ foreach ($consent_logs as $log){ $status_badge = 'warning'; if(strtolower($log['consent_status_raw']) == 'accept'){ $status_badge = 'success'; }elseif(strtolower($log['consent_status_raw']) == 'reject'){ $status_badge = 'danger'; } echo ' <tr> <td>'.esc_html($log['consent_id']).'</td> <td><span class="cookieadmin-badge cookieadmin-'.$status_badge.'">'.esc_html($log['consent_status']).'</span></td> <td>'.(!empty($log['country']) ? esc_html($log['country']) : '—').'</td> <td>'.esc_html($log['user_ip']).'</td> <td>'.esc_html($log['consent_time']).'</td> </tr>'; } }else{ echo ' <tr> <td colspan="4">'.esc_html__('No consent logs recorded yet!', 'cookieadmin-pro').'</td> </tr>'; } echo ' </tbody> </table> </div>'; if(!empty($consent_logs)){ echo ' <div class="cookieadmin-consent-logs-pagination" style="text-align:right;"> '.esc_html__('Displaying', 'cookieadmin-pro').' <span class="displaying-num">'.esc_html($log_data['min_items'].' - '.$log_data['max_items']).'</span> '.esc_html__('of', 'cookieadmin-pro').' <span class="max-num">'.esc_html($log_data['total_logs']).'</span> '.esc_html__('item(s)', 'cookieadmin-pro').' <!-- First Page Consent logs --> <a class="first-page cookieadmin-logs-paginate" id="cookieadmin-first-consent-logs" href="javascript:void(0)"> <span aria-hidden="true">«</span> </a> <!-- Previous Page Consent logs --> <a class="prev-page cookieadmin-logs-paginate" id="cookieadmin-previous-consent-logs" href="javascript:void(0)"> <span aria-hidden="true">‹</span> </a> <!-- Current Page logs --> <span class="paging-input"> <label for="current-page-selector" class="screen-reader-text">Current Page</label> <input class="current-page" id="current-page-selector" name="current-page-selector" value="'.(!empty($log_data['current_page']) ? esc_attr($log_data['current_page']) : '').'" size="3" aria-describedby="table-paging" type="text" style="text-align: center;"> <span class="tablenav-paging-text"> of <span class="total-pages">'.esc_html($log_data['total_pages']).'</span> </span> </span> <!-- Next Page Consent Logs --> <a class="next-page cookieadmin-logs-paginate" id="cookieadmin-next-consent-logs" href="javascript:void(0)"> <span aria-hidden="true">›</span> </a> <!-- Last Page Consent logs --> <a class="last-page cookieadmin-logs-paginate" id="cookieadmin-last-consent-logs" href="javascript:void(0)"> <span aria-hidden="true">»</span> </a> </div>'; } echo ' </div> </div> </div>'; wp_nonce_field('cookieadmin_pro_admin_nonce', 'cookieadmin_pro_security'); echo '<br/> <br/> </div> </form> </div>'; \CookieAdmin\Admin::footer_theme(); } //Load Consent logs data from the database static function get_consent_logs(){ global $wpdb; if($_POST && count($_POST) > 0){ $nonce_slug = (wp_doing_ajax() ? 'cookieadmin_pro_admin_js_nonce' : 'cookieadmin_pro_admin_nonce'); check_admin_referer($nonce_slug, 'cookieadmin_pro_security'); } if(!current_user_can('administrator')){ wp_send_json_error(array('message' => 'Sorry, but you do not have permissions to perform this action')); } $num_items = 0; $table_name = esc_sql($wpdb->prefix . 'cookieadmin_consents'); $current_page = isset($_POST['current_page']) ? intval($_POST['current_page']) : 1; if (!\CookieAdminPro\Admin::cookieadmin_pro_table_exists($table_name)) { // wp_send_json_error(['message' => 'Table does not exist']); return array(); } // Get total number of logs $total_consent_logs = (int) $wpdb->get_var("SELECT COUNT(*) FROM $table_name"); $logs_per_page = 25; // Calculate max pages $max_page = ceil($total_consent_logs / $logs_per_page); // Ensure current page is within valid range if ($current_page > $max_page) { $current_page = $max_page; } elseif ($current_page < 1) { $current_page = 1; } // Calculate pagination offset $offset = ($current_page - 1) * $logs_per_page; // Fetch paginated logs $consent_logs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $table_name ORDER BY id DESC LIMIT %d OFFSET %d", $logs_per_page, $offset ), ARRAY_A ); if(!empty($consent_logs)){ foreach($consent_logs as $lk => $log){ if(!empty($log['consent_status'])){ $_consent_status = json_decode($log['consent_status'], true)[0]; if($_consent_status == 'accept'){ $consent_logs[$lk]['consent_status_raw'] = 'accept'; $consent_logs[$lk]['consent_status'] = __('Accepted', 'cookieadmin-pro'); }elseif($_consent_status == 'reject'){ $consent_logs[$lk]['consent_status_raw'] = 'reject'; $consent_logs[$lk]['consent_status'] = __('Rejected', 'cookieadmin-pro'); }else{ $consent_logs[$lk]['consent_status_raw'] = 'partially_accepted'; $consent_logs[$lk]['consent_status'] = __('Partially Accepted', 'cookieadmin-pro'); } } if(!empty($log['consent_time'])){ $consent_logs[$lk]['consent_time'] = cookieadmin_pro_human_readable_time($log['consent_time']); } if(!empty($log['user_ip'])){ $consent_logs[$lk]['user_ip'] = inet_ntop($log['user_ip']); } } $num_items = count($consent_logs); } $min_items = $offset + 1; $max_items = $min_items + ($num_items - 1); $return = [ 'logs' => $consent_logs, 'total_logs' => $total_consent_logs, 'logs_per_page' => $logs_per_page, 'current_page' => $current_page, 'total_pages' => $max_page, 'min_items' => $min_items, 'max_items' => $max_items ]; // Return logs as JSON response if (defined('DOING_AJAX') && DOING_AJAX) { wp_send_json_success($return); } // Return paginated data return $return; } // Export Consent Logs from the Database static function export_logs() { global $wpdb; $cookieadmin_export_type = !empty($_REQUEST['cookieadmin_export_type']) ? sanitize_text_field(wp_unslash($_REQUEST['cookieadmin_export_type'])) : ''; if(!empty($cookieadmin_export_type)){ if($cookieadmin_export_type == 'consent_logs'){ $table_name = esc_sql($wpdb->prefix . 'cookieadmin_consents'); //First will check if the table in the database exists or not? if(!self::cookieadmin_pro_table_exists($table_name)){ wp_send_json_error(['message' => 'Table does not exists']); } $logs = $wpdb->get_results("SELECT * FROM $table_name ORDER BY id DESC", ARRAY_A); $filename = 'cookieadmin-consent-logs'; } } if(empty($logs)){ echo -1; echo __('No data to export', 'cookieadmin-pro'); wp_die(); } header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename='.$filename.'.csv'); $allowed_fields = array('consent_id' => 'Consent Id', 'consent_status' => 'Consent Status', 'country' => 'Country', 'user_ip' => 'User IP (Anonymized)', 'consent_time' => 'Consent Time'); $file = fopen("php://output","w"); fputcsv($file, array_values($allowed_fields)); foreach($logs as $ik => $log){ if(!empty($log['consent_status'])){ $_consent_status = json_decode($log['consent_status'], true)[0]; if($_consent_status == 'accept'){ $log['consent_status'] = __('Accepted', 'cookieadmin-pro'); }elseif($_consent_status == 'reject'){ $log['consent_status'] = __('Rejected', 'cookieadmin-pro'); }else{ $log['consent_status'] = __('Partially Accepted', 'cookieadmin-pro'); } } if(!empty($log['consent_time'])){ $log['consent_time'] = wp_date('M j Y g:i A T', $log['consent_time']); } if(!empty($log['user_ip'])){ $log['user_ip'] = inet_ntop($log['user_ip']); } $log['country'] = (!empty($log['country']) ? $log['country'] : '—'); $row = array(); foreach($allowed_fields as $ak => $av){ $row[$ak] = $log[$ak]; } fputcsv($file, $row); } fclose($file); wp_die(); } function version_notice(){ $type = ''; if(!empty($_REQUEST['type'])){ $type = sanitize_text_field(wp_unslash($_REQUEST['type'])); } if(empty($type)){ wp_send_json_error(__('Unknow version difference type', 'cookieadmin-pro')); } update_option('cookieadmin_version_'. $type .'_nag', time() + WEEK_IN_SECONDS); wp_send_json_success(); } function dismiss_expired_licenses(){ update_option('softaculous_expired_licenses', time()); wp_send_json_success(); } } PK �g[I���: : short-cirtuit.phpnu �[��� <?php /* * CookieAdmin * https://cookieadmin.net * (c) Softaculous Team */ // Are we being accessed directly ? if(!defined('COOKIEADMIN_PRO_VERSION')) { exit('Hacking Attempt !'); } // Prevent update of cookieadmin free // This also work for auto update add_filter('site_transient_update_plugins', 'cookieadmin_pro_disable_manual_update_for_plugin'); add_filter('pre_site_transient_update_plugins', 'cookieadmin_pro_disable_manual_update_for_plugin'); // Auto update free version after update pro version add_action('upgrader_process_complete', 'cookieadmin_pro_update_free_after_pro', 10, 2); add_action('plugins_loaded', 'cookieadmin_pro_load_plugin'); function cookieadmin_pro_load_plugin(){ global $cookieadmin; // Load license cookieadmin_pro_load_license(); cookieadmin_pro_update_checker(); // Check for updates include_once(COOKIEADMIN_PRO_DIR.'/includes/plugin-update-checker.php'); $cookieadmin_updater = CookieAdmin_PucFactory::buildUpdateChecker(cookieadmin_pro_api_url().'updates.php?version='.COOKIEADMIN_PRO_VERSION, COOKIEADMIN_PRO_FILE); // Add the license key to query arguments $cookieadmin_updater->addQueryArgFilter('cookieadmin_pro_updater_filter_args'); // Show the text to install the license key add_filter('puc_manual_final_check_link-cookieadmin-pro', 'cookieadmin_pro_updater_check_link', 10, 1); // Nag informing the user to install the free version. if(current_user_can('activate_plugins')){ add_action('admin_notices', 'cookieadmin_pro_free_version_nag', 9); add_action('admin_menu', 'cookieadmin_pro_add_menu', 9); } $is_network_wide = cookieadmin_pro_is_network_active('cookieadmin-pro'); $_do_version = get_option('cookieadmin_version'); $req_free_update = !empty($_do_version) && version_compare($_do_version, COOKIEADMIN_PRO_VERSION, '<'); if($is_network_wide){ $free_installed = get_site_option('cookieadmin_free_installed'); }else{ $free_installed = get_option('cookieadmin_free_installed'); } if(!empty($free_installed)){ return; } // Include the necessary stuff include_once(ABSPATH . 'wp-admin/includes/plugin-install.php'); include_once(ABSPATH . 'wp-admin/includes/plugin.php'); include_once(ABSPATH . 'wp-admin/includes/file.php'); if(file_exists(WP_PLUGIN_DIR . '/cookieadmin/cookieadmin.php') && is_plugin_inactive('/cookieadmin/cookieadmin.php') && empty($req_free_update)) { if($is_network_wide){ update_site_option('cookieadmin_free_installed', time()); }else{ update_option('cookieadmin_free_installed', time()); } activate_plugin('/cookieadmin/cookieadmin.php', '', $is_network_wide); remove_action('admin_notices', 'cookieadmin_pro_free_version_nag', 9); remove_action('admin_menu', 'cookieadmin_pro_add_menu', 9); return; } // Includes necessary for Plugin_Upgrader and Plugin_Installer_Skin include_once(ABSPATH . 'wp-admin/includes/misc.php'); include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); // Filter to prevent the activate text add_filter('install_plugin_complete_actions', 'cookieadmin_pro_prevent_activation_text', 10, 3); $upgrader = new Plugin_Upgrader(new WP_Ajax_Upgrader_Skin()); // Upgrade the plugin to the latest version of free already installed. if(!empty($req_free_update)){ $installed = $upgrader->upgrade('cookieadmin/cookieadmin.php'); }else{ $installed = $upgrader->install('https://downloads.wordpress.org/plugin/cookieadmin.zip'); } if(!is_wp_error($installed) && $installed){ if($is_network_wide){ update_site_option('cookieadmin_free_installed', time()); }else{ update_option('cookieadmin_free_installed', time()); } activate_plugin('cookieadmin/cookieadmin.php', '', $is_network_wide); remove_action('admin_notices', 'cookieadmin_pro_free_version_nag', 9); remove_action('admin_menu', 'cookieadmin_pro_add_menu', 9); } } // Do not shows the activation text if function cookieadmin_pro_prevent_activation_text($install_actions, $api, $plugin_file){ if($plugin_file == 'cookieadmin/cookieadmin.php'){ return array(); } return $install_actions; } function cookieadmin_pro_free_version_nag(){ $cookieadmin_version = get_option('cookieadmin_version'); $lower_version = __('You have not installed the free version of CookieAdmin. CookieAdmin Pro depends on the free version, so you must install it first in order to use CookieAdmin Pro.', 'cookieadmin-pro'); echo '<div class="notice notice-error"> <p style="font-size:16px;">'.esc_html($lower_version).' <a href="'.admin_url('plugin-install.php?s=cookieadmin&tab=search').'" class="button button-primary">Install/Update Now</a></p> </div>'; } function cookieadmin_pro_add_menu(){ add_menu_page('CookieAdmin Settings', 'CookieAdmin', 'activate_plugins', 'cookieadmin', 'cookieadmin_pro_menu_page'); } function cookieadmin_pro_menu_page(){ echo '<div style="color: #333;padding: 50px;text-align: center;"> <h1 style="font-size: 2em;margin-bottom: 10px;">CookieAdmin Free version is not installed / outdated!</h> <p style=" font-size: 16px;margin-bottom: 20px; font-weight:400;">'.esc_html__('CookieAdmin Pro depends on the free version of CookieAdmin, so you need to install / update the free version first.', 'cookieadmin-pro').'</p> <a href="'.admin_url('plugin-install.php?s=cookieadmin&tab=search').'" style="text-decoration: none;font-size:16px;">'.esc_html__('Install/Update Now', 'cookieadmin-pro').'</a> </div>'; }PK �*n[�P�� "