Initial commit of 0.2.0

This commit is contained in:
Cooper Dalrymple
2025-07-22 15:53:23 -05:00
parent 58a5fbbcb2
commit 70a9adac4c
13 changed files with 775 additions and 3 deletions

73
inc/filter.php Normal file
View File

@@ -0,0 +1,73 @@
<?php
/**
* @package ogre-obfuscation
* @author cleverogre
* @version 0.2.0
* @since 0.1.0
*/
namespace Ogre\Obfuscation;
use Ogre\Singleton;
use Ogre\Obfuscation;
defined('ABSPATH') || exit;
final class Filter {
use Singleton;
protected function __construct() {
add_action('wp', array($this, 'init'));
}
public function init() {
if (!email_enabled()) return;
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('the_content', array($this, 'filter_content'), 100, 1);
add_filter('wp_nav_menu_items', array($this, 'filter_content'), 100, 1);
add_filter('dynamic_sidebar_params', array($this, 'sidebar_params'), 100, 1);
add_filter('widget_output', array($this, 'filter_content'), 100, 1);
}
public function enqueue_scripts() {
wp_enqueue_script('obfuscation', Obfuscation::get_url('assets/js/obfuscation.js'), array(), Obfuscation::get_version(), true);
}
public function filter_content($content) {
if (!find_emails($content)) return $content;
return filter($content);
}
public function sidebar_params($params) {
global $wp_registered_widgets;
$widget_id = $params[0]['widget_id'];
$wp_registered_widgets[$widget_id]['_callback'] = $wp_registered_widgets[$widget_id]['callback'];
$wp_registered_widgets[$widget_id]['callback'] = array($this, 'widget_callback');
return $params;
}
public function widget_callback() {
global $wp_registered_widgets;
$params = func_get_args();
$widget_id = $params[0]['widget_id'];
$callback = $wp_registered_widgets[$widget_id]['_callback'];
$wp_registered_widgets[$widget_id]['callback'] = $callback;
$widget_id_base = $wp_registered_widgets[$widget_id]['callback'][0]->id_base;
if (is_callable($callback)) {
ob_start();
call_user_func_array($callback, $params);
$widget_output = ob_get_clean();
echo apply_filters('widget_output', $widget_output, $widget_id_base, $widget_id);
}
}
}
Filter::instance();

154
inc/global.php Normal file
View File

