Plugin Directory

Changeset 2967476


Ignore:
Timestamp:
09/15/2023 11:37:18 AM (2 years ago)
Author:
rmanaf
Message:

2.4.14

Location:
code-injection/trunk
Files:
2 added
14 edited

Legend:

Unmodified
Added
Removed
  • code-injection/trunk/code-injection.php

    r2943916 r2967476  
    55 * Plugin URI: https://github.com/Rmanaf/wp-code-injection
    66 * 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.13
     7 * Version: 2.4.14
    88 * Author: Rmanaf
    99 * Author URI: https://profiles.wordpress.org/rmanaf/
     
    2323define('__CI_URL__', plugin_dir_url(__FILE__));
    2424define('__CI_PATH__', plugin_dir_path(__FILE__));
    25 define('__CI_VERSION__', '2.4.13');
     25define('__CI_VERSION__', '2.4.14');
    2626
    2727// Require the necessary files for the plugin
     
    3838require_once __DIR__ . '/includes/class-widget.php';
    3939require_once __DIR__ . '/includes/class-code-type.php';
     40require_once __DIR__ . '/includes/class-block.php';
    4041require_once __DIR__ . '/includes/class-core.php';
    4142
  • code-injection/trunk/includes/class-asset-manager.php

    r2939201 r2967476  
    88namespace ci;
    99
     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 */
    1019class AssetManager
    1120{
    1221
    1322
     23    private static $CI_LOCALIZE_OBJ = '_ci';
     24
     25
    1426    /**
     27     * Initialize the Asset Manager
     28     *
     29     * Registers and enqueues necessary styles and scripts for the Code Injection plugin's functionality.
     30     *
    1531     * @since 2.4.2
    1632     */
    1733    static function init()
    1834    {
    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'));
    2037    }
    2138
     
    2340
    2441    /**
     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
    2549     * @since 2.2.8
    2650     */
    27     static function enqueue_scripts()
     51    static function _enqueue_scripts()
    2852    {
    2953
     54        // Array of localized texts for internationalization
    3055        $texts = array(
    3156            "The File is too large. Do you want to proceed?",
     
    3560        );
    3661
     62        // Internationalization for JavaScript
    3763        $i18n = array(
    3864            'code-injection' => array(
     
    4470        );
    4571
     72
     73        // Register custom styles and scripts
    4674        wp_register_style('ci-custom-code-editor', Helpers::get_asset_url('/css/code-editor.css'), array(), __CI_VERSION__, 'all');
    47 
    4875        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);
    4976        wp_register_script('ci-editor', Helpers::get_asset_url('/js/code-editor.js'), array(), __CI_VERSION__, false);
    5077
     78
     79        // Enqueue essential scripts
    5180        wp_enqueue_script('ci-essentials', Helpers::get_asset_url('/js/essentials.js'), array('jquery'), __CI_VERSION__, true);
    5281
    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(
    5485            'ajax_url'      => admin_url('admin-ajax.php'),
    5586            "ajax_nonce"    => wp_create_nonce("code-injection-ajax-nonce"),
    5687            "is_rtl"        => is_rtl() ? "true" : "false",
    5788            "i18n"          => $i18n
    58         ));
     89        )));
    5990
     91
     92        // Enqueue plugin-specific styles
    6093        wp_enqueue_style('ci-styles', Helpers::get_asset_url('/css/wp-code-injection-admin.css'), array(), __CI_VERSION__, 'all');
    6194
     95
     96        // Enqueue additional styles and scripts for settings page
    6297        if (Helpers::is_settings_page()) {
    63 
    64             // tag-editor styles
    6598            wp_enqueue_style('ci-tag-editor', Helpers::get_asset_url('/css/jquery.tag-editor.css'), array(), __CI_VERSION__, 'all');
    66 
    67             // tag-editor scripts
    6899            wp_enqueue_script('ci-caret', Helpers::get_asset_url('/js/jquery.caret.min.js'), array('jquery'), __CI_VERSION__, false);
    69100            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 scripts
    72101            wp_enqueue_script('ci-code-injection', Helpers::get_asset_url('/js/wp-ci-general-settings.js'), array('jquery'), __CI_VERSION__, true);
    73102        }
     
    75104
    76105
     106
    77107    /**
     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     *
    78129     * @since 2.4.2
    79130     */
     
    85136        wp_enqueue_script('ci-editor');
    86137    }
     138
     139
     140
     141
    87142}
  • code-injection/trunk/includes/class-barchart.php

    r2943916 r2967476  
    88namespace ci;
    99
     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 */
    1018class Barchart
    1119{
    1220
    13 
    14     private $data = [];
    15 
     21    private $data = array();
    1622    private $width = 0;
    17 
    1823    private $height = 0;
    19 
    2024    private $gap = 1;
    2125
     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     */
    2235    function __construct($data, $w, $h, $g = 1)
    2336    {
     
    3043
    3144    /**
     45     * Render the Barchart
     46     *
     47     * Generates and outputs an SVG representation of the barchart.
     48     *
    3249     * @since 2.4.5
    3350     */
     
    3552    {
    3653
     54        // Find the maximum value in the data to calculate the yScale
    3755        $max = 0;
    38 
    39         $index = 0;
    40 
    41         if (count($this->data) > 0) {
     56        if (!empty($this->data)) {
    4257            $max = max(array_map(function ($item) {
    4358                return intval($item["value"]);
     
    4560        }
    4661
    47         $yScale = $max / $this->height;
    4862
    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;
    5065
    51         $barWidth = ($this->width / $length) - $this->gap;
     66        // Calculate the width of each bar
     67        $barWidth = ($this->width / count($this->data)) - $this->gap;
    5268
     69        // Calculate the total height of the SVG including margins
    5370        $svgHeight = $this->height + 25;
    5471
    5572
     73        // Start generating the SVG
    5674        echo "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" " .
    5775            "xmlns:xlink=\"http://www.w3.org/1999/xlink\" " .
     
    6078
    6179
     80        // Generate horizontal grid lines
    6281        foreach ([0, $this->height / 2, $this->height] as $y) {
    6382            echo "<g>" .
     
    6786
    6887
    69         foreach ($this->data as $d) {
     88        // Generate bars for each data point
     89        foreach ($this->data as $index => $d) {
    7090
    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'] : '';
    7394
    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;
    7997
     98            // Calculate the x and y coordinates for the bar and related elements
    8099            $x = ($index * ($barWidth + $this->gap));
    81 
    82100            $y = $this->height - $height;
    83 
    84101            $lineX = ($barWidth / 2) + $x;
    85 
    86102            $tooltipY = $this->height + 12;
    87 
    88103            $tooltipX = min([max([$lineX, 9]), $this->width - 9]);
    89104
    90 
     105            // Generate tooltip markup if a tooltip is available
     106            $tooltipMarkup = '';
    91107            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);\">" .
    94109                    "<circle class=\"bg\" r=\"9\" fill=\"#333\" />" .
    95110                    "<text dy=\".35em\" x=\"0\" y=\"0\" text-anchor=\"middle\" class=\"count\" fill=\"#fff\">$tooltip</text>" .
     
    97112            }
    98113
     114            // Output SVG elements for the bar and related components
    99115            echo "<g class=\"bar\">" .
    100116                "<line class=\"grid\" x1=\"$lineX\" y1=\"0\" x2=\"$lineX\" y2=\"$this->height\" stroke-width=\"4\" />" .
    101117                "<rect y=\"$y\" x=\"$x\" width=\"$barWidth\" height=\"$height\" />" .
    102                 $tooltip .
     118                $tooltipMarkup .
    103119                "</g>";
    104 
    105             $index++;
    106120        }
    107121
     122        // Close the SVG element
    108123        echo "</svg>";
    109124    }
  • code-injection/trunk/includes/class-code-type.php

    r2939201 r2967476  
    127127        $length = intval(date('t', mktime(0, 0, 0, $month, 1, $year)));
    128128
    129         $bcDataHolder = array_fill(0, $length, [
     129        $bcDataHolder = array_fill(0, $length, array(
    130130            "value" => 0
    131         ]);
     131        ));
    132132
    133133        $bcDataHolder = array_map(function ($item) {
    134134            $index = $item + 1;
    135             return [
     135            return array(
    136136                "value" => 0,
    137137                "index" => $index < 10 ? "0$index" : $index
    138             ];
     138            );
    139139        }, array_keys($bcDataHolder));
    140140
     
    150150
    151151        foreach ($bcData as $d) {
    152             $bcDataHolder[intval($d['day']) - 1] = [
     152            $bcDataHolder[intval($d['day']) - 1] = array(
    153153                "value" => $d["total_hits"],
    154154                "index" => $d["day"] < 10 ? "0{$d["day"]}" : $d["day"]
    155             ];
     155            );
    156156        }
    157157
     
    179179            return;
    180180
    181         $taxonomies = ['code_category'];
     181        $taxonomies = array('code_category');
    182182
    183183        foreach ($taxonomies as $taxonomy_slug) {
     
    239239            $status = get_post_status($post);
    240240
    241             $needles = [$post->post_title, '”', '“'];
     241            $needles = array($post->post_title, '”', '“');
    242242
    243243            if (isset($actions['edit'])) {
     
    346346    {
    347347
    348         $code_lables = [
     348        $code_lables = array(
    349349            'name' => esc_html__('Codes', "code-injection"),
    350350            'singular_name' => esc_html__('Code', "code-injection"),
     
    356356            'not_found_in_trash ' => esc_html__('No codes found in Trash', "code-injection"),
    357357            'all_items' => esc_html__('All Codes', "code-injection")
    358         ];
     358        );
    359359
    360360
     
    362362            'code_category',
    363363            'code',
    364             [
     364            array(
    365365                'show_admin_column' => true,
    366366                'public' => false,
     
    368368                'rewrite' => false,
    369369                'hierarchical' => true
    370             ]
     370            )
    371371        );
    372372
     
    374374        register_post_type(
    375375            'Code',
    376             [
     376            array(
    377377                'menu_icon' => 'dashicons-editor-code',
    378378                'labels' => $code_lables,
     
    383383                'exclude_from_search' => true,
    384384                'publicly_queryable' => false,
    385                 'supports' => ['author', 'revisions', 'title', 'editor'],
     385                'supports' => array('author', 'revisions', 'title', 'editor'),
    386386                'capability_type' => ['code', 'codes'],
    387387                'can_export' => true,
    388388                'map_meta_cap' => true
    389             ]
     389            )
    390390        );
    391391    }
     
    399399    {
    400400
    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
    410407    }
    411408
  • code-injection/trunk/includes/class-core.php

    r2939201 r2967476  
    88namespace ci;
    99
     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 */
    1020class Core
    1121{
    1222
    1323    /**
     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     *
    1431     * @since 2.4.12
    1532     */
    1633    static function setup()
    1734    {
    18 
     35        // Initialize code type management
    1936        CodeType::init();
     37
     38        // Initialize database-related functionality
    2039        Database::init();
     40
     41        // Initialize user roles and capabilities
    2142        Roles::init();
     43
     44        // Initialize metabox handling for posts
    2245        Metabox::init();
     46
     47        // Initialize asset management for styles and scripts
    2348        AssetManager::init();
     49
     50        // Initialize custom shortcodes for the plugin
    2451        Shortcodes::init();
     52
     53        // Initialize options management
    2554        Options::init();
    26        
    27 
     55
     56        Block::init();
     57
     58        // Hook to load plugins at the plugins_loaded action
    2859        add_action('plugins_loaded', array(__CLASS__, '_load_plugins'));
     60
     61        // Hook to check and handle raw content requests
    2962        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
    3471        if (get_option('ci_unsafe_widgets_shortcodes', 0)) {
     72            // Apply filters to allow shortcodes in widgets
    3573            add_filter('widget_text', 'shortcode_unautop');
    3674            add_filter('widget_text', 'do_shortcode');
    3775        }
    3876
    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
    5095        load_plugin_textdomain("code-injection", FALSE, basename(dirname(__CI_FILE__)) . '/languages/');
    5196    }
     
    5398
    5499    /**
     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
    55107     * @since 2.2.9
    56      * @access private
    57108     */
    58109    static function _load_plugins()
     
    61112        global $wpdb;
    62113
     114        // Check if PHP-based unsafe widgets are allowed
    63115        $use_php = get_option('ci_unsafe_widgets_php', false);
    64116
    65117        if (!$use_php) {
    66             return;
    67         }
    68 
     118            return; // If not allowed, exit early
     119        }
     120
     121        // Check if ignoring keys for unsafe widgets
    69122        $ignore_keys = get_option('ci_unsafe_ignore_keys', false);
    70123
     124        // Get keys that trigger activation
    71125        $keys = get_option('ci_unsafe_keys', '');
    72126
     127        // Retrieve all plugin codes from the database
    73128        $codes = Database::get_codes();
    74129
     130        // Filter and process plugins based on conditions
    75131        $plugins = array_filter($codes, function ($element) use ($ignore_keys, $keys) {
    76132
     
    79135            extract($options);
    80136
     137            // Check if the code is intended to be a plugin
    81138            $is_plugin = isset($code_is_plugin) && $code_is_plugin == '1';
    82139
     140            // Check if the code should be publicly queryable
    83141            $is_public = isset($code_is_publicly_queryable) && $code_is_publicly_queryable == '1';
    84142
    85 
     143            // If code_enabled is not set, default to false
    86144            if (!isset($code_enabled)) {
    87145                $code_enabled = false;
    88146            }
    89147
    90 
     148            // Check the code's status
    91149            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
    96154            if ($is_public) {
    97155                return false;
    98156            }
    99157
    100 
     158            // Skip non-plugin codes or disabled plugins
    101159            if (!$is_plugin || $code_enabled == false) {
    102160                return false;
    103161            }
    104162
     163            // If ignoring keys, include all plugins
    105164            if ($ignore_keys) {
    106165                return true;
    107166            }
    108167
     168            // Check if activator key is in the specified keys
    109169            return isset($code_activator_key) && in_array($code_activator_key, $instance->extract_keys($keys));
    110170        });
    111171
     172
     173        // Execute and enable filtered plugins
    112174        foreach ($plugins as $p) {
    113175
     176            // Get code options and disable the plugin initially
    114177            $code_options = Metabox::get_code_options($p->ID);
    115 
    116178            $code_options['code_enabled'] = false;
    117179
     180            // Update code options to disable the plugin
    118181            update_post_meta($p->ID, "code_options", $code_options);
    119182
     183            // Execute the plugin code using eval()
    120184            eval("?" . ">" . $p->post_content);
    121185
     186            // Enable the plugin in code options
    122187            $code_options['code_enabled'] = true;
    123 
    124188            update_post_meta($p->ID, "code_options", $code_options);
    125189        }
    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
    132202     */
    133203    static function _check_raw_content()
    134204    {
    135205
    136         global $wpdb;
    137 
     206        // Check if the request is on the home page or front page
    138207        if (!is_home() && !is_front_page()) {
    139208            return;
    140209        }
    141210
     211        // Check if "raw" parameter is set in the request
    142212        if (!isset($_GET["raw"])) {
    143213            return;
    144214        }
    145215
    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
    162225            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
    171231        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
    180239        $options = maybe_unserialize($code->meta_value);
    181 
    182240        extract($options);
    183241
    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
    201260        header("Content-Type: $code_content_type; charset=UTF-8", true);
    202261
    203262
    204         if ($no_cache) {
    205 
     263        // Set caching headers based on options
     264        if ($noCache) {
    206265            header("Pragma: no-cache", true);
    207 
    208266            header("Cache-Control: no-cache, must-revalidate, max-age=0", true);
    209 
    210267            header("Expires: Sat, 26 Jul 1997 05:00:00 GMT", true);
    211268        } 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');
    215270            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) {
    225278            exit(do_shortcode($code->post_content));
    226279        } else {
    227 
    228280            exit($code->post_content);
    229281        }
    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
    238297        register_widget(Widget::class);
    239298    }
     
    241300
    242301    /**
    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
    247313        flush_rewrite_rules();
    248314    }
     
    250316
    251317    /**
    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
    256330        flush_rewrite_rules();
    257331
     332        // Delete plugin-related options from the database
    258333        delete_option('ci_code_injection_db_version');
    259334        delete_option('ci_code_injection_role_version');
    260335
     336        // Remove the custom "developer" role
    261337        remove_role('developer');
    262338    }
     339
    263340}
  • code-injection/trunk/includes/class-database.php

    r2939201 r2967476  
    88namespace ci;
    99
    10 use DateInterval;
    11 use DateTime;
    12 
     10
     11use 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 */
    1325class Database
    1426{
    1527
     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     */
    1637    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     */
    1749    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     */
    1861    const db_errors             = array(
    19             '',                                   // 0 no error
    20             'PHP scripts are disabled',           // 1
    21             'Code not found',                     // 2
    22             'Infinite Loop',                      // 3
    23             'An unexpected error occurred',       // 4
    24             'Key not found',                      // 5
    25             'Unauthorized Request',               // 6
     62        '',                                   // 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
    2669    );
    2770
    2871
    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     *
    3384     * @since 2.4.12
    3485     */
    3586    static function init()
    3687    {
     88        // Perform the necessary setup actions, including checking and updating the database
    3789        self::check_db();
    3890    }
     
    4092
    4193
    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     *
    43105     * @since 2.2.6
    44106     */
    45107    private static function check_db()
    46108    {
    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
    54117        }
    55118
     119        // Define the custom table name for storing activity log entries
    56120        $table_name = self::table_activities_name;
    57121
     122        // Get charset collation for creating the table
    58123        $charset_collate = $wpdb->get_charset_collate();
    59124
    60         $sql = "CREATE TABLE $table_name (
     125        // SQL query for creating the custom table with required columns
     126        $sql = "
     127            CREATE TABLE $table_name (
    61128                id mediumint(9) NOT NULL AUTO_INCREMENT,
    62129                blog smallint,
     
    69136                error smallint,
    70137                PRIMARY KEY  (id)
    71                 ) $charset_collate;";
    72 
     138            ) $charset_collate;
     139        ";
     140
     141        // Include necessary WordPress upgrade functions
    73142        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    74143
     144        // Execute the SQL query and update the table schema
    75145        dbDelta($sql);
    76146
    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     *
    83164     * @since 2.4.8
     165     *
     166     * @return array An array of objects containing code snippet post data and metadata.
    84167     */
    85168    static function get_codes()
     
    88171        global $wpdb;
    89172
     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
    90217        $query = "SELECT $wpdb->posts.*, $wpdb->postmeta.*
    91218                FROM $wpdb->posts, $wpdb->postmeta
    92219                WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
    93                 AND $wpdb->postmeta.meta_key = 'code_options'
     220                AND $wpdb->posts.post_title = '$title'
    94221                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     *
    102244     * @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.
    103249     */
    104250    static function get_code_by_slug($slug)
    105251    {
    106 
    107         global $wpdb;
    108 
     252        global $wpdb;
     253
     254        // Construct the SQL query to retrieve the code snippet by slug
    109255        $query = "SELECT $wpdb->posts.*, $wpdb->postmeta.*
    110256                FROM $wpdb->posts, $wpdb->postmeta
     
    115261                LIMIT 1";
    116262
    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) {
    120268            return null;
    121269        }
    122270
    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     *
    128287     * @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).
    129293     */
    130294    static function record_activity($type = 0, $code = null, $error = 0, $id = null)
    131295    {
    132 
    133296        global $wpdb, $post;
    134297
    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) {
    138300            $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
    142303            }
    143304        }
    144305
    145         $ip         = Helpers::get_ip_address();
     306        // Capture essential information for the activity record
     307        $ip = Helpers::get_ip_address();
    146308        $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();
    152313        $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        );
    169332        $count = $wpdb->get_var($query);
    170333
    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
    177337            $wpdb->insert(
    178338                self::table_activities_name,
    179                 [
     339                array(
    180340                    'time'  => $time,
    181341                    'ip'    => $ip,
     
    186346                    'code'  => $code,
    187347                    'error' => $error
    188                 ]
     348                )
    189349            );
    190350        }
     
    193353
    194354
    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     *
    196365     * @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.
    197371     */
    198372    static function get_weekly_report_query($post_id, $start, $end)
    199373    {
    200374
     375        global $wpdb;
     376
    201377        $table_name = self::table_activities_name;
    202378
    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
    204384        $post = get_post($post_id);
    205385        $code = $post->post_title;
    206386
    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
    208430        $start = $start->format('Y-m-d H:i:s');
    209431        $end   = $end->format('Y-m-d H:i:s');
    210432
    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    }
    246448}
  • code-injection/trunk/includes/class-heatmap.php

    r2939201 r2967476  
    88namespace ci;
    99
     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 */
    1017class Heatmap
    1118{
    1219
    13     private $data = [];
    1420
    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');
    1623
     24
     25    /**
     26     * Constructor for initializing the Heatmap with data.
     27     *
     28     * @param array $data An array containing heatmap data.
     29     */
    1730    function __construct($data)
    1831    {
    19 
    2032        $this->data = $data;
    2133    }
    2234
    2335    /**
     36     * Render the heatmap.
     37     *
     38     * This function generates and displays the heatmap visualization based on the provided data.
     39     *
    2440     * @since 2.2.6
    2541     */
    2642    function render()
    2743    {
    28 
     44        // Determine the maximum value for color scaling
    2945        $max = 10;
    30 
    31         if (count($this->data) > 0) {
     46        if (!empty($this->data)) {
    3247            $max = max(array_map(function ($item) {
    3348                return intval($item["total_hits"]);
     
    4156        echo "<div class=\"gdcp-heatmap-container\">";
    4257
     58        // Generate rows for each day of the week
    4359        foreach (range(0, 6) as $weekday) {
    4460
    4561            echo "<div class=\"gdcp-heatmap-row\">";
    4662
     63            // Display the day of the week abbreviation
    4764            if ($weekday % 2 != 0) {
    4865                echo "<span class=\"dow\">{$this->dowmap[$weekday]}</span>";
     
    5168            }
    5269
    53 
     70            // Generate cells for each hour of the day
    5471            foreach (range(0, 24) as $hour) {
    5572
     
    6178
    6279                    $hits = intval($data[0]["total_hits"]);
    63 
    6480                    $plural = $hits > 1;
    6581
     
    6884                    $time = date_i18n("M j, H:i", strtotime($data[0]["time"]));
    6985
    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>";
    8190                } else {
    82 
    8391                    echo "<div class='gdcp-heatmap-cell'></div>";
    8492                }
     
    9199    }
    92100
    93 
    94101    /**
     102     * Generate a visual representation of the heatmap color scale.
     103     *
     104     * @return string A string containing HTML markup for the color scale.
    95105     * @since 2.2.6
    96106     */
    97107    static function map()
    98108    {
    99 
    100109        $result = "<span class=\"gdcp-chart-colors\">";
    101110
    102111        foreach (range(0, 9) as $i) {
    103 
    104112            $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>";
    107114        }
    108115
    109         $result = $result . "</span>";
     116        $result .= "</span>";
    110117
    111118        return $result;
     
    113120
    114121    /**
     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.
    115127     * @since 2.2.6
    116128     */
    117129    static function get_color($value, $max)
    118130    {
    119 
    120131        $h = (1.0 - ($value / $max)) * 240;
    121 
    122132        return "hsl(" . $h . ", 100%, 50%)";
    123133    }
  • code-injection/trunk/includes/class-helpers.php

    r2939201 r2967476  
    66 */
    77
     8
    89namespace ci;
    910
     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 */
    1022class Helpers
    1123{
     
    1325
    1426    /**
     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     *
    1536     * @since 2.4.12
    1637     */
     
    1839    {
    1940
     41        // Check if it's a new code creation page
    2042        if (self::is_edit_page('new')) {
    2143            if (isset($_GET['post_type']) && $_GET['post_type'] == 'code') {
     
    2446        }
    2547
     48        // Check if it's an edit page for an existing code snippet
    2649        if (self::is_edit_page('edit')) {
    27 
    2850            global $post;
    29 
    3051            if ('code' == get_post_type($post)) {
    3152                return true;
    3253            }
    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
    3657        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     *
    4274     * @since 2.4.12
    4375     */
     
    4779        global $pagenow;
    4880
     81        // Check if it's within the admin area
    4982        if (!is_admin()) {
    5083            return false;
    5184        }
    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     *
    66113     * @since 2.4.12
    67114     */
    68115    static function is_settings_page()
    69116    {
    70 
     117        // Define the target settings screen ID
     118        $TARGET_SCREEN_ID = 'ci-general';
     119
     120        // Check if the required function exists
    71121        if (!function_exists('get_current_screen')) {
    72122            return false;
    73123        }
    74124
     125        // Retrieve the current screen object
    75126        $screen = get_current_screen();
    76127
    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     *
    83144     * @since 2.4.12
    84145     */
    85146    static function get_ip_address()
    86147    {
    87 
    88         foreach ([
     148        // List of possible headers and server variables containing the IP address
     149        $ip_sources = [
    89150            'HTTP_CLIENT_IP',
    90151            'HTTP_X_FORWARDED_FOR',
     
    94155            'HTTP_FORWARDED',
    95156            '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) {
    101163                    $ip = trim($ip);
    102164
     165                    // Validate the IP address and exclude private and reserved ranges
    103166                    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"
    105168                    }
    106169                }
    107170            }
    108171        }
    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
    119200}
  • code-injection/trunk/includes/class-metabox.php

    r2939201 r2967476  
    2828    static function init()
    2929    {
    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
    3637     * @since 2.2.8
    3738     */
    38     static function add_meta_box()
     39    static function _add_meta_box()
    3940    {
    4041
     
    5051
    5152    /**
     53     * @access private
    5254     * @since 2.2.8
    5355     */
    54     static function save_post($id)
     56    static function _save_post($id)
    5557    {
    5658
  • code-injection/trunk/includes/class-options.php

    r2939201 r2967476  
    88namespace ci;
    99
     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 */
    1017class Options
    1118{
    1219
    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     *
    1727     * @since 2.4.12
    1828     */
    1929    static function init()
    2030    {
    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.
    2739     * @since 2.4.12
    2840     */
     
    3244    }
    3345
    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.
    3651     * @since 2.4.12
    3752     */
     
    4358    }
    4459
    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    {
    5268        add_submenu_page(
    5369            'options-general.php',
     
    5571            __('Code Injection', 'code-injection'),
    5672            'manage_options',
    57             self::option_group ,
    58             array(__CLASS__ , '_settings_page_cb')
     73            self::option_group,
     74            array(__CLASS__, '_settings_page_cb')
    5975        );
    60 
    61     }
    62 
    63 
    64     /**
     76    }
     77
     78    /**
     79     * Initialize the admin settings and register settings sections and fields.
     80     *
    6581     * @since 2.4.12
    6682     * @access private
     
    6884    static function _admin_init()
    6985    {
    70 
    71         // Settings Section
     86        // Register a settings section
    7287        add_settings_section('wp_code_injection_plugin', "", "__return_false", self::option_group);
    7388
    74         // register code settings
     89        // Register code-related settings
    7590        register_setting(self::option_group, 'ci_code_injection_cache_max_age', ['default' => '84600']);
    76 
    77         // register "CI" settings
    7891        register_setting(self::option_group, 'ci_code_injection_allow_shortcode', ['default' => false]);
    7992
    80         // register "Unsafe" settings
     93        // Register unsafe-related settings
    8194        register_setting(self::option_group, 'ci_unsafe_widgets_shortcodes', ['default' => false]);
    8295        register_setting(self::option_group, 'ci_unsafe_keys', ['default' => '']);
     
    8497        register_setting(self::option_group, 'ci_unsafe_ignore_keys', ['default' => false]);
    8598
    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"));
    88101        self::add_settings_field('ci_code_injection_allow_shortcode', false, esc_html__("Shortcodes", "code-injection"));
    89 
    90102        self::add_settings_field('ci_unsafe_widgets_shortcodes', false);
    91103        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"));
    93105        self::add_settings_field('ci_unsafe_keys');
    94106    }
     
    97109
    98110    /**
    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     *
    108116     * @since 2.4.12
    109117     * @access private
     
    133141
    134142    /**
    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
    136155     */
    137156    private static function add_settings_field($id, $default = '', $title = '', $section = 'wp_code_injection_plugin', $page = self::option_group)
     
    142161
    143162    /**
     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.
    144171     * @since 2.4.12
    145172     */
     
    150177
    151178
    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.
    153186     * @since 2.4.12
    154187     * @access private
     
    157190    {
    158191
    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);
    162195
    163196        switch ($key) {
    164 
    165197            case 'ci_code_injection_cache_max_age':
    166 
    167198                printf('<p>%1$s</p>', esc_html__('Cache max-age (Seconds)', 'code-injection'));
    168199                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.&nbsp;&nbsp;&nbsp;&nbsp;%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;
    173202            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.&nbsp;&nbsp;&nbsp;&nbsp;key-2im2a5ex4,&nbsp;&nbsp;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;
    181209            case 'ci_code_injection_allow_shortcode':
    182 
    183210                self::checkbox($key, $value, esc_html__("Allow nested shortcodes", "code-injection"));
    184 
    185                 break;
    186 
     211                break;
    187212            case 'ci_unsafe_ignore_keys':
    188 
    189213                self::checkbox($key, $value, esc_html__("Ignore activator keys", "code-injection"));
    190 
    191                 break;
    192 
     214                break;
    193215            case 'ci_unsafe_widgets_shortcodes':
    194 
    195216                self::checkbox($key, $value, esc_html__("Allow shortcodes in the Custom HTML widget", "code-injection"));
    196 
    197                 break;
    198 
     217                break;
    199218            case 'ci_unsafe_widgets_php':
    200 
    201219                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>',
    205221                    sprintf(
    206222                        esc_html__('See %1$s for more information.', "code-injection"),
     
    212228                    )
    213229                );
    214 
    215230                break;
    216231        }
  • code-injection/trunk/includes/class-roles.php

    r2939201 r2967476  
    88namespace ci;
    99
     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 */
    1018class Roles
    1119{
     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    }
    1232
    1333    /**
     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     *
    1440     * @since 2.4.12
    1541     */
    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');
    2047
     48        // Get the stored role version from options
     49        $roleVersion = get_option('ci_role_version', '');
    2150
    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
    3454            return;
    3555        }
    3656
    37 
     57        // Remove the existing 'Developer' role if it exists
    3858        remove_role('developer');
    3959
    40 
     60        // Add the 'Developer' role with specific capabilities
    4161        add_role(
    4262            'developer',
    4363            esc_html__('Developer', "code-injection"),
    44             [
     64            array(
    4565                'read' => true,
    4666                'edit_posts' => false,
     
    4868                'publish_posts' => false,
    4969                'upload_files' => true,
    50             ]
     70            )
    5171        );
    5272
     73        // Update the stored role version to the current version
     74        update_option('ci_role_version', __CI_VERSION__);
    5375
    54         update_option('ci_role_version', __CI_VERSION__);
    5576    }
    5677
     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');
    5791
    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);
    6496
    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
    72100                continue;
    73101            }
    74102
    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',
    78107                '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");
    82117            }
    83118        }
    84119    }
    85 
    86 
    87120}
  • code-injection/trunk/includes/class-shortcodes.php

    r2943916 r2967476  
    154154
    155155        if (!empty($id)) {
    156             $code = get_page_by_title($id, OBJECT, 'code');
     156            $code = Database::get_code_by_title($id);
    157157        } else {
    158158            $code = Database::get_code_by_slug($slug);
  • code-injection/trunk/includes/class-widget.php

    r2943916 r2967476  
    1010use WP_Widget;
    1111
     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 */
    1223class Widget extends WP_Widget
    1324{
    1425
    1526    /**
    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
    1732     */
    1833    function __construct()
     
    2136            'wp_code_injection_plugin_widget',
    2237            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            )
    2441        );
    2542    }
     
    2744
    2845    /**
     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     *
    2953     * @since 0.9.0
    3054     */
    3155    function widget($args, $instance)
    3256    {
    33         $title = apply_filters('widget_title', $instance['title']);
     57        $title = apply_filters('widget_title', isset( $instance['title'] ) ? $instance['title'] : '0');
    3458
    35         if ($title == '0') {
    36             return;
     59        if ($title !== '0') {
     60            echo do_shortcode("[inject id='$title']");
    3761        }
    38 
    39         //output
    40         echo do_shortcode("[inject id='$title']");
    4162    }
    4263
    4364
    4465    /**
     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     *
    4572     * @since 0.9.0
    4673     */
     
    4875    {
    4976
    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();
    5379
    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);
    5891        }
    5992
    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');
    6196
    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);
    8398    }
    8499
    85100
    86    
     101
    87102    /**
     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     *
    88112     * @since 0.9.0
    89113     */
     
    91115    {
    92116        $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']) : '';
    94118        return $instance;
    95119    }
  • code-injection/trunk/readme.txt

    r2943916 r2967476  
    33Tags: code, snippets, injection
    44Requires at least: 4.5.0
    5 Tested up to: 6.2.2
    6 Stable tag: 2.4.13
     5Tested up to: 6.3.1
     6Stable tag: 2.4.14
    77License: MIT License
    88License URI: https://github.com/Rmanaf/wp-code-injection/blob/master/LICENSE
Note: See TracChangeset for help on using the changeset viewer.