在Theme-editor.php中如何添加创建文件的方法

时间:2021-01-27 作者:Nadal

这是我目标的一个概念

concept image

我想通过在文本字段中输入完整的文件名和扩展名,在当前打开的目录中创建文件,单击创建并使用AJAX进程运行file_put_contents() 方法

我还没有尝试过任何编码方法,因为我甚至没有一个起点。经过18个小时的研究,我只找到了使用add_theme_page() 添加一个可以进行所有自定义编码的页面。虽然这是一个可靠的选项,但我希望将其全部保存在核心文件编辑器中。创建一个完整的文件编辑器,它可以完成与核心相同的任务,唯一的区别是一个文本字段,这简直是小题大做。

在绝望中,我使用了admin_notices 操作以插入输入字段和按钮,并附加一个只在指定主题上显示的函数,并运行文件创建过程。这不是我想要的解决方案,所以我认为不适合作为答案发布。

public static function makeFile($file, $data=null)
{
    if( !is_null(mb::getPost(\'makecss\')) ) {
        file_put_contents(DEF_THEMEPATH.\'/styles/\'.$file.\'.css\', $data);
        
        wp_redirect( add_query_arg([\'file\'=>\'styles/\'.$file.\'.css\',\'theme\'=>\'thor\'],admin_url(\'theme-editor.php\')) );
        exit;
    }
    
    $newfile = \'
    <div class="newfile-form">
    <form method="post" action="">
        <p>Create New CSS File</p>
        <span>File name: <input type="text" name="newfile" id="newfile" value="" /></span>
        <span><button type="submit" name="makecss" class="button button-primary">Create File</button></span>
    </form>
    </div>
    \';
    return $newfile;
}

action

if( strstr(mb::urlVar(\'theme\'), \'thor\') ) {
 add_action(\'admin_notices\', function() {
    echo mb::makeFile(mb::getPost(\'newfile\'));
 });
}

结果

result of method used

注:mb 表示我的php类的名称

注意:尽管.css 扩展如图所示,我将其作为默认扩展,并且是唯一可能的扩展。javascript方法将任何句点和后面的字符串替换为null

1 个回复
最合适的回答,由SO网友:Nadal 整理而成

我无法定义一个;“准确”;方法来实现我想要的表单,因此我决定admin_notices 作为可行解决方案的行动。

在中时查看结果图示Theme Editor 关联主题的。默认值style.css 已选中,但不可编辑。如果出现以下情况,将显示错误消息Update File 单击按钮。

theme editor view


创建CSS文件后返回视图。成功创建文件后,页面将重新加载并在代码编辑器中打开新文件。

file created


CSS文件可在主题的支持插件中选择。如果选择了样式表,它将不会列在主题编辑器的删除列表中。

supporting plugin config


编码

Form process function

public static function makeFile($file, $data=null)
{
    if( !is_null(mb::getPost(\'makecss\')) ) 
    {
        // suppress default error notice since it is not related
        echo \'<style>div#message.notice.notice-error {display: none;}</style>\';
        
        $file = esc_html($file);
        file_put_contents(MBTHEMEDIR.\'/styles/\'.$file.\'.css\', $data);
        mb::redirect(admin_url(\'theme-editor.php?file=styles/\'.$file.\'.css&theme=thor\'));
    }
    
    //delete file
    if( !is_null(mb::getPost(\'deletecss\')) ) 
    {
        // suppress default error notice since it is not related
        echo \'<style>div#message.notice.notice-error {display: none;}</style>\';
        
        if( mb::getPost(\'csslist\') != \'\' ) {
            unlink(MBTHEMEDIR.\'/styles/\'.mb::getPost(\'csslist\'));
            mb::redirect(admin_url(\'theme-editor.php?theme=thor\'));
        }else{
            echo \'<div class="notice notice-warning is-dismissible"><p>No file was selected</p></div>\';
        }
    }
    
    $newfile = \'
    <div class="newfile-form">
    <form action="" method="POST">
        <p>Create New CSS File</p>
        <span>File name: <input type="text" name="newfile" id="newfile" value="" placeholder="mystyle" /></span>
        <span><button type="submit" name="makecss" class="button button-primary">Create File</button></span>
        <span>
        <select name="csslist">
            <option value="">None</option>\';
        foreach(mb::filelist(MBTHEMEDIR.\'/styles\', \'css\') as $css) {
            $newfile .= \'<option value="\'.$css.\'">\'.$css.\'</option>\';
        }
        $newfile .= \'</select>
        </span>
        <span><button type="submit" name="deletecss" class="button">Delete File</button></span>
    </form>
    </div>
    \';
    
    return $newfile;
}

Action Hook

if( current_user_can(\'edit_files\') ) 
{
   // confirm that the specified theme is selected 
    if( strstr(mb::urlVar(\'theme\'), \'thor\') ) 
    {
       // suppress default WP missing file notice when file create request is sent
       echo \'<style>div#message.notice.notice-info {display: none;}</style>\';

       // implement form process action
       add_action(\'admin_notices\', function() {
            echo mb::makeFile(sanitize_text_field(mb::getPost(\'newfile\')));
        });

        // action to disable editing core files
        add_action(\'load-theme-editor.php\', function()
        {
            $file = filter_input(INPUT_GET, \'file\', FILTER_SANITIZE_STRING);
            if( in_array($file, [\'style.css\', \'404.php\',\'index.php\']) ) {
                wp_redirect(add_query_arg([],self_admin_url(\'theme-editor.php?theme=thor\')));
                exit;
            }
        });
    }
}
由于使用时发送的标题错误,我不得不使用不同的页面重定向方法wp_redirect()

public static function redirect($url) {
    if( !headers_sent() ) {
        wp_redirect(admin_url($url));
    }else{
        echo \'<meta http-equiv="refresh" content="0; URL=\'.$url.\'">\';
    }
}
Thefilelist() 用于输出删除字段的选择选项的方法。WP对此有一个方法,但我无法使其按预期运行,因此我更正了它

public static function filelist($path, $filter=null, $getpath=false)
{
    $files = new \\DirectoryIterator($path);
    $filelist=[];
    foreach($files as $file) 
    {
        if( $file->isFile() && !$file->isDot() ) 
        {
            // include only files in $filter 
            // methods: \'css\' or \'css|txt\' or starting with \'^cat\' or ending with \'$er\'
            if( !empty($filter) && !preg_match(chr(1).$filter.chr(1), $file) ) {
                continue;
            }
            
            $filelist[] = ($getpath == true ? $file->getPath().\'/\'.$file->getFilename() : $file->getFilename());
        }
    }
    
    return $filelist;
}
ThegetPost() 方法只是一组检查表单请求值的全局函数。可湿性粉剂方法可用于完成相同的任务。

这个urlVar() 方法是一组全局函数,用于检查URL字符串中的查询变量及其值。WP方法同样适用。

这就是我的故事,我会坚持下去!

相关推荐