WordPress所见即所得发布方法总结

错误信息表明 wp_generate_attachment_metadata 函数未定义。这是因为在 WordPress 中,wp_generate_attachment_metadata 函数位于 wp-admin/includes/image.php 文件中,而这个文件默认不会在插件或主题中自动加载。


解决方法

在调用 wp_generate_attachment_metadata 之前,需要手动引入 wp-admin/includes/image.php 文件。以下是修复后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php
/*
Plugin Name: MY Auto Save Remote Image
Plugin URI: http://www.devsaab.com/wordpress/
Description: This plugin automatically downloads all remote images from a post and saves them locally.
Version: 1.4
Author: Prebhdev Singh
Disclaimer: No warranty or guarantee of any kind! Use this at your own risk.
*/

add_action('publish_post', 'fetch_images');

function fetch_images($post_ID) {
// 检查是否正在自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}

// 检查用户权限
if (!current_user_can('edit_post', $post_ID)) {
return;
}

// 引入 WordPress 图像处理函数
require_once(ABSPATH . 'wp-admin/includes/image.php');

// 获取文章内容
$post = get_post($post_ID);
$updated = $post->post_content;

// 提取所有图片 URL
if (preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)) {
$first_images = $matches[1];

foreach ($first_images as $first_image) {
// 检查图片域名是否与当前站点一致
if (strpos($first_image, $_SERVER['HTTP_HOST']) === false) {
// 处理 HTTPS
$first_image = str_replace('http://', 'https://', $first_image);

// 下载图片
$get = wp_remote_get($first_image);
if (!is_wp_error($get)) {
$type = wp_remote_retrieve_header($get, 'content-type');
if (strpos($type, 'image') === false) {
continue; // 如果不是图片,跳过
}

// 生成唯一文件名
$filename = wp_unique_filename(wp_upload_dir()['path'], rawurldecode(basename($first_image)));

// 保存图片
$mirror = wp_upload_bits($filename, '', wp_remote_retrieve_body($get));

if (!$mirror['error']) {
// 创建附件
$attachment = array(
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_mime_type' => $type
);
$attach_id = wp_insert_attachment($attachment, $mirror['file'], $post_ID);

if (!is_wp_error($attach_id)) {
// 生成附件元数据并更新
$attach_data = wp_generate_attachment_metadata($attach_id, $mirror['file']);
wp_update_attachment_metadata($attach_id, $attach_data);

// 替换文章中的图片 URL
$updated = str_replace($first_image, $mirror['url'], $updated);
}
} else {
error_log('Failed to save image: ' . $first_image);
}
} else {
error_log('Failed to download image: ' . $first_image);
}
}
}

// 更新文章内容
if ($updated !== $post->post_content) {
wp_update_post(array('ID' => $post_ID, 'post_content' => $updated));
}
}
}
?>

关键修复点

  1. 引入 wp-admin/includes/image.php

    • 在函数开头添加以下代码:
      1
      require_once(ABSPATH . 'wp-admin/includes/image.php');
    • 这确保了 wp_generate_attachment_metadata 函数可用。
  2. 确保文件路径正确

    • ABSPATH 是 WordPress 根目录的绝对路径,确保路径拼接正确。

测试步骤

  1. 将修复后的代码保存为 my-auto-save-remote-image.php
  2. 上传到 WordPress 的 wp-content/plugins/ 目录。
  3. 在 WordPress 后台激活插件。
  4. 发布一篇包含远程图片的文章,检查插件是否正常工作。

注意事项

  1. 权限问题

    • 确保 WordPress 的上传目录(wp-content/uploads)有正确的写权限。
  2. HTTPS 支持

    • 如果远程图片使用 HTTPS,确保服务器支持 HTTPS 请求。
  3. 性能监控

    • 如果文章中有大量图片,可能会影响发布速度,建议监控服务器性能。

如果问题仍未解决,请提供更多错误信息或上下文,我会进一步帮助你排查问题!

时间: 2025-02-25T01:16:33


👤 用户

下面是你之前的代码,目的是直接把markdown内容转换为html格式并发布到wordpress中,我现在想知道有没有方法选择复制一个页面的内容,然后所见即所得的发布到我的站点中?
<?php
// 加载 WordPress 环境
require_once(‘../wp-load.php’);

// 引入 Parsedown 库(用于解析 Markdown)
require_once ‘Parsedown.php’;

// 检查是否提交了表单
if ($_SERVER[‘REQUEST_METHOD’] === ‘POST’ && isset($_POST[‘markdown’]) && isset($_POST[‘title’])) {
// 检查 nonce 和用户权限
if (!isset($_POST[‘markdown_publish_nonce’]) || !wp_verify_nonce($_POST[‘markdown_publish_nonce’], ‘markdown_publish_action’)) {
echo ‘

安全验证失败,请重试。
‘;
} elseif (!current_user_can(‘publish_posts’)) {
echo ‘
你没有权限发布文章。
‘;
} else {
// 获取表单数据
$title = sanitize_text_field($_POST[‘title’]);
$markdown = $_POST[‘markdown’];
$category = isset($_POST[‘category’]) ? intval($_POST[‘category’]) : 0; // 分类 ID
$tags = isset($_POST[‘tags’]) ? sanitize_text_field($_POST[‘tags’]) : ‘’; // 标签

    // 使用 Parsedown 解析 Markdown
    $parsedown = new Parsedown();
    //$html = $parsedown->text($markdown);
    // 将 HTML 转换为纯文本
    //$content = strip_tags($html);
    //******
    $content = $parsedown->text($markdown); // 直接保存为 HTML
    //***********
    //$content = $markdown;
    //在 WordPress 后台,进入“插件” -> “安装插件”。搜索“Jetpack”,安装并激活。
    // 发布文章
    $post_id = wp_insert_post([
        'post_title'   => $title,
        'post_content' => $content,
        'post_status'  => 'publish', // 直接发布
        'post_author'  => get_current_user_id(), // 当前用户为作者
        'post_category' => [$category], // 分配分类
    ]);

    if ($post_id) {
        // 分配标签
        if (!empty($tags)) {
            wp_set_post_tags($post_id, $tags);
        }

        echo '<div class="success">文章发布成功!<a href="' . get_permalink($post_id) . '">查看文章</a></div>';
    } else {
        echo '<div class="error">文章发布失败,请重试。</div>';
    }
}

}

// 获取所有分类
$categories = get_categories([‘hide_empty’ => false]);
?>

Markdown 发布工具

Markdown 发布工具

时间: 2025-02-25T00:35:33


🤖 DeepSeek (deepseek-chat)

要将一个页面的内容所见即所得地发布到你的 WordPress 站点中,你可以考虑以下几种方法:

方法 1:使用 WordPress 的编辑器(Gutenberg 或 Classic Editor)

