added additional plugins

This commit is contained in:
Rodolfo Martinez 2025-12-12 19:05:48 -05:00
parent c85895d306
commit 00e60ec1b7
132 changed files with 27514 additions and 0 deletions

View file

@ -0,0 +1,286 @@
<?php
/**
* Plugin Name: Maple Code Blocks
* Plugin URI: https://sspmedia.ca/wordpress/
* Description: Display code files from GitHub, GitLab, Bitbucket, and Codeberg repositories in a beautiful, safe terminal/IDE-style view
* Version: 2.0.0
* Author: SSP Media
* Author URI: https://sspmedia.ca/wordpress/
* License: GPL v2 or later
* Text Domain: maple-code-blocks
*/
// Prevent direct access
if (!defined('WPINC')) {
die('Direct access not permitted.');
}
if (!defined('ABSPATH')) {
exit;
}
// Define plugin constants
define('MCB_PLUGIN_URL', plugin_dir_url(__FILE__));
define('MCB_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('MCB_PLUGIN_VERSION', '2.0.0');
define('MCB_PLUGIN_BASENAME', plugin_basename(__FILE__));
// Include required files
require_once MCB_PLUGIN_PATH . 'includes/class-security.php';
require_once MCB_PLUGIN_PATH . 'includes/class-security-fixes.php';
require_once MCB_PLUGIN_PATH . 'includes/class-privacy-manager.php';
require_once MCB_PLUGIN_PATH . 'includes/class-github-api.php';
require_once MCB_PLUGIN_PATH . 'includes/class-code-renderer.php';
require_once MCB_PLUGIN_PATH . 'includes/class-shortcode.php';
require_once MCB_PLUGIN_PATH . 'includes/class-simple-block.php';
require_once MCB_PLUGIN_PATH . 'includes/basic-block.php';
// require_once MCB_PLUGIN_PATH . 'includes/class-block-editor.php';
// require_once MCB_PLUGIN_PATH . 'includes/class-block-patterns.php';
// Initialize plugin
class Maple_Code_Blocks {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
add_action('init', array($this, 'init'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('wp_ajax_mcb_load_file', array($this, 'ajax_load_file'));
add_action('wp_ajax_nopriv_mcb_load_file', array($this, 'ajax_load_file'));
add_action('wp_ajax_mcb_get_repo_files', array($this, 'ajax_get_repo_files'));
add_action('wp_ajax_nopriv_mcb_get_repo_files', array($this, 'ajax_get_repo_files'));
}
public function init() {
// Initialize shortcode
MCB_Shortcode::init();
// Simple block is self-initializing via class-simple-block.php
// Add admin menu if needed
if (is_admin()) {
add_action('admin_menu', array($this, 'add_admin_menu'));
}
}
public function enqueue_scripts() {
// Load styles
wp_enqueue_style('prism-css', MCB_PLUGIN_URL . 'assets/css/prism.css', array(), MCB_PLUGIN_VERSION);
wp_enqueue_style('mcb-styles', MCB_PLUGIN_URL . 'assets/css/mcb-styles.css', array(), MCB_PLUGIN_VERSION);
// Load scripts
wp_enqueue_script('prism-core', MCB_PLUGIN_URL . 'assets/js/prism.js', array(), MCB_PLUGIN_VERSION, true);
wp_enqueue_script('mcb-script', MCB_PLUGIN_URL . 'assets/js/mcb-script.js', array('jquery'), MCB_PLUGIN_VERSION, true);
// Localize script for AJAX
wp_localize_script('mcb-script', 'mcb_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('mcb_ajax_nonce')
));
}
public function ajax_load_file() {
// Check request method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
wp_die('Invalid request method', 405);
}
// Rate limiting check
if (class_exists('MCB_Privacy_Manager') && MCB_Privacy_Manager::is_privacy_mode()) {
// Use nonce-based rate limiting in privacy mode
$rate_limit_key = 'mcb_rate_' . wp_get_current_user()->ID . '_' . wp_create_nonce('mcb_rate');
} else {
// IP-based rate limiting
$user_ip = $this->get_client_ip();
$rate_limit_key = 'mcb_rate_' . md5($user_ip);
}
$requests = get_transient($rate_limit_key);
if ($requests !== false && $requests > 30) { // 30 requests per minute
wp_die('Rate limit exceeded. Please try again later.', 429);
}
set_transient($rate_limit_key, ($requests ? $requests + 1 : 1), 60);
// Verify nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'mcb_ajax_nonce')) {
wp_die('Security check failed', 403);
}
// Note: We allow public viewing of public repositories by default
// Site admins can restrict access if needed via filter
$require_login = apply_filters('mcb_require_login_for_viewing', false);
if ($require_login && !is_user_logged_in()) {
wp_die('Please log in to view code repositories', 403);
}
$repo = isset($_POST['repo']) ? sanitize_text_field($_POST['repo']) : '';
$file_path = isset($_POST['file_path']) ? sanitize_text_field($_POST['file_path']) : '';
// Additional validation using security class
if (!MCB_Security::validate_repo_format($repo)) {
MCB_Security::log_security_event('invalid_repo_format', array('repo' => $repo));
wp_send_json_error('Invalid repository format');
return;
}
if (!MCB_Security::validate_file_path($file_path)) {
MCB_Security::log_security_event('invalid_file_path', array('path' => $file_path));
wp_send_json_error('Invalid file path');
return;
}
$github_api = new MCB_GitHub_API();
$content = $github_api->get_file_content($repo, $file_path);
if (is_wp_error($content)) {
wp_send_json_error($content->get_error_message());
return;
}
// Validate content before sending
$renderer = new MCB_Code_Renderer();
$validation = $renderer->validate_content($content);
if (is_wp_error($validation)) {
wp_send_json_error($validation->get_error_message());
return;
}
// Return raw content - JavaScript will handle escaping and rendering
// This is more secure as it avoids double-escaping issues
wp_send_json_success(array(
'content' => $content, // Send raw content, not rendered HTML
'filename' => basename($file_path)
));
}
public function ajax_get_repo_files() {
// Check request method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
wp_die('Invalid request method', 405);
}
// Rate limiting check
$user_ip = $this->get_client_ip();
$rate_limit_key = 'mcb_rate_' . md5($user_ip);
$requests = get_transient($rate_limit_key);
if ($requests !== false && $requests > 30) { // 30 requests per minute
wp_die('Rate limit exceeded. Please try again later.', 429);
}
set_transient($rate_limit_key, ($requests ? $requests + 1 : 1), 60);
// Verify nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'mcb_ajax_nonce')) {
wp_die('Security check failed', 403);
}
// Note: We allow public viewing of public repositories by default
// Site admins can restrict access if needed via filter
$require_login = apply_filters('mcb_require_login_for_viewing', false);
if ($require_login && !is_user_logged_in()) {
wp_die('Please log in to view code repositories', 403);
}
$repo = isset($_POST['repo']) ? sanitize_text_field($_POST['repo']) : '';
$path = isset($_POST['path']) ? sanitize_text_field($_POST['path']) : '';
// Validate repository format
if (!MCB_Security::validate_repo_format($repo)) {
wp_send_json_error('Invalid repository format');
return;
}
$github_api = new MCB_GitHub_API();
$files = $github_api->get_repository_files($repo, $path);
if (is_wp_error($files)) {
wp_send_json_error($files->get_error_message());
return;
}
wp_send_json_success($files);
}
public function add_admin_menu() {
add_options_page(
'GitHub Code Viewer Settings',
'GitHub Code Viewer',
'manage_options',
'maple-code-blocks',
array($this, 'admin_page')
);
}
public function admin_page() {
include MCB_PLUGIN_PATH . 'admin/settings-page.php';
}
/**
* Get client IP address for rate limiting
*/
private function get_client_ip() {
$ip_keys = array('HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
foreach ($ip_keys as $key) {
if (array_key_exists($key, $_SERVER) === true) {
$ips = explode(',', $_SERVER[$key]);
foreach ($ips as $ip) {
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP,
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
return $ip;
}
}
}
}
return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
}
}
// Initialize the plugin
Maple_Code_Blocks::get_instance();
// Register deactivation hook to clean up scheduled events
register_deactivation_hook(__FILE__, 'mcb_deactivate');
function mcb_deactivate() {
// Remove scheduled cleanup event
$timestamp = wp_next_scheduled('mcb_privacy_cleanup');
if ($timestamp) {
wp_unschedule_event($timestamp, 'mcb_privacy_cleanup');
}
// Clear all MCB transients
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mcb_%'");
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_mcb_%'");
}
// Register uninstall hook for complete cleanup
register_uninstall_hook(__FILE__, 'mcb_uninstall');
function mcb_uninstall() {
// Remove all plugin options
delete_option('mcb_settings');
delete_option('mcb_github_token_encrypted');
delete_option('mcb_gitlab_token_encrypted');
delete_option('mcb_bitbucket_token_encrypted');
delete_option('mcb_codeberg_token_encrypted');
// Clear all transients
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mcb_%'");
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_mcb_%'");
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_site_transient_mcb_%'");
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_site_transient_timeout_mcb_%'");
}