Changeset 3391879
- Timestamp:
- 11/07/2025 05:29:18 PM (5 weeks ago)
- Location:
- church-theme-content
- Files:
-
- 106 added
- 5 edited
-
tags/2.7 (added)
-
tags/2.7/church-theme-content.php (added)
-
tags/2.7/css (added)
-
tags/2.7/css/dashboard.css (added)
-
tags/2.7/css/map-after-fields.css (added)
-
tags/2.7/css/settings.css (added)
-
tags/2.7/css/style.css (added)
-
tags/2.7/includes (added)
-
tags/2.7/includes/add-ons.php (added)
-
tags/2.7/includes/admin (added)
-
tags/2.7/includes/admin/admin-add-ons.php (added)
-
tags/2.7/includes/admin/admin-enqueue-scripts.php (added)
-
tags/2.7/includes/admin/admin-enqueue-styles.php (added)
-
tags/2.7/includes/admin/admin-event-fields.php (added)
-
tags/2.7/includes/admin/admin-helpers.php (added)
-
tags/2.7/includes/admin/admin-location-fields.php (added)
-
tags/2.7/includes/admin/admin-maps.php (added)
-
tags/2.7/includes/admin/admin-menu.php (added)
-
tags/2.7/includes/admin/admin-person-fields.php (added)
-
tags/2.7/includes/admin/admin-posts.php (added)
-
tags/2.7/includes/admin/admin-sermon-fields.php (added)
-
tags/2.7/includes/admin/admin-support.php (added)
-
tags/2.7/includes/admin/dashboard.php (added)
-
tags/2.7/includes/admin/edd-license.php (added)
-
tags/2.7/includes/admin/editor.php (added)
-
tags/2.7/includes/admin/import.php (added)
-
tags/2.7/includes/admin/migrate-risen.php (added)
-
tags/2.7/includes/admin/notices.php (added)
-
tags/2.7/includes/admin/upgrade.php (added)
-
tags/2.7/includes/classes (added)
-
tags/2.7/includes/classes/CTC_Dashboard_News.php (added)
-
tags/2.7/includes/classes/CTC_EDD_SL_Plugin_Updater.php (added)
-
tags/2.7/includes/event-fields.php (added)
-
tags/2.7/includes/helpers.php (added)
-
tags/2.7/includes/libraries (added)
-
tags/2.7/includes/libraries/ct-meta-box (added)
-
tags/2.7/includes/libraries/ct-meta-box/css (added)
-
tags/2.7/includes/libraries/ct-meta-box/css/ct-meta-box.css (added)
-
tags/2.7/includes/libraries/ct-meta-box/css/datepicker.min.css (added)
-
tags/2.7/includes/libraries/ct-meta-box/css/jquery.timepicker.css (added)
-
tags/2.7/includes/libraries/ct-meta-box/ct-meta-box.php (added)
-
tags/2.7/includes/libraries/ct-meta-box/js (added)
-
tags/2.7/includes/libraries/ct-meta-box/js/ct-meta-box.js (added)
-
tags/2.7/includes/libraries/ct-meta-box/js/datepicker.min.js (added)
-
tags/2.7/includes/libraries/ct-meta-box/js/jquery.timepicker.min.js (added)
-
tags/2.7/includes/libraries/ct-meta-box/license.txt (added)
-
tags/2.7/includes/libraries/ct-plugin-settings (added)
-
tags/2.7/includes/libraries/ct-plugin-settings/css (added)
-
tags/2.7/includes/libraries/ct-plugin-settings/css/ct-plugin-settings.css (added)
-
tags/2.7/includes/libraries/ct-plugin-settings/ct-plugin-settings.php (added)
-
tags/2.7/includes/libraries/ct-plugin-settings/js (added)
-
tags/2.7/includes/libraries/ct-plugin-settings/js/ct-plugin-settings.js (added)
-
tags/2.7/includes/libraries/ct-plugin-settings/license.txt (added)
-
tags/2.7/includes/libraries/ct-recurrence (added)
-
tags/2.7/includes/libraries/ct-recurrence/ct-recurrence-compat.php (added)
-
tags/2.7/includes/libraries/ct-recurrence/ct-recurrence-load.php (added)
-
tags/2.7/includes/libraries/ct-recurrence/ct-recurrence.php (added)
-
tags/2.7/includes/libraries/ct-recurrence/license.txt (added)
-
tags/2.7/includes/libraries/ct-recurrence/php-rrule (added)
-
tags/2.7/includes/libraries/ct-recurrence/php-rrule/RRule.modified.php (added)
-
tags/2.7/includes/libraries/ct-recurrence/php-rrule/RRuleInterface.php (added)
-
tags/2.7/includes/libraries/ct-recurrence/php-rrule/RSet.modified.php (added)
-
tags/2.7/includes/libraries/ct-recurrence/php-rrule/RfcParser.php (added)
-
tags/2.7/includes/mime-types.php (added)
-
tags/2.7/includes/podcast.php (added)
-
tags/2.7/includes/post-types.php (added)
-
tags/2.7/includes/schedule.php (added)
-
tags/2.7/includes/settings.php (added)
-
tags/2.7/includes/support.php (added)
-
tags/2.7/includes/taxonomies.php (added)
-
tags/2.7/js (added)
-
tags/2.7/js/lib (added)
-
tags/2.7/js/lib/clipboard.min.js (added)
-
tags/2.7/js/map-after-fields.js (added)
-
tags/2.7/js/settings.js (added)
-
tags/2.7/languages (added)
-
tags/2.7/languages/church-theme-content-af.mo (added)
-
tags/2.7/languages/church-theme-content-af.po (added)
-
tags/2.7/languages/church-theme-content-da_DK.mo (added)
-
tags/2.7/languages/church-theme-content-da_DK.po (added)
-
tags/2.7/languages/church-theme-content-de_DE.mo (added)
-
tags/2.7/languages/church-theme-content-de_DE.po (added)
-
tags/2.7/languages/church-theme-content-es_ES.mo (added)
-
tags/2.7/languages/church-theme-content-es_ES.po (added)
-
tags/2.7/languages/church-theme-content-es_MX.mo (added)
-
tags/2.7/languages/church-theme-content-es_MX.po (added)
-
tags/2.7/languages/church-theme-content-fr_FR.mo (added)
-
tags/2.7/languages/church-theme-content-fr_FR.po (added)
-
tags/2.7/languages/church-theme-content-nb_NO.mo (added)
-
tags/2.7/languages/church-theme-content-nb_NO.po (added)
-
tags/2.7/languages/church-theme-content-nl_NL.mo (added)
-
tags/2.7/languages/church-theme-content-nl_NL.po (added)
-
tags/2.7/languages/church-theme-content-nn_NO.mo (added)
-
tags/2.7/languages/church-theme-content-nn_NO.po (added)
-
tags/2.7/languages/church-theme-content-pt_BR.mo (added)
-
tags/2.7/languages/church-theme-content-pt_BR.po (added)
-
tags/2.7/languages/church-theme-content-sk_SK.mo (added)
-
tags/2.7/languages/church-theme-content-sk_SK.po (added)
-
tags/2.7/languages/church-theme-content-sr_RS.mo (added)
-
tags/2.7/languages/church-theme-content-sr_RS.po (added)
-
tags/2.7/languages/church-theme-content-sv_SE.mo (added)
-
tags/2.7/languages/church-theme-content-sv_SE.po (added)
-
tags/2.7/languages/church-theme-content.pot (added)
-
tags/2.7/languages/important.txt (added)
-
tags/2.7/license.txt (added)
-
tags/2.7/readme.txt (added)
-
trunk/church-theme-content.php (modified) (19 diffs)
-
trunk/includes/add-ons.php (modified) (7 diffs)
-
trunk/includes/admin/edd-license.php (modified) (68 diffs)
-
trunk/includes/classes/CTC_EDD_SL_Plugin_Updater.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
church-theme-content/trunk/church-theme-content.php
r3039815 r3391879 1 1 <?php 2 2 3 /** 3 4 * Plugin Name: Church Content 4 5 * Plugin URI: https://churchthemes.com/plugins/church-content/ 5 6 * Description: Provides an interface for managing sermons, events, people and locations. A <strong>compatible theme is required</strong> for presenting content from these church-centric post types in a tightly-integrated manner. 6 * Version: 2. 6.27 * Version: 2.7 7 8 * Author: ChurchThemes.com 8 9 * Author URI: https://churchthemes.com … … 12 13 * 13 14 * @package Church_Theme_Content 14 * @copyright Copyright (c) 2013 - 202 4, ChurchThemes.com, LLC15 * @copyright Copyright (c) 2013 - 2025, ChurchThemes.com, LLC 15 16 * @link https://github.com/churchthemes/church-theme-content 16 17 * @license GPLv2 or later … … 18 19 19 20 // No direct access 20 if (! defined( 'ABSPATH')) exit;21 if (! defined('ABSPATH')) exit; 21 22 22 23 /** … … 25 26 * @since 0.9 26 27 */ 27 class Church_Theme_Content { 28 class Church_Theme_Content 29 { 28 30 29 31 /** … … 51 53 * @access public 52 54 */ 53 public function __construct() { 55 public function __construct() 56 { 54 57 55 58 // Set plugin data. 56 add_action( 'plugins_loaded', array( $this, 'set_plugin_data' ), 1);59 add_action('plugins_loaded', array($this, 'set_plugin_data'), 1); 57 60 58 61 // Define constants. 59 add_action( 'plugins_loaded', array( $this, 'define_constants' ), 1);62 add_action('plugins_loaded', array($this, 'define_constants'), 1); 60 63 61 64 // Load language file for old versions of WordPress. 62 add_action( 'plugins_loaded', array( $this, 'load_textdomain' ), 1);65 add_action('plugins_loaded', array($this, 'load_textdomain'), 1); 63 66 64 67 // Set includes. 65 add_action( 'plugins_loaded', array( $this, 'set_includes' ), 1);68 add_action('plugins_loaded', array($this, 'set_includes'), 1); 66 69 67 70 // Load includes. 68 add_action( 'plugins_loaded', array( $this, 'load_includes' ), 1);71 add_action('plugins_loaded', array($this, 'load_includes'), 1); 69 72 70 73 // Trigger flushing of rewrite rules on plugin activation. 71 74 // This must be done early (not on plugins_loaded or init). 72 register_activation_hook( __FILE__, array( &$this, 'trigger_flush_rewrite_rules' ));75 register_activation_hook(__FILE__, array(&$this, 'trigger_flush_rewrite_rules')); 73 76 74 77 // Check if rewrite rules should be flushed. 75 add_action( 'init', array( $this, 'ctc_check_flush_rewrite_rules' ), 1 ); 76 78 add_action('init', array($this, 'ctc_check_flush_rewrite_rules'), 1); 77 79 } 78 80 … … 85 87 * @access public 86 88 */ 87 public function set_plugin_data() { 89 public function set_plugin_data() 90 { 88 91 89 92 // Load plugin.php if get_plugins() not available 90 if (! function_exists( 'get_plugins')) {93 if (! function_exists('get_plugins')) { 91 94 require_once ABSPATH . 'wp-admin/includes/plugin.php'; 92 95 } 93 96 94 97 // Get path to plugin's directory 95 $plugin_dir = plugin_basename( dirname( __FILE__ ));98 $plugin_dir = plugin_basename(dirname(__FILE__)); 96 99 97 100 // Get plugin data 98 $plugin_data = current( get_plugins( '/' . $plugin_dir ));101 $plugin_data = current(get_plugins('/' . $plugin_dir)); 99 102 100 103 // Set plugin data 101 $this->plugin_data = apply_filters( 'ctc_plugin_data', $plugin_data ); 102 104 $this->plugin_data = apply_filters('ctc_plugin_data', $plugin_data); 103 105 } 104 106 … … 109 111 * @access public 110 112 */ 111 public function define_constants() { 113 public function define_constants() 114 { 112 115 113 116 // Plugin details 114 define( 'CTC_VERSION', $this->plugin_data['Version']); // plugin version115 define( 'CTC_NAME', $this->plugin_data['Name']); // plugin name116 define( 'CTC_AUTHOR', strip_tags( $this->plugin_data['Author'] )); // plugin author117 define( 'CTC_INFO_URL', $this->plugin_data['PluginURI']); // plugin's info page URL118 define( 'CTC_FILE', __FILE__); // plugin's main file absolute path119 define( 'CTC_FILE_BASE', plugin_basename( CTC_FILE )); // plugin's main file path relative to plugin directory120 define( 'CTC_DIR', dirname( CTC_FILE_BASE )); // plugin's directory121 define( 'CTC_PATH', untrailingslashit( plugin_dir_path( CTC_FILE ) )); // plugin's absolute path122 define( 'CTC_URL', untrailingslashit( plugin_dir_url( CTC_FILE ) )); // plugin's directory URL117 define('CTC_VERSION', $this->plugin_data['Version']); // plugin version 118 define('CTC_NAME', $this->plugin_data['Name']); // plugin name 119 define('CTC_AUTHOR', strip_tags($this->plugin_data['Author'])); // plugin author 120 define('CTC_INFO_URL', $this->plugin_data['PluginURI']); // plugin's info page URL 121 define('CTC_FILE', __FILE__); // plugin's main file absolute path 122 define('CTC_FILE_BASE', plugin_basename(CTC_FILE)); // plugin's main file path relative to plugin directory 123 define('CTC_DIR', dirname(CTC_FILE_BASE)); // plugin's directory 124 define('CTC_PATH', untrailingslashit(plugin_dir_path(CTC_FILE))); // plugin's absolute path 125 define('CTC_URL', untrailingslashit(plugin_dir_url(CTC_FILE))); // plugin's directory URL 123 126 124 127 // Directories 125 define( 'CTC_INC_DIR', 'includes'); // includes directory126 define( 'CTC_ADMIN_DIR', CTC_INC_DIR . '/admin'); // admin directory127 define( 'CTC_CLASS_DIR', CTC_INC_DIR . '/classes'); // classes directory128 define( 'CTC_LIB_DIR', CTC_INC_DIR . '/libraries'); // libraries directory129 define( 'CTC_CSS_DIR', 'css'); // stylesheets directory130 define( 'CTC_JS_DIR', 'js'); // JavaScript directory131 define( 'CTC_IMG_DIR', 'images'); // images directory132 define( 'CTC_LANG_DIR', 'languages'); // languages directory128 define('CTC_INC_DIR', 'includes'); // includes directory 129 define('CTC_ADMIN_DIR', CTC_INC_DIR . '/admin'); // admin directory 130 define('CTC_CLASS_DIR', CTC_INC_DIR . '/classes'); // classes directory 131 define('CTC_LIB_DIR', CTC_INC_DIR . '/libraries'); // libraries directory 132 define('CTC_CSS_DIR', 'css'); // stylesheets directory 133 define('CTC_JS_DIR', 'js'); // JavaScript directory 134 define('CTC_IMG_DIR', 'images'); // images directory 135 define('CTC_LANG_DIR', 'languages'); // languages directory 133 136 134 137 // CT Meta Box 135 if (! defined( 'CTMB_URL' )) { // in case also used in theme or other plugin 136 define( 'CTMB_URL', CTC_URL . '/' . CTC_LIB_DIR . '/ct-meta-box' ); // for enqueueing JS/CSS 137 } 138 138 if (! defined('CTMB_URL')) { // in case also used in theme or other plugin 139 define('CTMB_URL', CTC_URL . '/' . CTC_LIB_DIR . '/ct-meta-box'); // for enqueueing JS/CSS 140 } 139 141 } 140 142 … … 154 156 * @access public 155 157 */ 156 public function load_textdomain() { 158 public function load_textdomain() 159 { 157 160 158 161 // Get version of WordPress in use. 159 $wp_version = get_bloginfo( 'version');162 $wp_version = get_bloginfo('version'); 160 163 161 164 // Textdomain. … … 163 166 164 167 // WordPress core locale filter. 165 $locale = apply_filters( 'plugin_locale', get_locale(), $domain);168 $locale = apply_filters('plugin_locale', get_locale(), $domain); 166 169 167 170 // WordPress 3.6 and earlier don't auto-load from wp-content/languages, so check and load manually: http://core.trac.wordpress.org/changeset/22346. 168 171 $external_mofile = WP_LANG_DIR . '/plugins/' . $domain . '-' . $locale . '.mo'; 169 if (version_compare( $wp_version, '3.6', '<=' ) && file_exists( $external_mofile)) { // external translation exists.170 load_textdomain( $domain, $external_mofile);172 if (version_compare($wp_version, '3.6', '<=') && file_exists($external_mofile)) { // external translation exists. 173 load_textdomain($domain, $external_mofile); 171 174 } 172 175 … … 174 177 // Either using WordPress 3.7+ or older version with external translation. 175 178 else { 176 $languages_dir = CTC_DIR . '/' . trailingslashit( CTC_LANG_DIR ); // ensure trailing slash. 177 load_plugin_textdomain( $domain, false, $languages_dir ); 178 } 179 179 $languages_dir = CTC_DIR . '/' . trailingslashit(CTC_LANG_DIR); // ensure trailing slash. 180 load_plugin_textdomain($domain, false, $languages_dir); 181 } 180 182 } 181 183 … … 186 188 * @access public 187 189 */ 188 public function set_includes() { 189 190 $this->includes = apply_filters( 'ctc_includes', array( 190 public function set_includes() 191 { 192 193 $this->includes = apply_filters('ctc_includes', array( 191 194 192 195 // Frontend or admin … … 252 255 */ 253 256 254 ) ); 255 257 )); 256 258 } 257 259 … … 259 261 * Load includes 260 262 * 261 * Include files based on whether or not condition is met. 262 * 263 * @since 0.9 264 * @access public 265 */ 266 public function load_includes() { 263 * Include files based on whether or not condition is met. 264 * 265 * @since 0.9 266 * @access public 267 */ 268 public function load_includes() 269 { 267 270 268 271 // Get includes … … 275 278 276 279 // Check condition 277 switch ($condition) {280 switch ($condition) { 278 281 279 282 // Admin Only … … 301 304 302 305 break; 303 304 306 } 305 307 … … 308 310 309 311 foreach ($files as $file) { 310 require_once trailingslashit( CTC_PATH) . $file;312 require_once trailingslashit(CTC_PATH) . $file; 311 313 } 312 313 314 } 314 315 } 316 315 } 317 316 } 318 317 … … 325 324 * @access public 326 325 */ 327 public static function trigger_flush_rewrite_rules() { 326 public static function trigger_flush_rewrite_rules() 327 { 328 328 329 329 // Tell to flush rules after post types registered. 330 update_option( 'ctc_flush_rewrite_rules', '1' ); 331 330 update_option('ctc_flush_rewrite_rules', '1'); 332 331 } 333 332 … … 338 337 * so that the rewrite rules can be flushed later. 339 338 */ 340 public function ctc_check_flush_rewrite_rules() { 339 public function ctc_check_flush_rewrite_rules() 340 { 341 341 342 342 // Check if option was set. 343 if (get_option( 'ctc_flush_rewrite_rules')) {343 if (get_option('ctc_flush_rewrite_rules')) { 344 344 345 345 // Flush rewrite rules. … … 347 347 348 348 // Delete option so this doesn't run again. 349 delete_option( 'ctc_flush_rewrite_rules' ); 350 351 } 352 353 } 354 349 delete_option('ctc_flush_rewrite_rules'); 350 } 351 } 355 352 } 356 353 -
church-theme-content/trunk/includes/add-ons.php
r1949935 r3391879 1 1 <?php 2 2 3 /** 3 4 * Add-ons (Global) … … 6 7 * 7 8 * @package Church_Theme_Content 8 * @copyright Copyright (c) 2014 , ChurchThemes.com9 * @copyright Copyright (c) 2014 - 2025, ChurchThemes.com 9 10 * @link https://github.com/churchthemes/church-theme-content 10 11 * @license GPLv2 or later … … 13 14 14 15 // No direct access 15 if ( ! defined( 'ABSPATH' )) exit;16 if (! defined('ABSPATH')) exit; 16 17 17 18 /************************************************* … … 34 35 * ctc_register_add_on( array( 35 36 * 'plugin_file' => __FILE__, // Full path to plugin main file (__FILE__ if this code is in main file) 36 * 'store_url' => 'https://churchthemes.com', // URL of store running EDD with Software Licensing extension 37 * 'store_url' => 'https://churchthemes.com', // URL of store running EDD with Software Licensing extension (or proxy) 37 38 * 'renewal_url' => 'https://churchthemes.com/renew/?license_key={license_key}', // It is recommended to provide a URL for renewal links (ie. redirecting to EDD checkout); {license_key} will be replaced with key 38 39 * 'renewal_info_url' => 'https://churchthemes.com/go/license-renewal', // Optional URL for renewal information … … 52 53 * @global array $ctc_add_ons 53 54 */ 54 function ctc_register_add_on( $args ) { 55 function ctc_register_add_on($args) 56 { 55 57 56 58 global $ctc_add_ons; 57 59 58 60 // Prepare array to receive add-ons 59 if ( ! isset( $ctc_add_ons )) {61 if (! isset($ctc_add_ons)) { 60 62 $ctc_add_ons = array(); 61 63 } 62 64 63 65 // Add add-on to global 64 if ( ! empty( $args['plugin_file'] )) {66 if (! empty($args['plugin_file'])) { 65 67 66 68 // Plugin file relative path 67 69 // plugin-name/plugin-name.php 68 $args['plugin_file_base'] = plugin_basename( $args['plugin_file']);70 $args['plugin_file_base'] = plugin_basename($args['plugin_file']); 69 71 70 72 // Plugin's directory name (e.g. plugin-name) 71 73 // This serves as a nice clean, unique slug -- good for use in settings 72 $args['plugin_dir'] = dirname( $args['plugin_file_base'] );74 $args['plugin_dir'] = dirname($args['plugin_file_base']); 73 75 74 76 // Get plugin data 75 77 // wp-admin/includes/plugin.php is already included by Church_Theme_Content class 76 $plugin_data = current( get_plugins( '/' . $args['plugin_dir'] ));78 $plugin_data = current(get_plugins('/' . $args['plugin_dir'])); 77 79 78 80 // Plugin name 79 81 $args['name_full'] = $plugin_data['Name']; 80 $name_short = str_replace( array( CTC_NAME . ' - ', 'Church Theme Content - ' ), '', $args['name_full']); // with "Church Content - " or "Church Theme Content - " prefix removed82 $name_short = str_replace(array(CTC_NAME . ' - ', 'Church Theme Content - '), '', $args['name_full']); // with "Church Content - " or "Church Theme Content - " prefix removed 81 83 82 84 // Plugin author 83 $author = strip_tags( $plugin_data['Author']);85 $author = strip_tags($plugin_data['Author']); 84 86 85 87 // Apply defaults 86 $args = wp_parse_args( $args, array(88 $args = wp_parse_args($args, array( 87 89 88 90 // Add-on Information … … 95 97 // EDD Software Licensing 96 98 // The translation strings are automatically escaped on use in edd-license.php 97 'store_url' => '', // URL of store running EDD with Software Licensing extension 99 'store_url' => '', // URL of store running EDD with Software Licensing extension (or proxy) 98 100 'version' => $plugin_data['Version'], // current version of the add-on plugin; default is to auto-determine 99 101 'item_name' => $name_short, // must match download's name in EDD store … … 104 106 'renewal_info_url' => '', // optional URL for renewal information 105 107 'changelog_url' => '', // optional URL for external changelog 106 'activate_success_notice' => __( '<strong>License key activated.</strong>', 'church-theme-content'),107 'activate_fail_notice' => __( '<strong>License key could not be activated.</strong>', 'church-theme-content'),108 'deactivate_success_notice' => __( '<strong>License key deactivated.</strong>', 'church-theme-content'),109 'deactivate_fail_notice' => __( '<strong>License key could not be deactivated.</strong>', 'church-theme-content'),110 'inactive_notice' => __( '<strong>Add-on License Inactive:</strong> <a href="%1$s">Activate Your Add-on License</a> to enable updates for <strong>%2$s</strong>.', 'church-theme-content'),111 'expired_notice' => __( '<strong>Add-on License Expired:</strong> <a href="%1$s">Renew Your Add-on License</a> for <strong>%2$s</strong> to re-enable updates (expired on <strong>%3$s</strong>).', 'church-theme-content'),112 'expiring_soon_notice' => __( '<strong>Add-on License Expiring Soon:</strong> <a href="%1$s">Renew Your Add-on License</a> for <strong>%2$s</strong> to continue receiving updates (expires on <strong>%3$s</strong>).', 'church-theme-content'),108 'activate_success_notice' => __('<strong>License key activated.</strong>', 'church-theme-content'), 109 'activate_fail_notice' => __('<strong>License key could not be activated.</strong>', 'church-theme-content'), 110 'deactivate_success_notice' => __('<strong>License key deactivated.</strong>', 'church-theme-content'), 111 'deactivate_fail_notice' => __('<strong>License key could not be deactivated.</strong>', 'church-theme-content'), 112 'inactive_notice' => __('<strong>Add-on License Inactive:</strong> <a href="%1$s">Activate Your Add-on License</a> to enable updates for <strong>%2$s</strong>.', 'church-theme-content'), 113 'expired_notice' => __('<strong>Add-on License Expired:</strong> <a href="%1$s">Renew Your Add-on License</a> for <strong>%2$s</strong> to re-enable updates (expired on <strong>%3$s</strong>).', 'church-theme-content'), 114 'expiring_soon_notice' => __('<strong>Add-on License Expiring Soon:</strong> <a href="%1$s">Renew Your Add-on License</a> for <strong>%2$s</strong> to continue receiving updates (expires on <strong>%3$s</strong>).', 'church-theme-content'), 113 115 114 ) );116 )); 115 117 116 118 // Add add-on to global array 117 119 $ctc_add_ons[$args['plugin_dir']] = $args; 118 119 120 } 120 121 121 } -
church-theme-content/trunk/includes/admin/edd-license.php
r2187690 r3391879 1 1 <?php 2 2 3 /** 3 4 * EDD License Handling … … 15 16 * @package Church_Theme_Content 16 17 * @subpackage Admin 17 * @copyright Copyright (c) 2014 - 20 19, ChurchThemes.com18 * @copyright Copyright (c) 2014 - 2025, ChurchThemes.com 18 19 * @link https://github.com/churchthemes/church-theme-content 19 20 * @license GPLv2 or later … … 22 23 23 24 // No direct access 24 if ( ! defined( 'ABSPATH' )) {25 if (! defined('ABSPATH')) { 25 26 exit; 26 27 } … … 36 37 * @param string $add_on_dir Add-on to work with 37 38 */ 38 function ctc_edd_license_supported( $add_on_dir ) { 39 function ctc_edd_license_supported($add_on_dir) 40 { 39 41 40 42 $supported = false; … … 42 44 // Store URL is all that is required 43 45 // Everything else can be auto-detected 44 if ( ctc_get_add_on( $add_on_dir, 'store_url' )) {46 if (ctc_get_add_on($add_on_dir, 'store_url')) { 45 47 $supported = true; 46 48 } 47 49 48 return apply_filters( 'ctc_edd_license_supported', $supported, $add_on_dir ); 49 50 return apply_filters('ctc_edd_license_supported', $supported, $add_on_dir); 50 51 } 51 52 … … 63 64 * @return array Modified setting fields with license key fields inserted 64 65 */ 65 function ctc_edd_license_settings( $section ) { 66 function ctc_edd_license_settings($section) 67 { 66 68 67 69 // Get registered add-ons … … 69 71 70 72 // Any add-ons registered? 71 if ( $add_ons) {73 if ($add_ons) { 72 74 73 75 // Loop add-ons 74 76 $fields = array(); 75 foreach ( $add_ons as $add_on) {77 foreach ($add_ons as $add_on) { 76 78 77 79 // Add-on supports EDD licensing? 78 if ( ! ctc_edd_license_supported( $add_on['plugin_dir'] )) {80 if (! ctc_edd_license_supported($add_on['plugin_dir'])) { 79 81 continue; 80 82 } … … 84 86 85 87 // License Key 86 $fields[ $key] = array(88 $fields[$key] = array( 87 89 'name' => $add_on['name'], 88 90 'desc' => '', … … 97 99 'custom_sanitize' => 'ctc_edd_license_sanitize', // function to do additional sanitization 98 100 ); 99 100 101 } 101 102 102 103 // Make fields filterable. 103 $fields = apply_filters( 'ctc_edd_license_settings_fields', $fields);104 $fields = apply_filters('ctc_edd_license_settings_fields', $fields); 104 105 105 106 // Add fields to section. 106 $section['fields'] = array_merge( $fields, $section['fields']);107 $section['fields'] = array_merge($fields, $section['fields']); 107 108 108 109 // Hide Church Content Pro content field if it is active and showing license field. 109 if ( isset( $section['fields'][ 'church_content_pro_note' ] ) && ctc_pro_is_active() ) { 110 unset( $section['fields'][ 'church_content_pro_note' ] ); 111 } 112 110 if (isset($section['fields']['church_content_pro_note']) && ctc_pro_is_active()) { 111 unset($section['fields']['church_content_pro_note']); 112 } 113 113 } 114 114 115 115 // No add-ons. 116 116 else { 117 118 117 } 119 118 120 119 return $section; 121 122 } 123 124 add_filter( 'ctps_section-licenses', 'ctc_edd_license_settings' ); 120 } 121 122 add_filter('ctps_section-licenses', 'ctc_edd_license_settings'); 125 123 126 124 /** … … 136 134 * @return string HTML for field output 137 135 */ 138 function ctc_edd_license_key_field( $args, $data ) { 136 function ctc_edd_license_key_field($args, $data) 137 { 139 138 140 139 // Get add-on 141 $add_on_dir = str_replace( '_license_key', '', $data['id']);140 $add_on_dir = str_replace('_license_key', '', $data['id']); 142 141 143 142 // License key and status 144 $license = ctc_edd_license_key( $add_on_dir);145 $status = ctc_edd_license_status( $add_on_dir); // local status143 $license = ctc_edd_license_key($add_on_dir); 144 $status = ctc_edd_license_status($add_on_dir); // local status 146 145 147 146 // Renewal URL 148 $renewal_url = ctc_edd_license_renewal_url( $add_on_dir);147 $renewal_url = ctc_edd_license_renewal_url($add_on_dir); 149 148 150 149 // Text Input. 151 150 $input = '<input type="text" ' . $data['common_atts'] . ' id="' . $data['esc_element_id'] . '" value="' . $data['esc_value'] . '" />'; 152 $input = apply_filters( 'ctc_edd_license_key_input', $input, $args, $data);151 $input = apply_filters('ctc_edd_license_key_input', $input, $args, $data); 153 152 $html = $input; 154 153 … … 157 156 158 157 // Licensed provided? Show button and information 159 if ( $license) {158 if ($license) { 160 159 161 160 // Show Activate/Deactivate buttons unless expired (in that case show Renew alone) 162 if ( ! ctc_edd_license_expired( $add_on_dir )) {161 if (! ctc_edd_license_expired($add_on_dir)) { 163 162 164 163 // Activate Button (license is not active) 165 if ( ! ctc_edd_license_active( $add_on_dir )) {166 $html .= '<input type="submit" class="button button-primary ctc-license-button ctc-license-activate-button" name="ctc_edd_license_activate[' . esc_attr( $add_on_dir ) . ']" value="' . esc_attr__( 'Activate License', 'church-theme-content' ). '" />';164 if (! ctc_edd_license_active($add_on_dir)) { 165 $html .= '<input type="submit" class="button button-primary ctc-license-button ctc-license-activate-button" name="ctc_edd_license_activate[' . esc_attr($add_on_dir) . ']" value="' . esc_attr__('Activate License', 'church-theme-content') . '" />'; 167 166 } 168 167 169 168 // Deactivate Button (license is active) 170 169 else { 171 $html .= '<input type="submit" class="button button ctc-license-button ctc-license-deactivate-button" name="ctc_edd_license_deactivate[' . esc_attr( $add_on_dir ) . ']" value="' . esc_attr__( 'Deactivate License', 'church-theme-content' ) . '" />'; 172 } 173 170 $html .= '<input type="submit" class="button button ctc-license-button ctc-license-deactivate-button" name="ctc_edd_license_deactivate[' . esc_attr($add_on_dir) . ']" value="' . esc_attr__('Deactivate License', 'church-theme-content') . '" />'; 171 } 174 172 } 175 173 176 174 // Renew Button 177 175 // Show only if renewal URL provided and license is active or expired 178 if ( ctc_edd_license_renewal_url( $add_on_dir ) && ( ctc_edd_license_active( $add_on_dir ) || ctc_edd_license_expired( $add_on_dir ) )) {179 $html .= '<a href="' . esc_url( $renewal_url ) . '" class="button button' . ( ctc_edd_license_expired( $add_on_dir ) || ctc_edd_license_expiring_soon( $add_on_dir ) ? '-primary' : '' ) . ' ctc-license-button ctc-license-renew-button" target="_blank" />' . esc_html__( 'Renew License', 'church-theme-content') . '</a>';176 if (ctc_edd_license_renewal_url($add_on_dir) && (ctc_edd_license_active($add_on_dir) || ctc_edd_license_expired($add_on_dir))) { 177 $html .= '<a href="' . esc_url($renewal_url) . '" class="button button' . (ctc_edd_license_expired($add_on_dir) || ctc_edd_license_expiring_soon($add_on_dir) ? '-primary' : '') . ' ctc-license-button ctc-license-renew-button" target="_blank" />' . esc_html__('Renew License', 'church-theme-content') . '</a>'; 180 178 } 181 179 … … 183 181 //$license_info .= '<span class="ctc-license-info-label ctc-license-status-label">' . esc_html_x( 'Status:', 'license key', 'church-theme-content' ) . '</span> '; 184 182 185 // Status value 186 if ( ctc_edd_license_active( $add_on_dir ) ) { 187 188 // Active 189 $license_info .= '<span class="ctc-license-active">' . esc_html_x( 'Active', 'license key', 'church-theme-content' ) . '</span>'; 190 191 // Expiring soon 192 if ( ctc_edd_license_expiring_soon( $add_on_dir ) ) { 193 $license_info .= ' / <span class="ctc-license-expiring-soon">' . esc_html_x( 'Expiring Soon', 'license status', 'church-theme-content' ) . '</span>'; 194 } 195 196 } elseif ( ctc_edd_license_expired( $add_on_dir ) ) { 197 198 // Expired 199 $license_info .= '<span class="ctc-license-expired">' . esc_html_x( 'Expired', 'license key', 'church-theme-content' ) . '</span>'; 200 201 } else { 202 203 // Inactive 204 $license_info .= '<span class="ctc-license-inactive">' . esc_html_x( 'Inactive', 'license key', 'church-theme-content' ) . '</span>'; 205 206 } 183 // Status value 184 if (ctc_edd_license_active($add_on_dir)) { 185 186 // Active 187 $license_info .= '<span class="ctc-license-active">' . esc_html_x('Active', 'license key', 'church-theme-content') . '</span>'; 188 189 // Expiring soon 190 if (ctc_edd_license_expiring_soon($add_on_dir)) { 191 $license_info .= ' / <span class="ctc-license-expiring-soon">' . esc_html_x('Expiring Soon', 'license status', 'church-theme-content') . '</span>'; 192 } 193 } elseif (ctc_edd_license_expired($add_on_dir)) { 194 195 // Expired 196 $license_info .= '<span class="ctc-license-expired">' . esc_html_x('Expired', 'license key', 'church-theme-content') . '</span>'; 197 } else { 198 199 // Inactive 200 $license_info .= '<span class="ctc-license-inactive">' . esc_html_x('Inactive', 'license key', 'church-theme-content') . '</span>'; 201 } 207 202 208 203 // Expiration 209 204 // Show expiration only if license is active or expired, not just if have the data 210 if ( ctc_edd_license_expiration( $add_on_dir ) && ( ctc_edd_license_active( $add_on_dir ) || ctc_edd_license_expired( $add_on_dir ) )) {205 if (ctc_edd_license_expiration($add_on_dir) && (ctc_edd_license_active($add_on_dir) || ctc_edd_license_expired($add_on_dir))) { 211 206 212 207 // Expiration label 213 $license_info .= '<span class="ctc-license-info-label ctc-license-expiration-label">' . esc_html_x( 'Expiration:', 'license key', 'church-theme-content') . '</span> ';208 $license_info .= '<span class="ctc-license-info-label ctc-license-expiration-label">' . esc_html_x('Expiration:', 'license key', 'church-theme-content') . '</span> '; 214 209 215 210 // Expiration value 216 $license_info .= '<span class="ctc-license-expiration">' . esc_html( ctc_edd_license_expiration_formatted( $add_on_dir ) ) . '</span>'; 217 218 } 219 211 $license_info .= '<span class="ctc-license-expiration">' . esc_html(ctc_edd_license_expiration_formatted($add_on_dir)) . '</span>'; 212 } 220 213 } 221 214 222 215 // License key not provided 223 216 else { 224 $license_info .= '<p><span class="ctc-license-key-missing">' . esc_html__( 'Key Not Entered', 'church-theme-content') . '</span></p>';217 $license_info .= '<p><span class="ctc-license-key-missing">' . esc_html__('Key Not Entered', 'church-theme-content') . '</span></p>'; 225 218 } 226 219 227 220 // Append license info 228 if ( ! empty( $license_info )) {221 if (! empty($license_info)) { 229 222 $html .= '<p class="ctc-edd-license-info">' . $license_info . '</p>'; 230 223 } 231 224 232 225 return $html; 233 234 226 } 235 227 … … 245 237 * @return string Sanitized key 246 238 */ 247 function ctc_edd_license_sanitize( $new, $field ) { 239 function ctc_edd_license_sanitize($new, $field) 240 { 248 241 249 242 // Get add-on 250 $add_on_dir = str_replace( '_license_key', '', $field['id']);243 $add_on_dir = str_replace('_license_key', '', $field['id']); 251 244 252 245 // Get old license key value 253 $old = ctc_edd_license_key( $add_on_dir);246 $old = ctc_edd_license_key($add_on_dir); 254 247 255 248 // Unset local status as active and expiration date when changing key -- need to activate new key 256 if ( $old && $old != $new) {249 if ($old && $old != $new) { 257 250 258 251 // Note: status and expiration stored in their own options 259 252 // Not in plugin settings array (easier management and these are not user settings) 260 delete_option( $add_on_dir . '_license_status' ); 261 delete_option( $add_on_dir . '_license_expiration' ); 262 253 delete_option($add_on_dir . '_license_status'); 254 delete_option($add_on_dir . '_license_expiration'); 263 255 } 264 256 265 257 return $new; 266 267 258 } 268 259 … … 282 273 * @return string Option value 283 274 */ 284 function ctc_edd_license_key( $add_on_dir ) { 275 function ctc_edd_license_key($add_on_dir) 276 { 285 277 286 278 // Get license key setting 287 $license_key = trim( ctc_setting( $add_on_dir . '_license_key' ));279 $license_key = trim(ctc_setting($add_on_dir . '_license_key')); 288 280 289 281 // Return filtered 290 return apply_filters( 'ctc_edd_license_key', $license_key, $add_on_dir ); 291 282 return apply_filters('ctc_edd_license_key', $license_key, $add_on_dir); 292 283 } 293 284 … … 301 292 * @return string status active, expired or empty (inactive) 302 293 */ 303 function ctc_edd_license_status( $add_on_dir ) {304 305 $status = get_option( $add_on_dir . '_license_status' ); 306 307 return apply_filters( 'ctc_edd_license_status', $status, $add_on_dir ); 308 294 function ctc_edd_license_status($add_on_dir) 295 { 296 297 $status = get_option($add_on_dir . '_license_status'); 298 299 return apply_filters('ctc_edd_license_status', $status, $add_on_dir); 309 300 } 310 301 … … 316 307 * @return bool True if active 317 308 */ 318 function ctc_edd_license_active( $add_on_dir ) { 309 function ctc_edd_license_active($add_on_dir) 310 { 319 311 320 312 $active = false; 321 313 322 if ( 'active' == ctc_edd_license_status( $add_on_dir )) {314 if ('active' == ctc_edd_license_status($add_on_dir)) { 323 315 $active = true; 324 316 } 325 317 326 return apply_filters( 'ctc_edd_license_active', $active, $add_on_dir ); 327 318 return apply_filters('ctc_edd_license_active', $active, $add_on_dir); 328 319 } 329 320 … … 335 326 * @return bool True if inactive 336 327 */ 337 function ctc_edd_license_inactive( $add_on_dir ) { 328 function ctc_edd_license_inactive($add_on_dir) 329 { 338 330 339 331 $inactive = false; 340 332 341 if ( ! ctc_edd_license_status( $add_on_dir )) {333 if (! ctc_edd_license_status($add_on_dir)) { 342 334 $inactive = true; 343 335 } 344 336 345 return apply_filters( 'ctc_edd_license_inactive', $inactive, $add_on_dir ); 346 337 return apply_filters('ctc_edd_license_inactive', $inactive, $add_on_dir); 347 338 } 348 339 … … 354 345 * @return bool True if expired 355 346 */ 356 function ctc_edd_license_expired( $add_on_dir ) { 347 function ctc_edd_license_expired($add_on_dir) 348 { 357 349 358 350 $expired = false; 359 351 360 if ( 'expired' == ctc_edd_license_status( $add_on_dir )) {352 if ('expired' == ctc_edd_license_status($add_on_dir)) { 361 353 $expired = true; 362 354 } 363 355 364 return apply_filters( 'ctc_edd_license_expired', $expired, $add_on_dir ); 365 356 return apply_filters('ctc_edd_license_expired', $expired, $add_on_dir); 366 357 } 367 358 … … 373 364 * @return bool True if expiring within X days 374 365 */ 375 function ctc_edd_license_expiring_soon( $add_on_dir ) { 366 function ctc_edd_license_expiring_soon($add_on_dir) 367 { 376 368 377 369 $expiring_soon = false; 378 370 379 $expiration_data = ctc_edd_license_expiration_data( $add_on_dir);380 381 if ( ! empty( $expiration_data['expiring_soon'] )) {371 $expiration_data = ctc_edd_license_expiration_data($add_on_dir); 372 373 if (! empty($expiration_data['expiring_soon'])) { 382 374 $expiring_soon = true; 383 375 } 384 376 385 return apply_filters( 'ctc_edd_license_expiring_soon', $expiring_soon, $add_on_dir ); 386 377 return apply_filters('ctc_edd_license_expiring_soon', $expiring_soon, $add_on_dir); 387 378 } 388 379 … … 397 388 * @return string Expiration YYYY-MM-DD 398 389 */ 399 function ctc_edd_license_update_expiration( $add_on_dir, $expiration ) { 390 function ctc_edd_license_update_expiration($add_on_dir, $expiration) 391 { 400 392 401 393 // Only if have a value (old value better than no value) 402 if ( ! empty( $expiration )) {394 if (! empty($expiration)) { 403 395 404 396 // Remove seconds so stored value is YYYY-MM-DD 405 list( $expiration ) = explode( ' ', $expiration);406 $expiration = trim( $expiration);397 list($expiration) = explode(' ', $expiration); 398 $expiration = trim($expiration); 407 399 408 400 // Not an invalid key? 409 if ( $expiration != '1970-01-01') {401 if ($expiration != '1970-01-01') { 410 402 411 403 // Update local value 412 update_option( $add_on_dir . '_license_expiration', $expiration ); 413 414 } 415 416 } 417 404 update_option($add_on_dir . '_license_expiration', $expiration); 405 } 406 } 418 407 } 419 408 … … 425 414 * @return string Expiration YYYY-MM-DD 426 415 */ 427 function ctc_edd_license_expiration( $add_on_dir ) {428 429 $expiration = get_option( $add_on_dir . '_license_expiration' ); 430 431 return apply_filters( 'ctc_edd_license_expiration', $expiration, $add_on_dir ); 432 416 function ctc_edd_license_expiration($add_on_dir) 417 { 418 419 $expiration = get_option($add_on_dir . '_license_expiration'); 420 421 return apply_filters('ctc_edd_license_expiration', $expiration, $add_on_dir); 433 422 } 434 423 … … 441 430 * @return string Expiration date formatted 442 431 */ 443 function ctc_edd_license_expiration_formatted( $add_on_dir, $none_text = false ) { 444 445 $expiration = ctc_edd_license_expiration( $add_on_dir ); 432 function ctc_edd_license_expiration_formatted($add_on_dir, $none_text = false) 433 { 434 435 $expiration = ctc_edd_license_expiration($add_on_dir); 446 436 447 437 $date = ''; 448 438 449 if ( $expiration) {450 $date = date_i18n( get_option( 'date_format' ), strtotime( $expiration ));451 } elseif ( ! empty( $none_text )) {439 if ($expiration) { 440 $date = date_i18n(get_option('date_format'), strtotime($expiration)); 441 } elseif (! empty($none_text)) { 452 442 $date = $none_text; 453 443 } 454 444 455 return apply_filters( 'ctc_edd_license_expiration_formatted', $date, $add_on_dir ); 456 445 return apply_filters('ctc_edd_license_expiration_formatted', $date, $add_on_dir); 457 446 } 458 447 … … 464 453 * @return array date in various formats and whether it is expiring soon or not 465 454 */ 466 function ctc_edd_license_expiration_data( $add_on_dir ) { 455 function ctc_edd_license_expiration_data($add_on_dir) 456 { 467 457 468 458 $data = array(); 469 459 470 $data['expiration'] = ctc_edd_license_expiration( $add_on_dir ); 471 $data['expiration_date'] = ctc_edd_license_expiration_formatted( $add_on_dir, esc_html_x( 'unknown date', 'license expiration', 'church-theme-content' ) ); 472 $data['expiration_ts'] = ! empty( $data['expiration'] ) ? strtotime( $data['expiration'] ) : ''; 473 $data['expiring_soon_days'] = ctc_get_add_on( $add_on_dir, 'expiring_soon_days' ); 474 $data['expiring_soon_ts'] = time() + ( DAY_IN_SECONDS * $data['expiring_soon_days'] ); 475 $data['expiring_soon'] = ( ! ctc_edd_license_expired( $add_on_dir ) && ! empty( $data['expiration_ts'] ) && $data['expiration_ts'] < $data['expiring_soon_ts'] ) ? true : false; 476 477 return apply_filters( 'ctc_edd_license_expiration_data', $data, $add_on_dir ); 478 460 $data['expiration'] = ctc_edd_license_expiration($add_on_dir); 461 $data['expiration_date'] = ctc_edd_license_expiration_formatted($add_on_dir, esc_html_x('unknown date', 'license expiration', 'church-theme-content')); 462 $data['expiration_ts'] = ! empty($data['expiration']) ? strtotime($data['expiration']) : ''; 463 $data['expiring_soon_days'] = ctc_get_add_on($add_on_dir, 'expiring_soon_days'); 464 $data['expiring_soon_ts'] = time() + (DAY_IN_SECONDS * $data['expiring_soon_days']); 465 $data['expiring_soon'] = (! ctc_edd_license_expired($add_on_dir) && ! empty($data['expiration_ts']) && $data['expiration_ts'] < $data['expiring_soon_ts']) ? true : false; 466 467 return apply_filters('ctc_edd_license_expiration_data', $data, $add_on_dir); 479 468 } 480 469 … … 494 483 * @return string $result Result such as 'activate_success' or 'activate_fail' (not every action has result) 495 484 */ 496 function ctc_edd_license_activation( $add_on_dir, $action ) { 485 function ctc_edd_license_activation($add_on_dir, $action) 486 { 497 487 498 488 $result = ''; 499 489 500 490 // Add-on supports licensing? 501 if ( ! ctc_edd_license_supported( $add_on_dir )) {491 if (! ctc_edd_license_supported($add_on_dir)) { 502 492 return $result; 503 493 } 504 494 505 495 // Continue to activate or deactivate 506 if ( $action && $add_on_dir) {496 if ($action && $add_on_dir) { 507 497 508 498 // Get license data 509 $license_data = ctc_edd_license_action( $add_on_dir, $action);499 $license_data = ctc_edd_license_action($add_on_dir, $action); 510 500 511 501 // Call action via API 512 if ( $license_data) {502 if ($license_data) { 513 503 514 504 // If activated remotely, set local status; or set local status if was already active remotely -- keep in sync 515 if ( 'activate_license' == $action) {505 if ('activate_license' == $action) { 516 506 517 507 // Success 518 if ( 'valid' == $license_data->license || 'valid' == ctc_edd_license_check( $add_on_dir )) {519 520 update_option( $add_on_dir . '_license_status', 'active');508 if ('valid' == $license_data->license || 'valid' == ctc_edd_license_check($add_on_dir)) { 509 510 update_option($add_on_dir . '_license_status', 'active'); 521 511 522 512 $result = 'activate_success'; 523 524 513 } 525 514 … … 528 517 $result = 'activate_fail'; 529 518 } 530 531 519 } 532 520 … … 538 526 || 'disabled' == $license_data->license // if disabled would return failed... (leaving this just in case) 539 527 || 'failed' == $license_data->license // likely means deactivation failed because it's disabled 540 || 'inactive' == ctc_edd_license_check( $add_on_dir)528 || 'inactive' == ctc_edd_license_check($add_on_dir) 541 529 ) 542 530 ) { 543 531 544 532 // Success or failure? 545 if ( 'deactivated' == $license_data->license) {533 if ('deactivated' == $license_data->license) { 546 534 $result = 'deactivate_success'; 547 535 } else { … … 550 538 551 539 // Delete license status 552 delete_option( $add_on_dir . '_license_status' ); 553 540 delete_option($add_on_dir . '_license_status'); 554 541 } 555 542 556 543 // Set current expiration locally 557 544 // Local will be synced to remote daily in case changes 558 if ( isset( $license_data->expires ) ) { 559 ctc_edd_license_update_expiration( $add_on_dir, $license_data->expires ); 560 } 561 562 } 563 545 if (isset($license_data->expires)) { 546 ctc_edd_license_update_expiration($add_on_dir, $license_data->expires); 547 } 548 } 564 549 } 565 550 566 551 return $result; 567 568 552 } 569 553 … … 583 567 * @return array Settings to save 584 568 */ 585 function ctc_edd_license_detect_user_action( $settings, $old_settings ) { 569 function ctc_edd_license_detect_user_action($settings, $old_settings) 570 { 586 571 587 572 // Activate button clicked 588 if ( ! empty( $_POST['ctc_edd_license_activate'] )) {573 if (! empty($_POST['ctc_edd_license_activate'])) { 589 574 $action = 'activate_license'; // for EDD Software Licensing API 590 $add_on_dir = key( $_POST['ctc_edd_license_activate']);575 $add_on_dir = key($_POST['ctc_edd_license_activate']); 591 576 } 592 577 593 578 // Deactivate button clicked 594 elseif ( ! empty( $_POST['ctc_edd_license_deactivate'] )) {579 elseif (! empty($_POST['ctc_edd_license_deactivate'])) { 595 580 $action = 'deactivate_license'; // for EDD Software Licensing API 596 $add_on_dir = key( $_POST['ctc_edd_license_deactivate']);581 $add_on_dir = key($_POST['ctc_edd_license_deactivate']); 597 582 } 598 583 599 584 // Has action, add-on and license key? 600 if ( ! empty( $action ) && ! empty( $settings[$add_on_dir . '_license_key'] )) {585 if (! empty($action) && ! empty($settings[$add_on_dir . '_license_key'])) { 601 586 602 587 // Set transient with license key data 603 588 // ctc_edd_license_activation() will run this after redirect occurs 604 589 // It is done after everything is saved in case license key value changed 605 set_transient( 'ctc_edd_license_activation', array(590 set_transient('ctc_edd_license_activation', array( 606 591 'action' => $action, 607 592 'add_on_dir' => $add_on_dir, 608 ), 30 ); // expires when first run or after 30 seconds in case of timeout593 ), 30); // expires when first run or after 30 seconds in case of timeout 609 594 610 595 } … … 613 598 // Otherwise plugin settings will be wiped 614 599 return $settings; 615 616 600 } 617 601 618 602 // Using pre_update_option instead of update_option action because update_option 619 603 // will not fire unless values changed -- and we need $_POST to detect button action 620 add_filter( 'pre_update_option_ctc_settings', 'ctc_edd_license_detect_user_action', 10, 2);604 add_filter('pre_update_option_ctc_settings', 'ctc_edd_license_detect_user_action', 10, 2); 621 605 622 606 /** … … 632 616 * @global object $ctc_settings 633 617 */ 634 function ctc_edd_license_activation_after_user_action() { 618 function ctc_edd_license_activation_after_user_action() 619 { 635 620 636 621 global $ctc_settings; 637 622 638 623 // Is this plugin settings page? 639 if ( ! $ctc_settings->is_settings_page()) {624 if (! $ctc_settings->is_settings_page()) { 640 625 return; 641 626 } 642 627 643 628 // Get transient with add-on to activate license for 644 $activation_data = get_transient( 'ctc_edd_license_activation');629 $activation_data = get_transient('ctc_edd_license_activation'); 645 630 646 631 // Is a an add-on's license to be activated/deactivated? 647 if ( ! empty( $activation_data )) {632 if (! empty($activation_data)) { 648 633 649 634 // Delete transient so this is run once 650 delete_transient( 'ctc_edd_license_activation');635 delete_transient('ctc_edd_license_activation'); 651 636 652 637 // Prepare data … … 655 640 656 641 // Attempt activation/deactivation remotely and set the result locally 657 $result = ctc_edd_license_activation( $add_on_dir, $action);642 $result = ctc_edd_license_activation($add_on_dir, $action); 658 643 659 644 // Activation result 660 if ( $result) {645 if ($result) { 661 646 662 647 // Set transient so notice shows on next settings page load 663 set_transient( 'ctc_edd_license_activation_result', array(648 set_transient('ctc_edd_license_activation_result', array( 664 649 'result' => $result, 665 650 'add_on_dir' => $add_on_dir, 666 ), 15 ); // will be deleted after shown or in 15 seconds 667 668 } 669 670 } 671 672 } 673 674 add_action( 'ctps_after_save', 'ctc_edd_license_activation_after_user_action' ); 651 ), 15); // will be deleted after shown or in 15 seconds 652 653 } 654 } 655 } 656 657 add_action('ctps_after_save', 'ctc_edd_license_activation_after_user_action'); 675 658 676 659 /** … … 680 663 * @global object $ctc_settings 681 664 */ 682 function ctc_edd_license_activation_result_notice() { 665 function ctc_edd_license_activation_result_notice() 666 { 683 667 684 668 global $ctc_settings; 685 669 686 670 // Only on plugin settings 687 if ( ! $ctc_settings->is_settings_page()) {671 if (! $ctc_settings->is_settings_page()) { 688 672 return; 689 673 } 690 674 691 675 // Have a result transient? 692 $result = get_transient( 'ctc_edd_license_activation_result');693 if ( $result) {676 $result = get_transient('ctc_edd_license_activation_result'); 677 if ($result) { 694 678 695 679 // Get result data? … … 698 682 699 683 // Have result data? 700 if ( ! empty( $add_on_dir ) && ! empty( $result )) {684 if (! empty($add_on_dir) && ! empty($result)) { 701 685 702 686 // Get notice message 703 $notice_message = ctc_get_add_on( $add_on_dir, $result . '_notice');687 $notice_message = ctc_get_add_on($add_on_dir, $result . '_notice'); 704 688 705 689 // Output notice 706 if ( $notice_message) {690 if ($notice_message) { 707 691 708 692 // Show notice and hide "Settings saved." notice beneath 709 ?>710 711 <div id="ctc-license-notice-<?php echo esc_attr( $result ); ?>" class="notice notice-<?php if ( preg_match( '/success/', $result )) : ?>success<?php else : ?>error<?php endif; ?>">693 ?> 694 695 <div id="ctc-license-notice-<?php echo esc_attr($result); ?>" class="notice notice-<?php if (preg_match('/success/', $result)) : ?>success<?php else : ?>error<?php endif; ?>"> 712 696 <p> 713 697 <?php … … 730 714 731 715 <style type="text/css"> 732 #setting-error-settings_updated {733 display: none;734 }716 #setting-error-settings_updated { 717 display: none; 718 } 735 719 </style> 736 720 737 <?php 738 739 } 740 721 <?php 722 723 } 741 724 } 742 725 743 726 // Delete transient after showing notice once 744 delete_transient( 'ctc_edd_license_activation_result' ); 745 746 } 747 748 } 749 750 add_action( 'admin_notices', 'ctc_edd_license_activation_result_notice' ); 727 delete_transient('ctc_edd_license_activation_result'); 728 } 729 } 730 731 add_action('admin_notices', 'ctc_edd_license_activation_result_notice'); 751 732 752 733 /******************************************* … … 760 741 * @global object $ctc_settings 761 742 */ 762 function ctc_edd_license_notices() { 743 function ctc_edd_license_notices() 744 { 763 745 764 746 global $ctc_settings; … … 766 748 // User can manage plugins? 767 749 // Keeps notices from showing to non-admin users 768 if ( ! current_user_can( 'install_plugins' )) {750 if (! current_user_can('install_plugins')) { 769 751 return; 770 752 } … … 773 755 // Don't show on settings page (redundant on Licenses tab and irrelevants/distracting on others) 774 756 $screen = get_current_screen(); 775 if ( ! in_array( $screen->base, array( 'dashboard', 'plugins', 'update-core' ) )) {757 if (! in_array($screen->base, array('dashboard', 'plugins', 'update-core'))) { 776 758 return; 777 759 } … … 781 763 782 764 // Have add-ons? 783 if ( $add_ons) {765 if ($add_ons) { 784 766 785 767 // Collect add-ons requiring a notice … … 789 771 790 772 // Loop add-ons 791 foreach ( $add_ons as $add_on_dir => $add_on) {773 foreach ($add_ons as $add_on_dir => $add_on) { 792 774 793 775 // Add-on supports EDD licensing? 794 if ( ! ctc_edd_license_supported( $add_on_dir )) {776 if (! ctc_edd_license_supported($add_on_dir)) { 795 777 continue; 796 778 } 797 779 798 780 // Get expiration data 799 $expiration_data = ctc_edd_license_expiration_data( $add_on_dir);781 $expiration_data = ctc_edd_license_expiration_data($add_on_dir); 800 782 801 783 // Active But Expiring Soon 802 784 // Show a reminder notice 30 days before expiration 803 if ( ctc_edd_license_active( $add_on_dir ) && $expiration_data['expiring_soon']) {785 if (ctc_edd_license_active($add_on_dir) && $expiration_data['expiring_soon']) { 804 786 $expiring_soon_add_ons[$add_on_dir] = $add_on; 805 787 } … … 807 789 // Expired 808 790 // This shows as error not notice, since it has come to pass 809 elseif ( ctc_edd_license_expired( $add_on_dir )) {791 elseif (ctc_edd_license_expired($add_on_dir)) { 810 792 $expired_add_ons[$add_on_dir] = $add_on; 811 793 } 812 794 813 795 // Inactive 814 elseif ( ! ctc_edd_license_active( $add_on_dir )) {796 elseif (! ctc_edd_license_active($add_on_dir)) { 815 797 $inactive_add_ons[$add_on_dir] = $add_on; 816 798 } 817 818 799 } 819 800 820 801 // Get notices. 821 802 $notices = ''; 822 $notices .= ctc_edd_license_notice_content( 'inactive', $inactive_add_ons);823 $notices .= ctc_edd_license_notice_content( 'expired', $expired_add_ons);824 $notices .= ctc_edd_license_notice_content( 'expiring_soon', $expiring_soon_add_ons);803 $notices .= ctc_edd_license_notice_content('inactive', $inactive_add_ons); 804 $notices .= ctc_edd_license_notice_content('expired', $expired_add_ons); 805 $notices .= ctc_edd_license_notice_content('expiring_soon', $expiring_soon_add_ons); 825 806 826 807 // Filter notices. 827 $notices = apply_filters( 'ctc_edd_license_notices', $notices);808 $notices = apply_filters('ctc_edd_license_notices', $notices); 828 809 829 810 // Output notices. 830 811 echo $notices; 831 832 } 833 834 } 835 836 add_action( 'admin_notices', 'ctc_edd_license_notices', 8 ); // higher priority than regular notices (10) but lower than theme license notice (7) 812 } 813 } 814 815 add_action('admin_notices', 'ctc_edd_license_notices', 8); // higher priority than regular notices (10) but lower than theme license notice (7) 837 816 838 817 /** … … 844 823 * @return string HTML output for admin_notice 845 824 */ 846 function ctc_edd_license_notice_content( $notice, $add_ons ) { 825 function ctc_edd_license_notice_content($notice, $add_ons) 826 { 847 827 848 828 $content = ''; 849 829 850 830 // Count add-ons 851 $count = count( $add_ons);831 $count = count($add_ons); 852 832 853 833 // Have at least one? 854 if ( $count) {834 if ($count) { 855 835 856 836 // Empty vars. … … 865 845 866 846 // One add-on 867 if ( 1 == $count) {847 if (1 == $count) { 868 848 869 849 // Message to use. … … 871 851 872 852 // Get first and only add-on in array. 873 $values = array_values( $add_ons);874 $first_add_on = array_shift( $values);853 $values = array_values($add_ons); 854 $first_add_on = array_shift($values); 875 855 876 856 // Add-on data. 877 857 $add_on_dir = $first_add_on['plugin_dir']; 878 858 $add_on_names = $first_add_on['name']; // single name 879 $expiration_data = ctc_edd_license_expiration_data( $add_on_dir);859 $expiration_data = ctc_edd_license_expiration_data($add_on_dir); 880 860 $expiration_date = $expiration_data['expiration_date']; 881 861 882 862 // URLs for add-on overriding default notices during registration 883 $renewal_url = ctc_edd_license_renewal_url( $add_on_dir);884 $renewal_info_url = ctc_get_add_on( $add_on_dir, 'renewal_info_url');863 $renewal_url = ctc_edd_license_renewal_url($add_on_dir); 864 $renewal_info_url = ctc_get_add_on($add_on_dir, 'renewal_info_url'); 885 865 886 866 // Is this Pro add-on? Check if theme uses same license key. 887 867 888 if ( 'church-content-pro' === $add_on_dir) {868 if ('church-content-pro' === $add_on_dir) { 889 869 890 870 // Get Pro license key. 891 $pro_license_key = ctc_edd_license_key( $add_on_dir);871 $pro_license_key = ctc_edd_license_key($add_on_dir); 892 872 893 873 // Get ChurchThemes.com theme license key. 894 874 $active_theme = wp_get_theme(); 895 if ( function_exists( 'ctfw_edd_license_key' )) {875 if (function_exists('ctfw_edd_license_key')) { 896 876 $theme_license_key = ctfw_edd_license_key(); 897 877 } 898 878 899 879 // Have theme from ChurchTheme.com and license key is same as Pro. 900 if ( $theme_license_key && $theme_license_key === $pro_license_key) {880 if ($theme_license_key && $theme_license_key === $pro_license_key) { 901 881 902 882 // Message to use … … 904 884 905 885 // Theme name. 906 $theme_name = $active_theme->get( 'Name');886 $theme_name = $active_theme->get('Name'); 907 887 908 888 // Prevent the theme's notice from showing. … … 910 890 911 891 } 912 913 } 914 892 } 915 893 } 916 894 … … 924 902 $i = 0; 925 903 $add_on_names = ''; 926 foreach ( $add_ons as $add_on) {904 foreach ($add_ons as $add_on) { 927 905 928 906 $i++; 929 907 930 908 // Separate with comma or "and" 931 if ( $i == $count) {909 if ($i == $count) { 932 910 933 911 /* translators: separator between last and second to last add-ons in inactive/expired admin notice (instead of comma) */ 934 $add_on_names .= esc_html_x( ' and ', 'license notice', 'church-theme-content' ); 935 936 } elseif ( 1 != $i ) { 912 $add_on_names .= esc_html_x(' and ', 'license notice', 'church-theme-content'); 913 } elseif (1 != $i) { 937 914 938 915 /* translators: separator between add-on names in inactive/expired admin notice */ 939 $add_on_names .= esc_html_x( ', ', 'license notice', 'church-theme-content' ); 940 916 $add_on_names .= esc_html_x(', ', 'license notice', 'church-theme-content'); 941 917 } 942 918 943 919 // Append name to list 944 920 $add_on_names .= '<strong>' . $add_on['name'] . '</strong>'; 945 946 } 947 921 } 948 922 } 949 923 … … 957 931 958 932 /* translators: %1$s is URL to add-on license settings, %2$s is name of add-on */ 959 'inactive' => ctc_get_add_on( $add_on_dir, 'inactive_notice'),933 'inactive' => ctc_get_add_on($add_on_dir, 'inactive_notice'), 960 934 961 935 /* translators: %1$s is URL to add-on license settings, %2$s is names of add-ons */ 962 'inactive_multiple' => __( '<strong>Add-on Licenses Inactive:</strong> <a href="%1$s">Activate Your Add-on Licenses</a> to enable updates for %2$s.', 'church-theme-content'),936 'inactive_multiple' => __('<strong>Add-on Licenses Inactive:</strong> <a href="%1$s">Activate Your Add-on Licenses</a> to enable updates for %2$s.', 'church-theme-content'), 963 937 964 938 /* translators: %1$s is URL to add-on license settings, %2$s is name of add-on, %3$s is expiration date, %7$s agency name. */ 965 'expired' => ctc_get_add_on( $add_on_dir, 'expired_notice'),966 'expired_agency_mode' => __( '<strong>Add-on License Expired:</strong> Ask %7$s to renew their <a href="%1$s">Add-on License</a> for <strong>%2$s</strong> to re-enable updates for your site (expired <strong>%3$s</strong>). <a href="%5$s" target="_blank">Learn More</a>', 'church-content-pro'),939 'expired' => ctc_get_add_on($add_on_dir, 'expired_notice'), 940 'expired_agency_mode' => __('<strong>Add-on License Expired:</strong> Ask %7$s to renew their <a href="%1$s">Add-on License</a> for <strong>%2$s</strong> to re-enable updates for your site (expired <strong>%3$s</strong>). <a href="%5$s" target="_blank">Learn More</a>', 'church-content-pro'), 967 941 968 942 /* translators: %1$s is URL to add-on license settings, %2$s is names of add-ons, %7$s agency name. */ 969 'expired_multiple' => __( '<strong>Add-on Licenses Expired:</strong> <a href="%1$s">Renew Your Add-on Licenses</a> for %2$s to re-enable updates.', 'church-theme-content'),970 'expired_multiple_agency_mode' => __( '<strong>Add-on Licenses Expired:</strong> Ask %7$s to renew their <a href="%1$s">Add-on Licenses</a> for %2$s to re-enable updates for your site.', 'church-theme-content'),943 'expired_multiple' => __('<strong>Add-on Licenses Expired:</strong> <a href="%1$s">Renew Your Add-on Licenses</a> for %2$s to re-enable updates.', 'church-theme-content'), 944 'expired_multiple_agency_mode' => __('<strong>Add-on Licenses Expired:</strong> Ask %7$s to renew their <a href="%1$s">Add-on Licenses</a> for %2$s to re-enable updates for your site.', 'church-theme-content'), 971 945 972 946 /* translators: %2$s is name of Pro plugin, %3$s is expiration date, %4$s is link to renew, %5$s is link to learn more, %6$s is name of theme sharing same license as add-on, %7$s agency name. */ 973 947 // This shows only for ChurchThemes.com themes when license key is same for theme and Pro plugin. 974 'expired_theme_pro' => __( '<strong>License Expired:</strong> <a href="%4$s">Renew Your License</a> for the <b>%6$s</b> theme and <b>%2$s</b> add-on to reactivate updates and support (expired <b>%3$s</b>). <a href="%5$s" target="_blank">Learn More</a>', 'church-theme-content'),975 'expired_theme_pro_agency_mode' => __( '<strong>License Expired:</strong> Ask %7$s to renew their license for the <b>%6$s</b> theme and <b>%2$s</b> add-on to reactivate updates for your site (expired <b>%3$s</b>). <a href="%5$s" target="_blank">Learn More</a>', 'church-theme-content'),948 'expired_theme_pro' => __('<strong>License Expired:</strong> <a href="%4$s">Renew Your License</a> for the <b>%6$s</b> theme and <b>%2$s</b> add-on to reactivate updates and support (expired <b>%3$s</b>). <a href="%5$s" target="_blank">Learn More</a>', 'church-theme-content'), 949 'expired_theme_pro_agency_mode' => __('<strong>License Expired:</strong> Ask %7$s to renew their license for the <b>%6$s</b> theme and <b>%2$s</b> add-on to reactivate updates for your site (expired <b>%3$s</b>). <a href="%5$s" target="_blank">Learn More</a>', 'church-theme-content'), 976 950 977 951 /* translators: %1$s is URL to add-on license settings, %2$s is name of add-on, %3$s is expiration date */ 978 'expiring_soon' => ctc_get_add_on( $add_on_dir, 'expiring_soon_notice'),952 'expiring_soon' => ctc_get_add_on($add_on_dir, 'expiring_soon_notice'), 979 953 980 954 /* translators: %1$s is URL to add-on license settings, %2$s is names of add-ons */ 981 'expiring_soon_multiple' => __( '<strong>Add-on Licenses Expiring Soon:</strong> <a href="%1$s">Renew Your Add-on Licenses</a> for %2$s to continue receiving updates.', 'church-theme-content'),955 'expiring_soon_multiple' => __('<strong>Add-on Licenses Expiring Soon:</strong> <a href="%1$s">Renew Your Add-on Licenses</a> for %2$s to continue receiving updates.', 'church-theme-content'), 982 956 983 957 /* translators: %2$s is name of Pro plugin, %3$s is expiration date, %4$s is link to renew, %5$s is link to learn more, %6$s is name of theme sharing same license as add-on. */ 984 958 // This shows only for ChurchThemes.com themes when license key is same for theme and Pro plugin. 985 959 // Note that "Expiring Soon" notices not shown when Agency Mode is enabled. 986 'expiring_soon_theme_pro' => __( '<strong>License Expiring Soon:</strong> <a href="%4$s">Renew Your License</a> for the <b>%6$s</b> theme and <b>%2$s</b> add-on before expiration on <b>%3$s</b>. <a href="%5$s" target="_blank">Learn More</a>', 'church-theme-content'),960 'expiring_soon_theme_pro' => __('<strong>License Expiring Soon:</strong> <a href="%4$s">Renew Your License</a> for the <b>%6$s</b> theme and <b>%2$s</b> add-on before expiration on <b>%3$s</b>. <a href="%5$s" target="_blank">Learn More</a>', 'church-theme-content'), 987 961 988 962 ); … … 990 964 // Filter notice_key. 991 965 // Pro add-on can do this to append _agency_mode to an expired notice. 992 $notice_key = apply_filters( 'ctc_edd_license_notice_key', $notice_key, $notices);966 $notice_key = apply_filters('ctc_edd_license_notice_key', $notice_key, $notices); 993 967 994 968 // Have notice message. 995 if ( isset( $notices[$notice_key] )) {969 if (isset($notices[$notice_key])) { 996 970 997 971 // Notice message. … … 1001 975 // notice-warning (yellow) for expiring soon. 1002 976 // notice-error (red) for inactive and expired (everything else). 1003 $notice_class = preg_match( '/expiring_soon/', $notice_key) ? 'notice-warning' : 'notice-error';977 $notice_class = preg_match('/expiring_soon/', $notice_key) ? 'notice-warning' : 'notice-error'; 1004 978 1005 979 // Class to denote license status. 1006 $notice_class .= ' ctc-license-notice-' . str_replace( '_', '-', $notice_key);980 $notice_class .= ' ctc-license-notice-' . str_replace('_', '-', $notice_key); 1007 981 1008 982 // Agency name. 1009 983 /* translators: This is used in place of agency name for Agency Mode when no agency name available */ 1010 $agency_name = __( 'your website provider', 'church-theme-content');1011 if ( function_exists( 'ccp_agency_mode_name_linked' )) {984 $agency_name = __('your website provider', 'church-theme-content'); 985 if (function_exists('ccp_agency_mode_name_linked')) { 1012 986 $agency_name = ccp_agency_mode_name_linked(); 1013 987 } 1014 988 1015 989 // Build notice HTML. 1016 $content .= '<div class="ctc-license-status-notice notice ' . esc_attr( $notice_class) . '">';990 $content .= '<div class="ctc-license-status-notice notice ' . esc_attr($notice_class) . '">'; 1017 991 $content .= ' <p>'; 1018 992 $content .= sprintf( 1019 993 1020 wp_kses(1021 $message,1022 array(1023 'strong' => array(),1024 'b' => array(),1025 'em' => array(),1026 'i' => array(),1027 'a' => array(1028 'href' => array(),1029 'target' => array(),1030 ),1031 )1032 ),1033 1034 esc_url( admin_url( 'options-general.php?page=' . CTC_DIR ) . '#licenses'),1035 $add_on_names, // or single name1036 1037 // These are available only when the notice is for a single add-on1038 // Default notices should not use renewal URLs because they may not be available1039 // An add-on can, however, use the renewal URLs it provides1040 $expiration_date,1041 $renewal_url,1042 $renewal_info_url,1043 $theme_name,1044 $agency_name1045 1046 );994 wp_kses( 995 $message, 996 array( 997 'strong' => array(), 998 'b' => array(), 999 'em' => array(), 1000 'i' => array(), 1001 'a' => array( 1002 'href' => array(), 1003 'target' => array(), 1004 ), 1005 ) 1006 ), 1007 1008 esc_url(admin_url('options-general.php?page=' . CTC_DIR) . '#licenses'), 1009 $add_on_names, // or single name 1010 1011 // These are available only when the notice is for a single add-on 1012 // Default notices should not use renewal URLs because they may not be available 1013 // An add-on can, however, use the renewal URLs it provides 1014 $expiration_date, 1015 $renewal_url, 1016 $renewal_info_url, 1017 $theme_name, 1018 $agency_name 1019 1020 ); 1047 1021 $content .= ' </p>'; 1048 1022 $content .= '</div>'; 1049 1023 1050 1024 // Hide theme expired/expiring notice. 1051 if ( ! empty( $hide_theme_expiration_notice )) {1025 if (! empty($hide_theme_expiration_notice)) { 1052 1026 $content .= '<style type="text/css">'; 1053 1027 $content .= '#ctfw-license-notice {'; … … 1056 1030 $content .= '</style>'; 1057 1031 } 1058 1059 } 1060 1061 } 1062 1063 return apply_filters( 'ctc_edd_license_notice_content', $content, $notice, $add_ons ); 1064 1032 } 1033 } 1034 1035 return apply_filters('ctc_edd_license_notice_content', $content, $notice, $add_ons); 1065 1036 } 1066 1037 … … 1078 1049 * @return string Renewal URl with license key replaced 1079 1050 */ 1080 function ctc_edd_license_renewal_url( $add_on_dir ) { 1051 function ctc_edd_license_renewal_url($add_on_dir) 1052 { 1081 1053 1082 1054 // Get raw renewal URL 1083 $renewal_url = ctc_get_add_on( $add_on_dir, 'renewal_url');1055 $renewal_url = ctc_get_add_on($add_on_dir, 'renewal_url'); 1084 1056 1085 1057 // Have URL 1086 if ( $renewal_url) {1058 if ($renewal_url) { 1087 1059 1088 1060 // Replace {license_key} with license key 1089 $renewal_url = str_replace( '{license_key}', ctc_edd_license_key( $add_on_dir ), $renewal_url ); 1090 1061 $renewal_url = str_replace('{license_key}', ctc_edd_license_key($add_on_dir), $renewal_url); 1091 1062 } 1092 1063 1093 1064 // Return filtered 1094 return apply_filters( 'ctc_edd_license_renewal_url', $renewal_url, $add_on_dir ); 1095 1065 return apply_filters('ctc_edd_license_renewal_url', $renewal_url, $add_on_dir); 1096 1066 } 1097 1067 … … 1111 1081 * @return object License data from remote server 1112 1082 */ 1113 function ctc_edd_license_action( $add_on_dir, $action ) { 1083 function ctc_edd_license_action($add_on_dir, $action) 1084 { 1114 1085 1115 1086 $license_data = array(); 1116 1087 1117 1088 // Add-on supports EDD licensing 1118 if ( ctc_edd_license_supported( $add_on_dir )) {1089 if (ctc_edd_license_supported($add_on_dir)) { 1119 1090 1120 1091 // Valid action? 1121 $actions = array( 'activate_license', 'deactivate_license', 'check_license');1122 if ( in_array( $action, $actions )) {1092 $actions = array('activate_license', 'deactivate_license', 'check_license'); 1093 if (in_array($action, $actions)) { 1123 1094 1124 1095 // Get license 1125 $license = ctc_edd_license_key( $add_on_dir);1096 $license = ctc_edd_license_key($add_on_dir); 1126 1097 1127 1098 // Have license 1128 if ( $license ) { 1129 1130 // Data to send in API request 1131 $api_params = array( 1132 'edd_action' => $action, 1133 'license' => $license, 1134 'item_name' => urlencode( ctc_get_add_on( $add_on_dir, 'item_name' ) ), // name of download in EDD 1135 'url' => urlencode( home_url() ) // URL of this site activated for license 1136 ); 1099 if ($license) { 1137 1100 1138 1101 // Call the API 1139 $response = wp_remote_get( esc_url_raw( add_query_arg( $api_params, ctc_get_add_on( $add_on_dir, 'store_url' ) ) ), array( 'timeout' => 15, 'sslverify' => false ) ); 1102 $remote_api_url = ctc_get_add_on($add_on_dir, 'store_url'); 1103 $remote_api_url = trailingslashit($remote_api_url); 1104 $response = wp_remote_post($remote_api_url, [ 1105 'body' => [ 1106 'edd_action' => $action, 1107 'license' => $license, 1108 'item_name' => ctc_get_add_on($add_on_dir, 'item_name'), // name of download in EDD 1109 'url' => home_url(), // URL of this site activated for license 1110 'no_cache' => md5(microtime(true)), 1111 ], 1112 'timeout' => 15, 1113 'sslverify' => true, 1114 ]); 1140 1115 1141 1116 // Got a valid response? 1142 if ( ! is_wp_error( $response )) {1117 if (! is_wp_error($response)) { 1143 1118 1144 1119 // Decode the license data 1145 $license_data = json_decode( wp_remote_retrieve_body( $response ) ); 1146 1120 $license_data = json_decode(wp_remote_retrieve_body($response)); 1147 1121 } 1148 1149 } 1150 1151 } 1152 1153 } 1154 1155 return apply_filters( 'ctc_edd_license_action', $license_data, $add_on_dir, $action ); 1156 1122 } 1123 } 1124 } 1125 1126 return apply_filters('ctc_edd_license_action', $license_data, $add_on_dir, $action); 1157 1127 } 1158 1128 … … 1167 1137 * @return array License data array or single value for key 1168 1138 */ 1169 function ctc_edd_license_check_data( $add_on_dir, $key = false ) { 1139 function ctc_edd_license_check_data($add_on_dir, $key = false) 1140 { 1170 1141 1171 1142 // Get remote license data 1172 $data = ctc_edd_license_action( $add_on_dir, 'check_license');1143 $data = ctc_edd_license_action($add_on_dir, 'check_license'); 1173 1144 1174 1145 // Convert data to array … … 1176 1147 1177 1148 // Get value for specific key? 1178 if ( isset( $data[$key] )) { // key is given1149 if (isset($data[$key])) { // key is given 1179 1150 1180 1151 // Value exists for key in object 1181 if ( ! empty( $data[$key] )) {1152 if (! empty($data[$key])) { 1182 1153 $data = $data[$key]; 1183 1154 } … … 1188 1159 $data = ''; 1189 1160 } 1190 1191 } 1192 1193 return apply_filters( 'ctc_edd_license_check_data', $data, $add_on_dir, $key ); 1194 1161 } 1162 1163 return apply_filters('ctc_edd_license_check_data', $data, $add_on_dir, $key); 1195 1164 } 1196 1165 … … 1204 1173 * @return string Remote license status 1205 1174 */ 1206 function ctc_edd_license_check( $add_on_dir ) {1207 1208 $status = ctc_edd_license_check_data( $add_on_dir, 'license' ); 1209 1210 return apply_filters( 'ctc_edd_license_check', $status, $add_on_dir ); 1211 1175 function ctc_edd_license_check($add_on_dir) 1176 { 1177 1178 $status = ctc_edd_license_check_data($add_on_dir, 'license'); 1179 1180 return apply_filters('ctc_edd_license_check', $status, $add_on_dir); 1212 1181 } 1213 1182 … … 1226 1195 * @param string $add_on_dir Add-on to work with 1227 1196 */ 1228 function ctc_edd_license_sync( $add_on_dir ) { 1197 function ctc_edd_license_sync($add_on_dir) 1198 { 1229 1199 1230 1200 // Plugin supports EDD licensing? 1231 if ( ! ctc_edd_license_supported( $add_on_dir )) {1201 if (! ctc_edd_license_supported($add_on_dir)) { 1232 1202 return; 1233 1203 } 1234 1204 1235 1205 // Get remote license data 1236 $license_data = ctc_edd_license_check_data( $add_on_dir);1206 $license_data = ctc_edd_license_check_data($add_on_dir); 1237 1207 1238 1208 // Continue only if got a response 1239 if ( ! empty( $license_data )) { // don't do anything if times out1209 if (! empty($license_data)) { // don't do anything if times out 1240 1210 1241 1211 // Get remote status 1242 $status = isset( $license_data['license']) ? $license_data['license'] : false;1212 $status = isset($license_data['license']) ? $license_data['license'] : false; 1243 1213 1244 1214 // Active remotely 1245 1215 // This will activate locally if had been inactive or expired locally 1246 if ( 'valid' == $status) {1216 if ('valid' == $status) { 1247 1217 1248 1218 // Activate locally 1249 update_option( $add_on_dir . '_license_status', 'active' ); 1250 1219 update_option($add_on_dir . '_license_status', 'active'); 1251 1220 } 1252 1221 1253 1222 // Inactive remotely 1254 elseif ( in_array( $status, array( 'inactive', 'site_inactive', 'disabled' ) )) { // status is not valid1223 elseif (in_array($status, array('inactive', 'site_inactive', 'disabled'))) { // status is not valid 1255 1224 1256 1225 // Deactivate locally 1257 delete_option( $add_on_dir . '_license_status' ); 1258 1226 delete_option($add_on_dir . '_license_status'); 1259 1227 } 1260 1228 1261 1229 // Expired remotely 1262 elseif ( 'expired' == $status) {1230 elseif ('expired' == $status) { 1263 1231 1264 1232 // Set status expired locally 1265 update_option( $add_on_dir . '_license_status', 'expired' ); 1266 1233 update_option($add_on_dir . '_license_status', 'expired'); 1267 1234 } 1268 1235 1269 1236 // Update expiration data 1270 1237 // This helps the user know when to renew 1271 if ( isset( $license_data['expires'] ) ) { 1272 ctc_edd_license_update_expiration( $add_on_dir, $license_data['expires'] ); 1273 } 1274 1275 } 1276 1238 if (isset($license_data['expires'])) { 1239 ctc_edd_license_update_expiration($add_on_dir, $license_data['expires']); 1240 } 1241 } 1277 1242 } 1278 1243 … … 1288 1253 * @global object $ctc_settings 1289 1254 */ 1290 function ctc_edd_license_auto_sync() { 1255 function ctc_edd_license_auto_sync() 1256 { 1291 1257 1292 1258 global $ctc_settings; 1293 1259 1294 1260 // Admin only 1295 if ( ! is_admin()) {1261 if (! is_admin()) { 1296 1262 return; 1297 1263 } … … 1299 1265 // Periodically in relevant areas or always on Plugin Settings page (where license key status shown) 1300 1266 $screen = get_current_screen(); 1301 if ( ! $ctc_settings->is_settings_page() && ! in_array( $screen->base, array( 'dashboard', 'update-core', 'plugins' ) )) {1267 if (! $ctc_settings->is_settings_page() && ! in_array($screen->base, array('dashboard', 'update-core', 'plugins'))) { 1302 1268 return; 1303 1269 } … … 1308 1274 // Had add-ons? 1309 1275 // No need to run if no add-ons registered 1310 if ( ! $add_ons) {1276 if (! $add_ons) { 1311 1277 return; 1312 1278 } … … 1314 1280 // Has this been checked in last day or is it plugin settings page? 1315 1281 // Settings page always runs this 1316 if ( get_transient( 'ctc_edd_license_auto_sync' ) && ! $ctc_settings->is_settings_page()) {1282 if (get_transient('ctc_edd_license_auto_sync') && ! $ctc_settings->is_settings_page()) { 1317 1283 return; 1318 1284 } else { … … 1320 1286 // Set transient to prevent check until next day 1321 1287 // Once per day is enough to keep notice on dashboard and updates pages without hammering remote server 1322 set_transient( 'ctc_edd_license_auto_sync', true, DAY_IN_SECONDS ); 1323 1288 set_transient('ctc_edd_license_auto_sync', true, DAY_IN_SECONDS); 1324 1289 } 1325 1290 1326 1291 // Loop add-ons 1327 foreach ( $add_ons as $add_on_dir => $add_on) {1292 foreach ($add_ons as $add_on_dir => $add_on) { 1328 1293 1329 1294 // Add-on supports EDD licensing? 1330 if ( ! ctc_edd_license_supported( $add_on_dir )) {1295 if (! ctc_edd_license_supported($add_on_dir)) { 1331 1296 return; 1332 1297 } 1333 1298 1334 1299 // Check remote status and sync both ways if necessary 1335 ctc_edd_license_sync( $add_on_dir ); 1336 1337 } 1338 1339 } 1340 1341 add_action( 'current_screen', 'ctc_edd_license_auto_sync' ); 1300 ctc_edd_license_sync($add_on_dir); 1301 } 1302 } 1303 1304 add_action('current_screen', 'ctc_edd_license_auto_sync'); 1342 1305 1343 1306 /******************************************* … … 1352 1315 * @since 1.2 1353 1316 */ 1354 function ctc_edd_license_updater() { 1317 function ctc_edd_license_updater() 1318 { 1355 1319 1356 1320 // Get add-ons … … 1358 1322 1359 1323 // Have add-ons? 1360 if ( $add_ons) {1324 if ($add_ons) { 1361 1325 1362 1326 // Include Easy Digital Downloads Software Licensing plugin updater class 1363 if ( ! class_exists( 'CTC_EDD_SL_Plugin_Updater' )) {1327 if (! class_exists('CTC_EDD_SL_Plugin_Updater')) { 1364 1328 require CTC_PATH . '/' . CTC_CLASS_DIR . '/CTC_EDD_SL_Plugin_Updater.php'; 1365 1329 } 1366 1330 1367 1331 // Loop add-ons 1368 foreach ( $add_ons as $add_on_dir => $add_on) {1332 foreach ($add_ons as $add_on_dir => $add_on) { 1369 1333 1370 1334 // Supports licensing and updates? 1371 if ( ! ctc_edd_license_supported( $add_on_dir ) || empty( $add_on['updates'] )) {1335 if (! ctc_edd_license_supported($add_on_dir) || empty($add_on['updates'])) { 1372 1336 continue; 1373 1337 } 1374 1338 1375 1339 // License is active? 1376 if ( ! ctc_edd_license_active( $add_on_dir )) {1340 if (! ctc_edd_license_active($add_on_dir)) { 1377 1341 continue; 1378 1342 } 1379 1343 1380 1344 // Get license key 1381 $license_key = ctc_edd_license_key( $add_on_dir);1345 $license_key = ctc_edd_license_key($add_on_dir); 1382 1346 1383 1347 // Make sure we have the data necessary for using the updater class 1384 1348 if ( 1385 1349 $license_key 1386 && ! empty( $add_on['store_url'])1387 && ! empty( $add_on['item_name'])1388 && ! empty( $add_on['author'])1350 && ! empty($add_on['store_url']) 1351 && ! empty($add_on['item_name']) 1352 && ! empty($add_on['author']) 1389 1353 ) { 1390 1354 … … 1400 1364 ) 1401 1365 ); 1402 1403 } 1404 1405 } 1406 1407 } 1408 1409 } 1410 1411 add_action( 'admin_init', 'ctc_edd_license_updater', 0 ); // after add-on registration on plugins_loaded, but before other things 1366 } 1367 } 1368 } 1369 } 1370 1371 add_action('admin_init', 'ctc_edd_license_updater', 0); // after add-on registration on plugins_loaded, but before other things 1412 1372 1413 1373 /** … … 1425 1385 * @return array Modified request. 1426 1386 */ 1427 function ctc_prevent_wporg_plugin_update( $r, $url ) { 1387 function ctc_prevent_wporg_plugin_update($r, $url) 1388 { 1428 1389 1429 1390 // Stop if it's not a plugin update request. 1430 if ( 0 !== strpos( $url, 'https://api.wordpress.org/plugins/update-check/' )) {1391 if (0 !== strpos($url, 'https://api.wordpress.org/plugins/update-check/')) { 1431 1392 return $r; 1432 1393 } … … 1434 1395 // Get add-ons and stop if don't have any. 1435 1396 $add_ons = ctc_get_add_ons(); 1436 if ( ! $add_ons) {1397 if (! $add_ons) { 1437 1398 return $r; 1438 1399 } 1439 1400 1440 1401 // Require response with plugins. 1441 if ( ! isset( $r['body']['plugins'] )) {1402 if (! isset($r['body']['plugins'])) { 1442 1403 return $r; 1443 1404 } 1444 1405 1445 1406 // Decode the JSON response. 1446 $plugins = json_decode( $r['body']['plugins'], true); // as array.1407 $plugins = json_decode($r['body']['plugins'], true); // as array. 1447 1408 1448 1409 // Have plugins array. 1449 if ( ! empty( $plugins ) && is_array( $plugins )) {1410 if (! empty($plugins) && is_array($plugins)) { 1450 1411 1451 1412 // Loop to remove add-on plugins that use EDD Software Licensing from the check. 1452 foreach ( $add_ons as $add_on_dir => $add_on) {1413 foreach ($add_ons as $add_on_dir => $add_on) { 1453 1414 1454 1415 // Skip if doesn't support licensing and updates. 1455 if ( ! ctc_edd_license_supported( $add_on_dir ) || empty( $add_on['updates'] )) {1416 if (! ctc_edd_license_supported($add_on_dir) || empty($add_on['updates'])) { 1456 1417 continue; 1457 1418 } 1458 1419 1459 1420 // Make sure have necessary data (prevent errors if response ever changes). 1460 if ( empty( $add_on['plugin_file'] ) || empty( $plugins['active'] ) || ! is_array( $plugins['active'] ) || empty( $plugins['plugins'] ) || ! is_array( $plugins['plugins'] )) {1421 if (empty($add_on['plugin_file']) || empty($plugins['active']) || ! is_array($plugins['active']) || empty($plugins['plugins']) || ! is_array($plugins['plugins'])) { 1461 1422 continue; 1462 1423 } 1463 1424 1464 1425 // Plugin basename. 1465 $plugin_basename = plugin_basename( $add_on['plugin_file']);1426 $plugin_basename = plugin_basename($add_on['plugin_file']); 1466 1427 1467 1428 // Plugin key. 1468 1429 $plugin_key = ''; 1469 if ( $plugin_basename) {1470 $plugin_key = array_search( $plugin_basename, $plugins['active']);1430 if ($plugin_basename) { 1431 $plugin_key = array_search($plugin_basename, $plugins['active']); 1471 1432 } else { 1472 1433 continue; // basename and key required to continue. … … 1474 1435 1475 1436 // Remove add-on from the plugins object. 1476 if ( isset( $plugins['plugins'][ $plugin_basename ] )) {1477 unset( $plugins['plugins'][ $plugin_basename ]);1437 if (isset($plugins['plugins'][$plugin_basename])) { 1438 unset($plugins['plugins'][$plugin_basename]); 1478 1439 } 1479 1440 1480 1441 // Remove add-on from the active plugins array. 1481 if ( isset( $plugins['active'][ $plugin_key ] ) ) { 1482 unset( $plugins['active'][ $plugin_key ] ); 1483 } 1484 1485 } 1486 1442 if (isset($plugins['active'][$plugin_key])) { 1443 unset($plugins['active'][$plugin_key]); 1444 } 1445 } 1487 1446 } 1488 1447 1489 1448 // Encode the updated JSON response. 1490 $r['body']['plugins'] = wp_json_encode( $plugins);1449 $r['body']['plugins'] = wp_json_encode($plugins); 1491 1450 1492 1451 // Return updated response. 1493 1452 return $r; 1494 1495 } 1496 1497 add_filter( 'http_request_args', 'ctc_prevent_wporg_plugin_update', 5, 2 ); 1453 } 1454 1455 add_filter('http_request_args', 'ctc_prevent_wporg_plugin_update', 5, 2); -
church-theme-content/trunk/includes/classes/CTC_EDD_SL_Plugin_Updater.php
r2090032 r3391879 1 1 <?php 2 2 3 /** 3 4 * Easy Digital Downloads Software Licensing Plugin Updater … … 14 15 15 16 // Exit if accessed directly 16 if ( ! defined( 'ABSPATH' )) exit;17 if (! defined('ABSPATH')) exit; 17 18 18 19 /** … … 22 23 * @version 1.6.14 23 24 */ 24 class CTC_EDD_SL_Plugin_Updater {25 26 private $api_url = ''; 27 private $api_data = array();28 private $name = '';29 private $slug= '';30 private $version= '';31 private $wp_override = false;32 private $cache_key = '';33 34 /** 35 * Class constructor. 36 * 37 * @uses plugin_basename() 38 * @uses hook()39 * 40 * @param string $_api_url The URL pointing to the custom API endpoint. 41 * @param string $_plugin_file Path to the plugin file.42 * @param array $_api_data Optional data to send with API calls.43 */ 44 public function __construct( $_api_url, $_plugin_file, $_api_data = null ) { 45 46 global $edd_plugin_data; 47 48 $this->api_url = trailingslashit( $_api_url );49 $this->api_data = $_api_data; 50 $this->name = plugin_basename( $_plugin_file);51 $this->slug = basename( $_plugin_file, '.php' );52 $this->version = $_api_data['version'];53 $this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;54 $this->beta = ! empty( $this->api_data['beta'] ) ? true : false;55 $this->cache_key = md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );56 57 $edd_plugin_data[ $this->slug ] = $this->api_data;58 59 // Set up hooks. 60 $this->init(); 61 62 } 63 64 /** 65 * Set up WordPress filters to hook into WP's update process. 66 * 67 * @uses add_filter() 68 * 69 * @return void 70 */ 71 public function init() { 72 73 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) ); 74 add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 ); 75 remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10);76 add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2);77 add_action( 'admin_init', array( $this, 'show_changelog' ));78 79 } 80 81 /** 82 * Check for Updates at the defined API endpoint and modify the update array. 83 * 84 * This function dives into the update API just when WordPress creates its update array, 85 * then adds a custom API call and injects the custom plugin data retrieved from the API. 86 * It is reassembled from parts of the native WordPress plugin update code.87 * See wp-includes/update.php line 121 for the original wp_update_plugins() function.88 * 89 * @uses api_request() 90 * 91 * @param array $_transient_data Update array build by WordPress. 92 * @return array Modified update array with custom plugin data.93 */ 94 public function check_update( $_transient_data ) { 95 96 global $pagenow; 97 98 if ( ! is_object( $_transient_data ) ) { 99 $_transient_data = new stdClass; 100 } 101 102 if ( 'plugins.php' == $pagenow && is_multisite() ) { 103 return $_transient_data; 104 } 105 106 if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) { 107 return $_transient_data; 108 } 109 110 $version_info = $this->get_cached_version_info(); 111 112 if ( false === $version_info ) { 113 $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) ); 114 115 $this->set_version_info_cache( $version_info);116 117 } 118 119 if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) { 120 121 if ( version_compare( $this->version, $version_info->new_version, '<' ) ) { 122 123 $_transient_data->response[ $this->name ] = $version_info; 124 125 }126 127 $_transient_data->last_checked = current_time( 'timestamp');128 $_transient_data->checked[ $this->name] = $this->version;129 130 } 131 132 return $_transient_data; 133 } 134 135 /** 136 * show update notification row -- needed for multisite subsites, because WP won't tell you otherwise! 137 * 138 * @param string $file 139 * @param array $plugin 140 */ 141 public function show_update_notification( $file, $plugin ){142 143 if ( is_network_admin()) {144 return;145 }146 147 if( ! current_user_can( 'update_plugins' )) {148 return;149 }150 151 if( ! is_multisite()) {152 return;153 }154 155 if ( $this->name != $file) {156 return;157 }158 159 // Remove our filter on the site transient160 remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10);161 162 $update_cache = get_site_transient( 'update_plugins');163 164 $update_cache = is_object( $update_cache) ? $update_cache : new stdClass();165 166 if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] )) {167 168 $version_info = $this->get_cached_version_info();169 170 if ( false === $version_info) {171 $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ));172 173 $this->set_version_info_cache( $version_info);174 }175 176 if ( ! is_object( $version_info )) {177 return;178 }179 180 if ( version_compare( $this->version, $version_info->new_version, '<' )) {181 182 $update_cache->response[ $this->name] = $version_info;183 184 } 185 186 $update_cache->last_checked = current_time( 'timestamp' );187 $update_cache->checked[ $this->name ] = $this->version; 188 189 set_site_transient( 'update_plugins', $update_cache ); 190 191 } else { 192 193 $version_info = $update_cache->response[ $this->name ]; 194 195 } 196 197 // Restore our filter 198 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) ); 199 200 if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) { 201 202 // build a plugin list row, with update notification 203 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );204 # <tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"> 205 echo '<tr class="plugin-update-tr" id="' . $this->slug . '-update" data-slug="' . $this->slug . '" data-plugin="' . $this->slug . '/' . $file . '">'; 206 echo '<td colspan="3" class="plugin-update colspanchange">';207 echo '<div class="update-message notice inline notice-warning notice-alt">'; 208 209 $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' ); 210 211 // CT Mod 212 // Use external changelog URL instead of post-provided changelog embedded in modal 213 $ctc_changelog_url = ctc_get_add_on( $this->slug, 'changelog_url' );214 $ctc_changelog_link_class = 'thickbox';215 if ( $ctc_changelog_url ) { 216 $changelog_link = $ctc_changelog_url; 217 $ctc_changelog_link_class = ''; 218 } 219 220 // CT Mod 221 // 1. Added CTC textdomain 222 // 2. Added class replacement. If $changelog_link provided, class is none; otherwise class for modal is used 223 if ( empty( $version_info->download_link ) ) { 224 printf(225 wp_kses( // CTC Mod - escape translation string 226 __( 'There is a new version of %1$s available. <a target="_blank" class="%4$s" href="%2$s">View version %3$s details</a>.', 'church-theme-content' ), // CTC Mod textdomain 227 array( 228 'a' => array( 229 'href' => array(), 230 'target' => array(), 231 'class' => array(),232 ) 233 ) 234 ),235 esc_html( $version_info->name ), 236 esc_url( $changelog_link ), 237 esc_html( $version_info->new_version ), 238 $ctc_changelog_link_class 239 ); 240 } else { 241 printf(242 wp_kses( // CTC Mod - escape translation string 243 __( 'There is a new version of %1$s available. <a target="_blank" class="%5$s" href="%2$s">View version %3$s details</a> or <a href="%4$s">update now</a>.', 'church-theme-content' ), // CTC Mod textdomain 244 array( 245 'a' => array( 246 'href' => array(), 247 'target' => array(), 248 'class' => array(),249 ) 250 ) 251 ),252 esc_html( $version_info->name),253 esc_url( $changelog_link ), 254 esc_html( $version_info->new_version ), 255 esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) ), 256 $ctc_changelog_link_class 257 );258 } 259 260 do_action( "in_plugin_update_message-{$file}", $plugin, $version_info ); 261 262 echo '</div></td></tr>'; 263 } 264 } 265 266 /** 267 * Updates information on the "View version x.x details" page with custom data. 268 * 269 * @uses api_request() 270 * 271 * @param mixed$_data272 * @param string $_action 273 * @param object $_args 274 * @return object $_data 275 */ 276 public function plugins_api_filter( $_data, $_action = '', $_args = null) {277 278 if ( $_action != 'plugin_information' ) { 279 280 return $_data; 281 282 } 283 284 if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) { 285 286 return $_data; 287 288 } 289 290 $to_send = array( 291 'slug' => $this->slug, 292 'is_ssl' => is_ssl(), 293 'fields' => array( 294 'banners' => array(), 295 'reviews' => false 296 ) 297 ); 298 299 $cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ); 300 301 // Get the transient where we store the api request for this plugin for 24 hours 302 $edd_api_request_transient = $this->get_cached_version_info( $cache_key ); 303 304 //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now. 305 if ( empty( $edd_api_request_transient ) ) { 306 307 $api_response = $this->api_request( 'plugin_information', $to_send ); 308 309 // Expires in 3 hours 310 $this->set_version_info_cache( $api_response, $cache_key ); 311 312 if ( false !== $api_response ) { 313 $_data = $api_response; 314 } 315 316 } else{317 $_data = $edd_api_request_transient;318 } 319 320 // Convert sections into an associative array, since we're getting an object, but Core expects an array. 321 if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) { 322 $new_sections = array();323 foreach ( $_data->sections as $key => $value ) { 324 $new_sections[ $key ] = $value; 325 } 326 327 $_data->sections = $new_sections;328 } 329 330 // Convert banners into an associative array, since we're getting an object, but Core expects an array. 331 if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) { 332 $new_banners = array();333 foreach ( $_data->banners as $key => $value ) { 334 $new_banners[ $key ] = $value; 335 } 336 337 $_data->banners = $new_banners; 338 } 339 340 return $_data; 341 } 342 343 /** 344 * Disable SSL verification in order to prevent download update failures 345 * 346 * @param array $args 347 * @param string $url 348 * @return object $array 349 */ 350 public function http_request_args( $args, $url ) { 351 352 $verify_ssl = $this->verify_ssl();353 if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) { 354 $args['sslverify'] = $verify_ssl; 355 } 356 return $args; 357 358 } 359 360 /** 361 * Calls the API and, if successful, returns the object delivered by the API. 362 * 363 * @uses get_bloginfo() 364 * @uses wp_remote_post() 365 * @uses is_wp_error() 366 * 367 * @param string $_action The requested action. 368 * @param array $_data Parameters for the API action. 369 * @return false|object 370 */ 371 private function api_request( $_action, $_data ) { 372 373 global $wp_version; 374 375 $data = array_merge( $this->api_data, $_data ); 376 377 if ( $data['slug'] != $this->slug) {378 return; 379 }380 381 if( $this->api_url == trailingslashit (home_url() ) ) { 382 return false; // Don't allow a plugin to ping itself 383 } 384 385 $api_params = array( 386 'edd_action' => 'get_version',387 'license' => ! empty( $data['license'] ) ? $data['license'] : '',388 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,389 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,390 'version' => isset( $data['version'] ) ? $data['version'] : false,391 'slug' => $data['slug'],392 'author' => $data['author'],393 'url' => home_url(),394 'beta' => ! empty( $data['beta'] ),395 ); 396 397 $verify_ssl = $this->verify_ssl(); 398 $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) ); 399 400 if ( ! is_wp_error( $request ) ) { 401 $request = json_decode( wp_remote_retrieve_body( $request ) ); 402 } 403 404 if ( $request && isset( $request->sections ) ){405 $request->sections = maybe_unserialize( $request->sections );406 } else { 407 $request = false; 408 } 409 410 if ( $request && isset( $request->banners ) ) { 411 $request->banners = maybe_unserialize( $request->banners ); 412 } 413 414 if( ! empty( $request->sections ) ) { 415 foreach( $request->sections as $key => $section ) { 416 $request->$key = (array) $section; 417 } 418 } 419 420 return $request; 421 } 422 423 public function show_changelog() { 424 425 global $edd_plugin_data; 426 427 if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) { 428 return; 429 } 430 431 if( empty( $_REQUEST['plugin'] ) ) { 432 return; 433 } 434 435 if( empty( $_REQUEST['slug'] ) ) { 436 return; 437 } 438 439 if( ! current_user_can( 'update_plugins' ) ) { 440 wp_die( __( 'You do not have permission to install plugin updates', 'church-theme-content' ), __( 'Error', 'church-theme-content' ), array( 'response' => 403 ) ); 441 } 442 443 $data = $edd_plugin_data[ $_REQUEST['slug'] ];444 $beta = ! empty( $data['beta'] ) ? true : false;445 $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $beta . '_version_info');446 $version_info = $this->get_cached_version_info( $cache_key ); 447 448 if( false === $version_info ) { 449 450 $api_params = array( 451 'edd_action' => 'get_version',452 'item_name' => isset( $data['item_name']) ? $data['item_name'] : false,453 'item_id' => isset( $data['item_id']) ? $data['item_id'] : false,454 'slug' => $_REQUEST['slug'],455 'author' => $data['author'],456 'url' => home_url(),457 'beta' => ! empty( $data['beta'] ) 458 ); 459 460 $verify_ssl = $this->verify_ssl(); 461 $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) ); 462 463 if ( ! is_wp_error( $request ) ) { 464 $version_info = json_decode( wp_remote_retrieve_body( $request ) ); 465 } 466 467 468 if ( ! empty( $version_info ) && isset( $version_info->sections ) ) { 469 $version_info->sections = maybe_unserialize( $version_info->sections ); 470 } else { 471 $version_info = false; 472 } 473 474 if( ! empty( $version_info ) ) { 475 foreach( $version_info->sections as $key => $section) {476 $version_info->$key = (array) $section; 477 } 478 }479 480 $this->set_version_info_cache( $version_info, $cache_key ); 481 482 }483 484 if( ! empty( $version_info ) && isset( $version_info->sections['changelog'] )) {485 echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';486 }487 488 exit;489 }490 491 public function get_cached_version_info( $cache_key = '' ) { 492 493 if( empty( $cache_key ) ) { 494 $cache_key = $this->cache_key; 495 } 496 497 $cache = get_option( $cache_key ); 498 499 if( empty( $cache['timeout'] ) || current_time( 'timestamp' ) > $cache['timeout'] ) { 500 return false; // Cache is expired 501 } 502 503 return json_decode( $cache['value'] ); 504 505 }506 507 public function set_version_info_cache( $value = '', $cache_key = '' ) { 508 509 if( empty( $cache_key ) ) { 510 $cache_key = $this->cache_key; 511 } 512 513 $data = array( 514 'timeout' => strtotime( '+3 hours', current_time( 'timestamp' ) ), 515 'value' => json_encode( $value ) 516 ); 517 518 update_option( $cache_key, $data, 'no' ); 519 520 }521 522 /**523 * Returns if the SSL of the store should be verified.524 *525 * @since 1.6.13526 * @return bool527 */528 private function verify_ssl() { 529 return (bool) apply_filters( 'edd_sl_api_request_verify_ssl', true, $this ); 530 } 531 25 class CTC_EDD_SL_Plugin_Updater 26 { 27 28 private $api_url = ''; 29 private $api_data = array(); 30 private $name = ''; 31 private $slug = ''; 32 private $version = ''; 33 private $wp_override = false; 34 private $cache_key = ''; 35 36 /** 37 * Class constructor. 38 * 39 * @uses plugin_basename() 40 * @uses hook() 41 * 42 * @param string $_api_url The URL pointing to the custom API endpoint. 43 * @param string $_plugin_file Path to the plugin file. 44 * @param array $_api_data Optional data to send with API calls. 45 */ 46 public function __construct($_api_url, $_plugin_file, $_api_data = null) 47 { 48 49 global $edd_plugin_data; 50 51 $this->api_url = trailingslashit($_api_url); 52 $this->api_data = $_api_data; 53 $this->name = plugin_basename($_plugin_file); 54 $this->slug = basename($_plugin_file, '.php'); 55 $this->version = $_api_data['version']; 56 $this->wp_override = isset($_api_data['wp_override']) ? (bool) $_api_data['wp_override'] : false; 57 $this->beta = ! empty($this->api_data['beta']) ? true : false; 58 $this->cache_key = md5(serialize($this->slug . $this->api_data['license'] . $this->beta)); 59 60 $edd_plugin_data[$this->slug] = $this->api_data; 61 62 // Set up hooks. 63 $this->init(); 64 } 65 66 /** 67 * Set up WordPress filters to hook into WP's update process. 68 * 69 * @uses add_filter() 70 * 71 * @return void 72 */ 73 public function init() 74 { 75 76 add_filter('pre_set_site_transient_update_plugins', array($this, 'check_update')); 77 add_filter('plugins_api', array($this, 'plugins_api_filter'), 10, 3); 78 remove_action('after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10); 79 add_action('after_plugin_row_' . $this->name, array($this, 'show_update_notification'), 10, 2); 80 add_action('admin_init', array($this, 'show_changelog')); 81 } 82 83 /** 84 * Check for Updates at the defined API endpoint and modify the update array. 85 * 86 * This function dives into the update API just when WordPress creates its update array, 87 * then adds a custom API call and injects the custom plugin data retrieved from the API. 88 * It is reassembled from parts of the native WordPress plugin update code. 89 * See wp-includes/update.php line 121 for the original wp_update_plugins() function. 90 * 91 * @uses api_request() 92 * 93 * @param array $_transient_data Update array build by WordPress. 94 * @return array Modified update array with custom plugin data. 95 */ 96 public function check_update($_transient_data) 97 { 98 99 global $pagenow; 100 101 if (! is_object($_transient_data)) { 102 $_transient_data = new stdClass; 103 } 104 105 if ('plugins.php' == $pagenow && is_multisite()) { 106 return $_transient_data; 107 } 108 109 if (! empty($_transient_data->response) && ! empty($_transient_data->response[$this->name]) && false === $this->wp_override) { 110 return $_transient_data; 111 } 112 113 $version_info = $this->get_cached_version_info(); 114 115 if (false === $version_info) { 116 $version_info = $this->api_request('plugin_latest_version', array('slug' => $this->slug, 'beta' => $this->beta)); 117 118 $this->set_version_info_cache($version_info); 119 } 120 121 if (false !== $version_info && is_object($version_info) && isset($version_info->new_version)) { 122 123 if (version_compare($this->version, $version_info->new_version, '<')) { 124 125 $_transient_data->response[$this->name] = $version_info; 126 } 127 128 $_transient_data->last_checked = current_time('timestamp'); 129 $_transient_data->checked[$this->name] = $this->version; 130 } 131 132 return $_transient_data; 133 } 134 135 /** 136 * show update notification row -- needed for multisite subsites, because WP won't tell you otherwise! 137 * 138 * @param string $file 139 * @param array $plugin 140 */ 141 public function show_update_notification($file, $plugin) 142 { 143 144 if (is_network_admin()) { 145 return; 146 } 147 148 if (! current_user_can('update_plugins')) { 149 return; 150 } 151 152 if (! is_multisite()) { 153 return; 154 } 155 156 if ($this->name != $file) { 157 return; 158 } 159 160 // Remove our filter on the site transient 161 remove_filter('pre_set_site_transient_update_plugins', array($this, 'check_update'), 10); 162 163 $update_cache = get_site_transient('update_plugins'); 164 165 $update_cache = is_object($update_cache) ? $update_cache : new stdClass(); 166 167 if (empty($update_cache->response) || empty($update_cache->response[$this->name])) { 168 169 $version_info = $this->get_cached_version_info(); 170 171 if (false === $version_info) { 172 $version_info = $this->api_request('plugin_latest_version', array('slug' => $this->slug, 'beta' => $this->beta)); 173 174 $this->set_version_info_cache($version_info); 175 } 176 177 if (! is_object($version_info)) { 178 return; 179 } 180 181 if (version_compare($this->version, $version_info->new_version, '<')) { 182 183 $update_cache->response[$this->name] = $version_info; 184 } 185 186 $update_cache->last_checked = current_time('timestamp'); 187 $update_cache->checked[$this->name] = $this->version; 188 189 set_site_transient('update_plugins', $update_cache); 190 } else { 191 192 $version_info = $update_cache->response[$this->name]; 193 } 194 195 // Restore our filter 196 add_filter('pre_set_site_transient_update_plugins', array($this, 'check_update')); 197 198 if (! empty($update_cache->response[$this->name]) && version_compare($this->version, $version_info->new_version, '<')) { 199 200 // build a plugin list row, with update notification 201 $wp_list_table = _get_list_table('WP_Plugins_List_Table'); 202 # <tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"> 203 echo '<tr class="plugin-update-tr" id="' . $this->slug . '-update" data-slug="' . $this->slug . '" data-plugin="' . $this->slug . '/' . $file . '">'; 204 echo '<td colspan="3" class="plugin-update colspanchange">'; 205 echo '<div class="update-message notice inline notice-warning notice-alt">'; 206 207 $changelog_link = self_admin_url('index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911'); 208 209 // CT Mod 210 // Use external changelog URL instead of post-provided changelog embedded in modal 211 $ctc_changelog_url = ctc_get_add_on($this->slug, 'changelog_url'); 212 $ctc_changelog_link_class = 'thickbox'; 213 if ($ctc_changelog_url) { 214 $changelog_link = $ctc_changelog_url; 215 $ctc_changelog_link_class = ''; 216 } 217 218 // CT Mod 219 // 1. Added CTC textdomain 220 // 2. Added class replacement. If $changelog_link provided, class is none; otherwise class for modal is used 221 if (empty($version_info->download_link)) { 222 printf( 223 wp_kses( // CTC Mod - escape translation string 224 __('There is a new version of %1$s available. <a target="_blank" class="%4$s" href="%2$s">View version %3$s details</a>.', 'church-theme-content'), // CTC Mod textdomain 225 array( 226 'a' => array( 227 'href' => array(), 228 'target' => array(), 229 'class' => array(), 230 ) 231 ) 232 ), 233 esc_html($version_info->name), 234 esc_url($changelog_link), 235 esc_html($version_info->new_version), 236 $ctc_changelog_link_class 237 ); 238 } else { 239 printf( 240 wp_kses( // CTC Mod - escape translation string 241 __('There is a new version of %1$s available. <a target="_blank" class="%5$s" href="%2$s">View version %3$s details</a> or <a href="%4$s">update now</a>.', 'church-theme-content'), // CTC Mod textdomain 242 array( 243 'a' => array( 244 'href' => array(), 245 'target' => array(), 246 'class' => array(), 247 ) 248 ) 249 ), 250 esc_html($version_info->name), 251 esc_url($changelog_link), 252 esc_html($version_info->new_version), 253 esc_url(wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=') . $this->name, 'upgrade-plugin_' . $this->name)), 254 $ctc_changelog_link_class 255 ); 256 } 257 258 do_action("in_plugin_update_message-{$file}", $plugin, $version_info); 259 260 echo '</div></td></tr>'; 261 } 262 } 263 264 /** 265 * Updates information on the "View version x.x details" page with custom data. 266 * 267 * @uses api_request() 268 * 269 * @param mixed $_data 270 * @param string $_action 271 * @param object $_args 272 * @return object $_data 273 */ 274 public function plugins_api_filter($_data, $_action = '', $_args = null) 275 { 276 277 if ($_action != 'plugin_information') { 278 279 return $_data; 280 } 281 282 if (! isset($_args->slug) || ($_args->slug != $this->slug)) { 283 284 return $_data; 285 } 286 287 $to_send = array( 288 'slug' => $this->slug, 289 'is_ssl' => is_ssl(), 290 'fields' => array( 291 'banners' => array(), 292 'reviews' => false 293 ) 294 ); 295 296 $cache_key = 'edd_api_request_' . md5(serialize($this->slug . $this->api_data['license'] . $this->beta)); 297 298 // Get the transient where we store the api request for this plugin for 24 hours 299 $edd_api_request_transient = $this->get_cached_version_info($cache_key); 300 301 //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now. 302 if (empty($edd_api_request_transient)) { 303 304 $api_response = $this->api_request('plugin_information', $to_send); 305 306 // Expires in 3 hours 307 $this->set_version_info_cache($api_response, $cache_key); 308 309 if (false !== $api_response) { 310 $_data = $api_response; 311 } 312 } else { 313 $_data = $edd_api_request_transient; 314 } 315 316 // Convert sections into an associative array, since we're getting an object, but Core expects an array. 317 if (isset($_data->sections) && ! is_array($_data->sections)) { 318 $new_sections = array(); 319 foreach ($_data->sections as $key => $value) { 320 $new_sections[$key] = $value; 321 } 322 323 $_data->sections = $new_sections; 324 } 325 326 // Convert banners into an associative array, since we're getting an object, but Core expects an array. 327 if (isset($_data->banners) && ! is_array($_data->banners)) { 328 $new_banners = array(); 329 foreach ($_data->banners as $key => $value) { 330 $new_banners[$key] = $value; 331 } 332 333 $_data->banners = $new_banners; 334 } 335 336 return $_data; 337 } 338 339 /** 340 * Disable SSL verification in order to prevent download update failures 341 * 342 * @param array $args 343 * @param string $url 344 * @return object $array 345 */ 346 public function http_request_args($args, $url) 347 { 348 349 $verify_ssl = $this->verify_ssl(); 350 if (strpos($url, 'https://') !== false && strpos($url, 'edd_action=package_download')) { 351 $args['sslverify'] = $verify_ssl; 352 } 353 return $args; 354 } 355 356 /** 357 * Calls the API and, if successful, returns the object delivered by the API. 358 * 359 * @uses get_bloginfo() 360 * @uses wp_remote_post() 361 * @uses is_wp_error() 362 * 363 * @param string $_action The requested action. 364 * @param array $_data Parameters for the API action. 365 * @return false|object 366 */ 367 private function api_request($_action, $_data) 368 { 369 370 global $wp_version; 371 372 $data = array_merge($this->api_data, $_data); 373 374 if ($data['slug'] != $this->slug) { 375 return; 376 } 377 378 if ($this->api_url == trailingslashit(home_url())) { 379 return false; // Don't allow a plugin to ping itself 380 } 381 382 $request = wp_remote_post($this->api_url, [ 383 'body' => [ 384 'edd_action' => 'get_version', 385 'license' => ! empty($data['license']) ? $data['license'] : '', 386 'item_name' => isset($data['item_name']) ? $data['item_name'] : false, 387 'item_id' => isset($data['item_id']) ? $data['item_id'] : false, 388 'version' => isset($data['version']) ? $data['version'] : false, 389 'slug' => $data['slug'], 390 'author' => $data['author'], 391 'url' => home_url(), 392 'beta' => ! empty($data['beta']), 393 'no_cache' => md5(microtime(true)), 394 ], 395 'timeout' => 15, 396 'sslverify' => $this->verify_ssl(), 397 ]); 398 399 if (! is_wp_error($request)) { 400 $request = json_decode(wp_remote_retrieve_body($request)); 401 } 402 403 if ($request && isset($request->sections)) { 404 $request->sections = maybe_unserialize($request->sections); 405 } else { 406 $request = false; 407 } 408 409 if ($request && isset($request->banners)) { 410 $request->banners = maybe_unserialize($request->banners); 411 } 412 413 if (! empty($request->sections)) { 414 foreach ($request->sections as $key => $section) { 415 $request->$key = (array) $section; 416 } 417 } 418 419 return $request; 420 } 421 422 public function show_changelog() 423 { 424 425 global $edd_plugin_data; 426 427 if (empty($_REQUEST['edd_sl_action']) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action']) { 428 return; 429 } 430 431 if (empty($_REQUEST['plugin'])) { 432 return; 433 } 434 435 if (empty($_REQUEST['slug'])) { 436 return; 437 } 438 439 if (! current_user_can('update_plugins')) { 440 wp_die(__('You do not have permission to install plugin updates', 'church-theme-content'), __('Error', 'church-theme-content'), array('response' => 403)); 441 } 442 443 $data = $edd_plugin_data[$_REQUEST['slug']]; 444 $beta = ! empty($data['beta']) ? true : false; 445 $cache_key = md5('edd_plugin_' . sanitize_key($_REQUEST['plugin']) . '_' . $beta . '_version_info'); 446 $version_info = $this->get_cached_version_info($cache_key); 447 448 if (false === $version_info) { 449 450 $request = wp_remote_post($this->api_url, [ 451 'body' => [ 452 'edd_action' => 'get_version', 453 'item_name' => isset($data['item_name']) ? $data['item_name'] : false, 454 'item_id' => isset($data['item_id']) ? $data['item_id'] : false, 455 'slug' => $_REQUEST['slug'], 456 'author' => $data['author'], 457 'url' => home_url(), 458 'beta' => ! empty($data['beta']), 459 'no_cache' => md5(microtime(true)), 460 ], 461 'timeout' => 15, 462 'sslverify' => $this->verify_ssl(), 463 ]); 464 465 if (! is_wp_error($request)) { 466 $version_info = json_decode(wp_remote_retrieve_body($request)); 467 } 468 469 470 if (! empty($version_info) && isset($version_info->sections)) { 471 $version_info->sections = maybe_unserialize($version_info->sections); 472 } else { 473 $version_info = false; 474 } 475 476 if (! empty($version_info)) { 477 foreach ($version_info->sections as $key => $section) { 478 $version_info->$key = (array) $section; 479 } 480 } 481 482 $this->set_version_info_cache($version_info, $cache_key); 483 } 484 485 if (! empty($version_info) && isset($version_info->sections['changelog'])) { 486 echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>'; 487 } 488 489 exit; 490 } 491 492 public function get_cached_version_info($cache_key = '') 493 { 494 495 if (empty($cache_key)) { 496 $cache_key = $this->cache_key; 497 } 498 499 $cache = get_option($cache_key); 500 501 if (empty($cache['timeout']) || current_time('timestamp') > $cache['timeout']) { 502 return false; // Cache is expired 503 } 504 505 return json_decode($cache['value']); 506 } 507 508 public function set_version_info_cache($value = '', $cache_key = '') 509 { 510 511 if (empty($cache_key)) { 512 $cache_key = $this->cache_key; 513 } 514 515 $data = array( 516 'timeout' => strtotime('+3 hours', current_time('timestamp')), 517 'value' => json_encode($value) 518 ); 519 520 update_option($cache_key, $data, 'no'); 521 } 522 523 /** 524 * Returns if the SSL of the store should be verified. 525 * 526 * @since 1.6.13 527 * @return bool 528 */ 529 private function verify_ssl() 530 { 531 return (bool) apply_filters('edd_sl_api_request_verify_ssl', true, $this); // could be made false for local self-signed SSL 532 } 532 533 } -
church-theme-content/trunk/readme.txt
r3208663 r3391879 3 3 Tags: church, churches, sermon, sermons, ministry, ministries, event, events, calendar, location, locations 4 4 Requires at least: 3.6 5 Tested up to: 6. 75 Tested up to: 6.8.3 6 6 Requires PHP: 7.4 7 Stable tag: 2. 6.27 Stable tag: 2.7 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html
Note: See TracChangeset
for help on using the changeset viewer.