WordPress 自带的编辑器(Gutenberg 或 Classic Editor)已经支持所见即所得的编辑方式。你可以直接将内容复制到编辑器中,然后发布。

步骤:

  1. 登录 WordPress 后台
  2. 创建新文章:进入“文章” -> “写文章”。
  3. 复制内容:从你想要复制的页面中选中内容,然后粘贴到 WordPress 编辑器中。
  4. 调整格式:根据需要调整格式(如标题、段落、图片等)。
  5. 发布文章:点击“发布”按钮。

方法 2:使用浏览器扩展或插件

有一些浏览器扩展或 WordPress 插件可以帮助你更方便地将内容复制并发布到 WordPress 中。

推荐插件:

  • WordPress Importer:可以导入其他 WordPress 站点的内容。
  • Press This:一个 WordPress 官方提供的书签工具,可以快速将网页内容发布到你的站点。
  • Jetpack:Jetpack 插件中的“Markdown”模块可以让你在编辑器中直接使用 Markdown 语法。

使用 Press This 的步骤:

  1. 安装 Press This:在 WordPress 后台,进入“工具” -> “可用工具”,找到“Press This”并安装。
  2. 添加书签:将“Press This”按钮拖到浏览器的书签栏。
  3. 复制内容:打开你想要复制的页面,点击书签栏中的“Press This”按钮。
  4. 编辑并发布:在弹出的编辑器中,你可以编辑内容并直接发布。

方法 3:自定义所见即所得的编辑器

如果你希望在你的自定义工具中实现所见即所得的编辑功能,可以考虑集成一个富文本编辑器(如 TinyMCE 或 Quill)到你的表单中。

集成 TinyMCE 的示例:

  1. 引入 TinyMCE

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
    <script>
    tinymce.init({
    selector: '#markdown',
    height: 500,
    menubar: false,
    plugins: [
    'advlist autolink lists link image charmap print preview anchor',
    'searchreplace visualblocks code fullscreen',
    'insertdatetime media table paste code help wordcount'
    ],
    toolbar: 'undo redo | formatselect | bold italic backcolor | \
    alignleft aligncenter alignright alignjustify | \
    bullist numlist outdent indent | removeformat | help'
    });
    </script>
  2. 修改表单

    1
    <textarea name="markdown" id="markdown" placeholder="在此输入 Markdown 文本..." required></textarea>
  3. 处理表单提交
    由于 TinyMCE 输出的是 HTML,你需要调整你的 PHP 代码以处理 HTML 内容而不是 Markdown。

    1
    $content = $_POST['markdown']; // 直接保存为 HTML

方法 4:使用 Markdown 编辑器

如果你仍然希望使用 Markdown,但想要所见即所得的编辑体验,可以考虑使用支持实时预览的 Markdown 编辑器,如 SimpleMDEEditor.md

集成 SimpleMDE 的示例:

  1. 引入 SimpleMDE

    1
    2
    3
    4
    5
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
    <script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
    <script>
    var simplemde = new SimpleMDE({ element: document.getElementById("markdown") });
    </script>
  2. 修改表单

    1
    <textarea name="markdown" id="markdown" placeholder="在此输入 Markdown 文本..." required></textarea>
  3. 处理表单提交
    由于 SimpleMDE 输出的是 Markdown,你可以继续使用 Parsedown 将其转换为 HTML。

    1
    2
    $parsedown = new Parsedown();
    $content = $parsedown->text($_POST['markdown']);

总结

  • 直接使用 WordPress 编辑器是最简单的方法,适合大多数用户。
  • 使用浏览器扩展或插件可以简化复制和发布的过程。
  • 集成富文本编辑器(如 TinyMCE)可以实现所见即所得的编辑体验。
  • 使用支持实时预览的 Markdown 编辑器(如 SimpleMDE)可以在保留 Markdown 语法的情况下实现所见即所得。

根据你的需求选择合适的方法即可。

时间: 2025-02-25T00:35:33


👤 用户

行,根据方法3,请给我一段完整代码。

时间: 2025-02-25T00:41:47


🤖 DeepSeek (deepseek-chat)

好的!以下是基于 方法 3 的完整代码,集成了 TinyMCE 富文本编辑器,并支持将 HTML 内容直接发布到 WordPress 中。

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
// 加载 WordPress 环境
require_once('../wp-load.php');

// 检查是否提交了表单
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content']) && isset($_POST['title'])) {
// 检查 nonce 和用户权限
if (!isset($_POST['markdown_publish_nonce']) || !wp_verify_nonce($_POST['markdown_publish_nonce'], 'markdown_publish_action')) {
echo '<div class="error">安全验证失败,请重试。</div>';
} elseif (!current_user_can('publish_posts')) {
echo '<div class="error">你没有权限发布文章。</div>';
} else {
// 获取表单数据
$title = sanitize_text_field($_POST['title']);
$content = $_POST['content']; // TinyMCE 输出的 HTML 内容
$category = isset($_POST['category']) ? intval($_POST['category']) : 0; // 分类 ID
$tags = isset($_POST['tags']) ? sanitize_text_field($_POST['tags']) : ''; // 标签

// 发布文章
$post_id = wp_insert_post([
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish', // 直接发布
'post_author' => get_current_user_id(), // 当前用户为作者
'post_category' => [$category], // 分配分类
]);

if ($post_id) {
// 分配标签
if (!empty($tags)) {
wp_set_post_tags($post_id, $tags);
}

echo '<div class="success">文章发布成功!<a href="' . get_permalink($post_id) . '">查看文章</a></div>';
} else {
echo '<div class="error">文章发布失败,请重试。</div>';
}
}
}