@@ -0,0 +1,154 @@
<?php
/**
* @package ogre-obfuscation
* @author cleverogre
* @version 0.2.0
* @since 0.1.0
*/
namespace Ogre\Obfuscation;
use simplehtmldom\HtmlDocument;
use function is_user_logged_in;
defined('ABSPATH') || exit;
function email_enabled() {
if (is_user_logged_in()) return false;
if (Settings::instance()->email_enabled != '1') return false;
return true;
}
function obfuscate($str) {
static $obfuscate_id = 0;
$out = '';
for ($i = 0; $i < strlen($str); $i++) {
$out .= '&#' . ord(substr($str, $i, 1)) . ';';
}
$out2 = '';
for ($i = 0; $i < strlen($out); $i++) {
$out2 = substr($out, $i, 1) . $out2;
}
$output = "<span class=\"obfuscate\" id=\"obfuscate-{$obfuscate_id}\" data-content=\"{$out2}\"></span>";
$obfuscate_id++;
return $output;
}
function _obfuscate_element($element) {
return obfuscate($element->outertext);
}
function find_emails($str) {
preg_match_all('/[a-zA-Z0-9_\-\+\.]+@[a-zA-Z0-9\-]+\.([a-z]{2,4})(?:\.[a-z]{2})?/i', $str, $matches, PREG_OFFSET_CAPTURE);
if (!is_array($matches) || empty($matches)) return false;
$return = array();
foreach ($matches[0] as $match) {
$return[] = array(
'text' => $match[0],
'pos' => $match[1],
'len' => strlen($match[0]),
);
}
return $return;
}
function filter($content) {
// Parse content
$html = new HtmlDocument();
$html->load('<div id="dom_root">' . $content . '</div>');
//_filter_html($html->find('div[id=dom_root]', 0));
$html->find('div[id=dom_root]', 0)->outertext = _filter_html($html->find('div[id=dom_root]', 0));
$html->find('div[id=dom_root]', 0)->outertext = $html->find('div[id=dom_root]', 0)->innertext; // remove root div wrapper
$content = $html->save();
// Clean up memory
$html->clear();
unset($html);
return $content;
}
function _filter_html($element) {
if ($element == null) return false;
switch ($element->tag) {
case 'a':
if (_test_anchor($element)) {
return _obfuscate_element($element);
} else {
return $element->outertext;
}
default:
$node = _get_text_node($element);
$node['text'] = _filter_text($node['text']);
foreach ($node['tags'] as &$tag) {
$tag['content'] = _filter_html($tag['element']);
}
$element->outertext = _set_text_node($node);
return $element->outertext;
}
}
function _filter_text($text) {
$emails = find_emails($text);
if (!$emails) return $text;
for ($i = count($emails) - 1; $i >= 0; $i--) {
$text = substr($text, 0, $emails[$i]['pos']) . obfuscate($emails[$i]['text']) . substr($text, $emails[$i]['pos'] + $emails[$i]['len']);
}
return $text;
}
function _get_text_node($element) {
//$tag_pattern = '/<\s*[a-zA-Z]+[^>]*>.*?<\s*\/\s*[a-zA-Z]+>/is'
$text = $element->outertext;
$return = array(
'raw' => $text,
'text' => '',
'tags' => array(),
);
$i = 0;
foreach ($element->children() as $child) {
$return['tags'][$i] = array(
'element' => $child,
'index' => $i,
'key' => "[[{$i}]]",
'content' => $child->outertext,
'pos' => strpos($text, $child->outertext),
'len' => strlen($child->outertext),
);
$text = str_replace($child->outertext, "[[{$i}]]", $text);
$i++;
}
$return['text'] = $text;
return $return;
}
function _set_text_node($node) {
$text = $node['text'];
foreach ($node['tags'] as $tag) {
$text = str_replace($tag['key'], $tag['content'], $text);
}
return $text;
}
function _test_anchor($element) {
if ($element->tag != 'a') return false;
return preg_match('/<a.*>[a-zA-Z0-9_\-\+\.]+@[a-zA-Z0-9\-]+\.([a-z]{2,4})(?:\.[a-z]{2})?<\/a>/i', $element->outertext) == 1;
}

208
inc/settings.php Normal file
View File

