<?php
/**
* Plugin Name: Wp update seo
* Description: Plugin for displaying the seo
* Plugin URI: https://wpdev.com.cn
* Author: Wayne
* Auhtor URI: https://wpdev.com.cn
* Version: 1.0.2
*/
if (!defined('ABSPATH')) exit;
class Comprehensive_WordPress_SEO {
public function __construct() {
// Hook into WordPress
add_filter('pre_get_document_title', array($this, 'get_seo_title'), 999);
add_action('wp_head', array($this, 'output_seo_meta_tags'), 1);
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_init', array($this, 'register_settings'));
// Add meta boxes for posts, pages, and custom post types
add_action('add_meta_boxes', array($this, 'add_seo_meta_boxes'));
add_action('save_post', array($this, 'save_seo_meta_data'));
// Add fields to category, tag, and custom taxonomy edit forms
add_action('edit_category_form_fields', array($this, 'add_taxonomy_seo_fields'));
add_action('edit_tag_form_fields', array($this, 'add_taxonomy_seo_fields'));
add_action('edited_term', array($this, 'save_taxonomy_seo_fields'), 10, 3);
// Add support for custom taxonomies
$taxonomies = get_taxonomies(array('public' => true, '_builtin' => false), 'names');
foreach ($taxonomies as $taxonomy) {
add_action("{$taxonomy}_edit_form_fields", array($this, 'add_taxonomy_seo_fields'));
}
}
public function output_seo_meta_tags() {
$title = $this->get_seo_title();
$description = $this->get_seo_description();
if (!empty($title)) {
echo "<title>" . esc_html($title) . "</title>\n";
echo "<meta property='og:title' content='" . esc_attr($title) . "'>\n";
}
if (!empty($description)) {
echo "<meta name='description' content='" . esc_attr($description) . "'>\n";
echo "<meta property='og:description' content='" . esc_attr($description) . "'>\n";
}
// Add canonical URL
$canonical_url = $this->get_canonical_url();
if (!empty($canonical_url)) {
echo "<link rel='canonical' href='" . esc_url($canonical_url) . "'>\n";
}
}
public function get_seo_title($title = '') {
if (is_singular()) {
$custom_title = get_post_meta(get_the_ID(), '_seo_title', true);
if (!empty($custom_title)) {
return $custom_title;
}
} elseif (is_post_type_archive()) {
$post_type = get_query_var('post_type');
$custom_title = get_option("seo_{$post_type}_archive_title");
if (!empty($custom_title)) {
return $custom_title;
}
} elseif (is_tax() || is_category() || is_tag()) {
$term = get_queried_object();
$custom_title = get_term_meta($term->term_id, '_seo_title', true);
if (!empty($custom_title)) {
return $custom_title;
}
} elseif (is_home() || is_front_page()) {
$custom_title = get_option('seo_home_title');
if (!empty($custom_title)) {
return $custom_title;
}
}
// If we haven't returned a custom title, let WordPress handle it
return $title;
}
public function get_seo_description() {
if (is_singular()) {
$description = get_post_meta(get_the_ID(), '_seo_description', true);
if (!empty($description)) {
return $description;
}
return $this->get_default_description(get_post());
} elseif (is_post_type_archive()) {
$post_type = get_query_var('post_type');
$description = get_option("seo_{$post_type}_archive_description");
if (!empty($description)) {
return $description;
}
$post_type_obj = get_post_type_object($post_type);
return !empty($post_type_obj->description) ? wp_trim_words($post_type_obj->description, 30) : '';
} elseif (is_tax() || is_category() || is_tag()) {
$term = get_queried_object();
$description = get_term_meta($term->term_id, '_seo_description', true);
if (!empty($description)) {
return $description;
}
return wp_trim_words(strip_tags($term->description), 30);
} elseif (is_home() || is_front_page()) {
$description = get_option('seo_home_description');
if (!empty($description)) {
return $description;
}
return get_bloginfo('description');
}
return '';
}
private function get_default_description($post) {
$excerpt = get_the_excerpt($post);
if (!empty($excerpt)) {
return wp_trim_words($excerpt, 30);
}
return wp_trim_words(strip_tags($post->post_content), 30);
}
public function get_canonical_url() {
if (is_singular()) {
return get_permalink();
} elseif (is_tax() || is_category() || is_tag()) {
return get_term_link(get_queried_object());
} elseif (is_post_type_archive()) {
return get_post_type_archive_link(get_query_var('post_type'));
} elseif (is_home() || is_front_page()) {
return home_url('/');
}
return '';
}
public function add_admin_menu() {
add_options_page(
'SEO Settings',
'SEO Settings',
'manage_options',
'comprehensive-wordpress-seo',
array($this, 'seo_settings_page')
);
}
public function register_settings() {
register_setting('comprehensive-wordpress-seo', 'seo_home_title');
register_setting('comprehensive-wordpress-seo', 'seo_home_description');
$post_types = get_post_types(array('public' => true, 'has_archive' => true), 'names');
foreach ($post_types as $post_type) {
register_setting('comprehensive-wordpress-seo', "seo_{$post_type}_archive_title");
register_setting('comprehensive-wordpress-seo', "seo_{$post_type}_archive_description");
}
}
public function seo_settings_page() {
// Implementation remains the same ?>
<div class="wrap">
<h1>SEO Settings</h1>
<form method="post" action="options.php">
<?php settings_fields('comprehensive-wordpress-seo'); ?>
<?php do_settings_sections('comprehensive-wordpress-seo'); ?>
<h2>Home Page SEO</h2>
<table class="form-table">
<tr valign="top">
<th scope="row">Home Page Title</th>
<td><input type="text" name="seo_home_title" value="<?php echo esc_attr(get_option('seo_home_title')); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row">Home Page Description</th>
<td><textarea name="seo_home_description" rows="3" cols="50"><?php echo esc_textarea(get_option('seo_home_description')); ?></textarea></td>
</tr>
</table>
<h2>Custom Post Type Archive SEO</h2>
<?php
$post_types = get_post_types(array('public' => true, 'has_archive' => true), 'objects');
foreach ($post_types as $post_type) :
if ($post_type->name === 'post' || $post_type->name === 'page') continue; // Skip default post types
?>
<h3><?php echo esc_html($post_type->label); ?> Archive</h3>
<table class="form-table">
<tr valign="top">
<th scope="row"><?php echo esc_html($post_type->label); ?> Archive Title</th>
<td><input type="text" name="seo_<?php echo esc_attr($post_type->name); ?>_archive_title" value="<?php echo esc_attr(get_option("seo_{$post_type->name}_archive_title")); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row"><?php echo esc_html($post_type->label); ?> Archive Description</th>
<td><textarea name="seo_<?php echo esc_attr($post_type->name); ?>_archive_description" rows="3" cols="50"><?php echo esc_textarea(get_option("seo_{$post_type->name}_archive_description")); ?></textarea></td>
</tr>
</table>
<?php endforeach; ?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
public function add_seo_meta_boxes() {
$post_types = get_post_types(array('public' => true));
foreach ($post_types as $post_type) {
add_meta_box(
'seo_meta_box',
'SEO Settings',
array($this, 'seo_meta_box_callback'),
$post_type,
'normal',
'high'
);
}
}
public function seo_meta_box_callback($post) {
wp_nonce_field('seo_meta_box', 'seo_meta_box_nonce');
$seo_title = get_post_meta($post->ID, '_seo_title', true);
$seo_description = get_post_meta($post->ID, '_seo_description', true);
?>
<p>
<label for="seo_title">SEO Title:</label>
<input type="text" id="seo_title" name="seo_title" value="<?php echo esc_attr($seo_title); ?>" style="width: 100%;" />
</p>
<p>
<label for="seo_description">SEO Description:</label>
<textarea id="seo_description" name="seo_description" rows="3" style="width: 100%;"><?php echo esc_textarea($seo_description); ?></textarea>
</p>
<?php
}
public function save_seo_meta_data($post_id) {
if (!isset($_POST['seo_meta_box_nonce']) || !wp_verify_nonce($_POST['seo_meta_box_nonce'], 'seo_meta_box')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['seo_title'])) {
update_post_meta($post_id, '_seo_title', sanitize_text_field($_POST['seo_title']));
}
if (isset($_POST['seo_description'])) {
update_post_meta($post_id, '_seo_description', sanitize_textarea_field($_POST['seo_description']));
}
}
public function add_taxonomy_seo_fields($term) {
$term_id = $term->term_id;
$seo_title = get_term_meta($term_id, '_seo_title', true);
$seo_description = get_term_meta($term_id, '_seo_description', true);
?>
<tr class="form-field">
<th scope="row"><label for="seo_title">SEO Title</label></th>
<td>
<input type="text" name="seo_title" id="seo_title" value="<?php echo esc_attr($seo_title); ?>" />
<p class="description">Enter a custom SEO title for this term.</p>
</td>
</tr>
<tr class="form-field">
<th scope="row"><label for="seo_description">SEO Description</label></th>
<td>
<textarea name="seo_description" id="seo_description" rows="5" cols="50"><?php echo esc_textarea($seo_description); ?></textarea>
<p class="description">Enter a custom SEO description for this term.</p>
</td>
</tr>
<?php
}
public function save_taxonomy_seo_fields($term_id, $tt_id, $taxonomy) {
if (!current_user_can('edit_term', $term_id)) {
return;
}
if (isset($_POST['seo_title'])) {
update_term_meta($term_id, '_seo_title', sanitize_text_field($_POST['seo_title']));
}
if (isset($_POST['seo_description'])) {
update_term_meta($term_id, '_seo_description', sanitize_textarea_field($_POST['seo_description']));
}
}
}
new Comprehensive_WordPress_SEO();