// 获取所有分类
$categories = get_categories(['hide_empty' => false]);
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>所见即所得发布工具</title>
<!-- 引入 TinyMCE -->
<script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
<script>
tinymce.init({
selector: '#content', // 绑定到 textarea
height: 500, // 编辑器高度
menubar: false, // 隐藏菜单栏
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code help wordcount'
],
toolbar: 'undo redo | formatselect | bold italic backcolor | \
alignleft aligncenter alignright alignjustify | \
bullist numlist outdent indent | removeformat | help'
});
</script>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.publish-tool {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
.publish-tool textarea {
width: 100%;
height: 200px;
padding: 10px;
font-size: 16px;
}
.publish-tool .buttons {
margin-top: 10px;
}
.publish-tool .buttons button {
padding: 10px 20px;
font-size: 16px;
margin-right: 10px;
cursor: pointer;
}
.success {
color: green;
margin: 10px 0;
}
.error {
color: red;
margin: 10px 0;
}
</style>
<script>
// 重置表单
function resetForm() {
tinymce.get('content').setContent(''); // 清空 TinyMCE 内容
document.querySelector('input[name="title"]').value = '';
document.querySelector('select[name="category"]').selectedIndex = 0;
document.querySelector('input[name="tags"]').value = '';
}
</script>
</head>
<body>
<div class="publish-tool">
<h1>所见即所得发布工具</h1>
<form method="POST">
<?php wp_nonce_field('markdown_publish_action', 'markdown_publish_nonce'); ?>
<div>
<label for="title">标题:</label>
<input type="text" name="title" id="title" required>
</div>
<div>
<label for="content">内容:</label>
<textarea name="content" id="content" placeholder="在此输入内容..." required></textarea>
</div>
<div>
<label for="category">分类:</label>
<select name="category" id="category">
<?php foreach ($categories as $cat): ?>
<option value="<?php echo $cat->term_id; ?>"><?php echo $cat->name; ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="tags">标签(用逗号分隔):</label>
<input type="text" name="tags" id="tags">
</div>
<div class="buttons">
<button type="submit" name="publish">发布</button>
<button type="button" onclick="resetForm()">重置</button>
</div>
</form>
</div>
</body>
</html>

代码说明

  1. TinyMCE 集成

    • 使用 TinyMCE 的 CDN 引入编辑器。
    • 初始化 TinyMCE,绑定到 textarea,并配置工具栏和插件。
  2. 表单处理

    • 表单提交后,直接获取 TinyMCE 输出的 HTML 内容($_POST['content'])。
    • 使用 wp_insert_post 将内容发布为 WordPress 文章。
  3. 所见即所得

    • TinyMCE 提供了富文本编辑功能,用户可以直接在编辑器中排版内容(如加粗、斜体、插入图片等)。
  4. 安全性

    • 使用 wp_nonce_fieldwp_verify_nonce 防止 CSRF 攻击。
    • 使用 sanitize_text_field 对标题和标签进行过滤。
  5. 重置功能

    • 点击“重置”按钮时,清空 TinyMCE 编辑器和表单其他字段。

使用方法

  1. 将代码保存为一个 PHP 文件(如 publish-tool.php),并放置在 WordPress 站点目录下。
  2. 访问该文件的 URL(如 https://your-site.com/publish-tool.php)。
  3. 在 TinyMCE 编辑器中输入内容,填写标题、选择分类和标签,然后点击“发布”。
  4. 文章将直接发布到 WordPress 中。

注意事项

  • TinyMCE API Key:如果需要更多功能(如图片上传),可以注册 TinyMCE 并获取 API Key。
  • 权限控制:确保只有有权限的用户可以访问该工具。
  • 样式调整:可以根据需要调整 TinyMCE 的工具栏配置和样式。

希望这段代码能满足你的需求!如果有其他问题,欢迎随时提问!

时间: 2025-02-25T00:41:47


👤 用户

使用你给的代码出现图中问题,怎么解决

时间: 2025-02-25T00:51:19


🤖 DeepSeek (deepseek-chat)

图中的问题是因为 TinyMCE 5 及以上版本需要 API Key 才能使用。你使用的 CDN 链接中没有提供 API Key,因此 TinyMCE 无法加载。

解决方法

以下是几种解决方案,选择其中一种即可:


方法 1:注册 TinyMCE 并获取 API Key

  1. 注册 TinyMCE

  2. 获取 API Key

    • 登录后,进入 Dashboard。
    • 创建一个新的应用程序(Application),系统会为你生成一个 API Key。
  3. 修改代码

    • 将代码中的 TinyMCE CDN 链接替换为包含你的 API Key 的链接。
    1
    <script src="https://cdn.tiny.cloud/1/你的API Key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>

    例如:

    1
    <script src="https://cdn.tiny.cloud/1/your-api-key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
  4. 测试

    • 刷新页面,TinyMCE 应该可以正常加载。

方法 2:使用 TinyMCE 4(无需 API Key)

如果你不想注册 TinyMCE,可以使用 TinyMCE 4 版本,它不需要 API Key。

  1. 修改代码

    • 将 TinyMCE 的 CDN 链接替换为 TinyMCE 4 的链接。
    1
    <script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/4/tinymce.min.js"></script>
  2. 初始化 TinyMCE

    • TinyMCE 4 的初始化代码与 TinyMCE 5 类似,可以直接使用。
  3. 测试

    • 刷新页面,TinyMCE 应该可以正常加载。

方法 3:使用本地 TinyMCE

如果你不想依赖 CDN,可以将 TinyMCE 下载到本地并引用。

  1. 下载 TinyMCE

  2. 解压并放置文件

    • 将解压后的文件放置在 WordPress 主题或插件目录中,例如:
      1
      /wp-content/themes/your-theme/tinymce/
  3. 修改代码

    • 引用本地的 TinyMCE 文件。
    1
    <script src="/wp-content/themes/your-theme/tinymce/tinymce.min.js"></script>
  4. 测试

    • 刷新页面,TinyMCE 应该可以正常加载。

方法 4:使用其他富文本编辑器

如果你不想使用 TinyMCE,可以选择其他不需要 API Key 的富文本编辑器,例如:

  • Quill:轻量级富文本编辑器。
  • CKEditor:功能强大的富文本编辑器。
  • Summernote:简单易用的富文本编辑器。

以 Quill 为例:

  1. 引入 Quill

    1
    2
    <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
    <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
  2. 初始化 Quill

    1
    2
    3
    4
    5
    6
    <div id="editor" style="height: 300px;"></div>
    <script>
    var quill = new Quill('#editor', {
    theme: 'snow'
    });
    </script>
  3. 获取内容

    • 在表单提交时,获取 Quill 的内容。
    1
    2
    3
    4
    document.querySelector('form').onsubmit = function() {
    var content = document.querySelector('#editor .ql-editor').innerHTML;
    document.querySelector('textarea[name="content"]').value = content;
    };
  4. 修改表单

    • 添加一个隐藏的 textarea 用于提交内容。
    1
    <textarea name="content" style="display: none;"></textarea>

总结

  • 推荐方法 1:注册 TinyMCE 并获取 API Key,这是官方推荐的方式。
  • 临时解决方案:使用 TinyMCE 4 或其他富文本编辑器(如 Quill)。
  • 本地化:下载 TinyMCE 并本地引用,避免依赖 CDN。

根据你的需求选择合适的方法即可。如果还有其他问题,欢迎继续提问!

时间: 2025-02-25T00:51:19


👤 用户

安全验证失败,请重试。
'; } elseif (!current_user_can('publish_posts')) { echo '
你没有权限发布文章。
'; } else { // 获取表单数据 $title = sanitize_text_field($_POST['title']); $content = $_POST['content']; // TinyMCE 输出的 HTML 内容 $category = isset($_POST['category']) ? intval($_POST['category']) : 0; // 分类 ID $tags = isset($_POST['tags']) ? sanitize_text_field($_POST['tags']) : ''; // 标签 // 发布文章 $post_id = wp_insert_post([ 'post_title' => $title, 'post_content' => $content, 'post_status' => 'publish', // 直接发布 'post_author' => get_current_user_id(), // 当前用户为作者 'post_category' => [$category], // 分配分类 ]); if ($post_id) { // 分配标签 if (!empty($tags)) { wp_set_post_tags($post_id, $tags); } echo '
文章发布成功!查看文章
'; } else { echo '
文章发布失败,请重试。
'; } } } // 获取所有分类 $categories = get_categories(['hide_empty' => false]); ?> 所见即所得发布工具

所见即所得发布工具

时间: 2025-02-25T00:59:49


🤖 DeepSeek (deepseek-chat)

你的代码已经集成了 TinyMCE 富文本编辑器,并且使用了有效的 API Key,整体逻辑是正确的。如果仍然遇到问题,可能是以下原因之一:


1. TinyMCE 加载问题

  • 原因:TinyMCE 的 CDN 链接可能无法正确加载,或者 API Key 无效。
  • 解决方法
    1. 确保 API Key 是正确的。你可以在 TinyMCE Dashboard 中检查 API Key 的状态。
    2. 尝试在浏览器中直接访问 TinyMCE 的 CDN 链接,确保能够正常加载:
      1
      https://cdn.tiny.cloud/1/ai2tag8ofr7pco5jz64wsp0b4ripk1jrpom8n67h6mbg009v/tinymce/5/tinymce.min.js
    3. 如果 CDN 链接无法访问,可以尝试使用本地 TinyMCE(参考下文)。

2. TinyMCE 初始化问题

  • 原因:TinyMCE 初始化代码可能未正确执行。
  • 解决方法
    1. 打开浏览器的开发者工具(按 F12),检查是否有 JavaScript 错误。
    2. 确保 tinymce.init 代码在页面加载完成后执行。可以将初始化代码放在 window.onload 中:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      window.onload = function() {
      tinymce.init({
      selector: '#content',
      height: 500,
      menubar: false,
      plugins: [
      'advlist autolink lists link image charmap print preview anchor',
      'searchreplace visualblocks code fullscreen',
      'insertdatetime media table paste code help wordcount'
      ],
      toolbar: 'undo redo | formatselect | bold italic backcolor | \
      alignleft aligncenter alignright alignjustify | \
      bullist numlist outdent indent | removeformat | help'
      });
      };

3. 表单提交问题

  • 原因:TinyMCE 的内容可能未正确传递到表单中。
  • 解决方法
    1. 确保表单提交时,TinyMCE 的内容被正确获取并传递到 textarea 中。
    2. 可以在表单提交时,手动将 TinyMCE 的内容同步到 textarea
      1
      2
      3
      4
      document.querySelector('form').onsubmit = function() {
      var content = tinymce.get('content').getContent();
      document.querySelector('textarea[name="content"]').value = content;
      };

4. 本地 TinyMCE 方案

如果 CDN 不可靠,可以将 TinyMCE 下载到本地。

步骤:

  1. 下载 TinyMCE

  2. 解压并放置文件

    • 将解压后的文件放置在 WordPress 主题或插件目录中,例如:
      1
      /wp-content/themes/your-theme/tinymce/
  3. 修改代码

    • 引用本地的 TinyMCE 文件:
      1
      <script src="/wp-content/themes/your-theme/tinymce/tinymce.min.js"></script>
  4. 测试

    • 刷新页面,TinyMCE 应该可以正常加载。

5. 完整代码(修复版)

以下是修复后的完整代码,确保 TinyMCE 内容正确提交:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php
// 加载 WordPress 环境
require_once('../wp-load.php');

// 检查是否提交了表单
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content']) && isset($_POST['title'])) {
// 检查 nonce 和用户权限
if (!isset($_POST['markdown_publish_nonce']) || !wp_verify_nonce($_POST['markdown_publish_nonce'], 'markdown_publish_action')) {
echo '<div class="error">安全验证失败,请重试。</div>';
} elseif (!current_user_can('publish_posts')) {
echo '<div class="error">你没有权限发布文章。</div>';
} else {
// 获取表单数据
$title = sanitize_text_field($_POST['title']);
$content = $_POST['content']; // TinyMCE 输出的 HTML 内容
$category = isset($_POST['category']) ? intval($_POST['category']) : 0; // 分类 ID
$tags = isset($_POST['tags']) ? sanitize_text_field($_POST['tags']) : ''; // 标签

// 发布文章
$post_id = wp_insert_post([
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish', // 直接发布
'post_author' => get_current_user_id(), // 当前用户为作者
'post_category' => [$category], // 分配分类
]);

if ($post_id) {
// 分配标签
if (!empty($tags)) {
wp_set_post_tags($post_id, $tags);
}

echo '<div class="success">文章发布成功!<a href="' . get_permalink($post_id) . '">查看文章</a></div>';
} else {
echo '<div class="error">文章发布失败,请重试。</div>';
}
}
}

// 获取所有分类
$categories = get_categories(['hide_empty' => false]);
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>所见即所得发布工具</title>
<!-- 引入 TinyMCE -->
<script src="https://cdn.tiny.cloud/1/ai2tag8ofr7pco5jz64wsp0b4ripk1jrpom8n67h6mbg009v/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
<script>
tinymce.init({
selector: '#content', // 绑定到 textarea
height: 500, // 编辑器高度
menubar: false, // 隐藏菜单栏
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code help wordcount'
],
toolbar: 'undo redo | formatselect | bold italic backcolor | \
alignleft aligncenter alignright alignjustify | \
bullist numlist outdent indent | removeformat | help'
});