@@ -0,0 +1,208 @@
<?php
/**
* @package ogre-obfuscation
* @author cleverogre
* @version 0.2.0
* @since 0.1.0
*/
namespace Ogre\Obfuscation;
use Ogre\Singleton;
defined('ABSPATH') || exit;
final class Settings {
use Singleton;
private $defaults; // Value set in get function
// Admin Settings
public $email_enabled;
protected function __construct() {
// Use getter/setter if not set
foreach ($this as $key => $value) {
unset($this->$key);
}
}
public function __set($key, $value) {
if (property_exists($this, $key)) {
switch ($key) {
/* // Read-only properties
case 'readonly':
break;
*/
default:
$options = get_option('obfuscation_options');
$options['obfuscation_settings_' . $key] = $value;
update_option('obfuscation_options', $options);
break;
}
}
return $this;
}
public function __get($key) {
if (property_exists($this, $key)) {
switch ($key) {
// Constant properties
case 'defaults':
return array(
'email_enabled' => '1',
);
break;
default:
$options = get_option('obfuscation_options');
if (isset($options['obfuscation_settings_' . $key]) && !empty($options['obfuscation_settings_' . $key])) {
return $options['obfuscation_settings_' . $key];
} else if (isset($this->defaults[$key])) {
return $this->defaults[$key];
} else {
return false;
}
break;
}
}
return null;
}
}
final class SettingsPage {
use Singleton;
protected function __construct() {
add_action('admin_init', array($this, 'init'));
add_action('admin_menu', array($this, 'menu'));
}
public function menu() {
if (!current_user_can('manage_options')) return;
$page = add_options_page(__('Ogre Obfuscation Settings', 'obfuscation'), __('Ogre Obfuscation', 'obfuscation'), 'manage_options', 'obfuscation_settings', array($this, 'page'));
add_action('load-' . $page, array($this, 'load'));
}
public function load() {
if (!current_user_can('manage_options')) return;
add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
}
public function admin_enqueue_scripts() {
//wp_enqueue_script('obfuscation-admin', Settings::instance()->dir . 'assets/js/obfuscation.admin.js', array('jquery'), Settings::instance()->version, true);
}
public function init() {
register_setting('obfuscation', 'obfuscation_options'); //, array($this, 'validate_options'));
// Message Settings
add_settings_section('obfuscation_section_obfuscation', __('Obfuscation', 'obfuscation'), array($this, 'section'), 'obfuscation');
add_settings_field('obfuscation_email_enabled', __('Email Obfuscation Enabled', 'obfuscation'), array($this, 'field_checkbox'), 'obfuscation', 'obfuscation_section_obfuscation', array(
'id' => 'obfuscation_settings_email_enabled',
'default' => Settings::instance()->defaults['email_enabled'],
));
}
public function page() {
if (!current_user_can('manage_options')) return;
// Check if the user has submitted the settings
if (isset($_GET['settings-updated'])) {
// Show update message
//add_settings_error('obfuscation_messages', 'obfuscation_message', __('Settings Saved', 'obfuscation'), 'updated');
}
// Show error/update messages
settings_errors('obfuscation_messages');
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<form action="options.php" method="post"><?php
settings_fields('obfuscation');
do_settings_sections('obfuscation');
submit_button(__('Save Settings', 'obfuscation'));
?></form>
</div>
<?php
}
// Sections
public function section($args) {
// <p>Description</p>
}
// Fields
public function field_text($args) {
$value = '';
$options = get_option('obfuscation_options');
if (isset($args['default'])) $value = $args['default'];
if (isset($args['id']) && !empty($args['id']) && isset($options[$args['id']]) && !empty($options[$args['id']])) $value = $options[$args['id']];
$type = 'text';
if (isset($args['type']) && !empty($args['type'])) {
$type = $args['type'];
}
echo '<input class="regular-text" type="' . $type . '" value="' . esc_attr($value) . '"';
if (isset($args['id']) && !empty($args['id'])) {
echo ' id="' . esc_attr($args['id']) . '"';
echo ' name="obfuscation_options[' . esc_attr($args['id']) . ']"';
}
if (isset($args['placeholder']) && !empty($args['placeholder'])) {
echo ' placeholder="' . esc_attr($args['placeholder']) . '"';
}
echo ' />';
if (isset($args['description']) && !empty($args['description'])) {
echo '<p class="description">';
_e($args['description'], 'obfuscation');
echo '</p>';
}
}
public function field_checkbox($args) {
$value = false;
$options = get_option('obfuscation_options');
if (isset($args['default'])) $value = $args['default'];
if (isset($args['id']) && !empty($args['id']) && isset($options[$args['id']]) && !empty($options[$args['id']])) $value = $options[$args['id']];
echo '<input type="checkbox" value="1" type="checkbox" ' . checked($value, 1, false);
if (isset($args['id']) && !empty($args['id'])) {
echo ' id="' . esc_attr($args['id']) . '"';
echo ' name="obfuscation_options[' . esc_attr($args['id']) . ']"';
}
echo ' />';
if (isset($args['description']) && !empty($args['description'])) {
echo '<p class="description">';
esc_html_e($args['description'], 'obfuscation');
echo '</p>';
}
}
public function validate_options($fields) {
$valid_fields = array();
foreach ($fields as $id => $field) {
if (!isset($input[$id])) continue;
}
return apply_filters('validate_options', $valid_fields, $fields);
}
}
SettingsPage::instance();