lelms-copyright/lelms-copyright.php
2025-04-07 11:51:54 +08:00

632 lines
29 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Plugin Name: LeLMS Copyright
* Plugin URI: https://wenpai.org/plugins/lelms-copyright
* Description: Adds watermark with username and prevents unauthorized screenshots
* Version: 1.1.7
* Author: LeLMS.com
* Author URI: https://lelms.com
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Requires at least: 5.9
* Requires PHP: 7.4
* Text Domain: lelms-copyright
* Domain Path: /languages
*/
if (!defined('ABSPATH')) {
exit;
}
define('LELMS_COPYRIGHT_VERSION', '1.1.7');
define('LELMS_COPYRIGHT_DIR_URL', plugin_dir_url(__FILE__));
define('LELMS_COPYRIGHT_DIR_PATH', plugin_dir_path(__FILE__));
define('LELMS_COPYRIGHT_BASENAME', plugin_basename(__FILE__));
class LELMS_Copyright {
private $options;
public function __construct() {
load_plugin_textdomain('lelms-copyright', false, dirname(plugin_basename(__FILE__)) . '/languages/');
$defaults = array(
'watermark_opacity' => 0.1,
'watermark_size' => 20,
'watermark_spacing' => 150,
'watermark_color' => '#000000',
'watermark_angle' => -45,
'enable_devtools_protection' => 'yes',
'enable_print_protection' => 'yes',
'enable_copy_protection' => 'yes',
'enable_for_guests' => 'no',
'enable_guest_protection_only' => 'no',
'enable_guest_custom_watermark' => 'no',
'enable_custom_watermark' => 'no',
'custom_watermark_text' => '',
'watermark_type' => 'username',
'excluded_post_types' => array(),
'excluded_roles' => array(),
);
$current_options = get_option('lelms_copyright_options', false);
if ($current_options === false) {
update_option('lelms_copyright_options', $defaults);
$this->options = $defaults;
} else {
$this->options = wp_parse_args($current_options, $defaults);
}
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
if (did_action('wp_body_open')) {
add_action('wp_body_open', array($this, 'add_watermark_container'));
} else {
add_action('wp_footer', array($this, 'add_watermark_container'));
}
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_init', array($this, 'register_settings'));
add_action('wp_ajax_lelms_reset_options', array($this, 'reset_options'));
}
public function add_admin_menu() {
add_options_page(
__('LeLMS Copyright Settings', 'lelms-copyright'),
__('Copyright', 'lelms-copyright'),
'manage_options',
'lelms-copyright',
array($this, 'options_page')
);
}
public function register_settings() {
if (!isset($_GET['page']) || $_GET['page'] !== 'lelms-copyright') {
return;
}
register_setting('lelms_copyright', 'lelms_copyright_options', array($this, 'sanitize_options'));
add_settings_section(
'lelms_copyright_section',
__('Watermark Settings', 'lelms-copyright'),
array($this, 'section_description'),
'lelms-copyright'
);
add_settings_section(
'lelms_copyright_advanced_section',
__('Advanced Settings', 'lelms-copyright'),
array($this, 'advanced_section_description'),
'lelms-copyright-advanced'
);
$this->add_settings_fields();
}
public function section_description() {
echo '<p>' . esc_html__('Customize the watermark appearance and protection settings to secure your content.', 'lelms-copyright') . '</p>';
}
public function advanced_section_description() {
echo '<p>' . esc_html__('Configure advanced options to exclude specific post types or user roles from watermark and protection.', 'lelms-copyright') . '</p>';
}
public function sanitize_options($input) {
$sanitized = array();
$defaults = array(
'watermark_opacity' => 0.1,
'watermark_size' => 20,
'watermark_spacing' => 150,
'watermark_color' => '#000000',
'watermark_angle' => -45,
'enable_devtools_protection' => 'yes',
'enable_print_protection' => 'yes',
'enable_copy_protection' => 'yes',
'enable_for_guests' => 'no',
'enable_guest_protection_only' => 'no',
'enable_guest_custom_watermark' => 'no',
'enable_custom_watermark' => 'no',
'custom_watermark_text' => '',
'watermark_type' => 'username',
'excluded_post_types' => array(),
'excluded_roles' => array(),
);
$sanitized['watermark_opacity'] = min(max(floatval($input['watermark_opacity']), 0), 1);
$sanitized['watermark_size'] = absint($input['watermark_size']);
$sanitized['watermark_spacing'] = absint($input['watermark_spacing']);
$sanitized['watermark_color'] = sanitize_hex_color($input['watermark_color']);
$sanitized['watermark_angle'] = intval($input['watermark_angle']);
$sanitilized['enable_devtools_protection'] = isset($input['enable_devtools_protection']) && $input['enable_devtools_protection'] === 'yes' ? 'yes' : 'no';
$sanitized['enable_print_protection'] = isset($input['enable_print_protection']) && $input['enable_print_protection'] === 'yes' ? 'yes' : 'no';
$sanitized['enable_copy_protection'] = isset($input['enable_copy_protection']) && $input['enable_copy_protection'] === 'yes' ? 'yes' : 'no';
$sanitized['enable_for_guests'] = isset($input['enable_for_guests']) && $input['enable_for_guests'] === 'yes' ? 'yes' : 'no';
$sanitized['enable_guest_protection_only'] = isset($input['enable_guest_protection_only']) && $input['enable_guest_protection_only'] === 'yes' ? 'yes' : 'no';
$sanitized['enable_guest_custom_watermark'] = isset($input['enable_guest_custom_watermark']) && $input['enable_guest_custom_watermark'] === 'yes' ? 'yes' : 'no';
$sanitized['enable_custom_watermark'] = isset($input['enable_custom_watermark']) && $input['enable_custom_watermark'] === 'yes' ? 'yes' : 'no';
$sanitized['custom_watermark_text'] = sanitize_text_field($input['custom_watermark_text']);
$sanitized['watermark_type'] = in_array($input['watermark_type'], ['username', 'nickname', 'email', 'timestamp']) ? $input['watermark_type'] : 'username';
$sanitized['excluded_post_types'] = array_map('sanitize_key', (array) $input['excluded_post_types']);
$sanitized['excluded_roles'] = array_map('sanitize_key', (array) $input['excluded_roles']);
return wp_parse_args($sanitized, $defaults);
}
public function should_apply_protection() {
$enable_for_guests = $this->options['enable_for_guests'] === 'yes';
if (!is_user_logged_in() && !$enable_for_guests) {
return false;
}
$user = wp_get_current_user();
$user_roles = $user && $user->roles ? $user->roles : array('guest');
if (array_intersect($user_roles, (array) $this->options['excluded_roles'])) {
return false;
}
$post_type = get_post_type() ?: 'page';
if (in_array($post_type, (array) $this->options['excluded_post_types'])) {
return false;
}
return true;
}
public function should_apply_watermark() {
if (!$this->should_apply_protection()) {
return false;
}
$is_guest = !is_user_logged_in();
if ($is_guest) {
return $this->options['enable_for_guests'] === 'yes' && $this->options['enable_guest_custom_watermark'] === 'yes';
} else {
return true;
}
}
public function add_watermark_container() {
if ($this->should_apply_watermark()) {
echo '<div id="lelms-watermark"></div>';
}
}
private function add_settings_fields() {
$fields = array(
'watermark_opacity' => array(
'title' => __('Watermark Opacity', 'lelms-copyright'),
'type' => 'number',
'attrs' => 'step="0.1" min="0" max="1"',
'description' => __('Set the transparency of the watermark (0 = fully transparent, 1 = fully opaque).', 'lelms-copyright')
),
'watermark_size' => array(
'title' => __('Watermark Size (px)', 'lelms-copyright'),
'type' => 'number',
'description' => __('Define the font size of the watermark text in pixels.', 'lelms-copyright')
),
'watermark_spacing' => array(
'title' => __('Watermark Spacing (px)', 'lelms-copyright'),
'type' => 'number',
'description' => __('Set the distance between each watermark in pixels.', 'lelms-copyright')
),
'watermark_color' => array(
'title' => __('Watermark Color', 'lelms-copyright'),
'type' => 'color',
'description' => __('Choose the color of the watermark text.', 'lelms-copyright')
),
'watermark_angle' => array(
'title' => __('Watermark Angle', 'lelms-copyright'),
'type' => 'number',
'description' => __('Set the rotation angle of the watermark text in degrees (e.g., -45 for diagonal).', 'lelms-copyright')
),
'watermark_type' => array(
'title' => __('Watermark Type', 'lelms-copyright'),
'type' => 'select',
'description' => __('Choose the type of watermark to display for logged-in users (overridden by custom watermark if enabled).', 'lelms-copyright'),
'options' => array(
'username' => __('Username', 'lelms-copyright'),
'nickname' => __('Nickname', 'lelms-copyright'),
'email' => __('Email', 'lelms-copyright'),
'timestamp' => __('Timestamp', 'lelms-copyright'),
),
),
'enable_devtools_protection' => array(
'title' => __('Enable DevTools Protection', 'lelms-copyright'),
'type' => 'checkbox',
'description' => __('Prevent users from opening browser developer tools (e.g., F12 or Ctrl+Shift+I).', 'lelms-copyright')
),
'enable_print_protection' => array(
'title' => __('Enable Print Protection', 'lelms-copyright'),
'type' => 'checkbox',
'description' => __('Block printing of the page to protect your content.', 'lelms-copyright')
),
'enable_copy_protection' => array(
'title' => __('Enable Copy Protection', 'lelms-copyright'),
'type' => 'checkbox',
'description' => __('Disable copying of text and right-click menus outside of form fields.', 'lelms-copyright')
),
'enable_for_guests' => array(
'title' => __('Enable Guest Mode', 'lelms-copyright'),
'type' => 'checkbox',
'description' => __('Enable protection features for non-logged-in users. Additional options will appear when checked.', 'lelms-copyright')
),
'enable_guest_protection_only' => array(
'title' => __('Enable Protection Only for Guests', 'lelms-copyright'),
'type' => 'checkbox',
'description' => __('Apply only protection features (no watermark) to non-logged-in users.', 'lelms-copyright')
),
'enable_guest_custom_watermark' => array(
'title' => __('Show Custom Watermark for Guests', 'lelms-copyright'),
'type' => 'checkbox',
'description' => __('Display the custom watermark text (defined below) for non-logged-in users.', 'lelms-copyright')
),
'enable_custom_watermark' => array(
'title' => __('Enable Custom Watermark', 'lelms-copyright'),
'type' => 'checkbox',
'description' => __('Use a custom watermark text instead of the selected watermark type.', 'lelms-copyright')
),
'custom_watermark_text' => array(
'title' => __('Custom Watermark Text', 'lelms-copyright'),
'type' => 'text',
'description' => __('Enter custom watermark text (applies if "Enable Custom Watermark" or "Show Custom Watermark for Guests" is checked). If empty, "LeLMS Copyright" will be used.', 'lelms-copyright')
),
);
foreach ($fields as $key => $field) {
add_settings_field(
$key,
$field['title'],
array($this, 'render_field'),
'lelms-copyright',
'lelms_copyright_section',
array(
'key' => $key,
'type' => $field['type'],
'attrs' => isset($field['attrs']) ? $field['attrs'] : '',
'description' => $field['description'],
'options' => isset($field['options']) ? $field['options'] : array(),
)
);
}
$advanced_fields = array(
'excluded_post_types' => array(
'title' => __('Excluded Post Types', 'lelms-copyright'),
'type' => 'checkbox_group',
'description' => __('Select post types where watermark and protection should not apply.', 'lelms-copyright'),
'options' => $this->get_public_post_types(),
),
'excluded_roles' => array(
'title' => __('Excluded User Roles', 'lelms-copyright'),
'type' => 'checkbox_group',
'description' => __('Select user roles exempt from watermark and protection.', 'lelms-copyright'),
'options' => $this->get_user_roles(),
),
);
foreach ($advanced_fields as $key => $field) {
add_settings_field(
$key,
$field['title'],
array($this, 'render_field'),
'lelms-copyright-advanced',
'lelms_copyright_advanced_section',
array(
'key' => $key,
'type' => $field['type'],
'description' => $field['description'],
'options' => $field['options'],
)
);
}
}
private function get_public_post_types() {
$post_types = get_post_types(array('public' => true), 'objects');
$options = array();
foreach ($post_types as $post_type) {
$options[$post_type->name] = $post_type->label;
}
return $options;
}
private function get_user_roles() {
global $wp_roles;
$roles = $wp_roles->roles;
$options = array();
foreach ($roles as $role => $details) {
$options[$role] = $details['name'];
}
$options['guest'] = __('Guest (Not Logged In)', 'lelms-copyright');
return $options;
}
public function render_field($args) {
$key = $args['key'];
$type = $args['type'];
$value = $this->options[$key];
$attrs = isset($args['attrs']) ? $args['attrs'] : '';
$description = isset($args['description']) ? $args['description'] : '';
$options = isset($args['options']) ? $args['options'] : array();
if ($type === 'checkbox') {
printf(
'<input type="checkbox" name="lelms_copyright_options[%s]" %s value="yes" %s>',
esc_attr($key),
$attrs,
checked($value, 'yes', false)
);
} elseif ($type === 'select') {
printf('<select name="lelms_copyright_options[%s]" %s>', esc_attr($key), $attrs);
foreach ($options as $opt_value => $opt_label) {
printf('<option value="%s" %s>%s</option>', esc_attr($opt_value), selected($value, $opt_value, false), esc_html($opt_label));
}
echo '</select>';
} elseif ($type === 'checkbox_group') {
$value = (array) $value;
foreach ($options as $opt_value => $opt_label) {
printf(
'<label><input type="checkbox" name="lelms_copyright_options[%s][]" value="%s" %s> %s</label><br>',
esc_attr($key),
esc_attr($opt_value),
checked(in_array($opt_value, $value), true, false),
esc_html($opt_label)
);
}
} else {
printf(
'<input type="%s" name="lelms_copyright_options[%s]" value="%s" %s>',
esc_attr($type),
esc_attr($key),
esc_attr($value),
$attrs
);
}
if ($description) {
echo '<p class="description">' . esc_html($description) . '</p>';
}
}
public function options_page() {
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?>
<span style="font-size: 13px; padding-left: 10px;"><?php printf(esc_html__('Version: %s', 'lelms-copyright'), esc_html(LELMS_COPYRIGHT_VERSION)); ?></span>
<a href="https://sharecms.com/document/lelms-copyright" target="_blank" class="button button-secondary" style="margin-left: 10px;"><?php esc_html_e('Document', 'lelms-copyright'); ?></a>
<a href="https://sharecms.com/forums/" target="_blank" class="button button-secondary"><?php esc_html_e('Support', 'lelms-copyright'); ?></a>
</h1>
<div class="card">
<h2 class="nav-tab-wrapper">
<a href="#settings" class="nav-tab nav-tab-active"><?php esc_html_e('Watermark Settings', 'lelms-copyright'); ?></a>
<a href="#advanced" class="nav-tab"><?php esc_html_e('Advanced Settings', 'lelms-copyright'); ?></a>
<a href="#about" class="nav-tab"><?php esc_html_e('About', 'lelms-copyright'); ?></a>
</h2>
<form method="post" action="options.php">
<?php settings_fields('lelms_copyright'); ?>
<div id="lelms-tabs-content">
<div id="settings-tab" class="lelms-tab-content">
<?php do_settings_sections('lelms-copyright'); ?>
</div>
<div id="advanced-tab" class="lelms-tab-content" style="display: none;">
<?php do_settings_sections('lelms-copyright-advanced'); ?>
</div>
<div id="about-tab" class="lelms-tab-content" style="display: none;">
<h3><?php esc_html_e('How to Use LeLMS Copyright', 'lelms-copyright'); ?></h3>
<p><?php esc_html_e('This plugin adds a watermark and protection features to your WordPress site. Heres how to configure it:', 'lelms-copyright'); ?></p>
<ul style="list-style: decimal; padding-left: 2em;">
<li><?php esc_html_e('Watermark Settings: Adjust opacity, size, spacing, color, and angle.', 'lelms-copyright'); ?></li>
<li><?php esc_html_e('Protection Features: Enable options to block DevTools, printing, and copying.', 'lelms-copyright'); ?></li>
<li><?php esc_html_e('Guest Mode: Enable protection and/or custom watermark for non-logged-in users.', 'lelms-copyright'); ?></li>
<li><?php esc_html_e('Custom Watermark: Enable and set a custom text.', 'lelms-copyright'); ?></li>
</ul>
</div>
</div>
<div class="submit-group">
<?php submit_button(__('Save Changes', 'lelms-copyright'), 'primary'); ?>
<button type="button" id="lelms-reset-defaults" class="button"><?php esc_html_e('Reset to Defaults', 'lelms-copyright'); ?></button>
</div>
</form>
<style type="text/css">
.nav-tab {
border: 0px solid #c3c4c7;
background: #ffffff;
}
.nav-tab.nav-tab-active {
border-bottom: 2px solid #007cba;
font-weight: 600;
background: #f0f0f1;
}
.nav-tab:hover:not(.active) {
background: #f0f0f1;
border-bottom-color: #dcdcde;
}
.card {
background: #fff;
border: 1px solid #ccd0d4;
border-radius: 4px;
max-width: unset;
margin-top: 20px;
padding: 20px;
}
.submit-group {
display: flex;
gap: 10px;
align-items: center;
margin-top: 20px;
}
p.submit {
padding-top: 5px;
}
</style>
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.nav-tab').on('click', function(e) {
e.preventDefault();
var target = $(this).attr('href').substring(1);
$('.nav-tab').removeClass('nav-tab-active');
$(this).addClass('nav-tab-active');
$('.lelms-tab-content').hide();
$('#' + target + '-tab').show();
});
var $enableForGuests = $('input[name="lelms_copyright_options[enable_for_guests]"]');
var $guestProtectionOnly = $('input[name="lelms_copyright_options[enable_guest_protection_only]"]').closest('tr');
var $guestCustomWatermark = $('input[name="lelms_copyright_options[enable_guest_custom_watermark]"]').closest('tr');
var $enableCustomWatermark = $('input[name="lelms_copyright_options[enable_custom_watermark]"]');
var $customTextField = $('input[name="lelms_copyright_options[custom_watermark_text]"]').closest('tr');
function updateGuestFieldsVisibility() {
if ($enableForGuests.is(':checked')) {
$guestProtectionOnly.show();
$guestCustomWatermark.show();
} else {
$guestProtectionOnly.hide();
$guestCustomWatermark.hide();
}
}
function updateCustomTextVisibility() {
if ($enableCustomWatermark.is(':checked') || ($enableForGuests.is(':checked') && $('input[name="lelms_copyright_options[enable_guest_custom_watermark]"]').is(':checked'))) {
$customTextField.show();
} else {
$customTextField.hide();
}
}
$enableForGuests.on('change', function() {
updateGuestFieldsVisibility();
updateCustomTextVisibility();
});
$enableCustomWatermark.on('change', updateCustomTextVisibility);
$('input[name="lelms_copyright_options[enable_guest_custom_watermark]"]').on('change', updateCustomTextVisibility);
updateGuestFieldsVisibility();
updateCustomTextVisibility();
$('#lelms-reset-defaults').on('click', function() {
if (confirm('<?php esc_html_e('Are you sure you want to reset all settings to defaults?', 'lelms-copyright'); ?>')) {
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'lelms_reset_options',
nonce: '<?php echo wp_create_nonce('lelms_reset_nonce'); ?>'
},
success: function(response) {
if (response.success) {
alert('<?php esc_html_e('Settings have been reset to defaults. Please refresh the page to see the changes.', 'lelms-copyright'); ?>');
location.reload();
} else {
alert('<?php esc_html_e('Failed to reset settings.', 'lelms-copyright'); ?>');
}
},
error: function() {
alert('<?php esc_html_e('An error occurred while resetting settings.', 'lelms-copyright'); ?>');
}
});
}
});
});
})(jQuery);
</script>
</div>
</div>
<?php
}
public function enqueue_scripts() {
if ($this->should_apply_protection()) {
$style_url = plugins_url('css/style.css', __FILE__);
$script_url = plugins_url('js/watermark.js', __FILE__);
if (!file_exists(plugin_dir_path(__FILE__) . 'css/style.css')) {
error_log('LeLMS Copyright: CSS file not found at ' . plugin_dir_path(__FILE__) . 'css/style.css');
}
if (!file_exists(plugin_dir_path(__FILE__) . 'js/watermark.js')) {
error_log('LeLMS Copyright: JS file not found at ' . plugin_dir_path(__FILE__) . 'js/watermark.js');
}
wp_enqueue_style('lelms-copyright', $style_url, array(), '1.1.5');
wp_enqueue_script('lelms-copyright', $script_url, array('jquery'), '1.1.5', true);
$user = is_user_logged_in() ? wp_get_current_user() : null;
$watermark_text = '';
$is_guest = !is_user_logged_in();
if ($this->should_apply_watermark()) {
if ($is_guest) {
$watermark_text = !empty($this->options['custom_watermark_text']) ? $this->options['custom_watermark_text'] : 'LeLMS Copyright';
} else {
if ($this->options['enable_custom_watermark'] === 'yes') {
$watermark_text = !empty($this->options['custom_watermark_text']) ? $this->options['custom_watermark_text'] : 'LeLMS Copyright';
} else {
switch ($this->options['watermark_type']) {
case 'username':
$watermark_text = $user ? '@' . $user->user_login : '';
break;
case 'nickname':
$watermark_text = $user ? $user->display_name : '';
break;
case 'email':
$watermark_text = $user ? $user->user_email : '';
break;
case 'timestamp':
$watermark_text = current_time('Y-m-d H:i:s');
break;
}
}
}
}
wp_localize_script('lelms-copyright', 'lelmsData', array(
'username' => $watermark_text,
'options' => $this->options,
'warningMessage' => __('This action is disabled on this site.', 'lelms-copyright'),
'isGuest' => $is_guest,
));
}
}
public function reset_options() {
check_ajax_referer('lelms_reset_nonce', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error('Permission denied');
}
$defaults = array(
'watermark_opacity' => 0.1,
'watermark_size' => 20,
'watermark_spacing' => 150,
'watermark_color' => '#000000',
'watermark_angle' => -45,
'enable_devtools_protection' => 'yes',
'enable_print_protection' => 'yes',
'enable_copy_protection' => 'yes',
'enable_for_guests' => 'no',
'enable_guest_protection_only' => 'no',
'enable_guest_custom_watermark' => 'no',
'enable_custom_watermark' => 'no',
'custom_watermark_text' => '',
'watermark_type' => 'username',
'excluded_post_types' => array(),
'excluded_roles' => array(),
);
update_option('lelms_copyright_options', $defaults);
wp_send_json_success('Settings reset to defaults');
}
}
new LELMS_Copyright();
require_once plugin_dir_path(__FILE__) . 'lib/plugin-update-checker/plugin-update-checker.php';
use YahnisElsts\PluginUpdateChecker\v5p3\PucFactory;
$lelmsUpdateChecker = PucFactory::buildUpdateChecker(
'https://updates.weixiaoduo.com/lelms-copyright.json',
__FILE__,
'lelms-copyright'
);