// 表单提交时同步 TinyMCE 内容
document.querySelector('form').onsubmit = function() {
var content = tinymce.get('content').getContent();
document.querySelector('textarea[name="content"]').value = content;
};
</script>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.publish-tool {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
.publish-tool textarea {
width: 100%;
height: 200px;
padding: 10px;
font-size: 16px;
}
.publish-tool .buttons {
margin-top: 10px;
}
.publish-tool .buttons button {
padding: 10px 20px;
font-size: 16px;
margin-right: 10px;
cursor: pointer;
}
.success {
color: green;
margin: 10px 0;
}
.error {
color: red;
margin: 10px 0;
}
</style>
<script>
// 重置表单
function resetForm() {
tinymce.get('content').setContent(''); // 清空 TinyMCE 内容
document.querySelector('input[name="title"]').value = '';
document.querySelector('select[name="category"]').selectedIndex = 0;
document.querySelector('input[name="tags"]').value = '';
}
</script>
</head>
<body>
<div class="publish-tool">
<h1>所见即所得发布工具</h1>
<form method="POST">
<?php wp_nonce_field('markdown_publish_action', 'markdown_publish_nonce'); ?>
<div>
<label for="title">标题:</label>
<input type="text" name="title" id="title" required>
</div>
<div>
<label for="content">内容:</label>
<textarea name="content" id="content" placeholder="在此输入内容..." required></textarea>
</div>
<div>
<label for="category">分类:</label>
<select name="category" id="category">
<?php foreach ($categories as $cat): ?>
<option value="<?php echo $cat->term_id; ?>"><?php echo $cat->name; ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="tags">标签(用逗号分隔):</label>
<input type="text" name="tags" id="tags">
</div>
<div class="buttons">
<button type="submit" name="publish">发布</button>
<button type="button" onclick="resetForm()">重置</button>
</div>
</form>
</div>
</body>
</html>

总结

  • 确保 TinyMCE 的 API Key 有效。
  • 确保 TinyMCE 内容正确传递到表单中。
  • 如果问题仍然存在,可以尝试使用本地 TinyMCE 或其他富文本编辑器。

如果还有其他问题,欢迎继续提问!

时间: 2025-02-25T00:59:49


👤 用户

我已经更改了api key,已经可以加载tinymce,点击发布按钮后没有反应。

时间: 2025-02-25T01:04:38


🤖 DeepSeek (deepseek-chat)

如果 TinyMCE 已经成功加载,但点击“发布”按钮后没有反应,可能是以下原因之一:


1. 表单提交未正确处理

  • 原因:表单提交时,TinyMCE 的内容可能未正确同步到 textarea 中,导致 $_POST['content'] 为空。

  • 解决方法
    在表单提交时,确保 TinyMCE 的内容被正确同步到 textarea 中。可以在表单的 onsubmit 事件中手动同步内容。

    修改代码如下:

    1
    2
    3
    4
    document.querySelector('form').onsubmit = function() {
    var content = tinymce.get('content').getContent(); // 获取 TinyMCE 内容
    document.querySelector('textarea[name="content"]').value = content; // 同步到 textarea
    };

2. JavaScript 错误

  • 原因:页面中可能存在其他 JavaScript 错误,导致表单提交被中断。
  • 解决方法
    1. 打开浏览器的开发者工具(按 F12),切换到 Console 标签页。
    2. 检查是否有红色错误信息。
    3. 如果有错误,根据错误信息修复代码。

3. 表单未正确提交

  • 原因:表单的 action 属性未设置,或者提交方式不正确。
  • 解决方法
    确保表单的 methodaction 属性正确。你的代码中已经设置了 method="POST",但可以显式添加 action 属性:
    1
    <form method="POST" action="">

4. PHP 代码未正确处理 POST 数据

  • 原因:PHP 代码可能未正确接收到 $_POST 数据。
  • 解决方法
    在 PHP 代码中添加调试信息,检查 $_POST 数据是否正常:
    1
    2
    3
    4
    5
    6
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    echo '<pre>';
    print_r($_POST);
    echo '</pre>';
    exit;
    }
    提交表单后,查看输出的 $_POST 数据,确保 titlecontent 字段存在且不为空。

