创新实训(九) 博客的编辑

博客的编写采用富文本格式,可以设置标签方便检索,可以设置公开状态,可以对博客进行删除。
image
image

博客编辑器

该部分的代码编写在blog-editor.php文件中,定义了通用的博客编写格式
这段代码展示了一个用于编辑博客内容的表单。该表单具有标题、标签、内容输入框,以及博客的可见性选项。它还包括了相应的JavaScript代码,用于初始化博客编辑器和切换按钮。以下是每部分代码的详细解释:

  1. 表单的开始:

    • 表单采用了POST方法,并支持文件上传(enctype="multipart/form-data")。
    • 使用了一个隐藏的令牌来防止CSRF攻击。
    <form method="post" class="form-horizontal" id="form-<?= $editor->name ?>" enctype="multipart/form-data">
    <?= HTML::hiddenToken() ?>
    
  2. 标题和标签输入框:

    • 两个输入框分别用于博客的标题和标签,采用Bootstrap网格系统进行布局。
    <div class="row">
        <div class="col-sm-6">
            <?= HTML::div_vinput("{$editor->name}_title", 'text', $editor->label_text['title'], html_entity_decode($editor->cur_data['title'])) ?>
        </div>
        <div class="col-sm-6">
            <?= HTML::div_vinput("{$editor->name}_tags", 'text', $editor->label_text['tags'], join(', ', $editor->cur_data['tags'])) ?>
        </div>
    </div>
    
  3. 内容输入框:

    • 一个用于博客内容的多行文本输入框。
    <?= HTML::div_vtextarea("{$editor->name}_content_md", $editor->label_text['content'], $editor->cur_data['content_md']) ?>
    
  4. 操作按钮和隐藏选项:

    • 包含一个查看博客的按钮和一个用于切换博客可见性的复选框。
    <div class="row mt-2">
        <div class="col-sm-6">
            <?php if ($editor->blog_url): ?>
            <a id="a-<?= $editor->name ?>_view_blog" class="btn btn-info" href="<?= HTML::escape($editor->blog_url) ?>"><?= $editor->label_text['view blog'] ?></a>
            <?php else: ?>
            <a id="a-<?= $editor->name ?>_view_blog" class="btn btn-info" style="display: none;"><?= $editor->label_text['view blog'] ?></a>
            <?php endif ?>
        </div>
        <div class="col-sm-6 text-right">
            <?= HTML::checkbox("{$editor->name}_is_hidden", $editor->cur_data['is_hidden']) ?>
        </div>
    </div>
    
  5. 表单结束:

    • 结束表单标签。
    </form>
    
  6. JavaScript部分:

    • 使用bootstrapSwitch初始化可见性切换按钮。
    • 调用blog_editor_init函数初始化博客编辑器。
    <script type="text/javascript">
    $('#<?= "input-{$editor->name}_is_hidden" ?>').bootstrapSwitch({
        onText: <?= json_encode($editor->label_text['private']) ?>,
        onColor: 'danger',
        offText: <?= json_encode($editor->label_text['public']) ?>,
        offColor: 'primary',
        labelText: <?= json_encode($editor->label_text['blog visibility']) ?>,
        handleWidth: 100
    });
    blog_editor_init("<?= $editor->name ?>", <?= json_encode(array('type' => $editor->type)) ?>);
    </script>
    

博客编写

具体的博客编写的功能实现在blog-write.php文件中
这个PHP脚本展示了一个用于撰写和编辑博客的页面。包括权限验证、博客数据处理、博客编辑器初始化等部分。以下是每段代码的详细解释:

代码详细解释

权限验证和博客获取

  1. 加载必要的库和权限验证:

    • 加载form库。
    • 检查当前用户是否有权限撰写博客,如果没有权限则返回403错误页面。
    requirePHPLib('form');
    
    if (!UOJContext::hasBlogPermission()) {
        become403Page();
    }
    
  2. 获取博客数据:

    • 根据GET参数中的id值获取对应的博客。如果id无效或博客不存在,返回404错误页面。
    • 如果没有提供id,则尝试获取当前用户的草稿博客。
    if (isset($_GET['id'])) {
        if (!validateUInt($_GET['id']) || !($blog = queryBlog($_GET['id'])) || !UOJContext::isHisBlog($blog)) {
            become404Page();
        }
    } else {
        $blog = DB::selectFirst("select * from blogs where poster = '".UOJContext::user()['username']."' and type = 'B' and is_draft = true");
    }
    

初始化博客编辑器

  1. 初始化博客编辑器:

    • 创建UOJBlogEditor实例并设置博客编辑器的名称。
    • 根据获取的博客数据初始化编辑器的当前数据。如果没有博客数据,则设置默认值。
    $blog_editor = new UOJBlogEditor();
    $blog_editor->name = 'blog';
    if ($blog) {
        $blog_editor->cur_data = array(
            'title' => $blog['title'],
            'content_md' => $blog['content_md'],
            'content' => $blog['content'],
            'tags' => queryBlogTags($blog['id']),
            'is_hidden' => $blog['is_hidden']
        );
    } else {
        $blog_editor->cur_data = array(
            'title' => '新博客',
            'content_md' => '',
            'content' => '',
            'tags' => array(),
            'is_hidden' => true
        );
    }
    
  2. 设置博客URL:

    • 如果博客不是草稿,则设置博客的URL,否则设置为空。
    if ($blog && !$blog['is_draft']) {
        $blog_editor->blog_url = HTML::blog_url(UOJContext::user()['username'], "/post/{$blog['id']}");
    } else {
        $blog_editor->blog_url = null;
    }
    

