Changeset 2967476
- Timestamp:
- 09/15/2023 11:37:18 AM (2 years ago)
- Location:
- code-injection/trunk
- Files:
-
- 2 added
- 14 edited
-
assets/js/block.js (added)
-
code-injection.php (modified) (3 diffs)
-
includes/class-asset-manager.php (modified) (6 diffs)
-
includes/class-barchart.php (modified) (7 diffs)
-
includes/class-block.php (added)
-
includes/class-code-type.php (modified) (11 diffs)
-
includes/class-core.php (modified) (6 diffs)
-
includes/class-database.php (modified) (7 diffs)
-
includes/class-heatmap.php (modified) (7 diffs)
-
includes/class-helpers.php (modified) (6 diffs)
-
includes/class-metabox.php (modified) (2 diffs)
-
includes/class-options.php (modified) (12 diffs)
-
includes/class-roles.php (modified) (2 diffs)
-
includes/class-shortcodes.php (modified) (1 diff)
-
includes/class-widget.php (modified) (5 diffs)
-
readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
code-injection/trunk/code-injection.php
r2943916 r2967476 5 5 * Plugin URI: https://github.com/Rmanaf/wp-code-injection 6 6 * Description: This plugin allows you to effortlessly create custom ads for your website. Inject code snippets in HTML, CSS, and JavaScript, write and run custom plugins on-the-fly, and take your website's capabilities to the next level. 7 * Version: 2.4.1 37 * Version: 2.4.14 8 8 * Author: Rmanaf 9 9 * Author URI: https://profiles.wordpress.org/rmanaf/ … … 23 23 define('__CI_URL__', plugin_dir_url(__FILE__)); 24 24 define('__CI_PATH__', plugin_dir_path(__FILE__)); 25 define('__CI_VERSION__', '2.4.1 3');25 define('__CI_VERSION__', '2.4.14'); 26 26 27 27 // Require the necessary files for the plugin … … 38 38 require_once __DIR__ . '/includes/class-widget.php'; 39 39 require_once __DIR__ . '/includes/class-code-type.php'; 40 require_once __DIR__ . '/includes/class-block.php'; 40 41 require_once __DIR__ . '/includes/class-core.php'; 41 42 -
code-injection/trunk/includes/class-asset-manager.php
r2939201 r2967476 8 8 namespace ci; 9 9 10 /** 11 * The AssetManager class handles the enqueuing of styles and scripts required for the Code Injection plugin's functionality. 12 * It registers and enqueues various styles and scripts for both the admin panel and specific plugin features. The class is 13 * responsible for loading code editor styles, Monaco editor scripts, tag editor styles and scripts, essential plugin scripts, 14 * and custom styles for the plugin settings page. It also localizes script data to provide necessary variables to JavaScript 15 * functions. The class aids in maintaining the presentation and interactivity of the plugin's user interface. 16 * 17 * @since 2.4.2 18 */ 10 19 class AssetManager 11 20 { 12 21 13 22 23 private static $CI_LOCALIZE_OBJ = '_ci'; 24 25 14 26 /** 27 * Initialize the Asset Manager 28 * 29 * Registers and enqueues necessary styles and scripts for the Code Injection plugin's functionality. 30 * 15 31 * @since 2.4.2 16 32 */ 17 33 static function init() 18 34 { 19 add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_scripts'), 50); 35 add_action('admin_enqueue_scripts', array(__CLASS__, '_enqueue_scripts'), 50); 36 add_action('enqueue_block_editor_assets', array(__CLASS__, '_enqueue_block_editor_assets')); 20 37 } 21 38 … … 23 40 24 41 /** 42 * Enqueue Scripts and Styles 43 * 44 * Handles the enqueuing of scripts and styles for the Code Injection plugin's functionality. This includes loading 45 * code editor styles, scripts, Monaco editor, tag editor styles and scripts, and plugin-specific styles and scripts 46 * based on whether the plugin's settings page is being accessed or not. 47 * 48 * @access private 25 49 * @since 2.2.8 26 50 */ 27 static function enqueue_scripts()51 static function _enqueue_scripts() 28 52 { 29 53 54 // Array of localized texts for internationalization 30 55 $texts = array( 31 56 "The File is too large. Do you want to proceed?", … … 35 60 ); 36 61 62 // Internationalization for JavaScript 37 63 $i18n = array( 38 64 'code-injection' => array( … … 44 70 ); 45 71 72 73 // Register custom styles and scripts 46 74 wp_register_style('ci-custom-code-editor', Helpers::get_asset_url('/css/code-editor.css'), array(), __CI_VERSION__, 'all'); 47 48 75 wp_register_script('ci-monaco-editor-loader', 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.21.2/min/vs/loader.min.js', array('jquery'), null, true); 49 76 wp_register_script('ci-editor', Helpers::get_asset_url('/js/code-editor.js'), array(), __CI_VERSION__, false); 50 77 78 79 // Enqueue essential scripts 51 80 wp_enqueue_script('ci-essentials', Helpers::get_asset_url('/js/essentials.js'), array('jquery'), __CI_VERSION__, true); 52 81 53 wp_localize_script('ci-essentials', "_ci", array( 82 83 // Localize essential scripts with relevant data 84 wp_localize_script('ci-essentials', self::$CI_LOCALIZE_OBJ , apply_filters('ci_localize_obj' , array( 54 85 'ajax_url' => admin_url('admin-ajax.php'), 55 86 "ajax_nonce" => wp_create_nonce("code-injection-ajax-nonce"), 56 87 "is_rtl" => is_rtl() ? "true" : "false", 57 88 "i18n" => $i18n 58 )) ;89 ))); 59 90 91 92 // Enqueue plugin-specific styles 60 93 wp_enqueue_style('ci-styles', Helpers::get_asset_url('/css/wp-code-injection-admin.css'), array(), __CI_VERSION__, 'all'); 61 94 95 96 // Enqueue additional styles and scripts for settings page 62 97 if (Helpers::is_settings_page()) { 63 64 // tag-editor styles65 98 wp_enqueue_style('ci-tag-editor', Helpers::get_asset_url('/css/jquery.tag-editor.css'), array(), __CI_VERSION__, 'all'); 66 67 // tag-editor scripts68 99 wp_enqueue_script('ci-caret', Helpers::get_asset_url('/js/jquery.caret.min.js'), array('jquery'), __CI_VERSION__, false); 69 100 wp_enqueue_script('ci-tag-editor', Helpers::get_asset_url('/js/jquery.tag-editor.min.js'), array('jquery', 'ci-caret'), __CI_VERSION__, false); 70 71 // admin settings scripts72 101 wp_enqueue_script('ci-code-injection', Helpers::get_asset_url('/js/wp-ci-general-settings.js'), array('jquery'), __CI_VERSION__, true); 73 102 } … … 75 104 76 105 106 77 107 /** 108 * @access private 109 * @since 2.4.14 110 */ 111 static function _enqueue_block_editor_assets() { 112 113 $deps = array('wp-blocks', 'wp-element', 'wp-data', 'wp-components'); 114 $src = Helpers::get_asset_url('/js/block.js'); 115 116 wp_enqueue_script('ci-inject-block' , $src , $deps , __CI_VERSION__ , true); 117 118 } 119 120 121 122 123 124 /** 125 * Enqueue Editor Scripts and Styles 126 * 127 * Enqueues styles and scripts specifically for the code editor component. 128 * 78 129 * @since 2.4.2 79 130 */ … … 85 136 wp_enqueue_script('ci-editor'); 86 137 } 138 139 140 141 87 142 } -
code-injection/trunk/includes/class-barchart.php
r2943916 r2967476 8 8 namespace ci; 9 9 10 11 /** 12 * Barchart Class 13 * 14 * This class generates a simple bar chart SVG representation based on provided data and dimensions. 15 * 16 * @since 2.4.5 17 */ 10 18 class Barchart 11 19 { 12 20 13 14 private $data = []; 15 21 private $data = array(); 16 22 private $width = 0; 17 18 23 private $height = 0; 19 20 24 private $gap = 1; 21 25 26 27 /** 28 * Constructor 29 * 30 * @param array $data Data for the chart. 31 * @param int $w Width of the chart. 32 * @param int $h Height of the chart. 33 * @param int $g Gap between bars. 34 */ 22 35 function __construct($data, $w, $h, $g = 1) 23 36 { … … 30 43 31 44 /** 45 * Render the Barchart 46 * 47 * Generates and outputs an SVG representation of the barchart. 48 * 32 49 * @since 2.4.5 33 50 */ … … 35 52 { 36 53 54 // Find the maximum value in the data to calculate the yScale 37 55 $max = 0; 38 39 $index = 0; 40 41 if (count($this->data) > 0) { 56 if (!empty($this->data)) { 42 57 $max = max(array_map(function ($item) { 43 58 return intval($item["value"]); … … 45 60 } 46 61 47 $yScale = $max / $this->height;48 62 49 $length = count($this->data); 63 // Calculate the yScale to determine the scaling of the bars 64 $yScale = ($this->height > 0) ? $max / $this->height : 0; 50 65 51 $barWidth = ($this->width / $length) - $this->gap; 66 // Calculate the width of each bar 67 $barWidth = ($this->width / count($this->data)) - $this->gap; 52 68 69 // Calculate the total height of the SVG including margins 53 70 $svgHeight = $this->height + 25; 54 71 55 72 73 // Start generating the SVG 56 74 echo "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" " . 57 75 "xmlns:xlink=\"http://www.w3.org/1999/xlink\" " . … … 60 78 61 79 80 // Generate horizontal grid lines 62 81 foreach ([0, $this->height / 2, $this->height] as $y) { 63 82 echo "<g>" . … … 67 86 68 87 69 foreach ($this->data as $d) { 88 // Generate bars for each data point 89 foreach ($this->data as $index => $d) { 70 90 71 $num = intval(isset($d['value']) ? $d['value'] : 0); 72 $tooltip = isset($d['index']) ? $d['index'] : ''; 91 // Extract the value and tooltip from the data 92 $num = intval(isset($d['value']) ? $d['value'] : 0); 93 $tooltip = isset($d['index']) ? $d['index'] : ''; 73 94 74 if ($yScale > 0) { 75 $height = $num / $yScale; 76 } else { 77 $height = $num; 78 } 95 // Calculate the height of the bar based on the yScale 96 $height = ($yScale > 0) ? $num / $yScale : $num; 79 97 98 // Calculate the x and y coordinates for the bar and related elements 80 99 $x = ($index * ($barWidth + $this->gap)); 81 82 100 $y = $this->height - $height; 83 84 101 $lineX = ($barWidth / 2) + $x; 85 86 102 $tooltipY = $this->height + 12; 87 88 103 $tooltipX = min([max([$lineX, 9]), $this->width - 9]); 89 104 90 105 // Generate tooltip markup if a tooltip is available 106 $tooltipMarkup = ''; 91 107 if (!empty($tooltip)) { 92 93 $tooltip = "<g class=\"tooltip\" style=\"transform:translate({$tooltipX}px,{$tooltipY}px);\">" . 108 $tooltipMarkup = "<g class=\"tooltip\" style=\"transform:translate({$tooltipX}px,{$tooltipY}px);\">" . 94 109 "<circle class=\"bg\" r=\"9\" fill=\"#333\" />" . 95 110 "<text dy=\".35em\" x=\"0\" y=\"0\" text-anchor=\"middle\" class=\"count\" fill=\"#fff\">$tooltip</text>" . … … 97 112 } 98 113 114 // Output SVG elements for the bar and related components 99 115 echo "<g class=\"bar\">" . 100 116 "<line class=\"grid\" x1=\"$lineX\" y1=\"0\" x2=\"$lineX\" y2=\"$this->height\" stroke-width=\"4\" />" . 101 117 "<rect y=\"$y\" x=\"$x\" width=\"$barWidth\" height=\"$height\" />" . 102 $tooltip .118 $tooltipMarkup . 103 119 "</g>"; 104 105 $index++;106 120 } 107 121 122 // Close the SVG element 108 123 echo "</svg>"; 109 124 } -
code-injection/trunk/includes/class-code-type.php
r2939201 r2967476 127 127 $length = intval(date('t', mktime(0, 0, 0, $month, 1, $year))); 128 128 129 $bcDataHolder = array_fill(0, $length, [129 $bcDataHolder = array_fill(0, $length, array( 130 130 "value" => 0 131 ]);131 )); 132 132 133 133 $bcDataHolder = array_map(function ($item) { 134 134 $index = $item + 1; 135 return [135 return array( 136 136 "value" => 0, 137 137 "index" => $index < 10 ? "0$index" : $index 138 ];138 ); 139 139 }, array_keys($bcDataHolder)); 140 140 … … 150 150 151 151 foreach ($bcData as $d) { 152 $bcDataHolder[intval($d['day']) - 1] = [152 $bcDataHolder[intval($d['day']) - 1] = array( 153 153 "value" => $d["total_hits"], 154 154 "index" => $d["day"] < 10 ? "0{$d["day"]}" : $d["day"] 155 ];155 ); 156 156 } 157 157 … … 179 179 return; 180 180 181 $taxonomies = ['code_category'];181 $taxonomies = array('code_category'); 182 182 183 183 foreach ($taxonomies as $taxonomy_slug) { … … 239 239 $status = get_post_status($post); 240 240 241 $needles = [$post->post_title, '”', '“'];241 $needles = array($post->post_title, '”', '“'); 242 242 243 243 if (isset($actions['edit'])) { … … 346 346 { 347 347 348 $code_lables = [348 $code_lables = array( 349 349 'name' => esc_html__('Codes', "code-injection"), 350 350 'singular_name' => esc_html__('Code', "code-injection"), … … 356 356 'not_found_in_trash ' => esc_html__('No codes found in Trash', "code-injection"), 357 357 'all_items' => esc_html__('All Codes', "code-injection") 358 ];358 ); 359 359 360 360 … … 362 362 'code_category', 363 363 'code', 364 [364 array( 365 365 'show_admin_column' => true, 366 366 'public' => false, … … 368 368 'rewrite' => false, 369 369 'hierarchical' => true 370 ]370 ) 371 371 ); 372 372 … … 374 374 register_post_type( 375 375 'Code', 376 [376 array( 377 377 'menu_icon' => 'dashicons-editor-code', 378 378 'labels' => $code_lables, … … 383 383 'exclude_from_search' => true, 384 384 'publicly_queryable' => false, 385 'supports' => ['author', 'revisions', 'title', 'editor'],385 'supports' => array('author', 'revisions', 'title', 'editor'), 386 386 'capability_type' => ['code', 'codes'], 387 387 'can_export' => true, 388 388 'map_meta_cap' => true 389 ]389 ) 390 390 ); 391 391 } … … 399 399 { 400 400 401 $columns = []; 402 403 $columns['id'] = esc_html__("Code", "code-injection"); 404 405 $columns['info'] = esc_html__("Info", "code-injection"); 406 407 $columns['statistics'] = esc_html__("Hits", "code-injection"); 408 409 return $columns; 401 return array( 402 'id' => esc_html__("Code", "code-injection"), 403 'info' => esc_html__("Info", "code-injection"), 404 'statistics' => esc_html__("Hits", "code-injection") 405 ); 406 410 407 } 411 408 -
code-injection/trunk/includes/class-core.php
r2939201 r2967476 8 8 namespace ci; 9 9 10 11 /** 12 * Core Class for Code Injection Plugin 13 * 14 * The Core class serves as the central orchestrator for the Code Injection plugin. It provides the backbone structure 15 * for the plugin's functionalities by organizing and managing its various components and actions. This class encapsulates 16 * the main operations of the plugin and initializes key features such as code type management, database setup, user roles, 17 * metabox handling, asset management, shortcodes, options, and more. It also hooks into appropriate WordPress actions and 18 * filters to ensure proper functioning throughout different stages of the WordPress lifecycle. 19 */ 10 20 class Core 11 21 { 12 22 13 23 /** 24 * Setup Plugin Components and Actions 25 * 26 * This method initializes various components and actions of the plugin by calling their respective init methods. 27 * It sets up the core functionalities of the plugin such as code type management, database setup, user roles, 28 * metabox handling, asset management, shortcodes, options, and more. Additionally, it hooks into various actions 29 * and filters, ensuring that the plugin functions as intended during different stages of WordPress execution. 30 * 14 31 * @since 2.4.12 15 32 */ 16 33 static function setup() 17 34 { 18 35 // Initialize code type management 19 36 CodeType::init(); 37 38 // Initialize database-related functionality 20 39 Database::init(); 40 41 // Initialize user roles and capabilities 21 42 Roles::init(); 43 44 // Initialize metabox handling for posts 22 45 Metabox::init(); 46 47 // Initialize asset management for styles and scripts 23 48 AssetManager::init(); 49 50 // Initialize custom shortcodes for the plugin 24 51 Shortcodes::init(); 52 53 // Initialize options management 25 54 Options::init(); 26 27 55 56 Block::init(); 57 58 // Hook to load plugins at the plugins_loaded action 28 59 add_action('plugins_loaded', array(__CLASS__, '_load_plugins')); 60 61 // Hook to check and handle raw content requests 29 62 add_action("template_redirect", array(__CLASS__, '_check_raw_content')); 30 add_action('widgets_init', array(__CLASS__, 'widgets_init')); 31 add_action('plugins_loaded', array(__CLASS__, 'load_plugin_textdomain')); 32 33 // check "Unsafe" settings 63 64 // Hook to register and initialize custom widgets 65 add_action('widgets_init', array(__CLASS__, '_widgets_init')); 66 67 // Hook to load the plugin's text domain for translations 68 add_action('plugins_loaded', array(__CLASS__, '_load_plugin_textdomain')); 69 70 // Check if "Unsafe" settings for shortcodes in widgets are enabled 34 71 if (get_option('ci_unsafe_widgets_shortcodes', 0)) { 72 // Apply filters to allow shortcodes in widgets 35 73 add_filter('widget_text', 'shortcode_unautop'); 36 74 add_filter('widget_text', 'do_shortcode'); 37 75 } 38 76 39 register_activation_hook(__CI_FILE__, array(__CLASS__, 'activate')); 40 register_deactivation_hook(__CI_FILE__, array(__CLASS__, 'deactivate')); 41 } 42 43 44 45 /** 46 * @since 2.4.12 47 */ 48 static function load_plugin_textdomain() 49 { 77 // Register activation and deactivation hooks for the plugin 78 register_activation_hook(__CI_FILE__, array(__CLASS__, '_plugin_activate')); 79 register_deactivation_hook(__CI_FILE__, array(__CLASS__, '_plugin_deactivate')); 80 } 81 82 83 /** 84 * Load Plugin Text Domain for Localization 85 * 86 * This method is responsible for loading the plugin's text domain for localization purposes. 87 * It allows translations to be loaded from the "languages" directory within the plugin. 88 * 89 * @access private 90 * @since 2.4.12 91 */ 92 static function _load_plugin_textdomain() 93 { 94 // Load the text domain for translation 50 95 load_plugin_textdomain("code-injection", FALSE, basename(dirname(__CI_FILE__)) . '/languages/'); 51 96 } … … 53 98 54 99 /** 100 * Load and Execute Unsafe Plugins 101 * 102 * This private method loads and executes potentially unsafe plugins when the appropriate settings are enabled. 103 * It retrieves plugin codes from the database, filters and processes them based on certain conditions, then 104 * executes them using `eval()`. The execution is controlled by options and conditions defined in the database. 105 * 106 * @access private 55 107 * @since 2.2.9 56 * @access private57 108 */ 58 109 static function _load_plugins() … … 61 112 global $wpdb; 62 113 114 // Check if PHP-based unsafe widgets are allowed 63 115 $use_php = get_option('ci_unsafe_widgets_php', false); 64 116 65 117 if (!$use_php) { 66 return; 67 } 68 118 return; // If not allowed, exit early 119 } 120 121 // Check if ignoring keys for unsafe widgets 69 122 $ignore_keys = get_option('ci_unsafe_ignore_keys', false); 70 123 124 // Get keys that trigger activation 71 125 $keys = get_option('ci_unsafe_keys', ''); 72 126 127 // Retrieve all plugin codes from the database 73 128 $codes = Database::get_codes(); 74 129 130 // Filter and process plugins based on conditions 75 131 $plugins = array_filter($codes, function ($element) use ($ignore_keys, $keys) { 76 132 … … 79 135 extract($options); 80 136 137 // Check if the code is intended to be a plugin 81 138 $is_plugin = isset($code_is_plugin) && $code_is_plugin == '1'; 82 139 140 // Check if the code should be publicly queryable 83 141 $is_public = isset($code_is_publicly_queryable) && $code_is_publicly_queryable == '1'; 84 142 85 143 // If code_enabled is not set, default to false 86 144 if (!isset($code_enabled)) { 87 145 $code_enabled = false; 88 146 } 89 147 90 148 // Check the code's status 91 149 if (!CodeType::check_code_status($element)) { 92 return false; 93 } 94 95 150 return false; // Skip codes with invalid status 151 } 152 153 // Skip codes that are publicly queryable 96 154 if ($is_public) { 97 155 return false; 98 156 } 99 157 100 158 // Skip non-plugin codes or disabled plugins 101 159 if (!$is_plugin || $code_enabled == false) { 102 160 return false; 103 161 } 104 162 163 // If ignoring keys, include all plugins 105 164 if ($ignore_keys) { 106 165 return true; 107 166 } 108 167 168 // Check if activator key is in the specified keys 109 169 return isset($code_activator_key) && in_array($code_activator_key, $instance->extract_keys($keys)); 110 170 }); 111 171 172 173 // Execute and enable filtered plugins 112 174 foreach ($plugins as $p) { 113 175 176 // Get code options and disable the plugin initially 114 177 $code_options = Metabox::get_code_options($p->ID); 115 116 178 $code_options['code_enabled'] = false; 117 179 180 // Update code options to disable the plugin 118 181 update_post_meta($p->ID, "code_options", $code_options); 119 182 183 // Execute the plugin code using eval() 120 184 eval("?" . ">" . $p->post_content); 121 185 186 // Enable the plugin in code options 122 187 $code_options['code_enabled'] = true; 123 124 188 update_post_meta($p->ID, "code_options", $code_options); 125 189 } 126 } 127 128 129 /** 130 * @since 2.4.12 131 * @access private 190 191 } 192 193 194 /** 195 * Checks and processes raw content for code injection. 196 * 197 * This method checks if the request is targeting the home page or front page and if the "raw" parameter is set. 198 * It processes and serves raw code content with appropriate headers and caching directives. 199 * 200 * @access private 201 * @since 2.4.12 132 202 */ 133 203 static function _check_raw_content() 134 204 { 135 205 136 global $wpdb; 137 206 // Check if the request is on the home page or front page 138 207 if (!is_home() && !is_front_page()) { 139 208 return; 140 209 } 141 210 211 // Check if "raw" parameter is set in the request 142 212 if (!isset($_GET["raw"])) { 143 213 return; 144 214 } 145 215 146 $id = $_GET["raw"]; 147 148 $query = "SELECT $wpdb->posts.*, $wpdb->postmeta.* 149 FROM $wpdb->posts, $wpdb->postmeta 150 WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 151 AND $wpdb->postmeta.meta_key = 'code_options' 152 AND $wpdb->posts.post_type = 'code' 153 AND $wpdb->posts.post_title = '$id'"; 154 155 156 $results = $wpdb->get_results($query, OBJECT); 157 158 159 if (empty($results)) { 160 161 // Code not found 216 // Get the code ID from the "raw" parameter 217 $codeId = sanitize_text_field($_GET["raw"]); 218 219 // Retrieve code information based on the ID 220 $code = Database::get_code_by_title($codeId); 221 222 // Check if code exists 223 if (!$code) { 224 // Record activity for code not found 162 225 Database::record_activity(0, null, 2); 163 164 return; 165 } 166 167 168 $code = $results[0]; 169 170 226 return; 227 } 228 229 230 // Check if code type is authorized 171 231 if (!CodeType::check_code_status($code)) { 172 173 // Unauthorized Request 174 Database::record_activity(0, $id, 6, $code->ID); 175 176 return; 177 } 178 179 232 // Record activity for unauthorized request 233 Database::record_activity(0, $codeId, 6, $code->ID); 234 return; 235 } 236 237 238 // Extract options from code metadata 180 239 $options = maybe_unserialize($code->meta_value); 181 182 240 extract($options); 183 241 184 $active = isset($code_enabled) && $code_enabled == '1'; 185 186 $is_plugin = isset($code_is_plugin) && $code_is_plugin == '1'; 187 188 $is_public = isset($code_is_publicly_queryable) && $code_is_publicly_queryable == '1'; 189 190 $no_cache = isset($code_no_cache) && $code_no_cache == '1'; 191 192 if (!$active || $is_plugin || !$is_public) { 193 return; 194 } 195 196 $render_shortcodes = get_option('ci_code_injection_allow_shortcode', false); 197 198 Database::record_activity(0, $id, 0, $code->ID); 199 200 242 // Determine code status based on options 243 $isActive = isset($code_enabled) && $code_enabled == '1'; 244 $isPlugin = isset($code_is_plugin) && $code_is_plugin == '1'; 245 $isPublic = isset($code_is_publicly_queryable) && $code_is_publicly_queryable == '1'; 246 $noCache = isset($code_no_cache) && $code_no_cache == '1'; 247 248 // Check if code should be processed further 249 if (!$isActive || $isPlugin || !$isPublic) { 250 return; 251 } 252 253 // Check if shortcodes should be rendered 254 $renderShortcodes = get_option('ci_code_injection_allow_shortcode', false); 255 256 // Record activity for successful code request 257 Database::record_activity(0, $codeId, 0, $code->ID); 258 259 // Set appropriate content-type header 201 260 header("Content-Type: $code_content_type; charset=UTF-8", true); 202 261 203 262 204 if ($no_cache) {205 263 // Set caching headers based on options 264 if ($noCache) { 206 265 header("Pragma: no-cache", true); 207 208 266 header("Cache-Control: no-cache, must-revalidate, max-age=0", true); 209 210 267 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT", true); 211 268 } else { 212 213 $cache_max_age = get_option('ci_code_injection_cache_max_age', '84600'); 214 269 $cacheMaxAge = get_option('ci_code_injection_cache_max_age', '84600'); 215 270 header("Pragma: public", true); 216 217 header("Cache-Control: max-age=$cache_max_age, public, no-transform", true); 218 219 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $cache_max_age) . ' GMT', true); 220 } 221 222 223 if ($render_shortcodes) { 224 271 header("Cache-Control: max-age=$cacheMaxAge, public, no-transform", true); 272 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $cacheMaxAge) . ' GMT', true); 273 } 274 275 276 // Output processed code content and exit 277 if ($renderShortcodes) { 225 278 exit(do_shortcode($code->post_content)); 226 279 } else { 227 228 280 exit($code->post_content); 229 281 } 230 } 231 232 233 /** 234 * @since 2.4.12 235 */ 236 static function widgets_init() 237 { 282 283 } 284 285 286 /** 287 * Initialize and register custom widgets. 288 * 289 * This private method is responsible for registering custom widgets during WordPress widget initialization. 290 * 291 * @access private 292 * @since 2.4.12 293 */ 294 static function _widgets_init() 295 { 296 // Register the custom widget defined in the Widget class 238 297 register_widget(Widget::class); 239 298 } … … 241 300 242 301 /** 243 * @since 2.4.12 244 */ 245 static function activate() 246 { 302 * Activate Plugin Functionality and Flush Rewrite Rules 303 * 304 * This private method is called when the plugin is activated. It performs necessary actions to ensure 305 * that the plugin's functionality is activated and that rewrite rules are updated to handle new URLs. 306 * 307 * @access private 308 * @since 2.4.12 309 */ 310 static function _plugin_activate() 311 { 312 // Flush rewrite rules to update URL handling after activation 247 313 flush_rewrite_rules(); 248 314 } … … 250 316 251 317 /** 252 * @since 2.4.12 253 */ 254 static function deactivate() 255 { 318 * Deactivate plugin functionality. 319 * 320 * This private method is responsible for deactivating the plugin's functionality when the plugin is deactivated. 321 * It performs various cleanup actions, including flushing rewrite rules, deleting plugin-related options, 322 * and removing a custom role. 323 * 324 * @access private 325 * @since 2.4.12 326 */ 327 static function _plugin_deactivate() 328 { 329 // Flush rewrite rules to update URL handling after deactivation 256 330 flush_rewrite_rules(); 257 331 332 // Delete plugin-related options from the database 258 333 delete_option('ci_code_injection_db_version'); 259 334 delete_option('ci_code_injection_role_version'); 260 335 336 // Remove the custom "developer" role 261 337 remove_role('developer'); 262 338 } 339 263 340 } -
code-injection/trunk/includes/class-database.php
r2939201 r2967476 8 8 namespace ci; 9 9 10 use DateInterval; 11 use DateTime; 12 10 11 use DateInterval, DateTime; 12 13 14 /** 15 * The Database class handles interactions with the database for tracking and reporting activities. 16 * 17 * This class is responsible for managing database interactions related to tracking and reporting 18 * activities within the context of the code snippet tracking system. It encapsulates various 19 * functions that generate SQL queries for retrieving activity reports and recording activity events. 20 * The class utilizes DateInterval and DateTime objects for handling time calculations and formatting. 21 * 22 * @namespace ci 23 * @since 2.2.6 24 */ 13 25 class Database 14 26 { 15 27 28 /** 29 * The name of the database table used for storing activity records. 30 * 31 * This constant property stores the name of the database table where activity records 32 * are stored for tracking purposes. The table is used to record various details about 33 * activity events, such as timestamps, IP addresses, post IDs, and error statuses. 34 * 35 * @since 2.2.6 36 */ 16 37 const table_activities_name = 'ci_activities'; 38 39 40 /** 41 * The option name for storing the database version. 42 * 43 * This constant property represents the option name used to store the version of the 44 * database schema. It is utilized to keep track of the database schema version and 45 * facilitate updates when needed. 46 * 47 * @since 2.2.6 48 */ 17 49 const db_version_option = 'ci_db_version'; 50 51 52 /** 53 * An array of error messages for different error codes. 54 * 55 * This constant property holds an array of error messages associated with specific 56 * error codes. The array provides human-readable explanations for different types 57 * of errors that can occur during activity tracking and reporting. 58 * 59 * @since 2.2.6 60 */ 18 61 const db_errors = array( 19 '', // 0 no error20 'PHP scripts are disabled', // 121 'Code not found', // 222 'Infinite Loop', // 323 'An unexpected error occurred', // 424 'Key not found', // 525 'Unauthorized Request', // 662 '', // 0: No error 63 'PHP scripts are disabled', // 1 64 'Code not found', // 2 65 'Infinite Loop', // 3 66 'An unexpected error occurred', // 4 67 'Key not found', // 5 68 'Unauthorized Request', // 6 26 69 ); 27 70 28 71 29 private static $db_shortcodes_types = ['HTML', 'PHP']; 30 31 32 /** 72 private static $db_shortcodes_types = array('HTML', 'PHP'); 73 74 75 /** 76 * Initializes the plugin by performing necessary setup actions. 77 * 78 * This static function serves as the initialization point for the plugin. It is called 79 * upon plugin activation or when required during the plugin's lifecycle. The primary 80 * purpose of this function is to ensure the proper setup of the plugin's components. 81 * It accomplishes this by invoking the 'check_db' method, which verifies and updates 82 * the plugin's database schema as needed to maintain compatibility. 83 * 33 84 * @since 2.4.12 34 85 */ 35 86 static function init() 36 87 { 88 // Perform the necessary setup actions, including checking and updating the database 37 89 self::check_db(); 38 90 } … … 40 92 41 93 42 /** 94 95 /** 96 * Checks and updates the custom database table used by the plugin. 97 * 98 * This private function is responsible for verifying and updating the database 99 * schema to ensure compatibility with the plugin's version. It compares the stored 100 * database version with the current version of the plugin. If the versions match, 101 * no action is taken. If they differ, the function creates or updates a custom 102 * database table with necessary columns. This table is used to store activity log 103 * entries associated with various events triggered by the plugin. 104 * 43 105 * @since 2.2.6 44 106 */ 45 107 private static function check_db() 46 108 { 47 48 global $wpdb; 49 50 $dbv = get_option(self::db_version_option, ''); 51 52 if ($dbv == __CI_VERSION__) { 53 return; 109 global $wpdb; 110 111 // Retrieve the stored database version from options 112 $stored_db_version = get_option(self::db_version_option, ''); 113 114 // Compare database version with the current plugin version 115 if ($stored_db_version === __CI_VERSION__) { 116 return; // No action needed if versions match 54 117 } 55 118 119 // Define the custom table name for storing activity log entries 56 120 $table_name = self::table_activities_name; 57 121 122 // Get charset collation for creating the table 58 123 $charset_collate = $wpdb->get_charset_collate(); 59 124 60 $sql = "CREATE TABLE $table_name ( 125 // SQL query for creating the custom table with required columns 126 $sql = " 127 CREATE TABLE $table_name ( 61 128 id mediumint(9) NOT NULL AUTO_INCREMENT, 62 129 blog smallint, … … 69 136 error smallint, 70 137 PRIMARY KEY (id) 71 ) $charset_collate;"; 72 138 ) $charset_collate; 139 "; 140 141 // Include necessary WordPress upgrade functions 73 142 require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); 74 143 144 // Execute the SQL query and update the table schema 75 145 dbDelta($sql); 76 146 77 update_option(self::db_version_option , __CI_VERSION__); 78 } 79 80 81 82 /** 147 // Update the stored database version option with the current version 148 update_option(self::db_version_option, __CI_VERSION__); 149 } 150 151 152 153 154 155 /** 156 * Retrieves an array of code snippets with associated metadata. 157 * 158 * This static function queries the WordPress database to retrieve an array of code 159 * snippet posts along with their associated metadata. It retrieves posts that have 160 * the 'code' post type, have a meta key 'code_options', and have a post date earlier 161 * than the current date and time. The retrieved results are ordered in descending order 162 * based on the post date. 163 * 83 164 * @since 2.4.8 165 * 166 * @return array An array of objects containing code snippet post data and metadata. 84 167 */ 85 168 static function get_codes() … … 88 171 global $wpdb; 89 172 173 // Define the table names and placeholders 174 $posts_table = $wpdb->posts; 175 $postmeta_table = $wpdb->postmeta; 176 $code_options_meta_key = 'code_options'; 177 $code_post_type = 'code'; 178 179 // Construct the SQL query to retrieve code snippets 180 $query = $wpdb->prepare( 181 "SELECT $posts_table.*, $postmeta_table.* 182 FROM $posts_table, $postmeta_table 183 WHERE $posts_table.ID = $postmeta_table.post_id 184 AND $postmeta_table.meta_key = %s 185 AND $posts_table.post_type = %s 186 AND $posts_table.post_date < NOW() 187 ORDER BY $posts_table.post_date DESC", 188 $code_options_meta_key, 189 $code_post_type 190 ); 191 192 // Execute the query and fetch results as an array of objects 193 return $wpdb->get_results($query); 194 } 195 196 197 198 199 /** 200 * Retrieves a code snippet by its title. 201 * 202 * This function queries the WordPress database to retrieve a code snippet 203 * post based on the provided title. It fetches both post and postmeta 204 * information associated with the given title. 205 * 206 * @since 2.4.14 207 * 208 * @param string $title The title of the code snippet to retrieve. 209 * @return object|null An object containing the code snippet's post and postmeta data as properties, 210 * or null if no matching snippet is found. 211 */ 212 static function get_code_by_title($title) 213 { 214 global $wpdb; 215 216 // Construct the SQL query to retrieve the code snippet by title 90 217 $query = "SELECT $wpdb->posts.*, $wpdb->postmeta.* 91 218 FROM $wpdb->posts, $wpdb->postmeta 92 219 WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 93 AND $wpdb->post meta.meta_key = 'code_options'220 AND $wpdb->posts.post_title = '$title' 94 221 AND $wpdb->posts.post_type = 'code' 95 AND $wpdb->posts.post_date < NOW() 96 ORDER BY $wpdb->posts.post_date DESC"; 97 98 return $wpdb->get_results($query, OBJECT); 99 } 100 101 /** 222 LIMIT 1"; 223 224 // Execute the query and fetch a single row as an object 225 $row = $wpdb->get_row($query); 226 227 // If no matching snippet is found, return null 228 if (!$row) { 229 return null; 230 } 231 232 return $row; 233 } 234 235 236 237 /** 238 * Retrieves a code snippet by its unique slug. 239 * 240 * This function queries the WordPress database to retrieve a code snippet 241 * post based on the provided unique slug. It fetches both post and postmeta 242 * information associated with the given slug. 243 * 102 244 * @since 2.4.8 245 * 246 * @param string $slug The unique slug of the code snippet to retrieve. 247 * @return object|null An object containing the code snippet's post and postmeta data as properties, 248 * or null if no matching snippet is found. 103 249 */ 104 250 static function get_code_by_slug($slug) 105 251 { 106 107 global $wpdb; 108 252 global $wpdb; 253 254 // Construct the SQL query to retrieve the code snippet by slug 109 255 $query = "SELECT $wpdb->posts.*, $wpdb->postmeta.* 110 256 FROM $wpdb->posts, $wpdb->postmeta … … 115 261 LIMIT 1"; 116 262 117 $posts = $wpdb->get_results($query, ARRAY_A); 118 119 if (empty($posts)) { 263 // Execute the query and fetch a single row as an object 264 $row = $wpdb->get_row($query); 265 266 // If no matching snippet is found, return null 267 if (!$row) { 120 268 return null; 121 269 } 122 270 123 return $posts[0]; 124 } 125 126 127 /** 271 return $row; 272 } 273 274 275 276 277 /** 278 * Records an activity event in the database for tracking purposes. 279 * 280 * This static function is responsible for recording activity events in the database 281 * for tracking purposes. It records various details such as the event type, associated 282 * code snippet, error status, and relevant identifiers like IP address, post ID, blog ID, 283 * and user ID. The function first checks whether the event should be tracked based on 284 * provided conditions. If tracking is enabled, the function inserts a new activity record 285 * into the database table, capturing key information about the event. 286 * 128 287 * @since 2.2.6 288 * 289 * @param int $type The type of activity event (0 for HTML, CSS, JavaScript, 1 for PHP, etc.). 290 * @param string|null $code The code snippet associated with the activity. 291 * @param int $error The error status (0 for no error, 1 for error). 292 * @param int|null $id The post ID or identifier associated with the event (used in specific cases). 129 293 */ 130 294 static function record_activity($type = 0, $code = null, $error = 0, $id = null) 131 295 { 132 133 296 global $wpdb, $post; 134 297 135 136 if ($code != null && $type == 0 && $id != null) { 137 298 // Check if tracking is required based on provided conditions 299 if ($code !== null && $type === 0 && $id !== null) { 138 300 $co = Metabox::get_code_options($id); 139 140 if ($co['code_tracking'] == false) { 141 return; 301 if (!$co['code_tracking']) { 302 return; // No tracking needed 142 303 } 143 304 } 144 305 145 $ip = Helpers::get_ip_address(); 306 // Capture essential information for the activity record 307 $ip = Helpers::get_ip_address(); 146 308 $table_name = self::table_activities_name; 147 $time = current_time('mysql', 1); 148 $start = new DateTime($time); 149 $blog = get_current_blog_id(); 150 $user = get_current_user_id(); 151 309 $time = current_time('mysql', 1); 310 $start = new DateTime($time); 311 $blog = get_current_blog_id(); 312 $user = get_current_user_id(); 152 313 $start->sub(new DateInterval("PT10S")); 153 154 $start_date = $start->format('Y-m-d H:i:s'); 155 $post_param = isset($post->ID) && is_single() ? $post->ID : null; 156 $post_query_param = is_null($post_param) ? "`post` IS NULL" : "`post` = '$post_param'"; 157 $ip_query_param = is_null($ip) ? "`ip` IS NULL" : "`ip` = '$ip'"; 158 159 160 $query = "SELECT COUNT(*) FROM `$table_name` WHERE 161 $ip_query_param AND 162 `type` = '$type' AND 163 `blog` = '$blog' AND 164 `user` = '$user' AND 165 $post_query_param AND 166 `code` = '$code' AND 167 `time` BETWEEN '$start_date' AND '$time'"; 168 314 $start_date = $start->format('Y-m-d H:i:s'); 315 $post_param = isset($post->ID) && is_single() ? $post->ID : null; 316 $post_query_param = is_null($post_param) ? "`post` IS NULL" : "`post` = '$post_param'"; 317 $ip_query_param = is_null($ip) ? "`ip` IS NULL" : "`ip` = '$ip'"; 318 319 // Construct and execute query to check if similar event was recorded recently 320 $query = $wpdb->prepare(" 321 SELECT COUNT(*) 322 FROM `$table_name` 323 WHERE $ip_query_param 324 AND `type` = %d 325 AND `blog` = %d 326 AND `user` = %d 327 AND $post_query_param 328 AND `code` = %s 329 AND `time` BETWEEN %s AND %s", 330 $type, $blog, $user, $code, $start_date, $time 331 ); 169 332 $count = $wpdb->get_var($query); 170 333 171 if ($count == 0) { 172 173 /** 174 * type 0 for HTML, CSS and, javascript 175 * type 1 for PHP 176 */ 334 // If no similar event was recently recorded, insert the activity record 335 if ($count === 0) { 336 // Insert the activity record into the database 177 337 $wpdb->insert( 178 338 self::table_activities_name, 179 [339 array( 180 340 'time' => $time, 181 341 'ip' => $ip, … … 186 346 'code' => $code, 187 347 'error' => $error 188 ]348 ) 189 349 ); 190 350 } … … 193 353 194 354 195 /** 355 356 /** 357 * Generates a SQL query for retrieving a weekly activity report for a specific code snippet. 358 * 359 * This static function constructs a SQL query for retrieving a weekly activity report 360 * for a given code snippet within a specified time range. The query calculates metrics 361 * such as unique hits, total hits, and total errors for each day of the week and each hour 362 * of the day within the specified range. The report is organized by weekday and hour, 363 * providing insights into the snippet's activity patterns. 364 * 196 365 * @since 2.4.5 366 * 367 * @param int $post_id The ID of the code snippet post. 368 * @param DateTime $start The start date of the report's time range. 369 * @param DateTime $end The end date of the report's time range. 370 * @return string A SQL query for generating the weekly activity report. 197 371 */ 198 372 static function get_weekly_report_query($post_id, $start, $end) 199 373 { 200 374 375 global $wpdb; 376 201 377 $table_name = self::table_activities_name; 202 378 203 // get post title 379 // Convert the start and end dates to MySQL format 380 $start = $start->format('Y-m-d H:i:s'); 381 $end = $end->format('Y-m-d H:i:s'); 382 383 // Get the title of the code snippet based on its post ID 204 384 $post = get_post($post_id); 205 385 $code = $post->post_title; 206 386 207 // convert dates to mysql format 387 // Construct and return the SQL query for generating the weekly report 388 return $wpdb->prepare( 389 " 390 SELECT time, DAYOFWEEK(time) AS weekday, HOUR(time) AS hour, 391 COUNT(DISTINCT ip) AS unique_hits, 392 COUNT(*) AS total_hits, 393 SUM(CASE WHEN error != '' THEN 1 ELSE 0 END) AS total_errors 394 FROM $table_name 395 WHERE code = %s AND (time BETWEEN %s AND %s) 396 GROUP BY weekday, hour", 397 $code, 398 $start, 399 $end 400 ); 401 } 402 403 404 405 406 407 /** 408 * Generates a SQL query for retrieving a monthly activity report for a specific code snippet. 409 * 410 * This static function constructs a SQL query for retrieving a monthly activity report 411 * for a given code snippet within a specified time range. The query calculates metrics 412 * such as unique hits, total hits, and total errors for each day within the specified range. 413 * The report is organized by month and day, providing insights into the snippet's activity. 414 * 415 * @since 2.4.5 416 * 417 * @param int $post_id The ID of the code snippet post. 418 * @param DateTime $start The start date of the report's time range. 419 * @param DateTime $end The end date of the report's time range. 420 * @return string A SQL query for generating the monthly activity report. 421 */ 422 static function get_monthly_report_query($post_id, $start, $end) 423 { 424 425 global $wpdb; 426 427 $table_name = self::table_activities_name; 428 429 // Convert the start and end dates to MySQL format 208 430 $start = $start->format('Y-m-d H:i:s'); 209 431 $end = $end->format('Y-m-d H:i:s'); 210 432 211 return "SELECT time, WEEKDAY(time) weekday, HOUR(time) hour, 212 COUNT(DISTINCT ip) unique_hits, 213 COUNT(*) total_hits, 214 SUM(case when error = '' then 0 else 1 end) total_errors 215 FROM $table_name 216 WHERE code='$code' AND (time BETWEEN '$start' AND '$end') 217 GROUP BY weekday, hour"; 218 } 219 220 /** 221 * @since 2.4.5 222 */ 223 static function get_monthly_report_query($post_id, $start, $end) 224 { 225 226 $table_name = self::table_activities_name; 227 228 // get post title 229 $post = get_post($post_id); 230 $code = $post->post_title; 231 232 // convert dates to mysql format 233 $start = $start->format('Y-m-d H:i:s'); 234 $end = $end->format('Y-m-d H:i:s'); 235 236 return "SELECT time, MONTHNAME(time) month, DAYOFMONTH(time) day, 237 COUNT(DISTINCT ip) unique_hits, 238 COUNT(*) total_hits, 239 SUM(case when error = '' then 0 else 1 end) total_errors 240 FROM $table_name 241 WHERE code='$code' AND (time BETWEEN '$start' AND '$end') 242 GROUP BY month, day"; 243 } 244 245 433 // Construct and return the SQL query for generating the monthly report 434 return $wpdb->prepare( 435 " 436 SELECT time, MONTHNAME(time) AS month, DAYOFMONTH(time) AS day, 437 COUNT(DISTINCT ip) AS unique_hits, 438 COUNT(*) AS total_hits, 439 SUM(CASE WHEN error != '' THEN 1 ELSE 0 END) AS total_errors 440 FROM $table_name 441 WHERE code = (SELECT post_title FROM $wpdb->posts WHERE ID = %d) AND (time BETWEEN %s AND %s) 442 GROUP BY month, day", 443 $post_id, 444 $start, 445 $end 446 ); 447 } 246 448 } -
code-injection/trunk/includes/class-heatmap.php
r2939201 r2967476 8 8 namespace ci; 9 9 10 11 /** 12 * A class for rendering a heatmap visualization. 13 * 14 * This class generates and displays a heatmap based on provided data. 15 * @since 2.2.6 16 */ 10 17 class Heatmap 11 18 { 12 19 13 private $data = [];14 20 15 private $dowmap = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; 21 private $data = array(); 22 private $dowmap = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'); 16 23 24 25 /** 26 * Constructor for initializing the Heatmap with data. 27 * 28 * @param array $data An array containing heatmap data. 29 */ 17 30 function __construct($data) 18 31 { 19 20 32 $this->data = $data; 21 33 } 22 34 23 35 /** 36 * Render the heatmap. 37 * 38 * This function generates and displays the heatmap visualization based on the provided data. 39 * 24 40 * @since 2.2.6 25 41 */ 26 42 function render() 27 43 { 28 44 // Determine the maximum value for color scaling 29 45 $max = 10; 30 31 if (count($this->data) > 0) { 46 if (!empty($this->data)) { 32 47 $max = max(array_map(function ($item) { 33 48 return intval($item["total_hits"]); … … 41 56 echo "<div class=\"gdcp-heatmap-container\">"; 42 57 58 // Generate rows for each day of the week 43 59 foreach (range(0, 6) as $weekday) { 44 60 45 61 echo "<div class=\"gdcp-heatmap-row\">"; 46 62 63 // Display the day of the week abbreviation 47 64 if ($weekday % 2 != 0) { 48 65 echo "<span class=\"dow\">{$this->dowmap[$weekday]}</span>"; … … 51 68 } 52 69 53 70 // Generate cells for each hour of the day 54 71 foreach (range(0, 24) as $hour) { 55 72 … … 61 78 62 79 $hits = intval($data[0]["total_hits"]); 63 64 80 $plural = $hits > 1; 65 81 … … 68 84 $time = date_i18n("M j, H:i", strtotime($data[0]["time"])); 69 85 70 ?> 71 72 <div class="gdcp-heatmap-cell" style="background-color: <?php echo $color; ?>;"> 73 <p class="info"> 74 <strong><?php echo $hits . ($plural ? " hits - " : " hit - "); ?></strong><span><?php echo $time; ?><span> 75 <i class="arrow-down"></i> 76 </p> 77 </div> 78 79 <?php 80 86 // Display heatmap cell with hit information 87 echo "<div class=\"gdcp-heatmap-cell\" style=\"background-color: $color;\">"; 88 echo "<p class=\"info\"><strong>$hits " . ($plural ? "hits - " : "hit - ") . "</strong><span>$time</span><i class=\"arrow-down\"></i></p>"; 89 echo "</div>"; 81 90 } else { 82 83 91 echo "<div class='gdcp-heatmap-cell'></div>"; 84 92 } … … 91 99 } 92 100 93 94 101 /** 102 * Generate a visual representation of the heatmap color scale. 103 * 104 * @return string A string containing HTML markup for the color scale. 95 105 * @since 2.2.6 96 106 */ 97 107 static function map() 98 108 { 99 100 109 $result = "<span class=\"gdcp-chart-colors\">"; 101 110 102 111 foreach (range(0, 9) as $i) { 103 104 112 $color = self::get_color($i, 9); 105 106 $result = $result . "<i class=\"gradient\" style=\"background-color: $color;\" ></i>"; 113 $result .= "<i class=\"gradient\" style=\"background-color: $color;\"></i>"; 107 114 } 108 115 109 $result = $result ."</span>";116 $result .= "</span>"; 110 117 111 118 return $result; … … 113 120 114 121 /** 122 * Generate a color based on the value and maximum value for color scaling. 123 * 124 * @param int $value The value for which to generate a color. 125 * @param int $max The maximum value for color scaling. 126 * @return string A color in HSL format. 115 127 * @since 2.2.6 116 128 */ 117 129 static function get_color($value, $max) 118 130 { 119 120 131 $h = (1.0 - ($value / $max)) * 240; 121 122 132 return "hsl(" . $h . ", 100%, 50%)"; 123 133 } -
code-injection/trunk/includes/class-helpers.php
r2939201 r2967476 6 6 */ 7 7 8 8 9 namespace ci; 9 10 11 12 /** 13 * The Helpers class provides utility functions for various tasks within the code tracking system. 14 * 15 * This class offers a collection of static utility functions that are used across the code tracking system. 16 * These functions assist in tasks such as determining the type of page being displayed, checking if a specific 17 * page is an edit page, identifying settings pages, retrieving the user's IP address, and obtaining asset URLs. 18 * 19 * @namespace ci 20 * @since 2.4.12 21 */ 10 22 class Helpers 11 23 { … … 13 25 14 26 /** 27 * Checks if the current page is related to managing code snippets. 28 * 29 * This static function determines whether the current page is associated with code snippet management. 30 * It checks if the current page is either a new code creation page or an edit page for an existing code snippet. 31 * The function examines the page type using the internal `is_edit_page` function, and additionally checks 32 * if the post type matches 'code' to confirm that it's a code management page. 33 * 34 * @return bool True if the current page is a code management page, false otherwise. 35 * 15 36 * @since 2.4.12 16 37 */ … … 18 39 { 19 40 41 // Check if it's a new code creation page 20 42 if (self::is_edit_page('new')) { 21 43 if (isset($_GET['post_type']) && $_GET['post_type'] == 'code') { … … 24 46 } 25 47 48 // Check if it's an edit page for an existing code snippet 26 49 if (self::is_edit_page('edit')) { 27 28 50 global $post; 29 30 51 if ('code' == get_post_type($post)) { 31 52 return true; 32 53 } 33 34 } 35 54 } 55 56 // If neither edit nor new code page, or post type is not 'code', it's not a code management page 36 57 return false; 37 } 38 39 40 41 /** 58 59 } 60 61 62 63 /** 64 * Checks if the current page is an edit or new post creation page within the admin area. 65 * 66 * This static function determines whether the current page is an edit page or a new post creation page 67 * within the WordPress admin area. It accepts an optional parameter to specify the type of page to check: 68 * 'edit' for edit page and 'new' for new post creation page. The function examines the global variable `$pagenow` 69 * to identify the current page and compares it with relevant page slugs to determine if the page matches the type. 70 * 71 * @param string|null $new_edit Specifies the type of page to check ('edit' for edit page, 'new' for new post creation page). 72 * @return bool True if the current page is an edit or new post creation page, false otherwise. 73 * 42 74 * @since 2.4.12 43 75 */ … … 47 79 global $pagenow; 48 80 81 // Check if it's within the admin area 49 82 if (!is_admin()) { 50 83 return false; 51 84 } 52 53 if ($new_edit == "edit") { 54 return in_array($pagenow, array('post.php')); 55 } 56 57 if ($new_edit == "new") { 58 return in_array($pagenow, array('post-new.php')); 59 } 60 61 return in_array($pagenow, array('post.php', 'post-new.php')); 62 } 63 64 65 /** 85 86 switch ($new_edit) { 87 // Check if it's an edit page 88 case "edit": 89 return in_array($pagenow, array('post.php')); 90 91 // Check if it's a new post creation page 92 case "new": 93 return in_array($pagenow, array('post-new.php')); 94 95 // Check if it's either an edit or new post creation page 96 default: 97 return in_array($pagenow, array('post.php', 'post-new.php')); 98 } 99 100 } 101 102 103 /** 104 * Checks if the current page is a settings page within the WordPress admin area. 105 * 106 * This static function determines if the current page is a settings page within the WordPress admin area. 107 * It checks if the `get_current_screen` function exists, and if not, assumes it's not a settings page. 108 * If the function exists, it retrieves the current screen object and examines the screen ID to determine 109 * if it corresponds to the target settings screen ID, 'ci-general'. 110 * 111 * @return bool True if the current page is a settings page, false otherwise. 112 * 66 113 * @since 2.4.12 67 114 */ 68 115 static function is_settings_page() 69 116 { 70 117 // Define the target settings screen ID 118 $TARGET_SCREEN_ID = 'ci-general'; 119 120 // Check if the required function exists 71 121 if (!function_exists('get_current_screen')) { 72 122 return false; 73 123 } 74 124 125 // Retrieve the current screen object 75 126 $screen = get_current_screen(); 76 127 77 return strpos($screen->id , 'ci-general') !== false; 78 } 79 80 81 82 /** 128 // Check if the screen ID matches the target settings screen ID 129 return $screen->id === $TARGET_SCREEN_ID; 130 } 131 132 133 134 135 /** 136 * Retrieves the user's IP address from various possible sources. 137 * 138 * This static function retrieves the user's IP address from a list of potential headers and server variables 139 * that might contain the IP address. It iterates through these sources, validates the IP addresses, 140 * and returns the first valid IP address found. If no valid IP address is found, it returns "Unknown". 141 * 142 * @return string The user's IP address if found, otherwise "Unknown". 143 * 83 144 * @since 2.4.12 84 145 */ 85 146 static function get_ip_address() 86 147 { 87 88 foreach ([148 // List of possible headers and server variables containing the IP address 149 $ip_sources = [ 89 150 'HTTP_CLIENT_IP', 90 151 'HTTP_X_FORWARDED_FOR', … … 94 155 'HTTP_FORWARDED', 95 156 'REMOTE_ADDR' 96 ] as $key) { 97 98 if (array_key_exists($key, $_SERVER) === true) { 99 100 foreach (explode(',', $_SERVER[$key]) as $ip) { 157 ]; 158 159 // Iterate through each source to find the user's IP address 160 foreach ($ip_sources as $source) { 161 if (array_key_exists($source, $_SERVER)) { 162 foreach (explode(',', $_SERVER[$source]) as $ip) { 101 163 $ip = trim($ip); 102 164 165 // Validate the IP address and exclude private and reserved ranges 103 166 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) { 104 return $ip ?: "Unknown"; 167 return $ip ?: "Unknown"; // Return the IP address or "Unknown" 105 168 } 106 169 } 107 170 } 108 171 } 109 } 110 111 112 /** 113 * @since 2.4.12 114 */ 115 static function get_asset_url($path) 116 { 117 return plugins_url("/assets/" . rtrim(ltrim($path, "/"), "/"), __CI_FILE__); 118 } 172 173 return "Unknown"; // Return "Unknown" if no valid IP address is found 174 } 175 176 177 178 /** 179 * Retrieves the URL of an asset using the provided relative path. 180 * 181 * This static function constructs the URL for an asset using the provided relative path within the plugin's assets directory. 182 * It appends the provided path to the assets directory path, ensuring proper formatting by utilizing the `trailingslashit` function. 183 * The resulting URL is based on the WordPress `plugins_url` function and the plugin's main file constant `__CI_FILE__`. 184 * 185 * @param string $relative_path The relative path of the asset within the plugin's assets directory. 186 * @return string The complete URL of the asset. 187 * 188 * @since 2.4.12 189 */ 190 static function get_asset_url($relative_path) 191 { 192 // Construct the URL by appending the relative path to the assets directory path 193 $assets_dir_path = trailingslashit("/assets/"); 194 $asset_url = plugins_url($assets_dir_path . ltrim($relative_path, "/"), __CI_FILE__); 195 196 return $asset_url; 197 } 198 199 119 200 } -
code-injection/trunk/includes/class-metabox.php
r2939201 r2967476 28 28 static function init() 29 29 { 30 add_action('add_meta_boxes', array(__CLASS__, 'add_meta_box')); 31 add_action('save_post', array(__CLASS__, 'save_post')); 32 } 33 34 35 /** 30 add_action('add_meta_boxes', array(__CLASS__, '_add_meta_box')); 31 add_action('save_post', array(__CLASS__, '_save_post')); 32 } 33 34 35 /** 36 * @access private 36 37 * @since 2.2.8 37 38 */ 38 static function add_meta_box()39 static function _add_meta_box() 39 40 { 40 41 … … 50 51 51 52 /** 53 * @access private 52 54 * @since 2.2.8 53 55 */ 54 static function save_post($id)56 static function _save_post($id) 55 57 { 56 58 -
code-injection/trunk/includes/class-options.php
r2939201 r2967476 8 8 namespace ci; 9 9 10 /** 11 * A class for managing plugin options and settings. 12 * 13 * This class handles the registration of settings, options, and the settings page. 14 * 15 * @since 2.4.12 16 */ 10 17 class Options 11 18 { 12 19 13 const option_group = 'ci-general'; 14 15 16 /** 20 const option_group = 'ci-general'; // The option group used for registering settings 21 22 /** 23 * Initialize the Options class by adding necessary action hooks. 24 * 25 * This function is called when the class is loaded and adds action hooks to initialize the admin settings page and menu. 26 * 17 27 * @since 2.4.12 18 28 */ 19 29 static function init() 20 30 { 21 add_action('admin_init', array( __CLASS__ , '_admin_init')); 22 add_action('admin_menu', array( __CLASS__ , '_admin_menu')); 23 } 24 25 26 /** 31 add_action('admin_init', array(__CLASS__, '_admin_init')); 32 add_action('admin_menu', array(__CLASS__, '_admin_menu')); 33 } 34 35 /** 36 * Get the array of unsafe keys from the option. 37 * 38 * @return array An array of unsafe keys. 27 39 * @since 2.4.12 28 40 */ … … 32 44 } 33 45 34 35 /** 46 /** 47 * Extract keys from a comma-separated string. 48 * 49 * @param string $text The comma-separated string containing keys. 50 * @return array An array of keys. 36 51 * @since 2.4.12 37 52 */ … … 43 58 } 44 59 45 46 /** 47 * @since 2.4.12 48 * @access private 49 */ 50 static function _admin_menu(){ 51 60 /** 61 * Add the plugin settings page to the admin menu. 62 * 63 * @since 2.4.12 64 * @access private 65 */ 66 static function _admin_menu() 67 { 52 68 add_submenu_page( 53 69 'options-general.php', … … 55 71 __('Code Injection', 'code-injection'), 56 72 'manage_options', 57 self::option_group ,58 array(__CLASS__ , '_settings_page_cb')73 self::option_group, 74 array(__CLASS__, '_settings_page_cb') 59 75 ); 60 61 } 62 63 64 /**76 } 77 78 /** 79 * Initialize the admin settings and register settings sections and fields. 80 * 65 81 * @since 2.4.12 66 82 * @access private … … 68 84 static function _admin_init() 69 85 { 70 71 // Settings Section 86 // Register a settings section 72 87 add_settings_section('wp_code_injection_plugin', "", "__return_false", self::option_group); 73 88 74 // register codesettings89 // Register code-related settings 75 90 register_setting(self::option_group, 'ci_code_injection_cache_max_age', ['default' => '84600']); 76 77 // register "CI" settings78 91 register_setting(self::option_group, 'ci_code_injection_allow_shortcode', ['default' => false]); 79 92 80 // register "Unsafe"settings93 // Register unsafe-related settings 81 94 register_setting(self::option_group, 'ci_unsafe_widgets_shortcodes', ['default' => false]); 82 95 register_setting(self::option_group, 'ci_unsafe_keys', ['default' => '']); … … 84 97 register_setting(self::option_group, 'ci_unsafe_ignore_keys', ['default' => false]); 85 98 86 self::add_settings_field('ci_code_injection_cache_max_age', '84600', esc_html__("Code Options", "code-injection"));87 99 // Add settings fields 100 self::add_settings_field('ci_code_injection_cache_max_age', '84600', esc_html__("Code Options", "code-injection")); 88 101 self::add_settings_field('ci_code_injection_allow_shortcode', false, esc_html__("Shortcodes", "code-injection")); 89 90 102 self::add_settings_field('ci_unsafe_widgets_shortcodes', false); 91 103 self::add_settings_field('ci_unsafe_widgets_php', false); 92 self::add_settings_field('ci_unsafe_ignore_keys', false, esc_html__("Activator Keys", "code-injection"));104 self::add_settings_field('ci_unsafe_ignore_keys', false, esc_html__("Activator Keys", "code-injection")); 93 105 self::add_settings_field('ci_unsafe_keys'); 94 106 } … … 97 109 98 110 /** 99 * @since 2.4.12 100 * @access private 101 */ 102 static function _settings_section_cb() 103 { 104 } 105 106 107 /** 111 * Render the settings page content. 112 * 113 * This function is called to render the plugin settings page in the WordPress admin. 114 * It displays the registered settings sections and fields. 115 * 108 116 * @since 2.4.12 109 117 * @access private … … 133 141 134 142 /** 135 * @since 2.4.12 143 * Add a settings field to the options page. 144 * 145 * This function adds a settings field to the plugin options page in the WordPress admin. 146 * It allows users to input values or make selections for various plugin settings. 147 * 148 * @param string $id The unique identifier for the setting. 149 * @param mixed $default The default value for the setting. 150 * @param string $title The title of the settings field. 151 * @param string $section The settings section to which the field belongs. 152 * @param string $page The option group identifier. 153 * @since 2.4.12 154 * @access private 136 155 */ 137 156 private static function add_settings_field($id, $default = '', $title = '', $section = 'wp_code_injection_plugin', $page = self::option_group) … … 142 161 143 162 /** 163 * Generate a checkbox input for settings. 164 * 165 * This function generates a checkbox input field for the plugin settings. 166 * It allows users to enable or disable certain plugin features. 167 * 168 * @param string $key The option key. 169 * @param bool $value The current value of the checkbox. 170 * @param string $description The description of the checkbox. 144 171 * @since 2.4.12 145 172 */ … … 150 177 151 178 152 /** 179 /** 180 * Render the settings field callback. 181 * 182 * This function renders the content of a settings field callback. 183 * It generates different types of inputs based on the field type. 184 * 185 * @param array $args The arguments for the settings field. 153 186 * @since 2.4.12 154 187 * @access private … … 157 190 { 158 191 159 $key = $args['label_for'];160 $default = isset($args['default']) ? $args['default'] : '';161 $value = get_option($key, $default);192 $key = $args['label_for']; 193 $default = isset($args['default']) ? $args['default'] : ''; 194 $value = get_option($key, $default); 162 195 163 196 switch ($key) { 164 165 197 case 'ci_code_injection_cache_max_age': 166 167 198 printf('<p>%1$s</p>', esc_html__('Cache max-age (Seconds)', 'code-injection')); 168 199 printf('<input class="regular-text" type="number" value="%1$s" id="%2$s" name="%2$s" />', $value, $key); 169 printf('<p class="description">e.g. %1$s</p>', $default); 170 171 break; 172 200 printf('<p class="description">%1$s</p>', esc_html__('e.g. 84600', 'code-injection')); 201 break; 173 202 case 'ci_unsafe_keys': 174 175 printf('<p class="ack-head-wrapper"><span class="ack-header"><strong>%1$s</strong></span><a class="button ack-new" href="javascript:void(0);" id="ci_generate_key">%2$s</a></p>', esc_html__("Keys:", "code-injection"), esc_html__("Generate Key", "code-injection")); 176 printf('<p><textarea data-placeholder="%1$s" class="large-text code" id="%2$s" name="%2$s">%3$s</textarea></p>', esc_html__("Enter Keys:", "code-injection"), $key, $value); 177 printf('<p class="description">e.g. key-2im2a5ex4, key-6dp7mwt05 ...</p>', $default); 178 179 break; 180 203 printf('<p class="ack-head-wrapper"><span class="ack-header"><strong>%1$s</strong></span><a class="button ack-new" href="javascript:void(0);" id="ci_generate_key">%2$s</a></p>', 204 esc_html__("Keys:", "code-injection"), esc_html__("Generate Key", "code-injection")); 205 printf('<p><textarea data-placeholder="%1$s" class="large-text code" id="%2$s" name="%2$s">%3$s</textarea></p>', 206 esc_html__("Enter Keys:", "code-injection"), $key, $value); 207 printf('<p class="description">%1$s</p>', esc_html__('e.g. key-2im2a5ex4, key-6dp7mwt05 ...', 'code-injection')); 208 break; 181 209 case 'ci_code_injection_allow_shortcode': 182 183 210 self::checkbox($key, $value, esc_html__("Allow nested shortcodes", "code-injection")); 184 185 break; 186 211 break; 187 212 case 'ci_unsafe_ignore_keys': 188 189 213 self::checkbox($key, $value, esc_html__("Ignore activator keys", "code-injection")); 190 191 break; 192 214 break; 193 215 case 'ci_unsafe_widgets_shortcodes': 194 195 216 self::checkbox($key, $value, esc_html__("Allow shortcodes in the Custom HTML widget", "code-injection")); 196 197 break; 198 217 break; 199 218 case 'ci_unsafe_widgets_php': 200 201 219 self::checkbox($key, $value, sprintf(esc_html__("Enable %s shortcode", "code-injection"), "<code>[unsafe key='']</code>")); 202 203 printf( 204 '<p class="description">%1$s</p>', 220 printf('<p class="description">%1$s</p>', 205 221 sprintf( 206 222 esc_html__('See %1$s for more information.', "code-injection"), … … 212 228 ) 213 229 ); 214 215 230 break; 216 231 } -
code-injection/trunk/includes/class-roles.php
r2939201 r2967476 8 8 namespace ci; 9 9 10 /** 11 * Manages custom roles and capabilities related to the Code Injection plugin. 12 * 13 * This class handles the registration and updates of custom user roles and capabilities for the Code Injection plugin. 14 * It ensures that the 'Developer' role is properly registered with specific capabilities required for the plugin's functionality. 15 * 16 * @since 2.4.12 17 */ 10 18 class Roles 11 19 { 20 /** 21 * Initializes custom roles and capabilities. 22 * 23 * Registers actions to perform role registration and capability updates. 24 * 25 * @since 2.4.12 26 */ 27 public static function init() 28 { 29 add_action('admin_init', array(__CLASS__, '_register_developer_role')); 30 add_action('admin_init', array(__CLASS__, '_update_capabilities')); 31 } 12 32 13 33 /** 34 * Registers the 'Developer' custom role and sets its capabilities. 35 * 36 * This method registers the 'Developer' role with specific capabilities required for the Code Injection plugin. 37 * 38 * @access private 39 * 14 40 * @since 2.4.12 15 41 */ 16 static function init(){ 17 add_action('admin_init' , array(__CLASS__ , '_register_roles')); 18 add_action('admin_init' , array(__CLASS__ , '_update_caps')); 19 } 42 static function _register_developer_role() 43 { 44 45 // Get the 'Developer' role object 46 $developerRole = get_role('developer'); 20 47 48 // Get the stored role version from options 49 $roleVersion = get_option('ci_role_version', ''); 21 50 22 /** 23 * @since 2.4.12 24 * @access private 25 */ 26 static function _register_roles() 27 { 28 29 $developer = get_role('developer'); 30 $role_version = get_option('ci_role_version', ''); 31 32 33 if ($role_version == __CI_VERSION__ && isset($developer)) { 51 // Check if role version matches and 'Developer' role exists 52 if ($roleVersion === __CI_VERSION__ && isset($developerRole)) { 53 // Role is already registered with correct version, no need to re-register 34 54 return; 35 55 } 36 56 37 57 // Remove the existing 'Developer' role if it exists 38 58 remove_role('developer'); 39 59 40 60 // Add the 'Developer' role with specific capabilities 41 61 add_role( 42 62 'developer', 43 63 esc_html__('Developer', "code-injection"), 44 [64 array( 45 65 'read' => true, 46 66 'edit_posts' => false, … … 48 68 'publish_posts' => false, 49 69 'upload_files' => true, 50 ]70 ) 51 71 ); 52 72 73 // Update the stored role version to the current version 74 update_option('ci_role_version', __CI_VERSION__); 53 75 54 update_option('ci_role_version', __CI_VERSION__);55 76 } 56 77 78 /** 79 * Updates capabilities for specified roles. 80 * 81 * Adds capabilities related to managing code snippets for 'developer' and 'administrator' roles. 82 * 83 * @access private 84 * 85 * @since 2.2.6 86 */ 87 static function _update_capabilities() 88 { 89 // List of roles to update capabilities for 90 $rolesToUpdate = array('developer', 'administrator'); 57 91 58 /** 59 * @since 2.2.6 60 * @access private 61 */ 62 static function _update_caps() 63 { 92 // Iterate through each role to update capabilities 93 foreach ($rolesToUpdate as $role) { 94 // Get the role object for the current role 95 $roleObject = get_role($role); 64 96 65 $roles = array('developer', 'administrator'); 66 67 foreach ($roles as $role) { 68 69 $ur = get_role($role); 70 71 if (!isset($ur)) { 97 // Check if the role object exists 98 if (!isset($roleObject)) { 99 // If role object doesn't exist, move to the next role 72 100 continue; 73 101 } 74 102 75 foreach (array( 76 'publish', 'delete', 'delete_others', 'delete_private', 77 'delete_published', 'edit', 'edit_others', 'edit_private', 103 // List of capabilities to be added 104 $capabilities = array( 105 'publish', 'delete', 'delete_others', 'delete_private', 106 'delete_published', 'edit', 'edit_others', 'edit_private', 78 107 'edit_published', 'read_private' 79 ) as $cap) { 80 $ur->add_cap("{$cap}_code"); 81 $ur->add_cap("{$cap}_codes"); 108 ); 109 110 // Iterate through each capability to add to the role 111 foreach ($capabilities as $capability) { 112 // Add the capability for singular code management 113 $roleObject->add_cap("{$capability}_code"); 114 115 // Add the capability for plural code management 116 $roleObject->add_cap("{$capability}_codes"); 82 117 } 83 118 } 84 119 } 85 86 87 120 } -
code-injection/trunk/includes/class-shortcodes.php
r2943916 r2967476 154 154 155 155 if (!empty($id)) { 156 $code = get_page_by_title($id, OBJECT, 'code');156 $code = Database::get_code_by_title($id); 157 157 } else { 158 158 $code = Database::get_code_by_slug($slug); -
code-injection/trunk/includes/class-widget.php
r2943916 r2967476 10 10 use WP_Widget; 11 11 12 /** 13 * Custom WordPress widget for Code Injection. 14 * 15 * This class extends the WP_Widget class to create a custom widget named 'Code Injection'. 16 * It allows users to insert code snippets in HTML, CSS, and JavaScript into their website's sidebar 17 * or other widgetized areas. The widget provides a user-friendly interface to select from available code snippets. 18 * 19 * @subpackage Widget 20 * 21 * @since 0.9.0 22 */ 12 23 class Widget extends WP_Widget 13 24 { 14 25 15 26 /** 16 * @since 0.9.0 27 * Constructor for the Widget class. 28 * 29 * Sets up the widget with a unique ID, name, and description. 30 * 31 * @since 0.9.0 17 32 */ 18 33 function __construct() … … 21 36 'wp_code_injection_plugin_widget', 22 37 esc_html__('Code Injection', 'code-injection'), 23 ['description' => esc_html__("This plugin allows you to effortlessly create custom ads for your website. Inject code snippets in HTML, CSS, and JavaScript, write and run custom plugins on-the-fly, and take your website's capabilities to the next level.", 'code-injection')] 38 array( 39 'description' => esc_html__("This plugin allows you to effortlessly create custom ads for your website. Inject code snippets in HTML, CSS, and JavaScript, write and run custom plugins on-the-fly, and take your website's capabilities to the next level.", 'code-injection') 40 ) 24 41 ); 25 42 } … … 27 44 28 45 /** 46 * Outputs the content of the widget. 47 * 48 * Displays the selected code snippet in the widget area based on the user's choice. 49 * 50 * @param array $args Widget arguments. 51 * @param array $instance Saved values from the widget form. 52 * 29 53 * @since 0.9.0 30 54 */ 31 55 function widget($args, $instance) 32 56 { 33 $title = apply_filters('widget_title', $instance['title']);57 $title = apply_filters('widget_title', isset( $instance['title'] ) ? $instance['title'] : '0'); 34 58 35 if ($title == '0') {36 return;59 if ($title !== '0') { 60 echo do_shortcode("[inject id='$title']"); 37 61 } 38 39 //output40 echo do_shortcode("[inject id='$title']");41 62 } 42 63 43 64 44 65 /** 66 * Outputs the widget form in the WordPress admin. 67 * 68 * Provides a form to select and display available code snippets as options in the widget settings. 69 * 70 * @param array $instance Previously saved values from the widget form. 71 * 45 72 * @since 0.9.0 46 73 */ … … 48 75 { 49 76 50 $label = esc_html__('Code ID:', 'code-injection'); 51 $fieldId = $this->get_field_id('title'); 52 $fieldName = $this->get_field_name('title'); 77 $title = isset($instance['title']) ? $instance['title'] : 'code-#########'; 78 $codes = Database::get_codes(); 53 79 54 if (isset($instance['title'])) { 55 $title = $instance['title']; 56 } else { 57 $title = 'code-#########'; 80 // Filter and retain only published code snippets 81 $published_codes = array_filter($codes, function ($item) { 82 return $item->post_status === 'publish'; 83 }); 84 85 // Generate dropdown options for available code snippets 86 $options = '<option value="0">' . esc_html__("— Select —", "code-injection") . '</option>'; 87 foreach ($published_codes as $code) { 88 $codeTitle = get_post_meta($code->ID, "code_slug", true) ?: $code->post_title; 89 $selected = selected($code->post_title, $title, false); 90 $options .= sprintf('<option %1$s value="%2$s">%3$s</option>', $selected, esc_attr($code->post_title), $codeTitle); 58 91 } 59 92 60 $codes = Database::get_codes(); 93 $fieldId = $this->get_field_id('title'); 94 $fieldName = $this->get_field_name('title'); 95 $label = esc_html__('Code ID:', 'code-injection'); 61 96 62 $codes = array_filter($codes, function ($item) { 63 return $item->post_status == 'publish'; 64 }); 65 66 ob_start(); 67 68 printf('<option value="0">— %1$s —</option>', esc_html__("Select", "code-injection")); 69 70 foreach ($codes as $code) { 71 $codeTitle = get_post_meta($code->ID, "code_slug", true); 72 $codeTitle = $codeTitle ?: $code->post_title; 73 74 printf('<option %1$s value="%2$s">%3$s</option>', selected($code->post_title, $title, false), esc_attr($code->post_title), $codeTitle); 75 } 76 77 $options = ob_get_clean(); 78 79 printf('<p><label for="%1$s">%2$s</label><select style="width:100%;" id="%1$s" name="%2$s">%3$s</select></p>', $fieldId, $label , $fieldId, $fieldName, $options); 80 81 wp_reset_query(); 82 97 printf('<p><label for="%1$s">%2$s</label><select style="width:100%;" id="%1$s" name="%2$s">%3$s</select></p>', $fieldId, $label, $fieldId, $fieldName, $options); 83 98 } 84 99 85 100 86 101 87 102 /** 103 * Updates the widget settings when saved. 104 * 105 * Sanitizes and stores the selected code snippet ID. 106 * 107 * @param array $new_instance New settings for the widget. 108 * @param array $old_instance Old settings for the widget. 109 * 110 * @return array Updated settings for the widget. 111 * 88 112 * @since 0.9.0 89 113 */ … … 91 115 { 92 116 $instance = array(); 93 $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';117 $instance['title'] = !empty($new_instance['title']) ? strip_tags($new_instance['title']) : ''; 94 118 return $instance; 95 119 } -
code-injection/trunk/readme.txt
r2943916 r2967476 3 3 Tags: code, snippets, injection 4 4 Requires at least: 4.5.0 5 Tested up to: 6. 2.26 Stable tag: 2.4.1 35 Tested up to: 6.3.1 6 Stable tag: 2.4.14 7 7 License: MIT License 8 8 License URI: https://github.com/Rmanaf/wp-code-injection/blob/master/LICENSE
Note: See TracChangeset
for help on using the changeset viewer.