5. TinyMCE 初始化问题

  • 原因:TinyMCE 可能未正确初始化,导致 tinymce.get('content') 返回 null
  • 解决方法
    确保 TinyMCE 初始化代码正确执行。可以在初始化完成后添加日志:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    tinymce.init({
    selector: '#content',
    height: 500,
    menubar: false,
    plugins: [
    'advlist autolink lists link image charmap print preview anchor',
    'searchreplace visualblocks code fullscreen',
    'insertdatetime media table paste code help wordcount'
    ],
    toolbar: 'undo redo | formatselect | bold italic backcolor | \
    alignleft aligncenter alignright alignjustify | \
    bullist numlist outdent indent | removeformat | help',
    init_instance_callback: function(editor) {
    console.log('TinyMCE 初始化完成'); // 检查初始化是否成功
    }
    });

6. 完整修复代码

以下是修复后的完整代码,确保 TinyMCE 内容正确提交并处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<?php
// 加载 WordPress 环境
require_once('../wp-load.php');

// 检查是否提交了表单
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content']) && isset($_POST['title'])) {
// 检查 nonce 和用户权限
if (!isset($_POST['markdown_publish_nonce']) || !wp_verify_nonce($_POST['markdown_publish_nonce'], 'markdown_publish_action')) {
echo '<div class="error">安全验证失败,请重试。</div>';
} elseif (!current_user_can('publish_posts')) {
echo '<div class="error">你没有权限发布文章。</div>';
} else {
// 获取表单数据
$title = sanitize_text_field($_POST['title']);
$content = $_POST['content']; // TinyMCE 输出的 HTML 内容
$category = isset($_POST['category']) ? intval($_POST['category']) : 0; // 分类 ID
$tags = isset($_POST['tags']) ? sanitize_text_field($_POST['tags']) : ''; // 标签

// 发布文章
$post_id = wp_insert_post([
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish', // 直接发布
'post_author' => get_current_user_id(), // 当前用户为作者
'post_category' => [$category], // 分配分类
]);

if ($post_id) {
// 分配标签
if (!empty($tags)) {
wp_set_post_tags($post_id, $tags);
}

echo '<div class="success">文章发布成功!<a href="' . get_permalink($post_id) . '">查看文章</a></div>';
} else {
echo '<div class="error">文章发布失败,请重试。</div>';
}
}
}

// 获取所有分类
$categories = get_categories(['hide_empty' => false]);
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>所见即所得发布工具</title>
<!-- 引入 TinyMCE -->
<script src="https://cdn.tiny.cloud/1/你的API Key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
<script>
tinymce.init({
selector: '#content', // 绑定到 textarea
height: 500, // 编辑器高度
menubar: false, // 隐藏菜单栏
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code help wordcount'
],
toolbar: 'undo redo | formatselect | bold italic backcolor | \
alignleft aligncenter alignright alignjustify | \
bullist numlist outdent indent | removeformat | help',
init_instance_callback: function(editor) {
console.log('TinyMCE 初始化完成'); // 检查初始化是否成功
}
});