数据库操作函数

  1. 定义更新和插入博客的函数:

    • updateBlog函数更新已有博客的数据。
    • insertBlog函数插入新的博客数据。
    function updateBlog($id, $data) {
        DB::update("update blogs set title = '".DB::escape($data['title'])."', content = '".DB::escape($data['content'])."', content_md = '".DB::escape($data['content_md'])."', is_hidden = {$data['is_hidden']} where id = {$id}");
    }
    function insertBlog($data) {
        DB::insert("insert into blogs (title, content, content_md, poster, is_hidden, is_draft, post_time) values ('".DB::escape($data['title'])."', '".DB::escape($data['content'])."', '".DB::escape($data['content_md'])."', '".Auth::id()."', {$data['is_hidden']}, {$data['is_draft']}, now())");
    }
    

保存博客的处理逻辑

  1. 定义博客编辑器的保存逻辑:

    • 根据博客是否存在、是否是草稿、是否隐藏等条件进行不同的处理,包括更新博客、删除博客、插入博客,以及处理博客标签的更新。
    $blog_editor->save = function($data) {
        global $blog;
        $ret = array();
        if ($blog) {
            if ($blog['is_draft']) {
                if ($data['is_hidden']) {
                    updateBlog($blog['id'], $data);
                } else {
                    deleteBlog($blog['id']);
                    insertBlog(array_merge($data, array('is_draft' => 0)));
                    $blog = array('id' => DB::insert_id(), 'tags' => array());
                    $ret['blog_write_url'] = HTML::blog_url(UOJContext::user()['username'], "/post/{$blog['id']}/write");
                    $ret['blog_url'] = HTML::blog_url(UOJContext::user()['username'], "/post/{$blog['id']}");
                }
            } else {
                updateBlog($blog['id'], $data);
            }
        } else {
            insertBlog(array_merge($data, array('is_draft' => $data['is_hidden'] ? 1 : 0)));
            $blog = array('id' => DB::insert_id(), 'tags' => array());
            if (!$data['is_hidden']) {
                $ret['blog_write_url'] = HTML::blog_url(UOJContext::user()['username'], "/post/{$blog['id']}/write");
                $ret['blog_url'] = HTML::blog_url(UOJContext::user()['username'], "/post/{$blog['id']}");
            }
        }
        if ($data['tags'] !== $blog['tags']) {
            DB::delete("delete from blogs_tags where blog_id = {$blog['id']}");
            foreach ($data['tags'] as $tag) {
                DB::insert("insert into blogs_tags (blog_id, tag) values ({$blog['id']}, '".DB::escape($tag)."')");
            }
        }
        return $ret;
    };
    

运行博客编辑器

  1. 运行博客编辑器:

    • 执行博客编辑器的服务器端逻辑。
    $blog_editor->runAtServer();
    

输出页面

  1. 输出页面内容:

    • 输出页面头部、博客编辑器HTML和页面尾部。
    <?php echoUOJPageHeader('写博客') ?>
    <?php $blog_editor->printHTML() ?>
    <?php echoUOJPageFooter() ?>
    

博客的删除

image

博客删除的业务逻辑单独写在文件blog-delete.php中
该代码展示了一个博客删除确认页面,要求用户确认删除博客,并处理删除博客的操作。下面是对代码每个部分的详细解释:

引入库和权限检查

  1. 引入必要的库和权限检查:

    • 加载form库。
    • 检查当前用户是否有删除博客的权限,如果没有权限则返回403错误页面。
    requirePHPLib('form');
    
    if (!UOJContext::hasBlogPermission()) {
        become403Page();
    }
    
  2. 博客数据获取和验证:

    • 检查GET参数中的id是否存在且有效,确保博客存在且当前用户有权限操作该博客。如果验证失败,则返回404错误页面。
    if (!isset($_GET['id']) || !validateUInt($_GET['id']) || !($blog = queryBlog($_GET['id'])) || !UOJContext::isHis($blog)) {
        become404Page();
    }
    

删除表单处理

  1. 初始化删除表单:

    • 创建一个新的UOJForm实例,用于处理博客删除操作。
    • 设置表单的处理函数,删除对应的博客。
    • 配置删除按钮的样式和文本。
    • 设置删除成功后的重定向URL为博客存档页面。
    $delete_form = new UOJForm('delete');
    $delete_form->handle = function() {
        global $blog;
        deleteBlog($blog['id']); 
    };
    $delete_form->submit_button_config['class_str'] = 'btn btn-danger';
    $delete_form->submit_button_config['text'] = '是的,我确定要删除';
    $delete_form->succ_href = "/archive";
    
    $delete_form->runAtServer();
    

输出页面内容

  1. 输出页面头部和确认信息:

    • 输出页面头部,并显示确认删除博客的标题。
    • 使用HTML::stripTags函数来避免标题中的HTML标签。
    <?php echoUOJPageHeader('删除博客 - ' . HTML::stripTags($blog['title'])) ?>
    <h3>您真的要删除博客 <?= $blog['title'] ?> 吗?该操作不可逆!</h3>
    
  2. 输出删除表单的HTML:

    • 输出删除表单的HTML内容,包括提交按钮。
    <?php $delete_form->printHTML(); ?>
    
  3. 输出页面尾部:

    • 输出页面尾部内容。
    <?php echoUOJPageFooter() ?>
    
posted @   贺丁  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示