// 表单提交时同步 TinyMCE 内容
document.querySelector('form').onsubmit = function() {
var content = tinymce.get('content').getContent(); // 获取 TinyMCE 内容
document.querySelector('textarea[name="content"]').value = content; // 同步到 textarea
};
</script>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.publish-tool {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
.publish-tool textarea {
width: 100%;
height: 200px;
padding: 10px;
font-size: 16px;
}
.publish-tool .buttons {
margin-top: 10px;
}
.publish-tool .buttons button {
padding: 10px 20px;
font-size: 16px;
margin-right: 10px;
cursor: pointer;
}
.success {
color: green;
margin: 10px 0;
}
.error {
color: red;
margin: 10px 0;
}
</style>
<script>
// 重置表单
function resetForm() {
tinymce.get('content').setContent(''); // 清空 TinyMCE 内容
document.querySelector('input[name="title"]').value = '';
document.querySelector('select[name="category"]').selectedIndex = 0;
document.querySelector('input[name="tags"]').value = '';
}
</script>
</head>
<body>
<div class="publish-tool">
<h1>所见即所得发布工具</h1>
<form method="POST" action="">
<?php wp_nonce_field('markdown_publish_action', 'markdown_publish_nonce'); ?>
<div>
<label for="title">标题:</label>
<input type="text" name="title" id="title" required>
</div>
<div>
<label for="content">内容:</label>
<textarea name="content" id="content" placeholder="在此输入内容..." required></textarea>
</div>
<div>
<label for="category">分类:</label>
<select name="category" id="category">
<?php foreach ($categories as $cat): ?>
<option value="<?php echo $cat->term_id; ?>"><?php echo $cat->name; ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="tags">标签(用逗号分隔):</label>
<input type="text" name="tags" id="tags">
</div>
<div class="buttons">
<button type="submit" name="publish">发布</button>
<button type="button" onclick="resetForm()">重置</button>
</div>
</form>
</div>
</body>
</html>

测试步骤

  1. 打开页面,确保 TinyMCE 编辑器正常加载。
  2. 输入标题和内容,选择分类和标签。
  3. 点击“发布”按钮,检查是否有成功或失败的提示信息。
  4. 如果仍然没有反应,打开浏览器的开发者工具(按 F12),查看 ConsoleNetwork 标签页,检查是否有错误或请求未发送。

如果问题仍未解决,请提供更多详细信息(如浏览器控制台错误信息),我会进一步帮助你排查问题!

时间: 2025-02-25T01:04:38


👤 用户

出现以上提示

时间: 2025-02-25T01:09:16


🤖 DeepSeek (deepseek-chat)

根据错误提示,问题出在 <textarea> 元素上。具体原因是:

  1. <textarea> 被隐藏

    • TinyMCE 初始化后,会将原始的 <textarea> 隐藏(设置为 display: nonevisibility: hidden)。
    • 由于 <textarea> 被隐藏,浏览器无法对其进行验证(即使设置了 required 属性)。
  2. required 属性冲突

    • 你为 <textarea> 设置了 required 属性,但隐藏的表单控件无法通过浏览器的默认验证。

解决方法

方法 1:移除 required 属性

如果 TinyMCE 编辑器已经确保内容不为空,可以移除 <textarea>required 属性。

1
<textarea name="content" id="content" placeholder="在此输入内容..."></textarea>

方法 2:手动验证内容

在表单提交时,手动检查 TinyMCE 的内容是否为空。

1
2
3
4
5
6
7
8
document.querySelector('form').onsubmit = function() {
var content = tinymce.get('content').getContent(); // 获取 TinyMCE 内容
if (!content.trim()) {
alert('内容不能为空!');
return false; // 阻止表单提交
}
document.querySelector('textarea[name="content"]').value = content; // 同步到 textarea
};

方法 3:隐藏 <textarea> 但不影响验证

<textarea> 设置为透明且不可见,但仍然占据空间,以便通过浏览器验证。

1
2
<textarea name="content" id="content" placeholder="在此输入内容..." required
style="opacity: 0; height: 0; width: 0; position: absolute;"></textarea>

方法 4:禁用浏览器默认验证

在表单中添加 novalidate 属性,禁用浏览器的默认验证,完全依赖 JavaScript 验证。

1
<form method="POST" action="" novalidate>

修复后的完整代码

以下是结合 方法 2方法 4 的修复代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php
// 加载 WordPress 环境
require_once('../wp-load.php');

// 检查是否提交了表单
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content']) && isset($_POST['title'])) {
// 检查 nonce 和用户权限
if (!isset($_POST['markdown_publish_nonce']) || !wp_verify_nonce($_POST['markdown_publish_nonce'], 'markdown_publish_action')) {
echo '<div class="error">安全验证失败,请重试。</div>';
} elseif (!current_user_can('publish_posts')) {
echo '<div class="error">你没有权限发布文章。</div>';
} else {
// 获取表单数据
$title = sanitize_text_field($_POST['title']);
$content = $_POST['content']; // TinyMCE 输出的 HTML 内容
$category = isset($_POST['category']) ? intval($_POST['category']) : 0; // 分类 ID
$tags = isset($_POST['tags']) ? sanitize_text_field($_POST['tags']) : ''; // 标签

// 发布文章
$post_id = wp_insert_post([
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish', // 直接发布
'post_author' => get_current_user_id(), // 当前用户为作者
'post_category' => [$category], // 分配分类
]);

if ($post_id) {
// 分配标签
if (!empty($tags)) {
wp_set_post_tags($post_id, $tags);
}

echo '<div class="success">文章发布成功!<a href="' . get_permalink($post_id) . '">查看文章</a></div>';
} else {
echo '<div class="error">文章发布失败,请重试。</div>';
}
}
}

// 获取所有分类
$categories = get_categories(['hide_empty' => false]);
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>所见即所得发布工具</title>
<!-- 引入 TinyMCE -->
<script src="https://cdn.tiny.cloud/1/你的API Key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
<script>
tinymce.init({
selector: '#content', // 绑定到 textarea
height: 500, // 编辑器高度
menubar: false, // 隐藏菜单栏
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code help wordcount'
],
toolbar: 'undo redo | formatselect | bold italic backcolor | \
alignleft aligncenter alignright alignjustify | \
bullist numlist outdent indent | removeformat | help',
init_instance_callback: function(editor) {
console.log('TinyMCE 初始化完成'); // 检查初始化是否成功
}
});

// 表单提交时同步 TinyMCE 内容
document.querySelector('form').onsubmit = function() {
var content = tinymce.get('content').getContent(); // 获取 TinyMCE 内容
if (!content.trim()) {
alert('内容不能为空!');
return false; // 阻止表单提交
}
document.querySelector('textarea[name="content"]').value = content; // 同步到 textarea
};
</script>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.publish-tool {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
.publish-tool textarea {
width: 100%;
height: 200px;
padding: 10px;
font-size: 16px;
}
.publish-tool .buttons {
margin-top: 10px;
}
.publish-tool .buttons button {
padding: 10px 20px;
font-size: 16px;
margin-right: 10px;
cursor: pointer;
}
.success {
color: green;
margin: 10px 0;
}
.error {
color: red;
margin: 10px 0;
}
</style>
<script>
// 重置表单
function resetForm() {
tinymce.get('content').setContent(''); // 清空 TinyMCE 内容
document.querySelector('input[name="title"]').value = '';
document.querySelector('select[name="category"]').selectedIndex = 0;
document.querySelector('input[name="tags"]').value = '';
}
</script>
</head>
<body>
<div class="publish-tool">
<h1>所见即所得发布工具</h1>
<form method="POST" action="" novalidate>
<?php wp_nonce_field('markdown_publish_action', 'markdown_publish_nonce'); ?>
<div>
<label for="title">标题:</label>
<input type="text" name="title" id="title" required>
</div>
<div>
<label for="content">内容:</label>
<textarea name="content" id="content" placeholder="在此输入内容..."></textarea>
</div>
<div>
<label for="category">分类:</label>
<select name="category" id="category">
<?php foreach ($categories as $cat): ?>
<option value="<?php echo $cat->term_id; ?>"><?php echo $cat->name; ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="tags">标签(用逗号分隔):</label>
<input type="text" name="tags" id="tags">
</div>
<div class="buttons">
<button type="submit" name="publish">发布</button>
<button type="button" onclick="resetForm()">重置</button>
</div>
</form>
</div>
</body>
</html>

测试步骤

  1. 打开页面,确保 TinyMCE 编辑器正常加载。
  2. 输入标题和内容,选择分类和标签。
  3. 点击“发布”按钮,检查是否有成功或失败的提示信息。
  4. 如果内容为空,会弹出提示“内容不能为空!”并阻止表单提交。

如果还有其他问题,欢迎继续提问!

时间: 2025-02-25T01:09:16


👤 用户

下面是你之前修改的myautosave代码。当我通过tinymce发布文章是出现错误。

时间: 2025-02-25T01:14:26


👤 用户

post_content; // 提取所有图片 URL if (preg_match_all('//i', $post->post_content, $matches)) { $first_images = $matches[1]; foreach ($first_images as $first_image) { // 检查图片域名是否与当前站点一致 if (strpos($first_image, $_SERVER['HTTP_HOST']) === false) { // 下载并保存图片 $get = wp_remote_get($first_image); if (!is_wp_error($get)) { $type = wp_remote_retrieve_header($get, 'content-type'); $mirror = wp_upload_bits(rawurldecode(basename($first_image)), '', wp_remote_retrieve_body($get)); if (!$mirror['error']) { // 创建附件 $attachment = array( 'post_title' => basename($first_image), 'post_mime_type' => $type ); $attach_id = wp_insert_attachment($attachment, $mirror['file'], $post_ID); if (!is_wp_error($attach_id)) { // 生成附件元数据并更新 $attach_data = wp_generate_attachment_metadata($attach_id, $mirror['file']); wp_update_attachment_metadata($attach_id, $attach_data); // 替换文章中的图片 URL $updated = str_replace($first_image, $mirror['url'], $updated); } } } } } // 更新文章内容 wp_update_post(array('ID' => $post_ID, 'post_content' => $updated)); } } ?>

时间: 2025-02-25T01:14:32


🤖 DeepSeek (deepseek-chat)

你的 WordPress 插件代码旨在自动下载远程图片并保存到本地,然后在文章中使用本地图片 URL 替换远程图片 URL。这是一个非常有用的功能,尤其是在处理从其他网站复制的内容时。以下是对代码的分析和一些改进建议:


代码分析

  1. 钩子 publish_post

    • 当文章发布时,触发 fetch_images 函数。
    • 确保只在发布文章时执行,而不是在自动保存或草稿时执行。
  2. 权限检查

    • 使用 current_user_can('edit_post', $post_ID) 确保当前用户有权限编辑文章。
  3. 提取图片 URL

    • 使用正则表达式 preg_match_all 提取文章内容中的所有图片 URL。
  4. 下载并保存图片

    • 使用 wp_remote_get 下载远程图片。
    • 使用 wp_upload_bits 将图片保存到 WordPress 的上传目录。
  5. 创建附件

    • 使用 wp_insert_attachment 将图片作为附件插入到文章中。
    • 使用 wp_generate_attachment_metadata 生成附件的元数据(如缩略图)。
  6. 替换文章内容

    • 使用 str_replace 将文章中的远程图片 URL 替换为本地图片 URL。
    • 使用 wp_update_post 更新文章内容。

改进建议

  1. 处理 HTTPS 图片

    • 如果远程图片使用 HTTPS,确保下载时也使用 HTTPS。
    • 可以在 wp_remote_get 前检查 URL 的协议。
  2. 处理重复文件名

    • 如果多个图片具有相同的文件名,可能会导致文件覆盖。
    • 可以在保存文件时生成唯一的文件名。
  3. 错误处理

    • 增加对下载失败、文件保存失败等情况的错误处理。
    • 记录错误日志以便调试。
  4. 性能优化

    • 如果文章中有大量图片,可能会导致处理时间过长。
    • 可以考虑使用异步任务或分批处理。
  5. 支持更多图片格式

    • 确保插件支持常见的图片格式(如 .jpg, .png, .gif, .webp 等)。
  6. 增加设置选项

    • 允许用户选择是否启用自动下载远程图片功能。
    • 允许用户设置图片保存路径或其他选项。

改进后的代码

以下是改进后的代码,包含上述建议:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
/*
Plugin Name: MY Auto Save Remote Image
Plugin URI: http://www.devsaab.com/wordpress/
Description: This plugin automatically downloads all remote images from a post and saves them locally.
Version: 1.4
Author: Prebhdev Singh
Disclaimer: No warranty or guarantee of any kind! Use this at your own risk.
*/

add_action('publish_post', 'fetch_images');

function fetch_images($post_ID) {
// 检查是否正在自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}

// 检查用户权限
if (!current_user_can('edit_post', $post_ID)) {
return;
}

// 获取文章内容
$post = get_post($post_ID);
$updated = $post->post_content;

// 提取所有图片 URL
if (preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)) {
$first_images = $matches[1];

foreach ($first_images as $first_image) {
// 检查图片域名是否与当前站点一致
if (strpos($first_image, $_SERVER['HTTP_HOST']) === false) {
// 处理 HTTPS
$first_image = str_replace('http://', 'https://', $first_image);

// 下载图片
$get = wp_remote_get($first_image);
if (!is_wp_error($get)) {
$type = wp_remote_retrieve_header($get, 'content-type');
if (strpos($type, 'image') === false) {
continue; // 如果不是图片,跳过
}

// 生成唯一文件名
$filename = wp_unique_filename(wp_upload_dir()['path'], rawurldecode(basename($first_image)));

// 保存图片
$mirror = wp_upload_bits($filename, '', wp_remote_retrieve_body($get));

if (!$mirror['error']) {
// 创建附件
$attachment = array(
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_mime_type' => $type
);
$attach_id = wp_insert_attachment($attachment, $mirror['file'], $post_ID);

if (!is_wp_error($attach_id)) {
// 生成附件元数据并更新
$attach_data = wp_generate_attachment_metadata($attach_id, $mirror['file']);
wp_update_attachment_metadata($attach_id, $attach_data);

// 替换文章中的图片 URL
$updated = str_replace($first_image, $mirror['url'], $updated);
}
} else {
error_log('Failed to save image: ' . $first_image);
}
} else {
error_log('Failed to download image: ' . $first_image);
}
}
}

// 更新文章内容
if ($updated !== $post->post_content) {
wp_update_post(array('ID' => $post_ID, 'post_content' => $updated));
}
}
}
?>

改进点说明

  1. HTTPS 支持

    • 使用 str_replacehttp:// 替换为 https://,确保下载时使用 HTTPS。
  2. 唯一文件名

    • 使用 wp_unique_filename 生成唯一的文件名,避免文件覆盖。
  3. 错误日志

    • 使用 error_log 记录下载或保存失败的错误信息。
  4. 图片格式检查

    • 检查 content-type 是否为图片类型,避免下载非图片文件。
  5. 性能优化

    • 仅在文章内容发生变化时更新文章,避免不必要的数据库操作。

使用方法

  1. 将代码保存为 my-auto-save-remote-image.php
  2. 将文件上传到 WordPress 的 wp-content/plugins/ 目录。
  3. 在 WordPress 后台激活插件。
  4. 发布文章时,插件会自动下载远程图片并替换为本地图片。

注意事项

  • 测试环境:在生产环境使用前,建议在测试环境中测试插件功能。
  • 备份:在使用插件前,备份网站数据和文件,以防出现问题。
  • 性能监控:如果文章中有大量图片,可能会影响发布速度,建议监控服务器性能。

如果有其他问题或需要进一步优化,欢迎继续提问!

时间: 2025-02-25T01:14:32


👤 用户

错误如下:
Fatal error: Uncaught Error: Call to undefined function wp_generate_attachment_metadata() in /var/www/html/wp-content/plugins/myautosave.php:62 Stack trace: #0 /var/www/html/wp-includes/class-wp-hook.php(288): fetch_images(1311) #1 /var/www/html/wp-includes/class-wp-hook.php(310): WP_Hook->apply_filters(NULL, Array) #2 /var/www/html/wp-includes/plugin.php(453): WP_Hook->do_action(Array) #3 /var/www/html/wp-includes/post.php(4262): do_action(‘publish_post’, 1311, Object(WP_Post)) #4 /var/www/html/wp-includes/post.php(3689): wp_transition_post_status(‘publish’, ‘new’, Object(WP_Post)) #5 /var/www/html/pub/indexs.php(25): wp_insert_post(Array) #6 {main} thrown in /var/www/html/wp-content/plugins/myautosave.php on line 62

时间: 2025-02-25T01:16:33


🤖 DeepSeek (deepseek-chat)

错误信息表明 wp_generate_attachment_metadata 函数未定义。这是因为在 WordPress 中,wp_generate_attachment_metadata 函数位于 wp-admin/includes/image.php 文件中,而这个文件默认不会在插件或主题中自动加载。


解决方法

在调用 wp_generate_attachment_metadata 之前,需要手动引入 wp-admin/includes/image.php 文件。以下是修复后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php
/*
Plugin Name: MY Auto Save Remote Image
Plugin URI: http://www.devsaab.com/wordpress/
Description: This plugin automatically downloads all remote images from a post and saves them locally.
Version: 1.4
Author: Prebhdev Singh
Disclaimer: No warranty or guarantee of any kind! Use this at your own risk.
*/

add_action('publish_post', 'fetch_images');

function fetch_images($post_ID) {
// 检查是否正在自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}

// 检查用户权限
if (!current_user_can('edit_post', $post_ID)) {
return;
}

// 引入 WordPress 图像处理函数
require_once(ABSPATH . 'wp-admin/includes/image.php');

// 获取文章内容
$post = get_post($post_ID);
$updated = $post->post_content;

// 提取所有图片 URL
if (preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)) {
$first_images = $matches[1];

foreach ($first_images as $first_image) {
// 检查图片域名是否与当前站点一致
if (strpos($first_image, $_SERVER['HTTP_HOST']) === false) {
// 处理 HTTPS
$first_image = str_replace('http://', 'https://', $first_image);

// 下载图片
$get = wp_remote_get($first_image);
if (!is_wp_error($get)) {
$type = wp_remote_retrieve_header($get, 'content-type');
if (strpos($type, 'image') === false) {
continue; // 如果不是图片,跳过
}

// 生成唯一文件名
$filename = wp_unique_filename(wp_upload_dir()['path'], rawurldecode(basename($first_image)));

// 保存图片
$mirror = wp_upload_bits($filename, '', wp_remote_retrieve_body($get));

if (!$mirror['error']) {
// 创建附件
$attachment = array(
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_mime_type' => $type
);
$attach_id = wp_insert_attachment($attachment, $mirror['file'], $post_ID);

if (!is_wp_error($attach_id)) {
// 生成附件元数据并更新
$attach_data = wp_generate_attachment_metadata($attach_id, $mirror['file']);
wp_update_attachment_metadata($attach_id, $attach_data);

// 替换文章中的图片 URL
$updated = str_replace($first_image, $mirror['url'], $updated);
}
} else {
error_log('Failed to save image: ' . $first_image);
}
} else {
error_log('Failed to download image: ' . $first_image);
}
}
}

// 更新文章内容
if ($updated !== $post->post_content) {
wp_update_post(array('ID' => $post_ID, 'post_content' => $updated));
}
}
}
?>

关键修复点

  1. 引入 wp-admin/includes/image.php

    • 在函数开头添加以下代码:
      1
      require_once(ABSPATH . 'wp-admin/includes/image.php');
    • 这确保了 wp_generate_attachment_metadata 函数可用。
  2. 确保文件路径正确

    • ABSPATH 是 WordPress 根目录的绝对路径,确保路径拼接正确。

测试步骤

  1. 将修复后的代码保存为 my-auto-save-remote-image.php
  2. 上传到 WordPress 的 wp-content/plugins/ 目录。
  3. 在 WordPress 后台激活插件。
  4. 发布一篇包含远程图片的文章,检查插件是否正常工作。

注意事项

  1. 权限问题

    • 确保 WordPress 的上传目录(wp-content/uploads)有正确的写权限。
  2. HTTPS 支持

    • 如果远程图片使用 HTTPS,确保服务器支持 HTTPS 请求。
  3. 性能监控

    • 如果文章中有大量图片,可能会影响发布速度,建议监控服务器性能。

如果问题仍未解决,请提供更多错误信息或上下文,我会进一步帮助你排查问题!

时间: 2025-02-25T01:16:33



对话统计

  • 消息总数: 17 条
  • 处理状态: 成功转换