Дон Карлос (kastaneda) wrote,
В коммьюнити ru_php недавно один гражданин захотел «online php-editor». Объяснение, зачем ему это нужно, я толком не понял, но оно было связано с необходимостью из интернет-кафе что-то срочно поправить на сайте.

Я недавно написал мелкую штуку на схожую тему, правда, для совсем других задач. Да, просто текстовый редактор на PHP. Просто возможность редактировать в здоровенной <textarea> текстовые файлики, лежащие на сервере. (Код я редактирую в Quanta+ и в Vim'е. Это — запасное средство).

http://ваш сайт.com/edit.php?file=index.html

<?php // edit.php - minimalistic web-based text editor for server-side files

    define('TEMPLATE', '.template');
    define('LANG', 'ru');
    //header('Content-type: text/html; charset=koi8-r');

    define('_Page_Editing',        'Редактирование страницы');
    define('_Continue',            'Продолжить&hellip;');
    define('_Forbidden',           'Нет доступа');
    define('_Save',                'Сохранить');
    define('_Error',               'Ошибка: ');
    define('_WTF',                 'Ну, и что дальше?');
    define('_Not_Writable',        'Файл защищён от записи');
    define('_Cannot_Create',       'Невозможно создать файл');

    $known_users = array(
    //  'test'    => '098f6bcd4621d373cade4e832627b4f6', // md5('test')
        'gray'    => '8508b14bbaed0214b5da73dc449ed636',
    );

////// Main processing part ////////////////////////////////////////////////

    $fname = basename(@$_REQUEST['file']);
    if( !$fname ) {
        // Maybe we are used as 404 handler? It works too.
        list($fname) = explode('?',basename($_SERVER['REQUEST_URI']));
        if( file_exists($fname) ) {
            reject(_WTF);
        }
        header("HTTP/1.0 200 OK");
    }

    $user = @$_SERVER['PHP_AUTH_USER'];
    $pass = @$_SERVER['PHP_AUTH_PW'];
    if( md5($pass) != @$known_users[$user] ) {
        authenticate();
    }

    if( !isset($_POST['save']) ):

        // Edit file
        if( file_exists($fname) ) {
            if( !is_writable($fname) ) {
                reject(_Not_Writable);
            }
            $content = file_get_contents($fname);
        } else {
            if( !is_writable(dirname(__FILE__)) ) {
                reject(_Cannot_Create);
            }
            $content = '';
            if( is_readable(TEMPLATE) ) {
                $content = file_get_contents(TEMPLATE);
            }
        }
        draw_editor($fname,$content);

    else:

        $quit_url = $_POST['referrer'] ? $_POST['referrer'] : $fname;
        if ( !file_exists($fname) ) {
            $quit_url = $fname;
        }

        // Save file
        $content = $_POST['content'];
        if( get_magic_quotes_gpc() ) {
            $content = stripslashes($content);
        }
        if( !($f = @fopen($fname,'w')) ) {
            $message = file_exists($fname) ? _Not_Writable : _Cannot_Create;
            reject($message);
        }
        fwrite($f, $content);

        redirect($quit_url);
        die();

    endif;

////// Templates ///////////////////////////////////////////////////////////

function draw_message($head,$msg,$extra='') { ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo LANG; ?>">

<head>
    <title><?php echo $head; ?></title>
    <style type="text/css">  /* <![CDATA[ */

* { margin: 0; padding: 0 }
div { position: absolute; left: 50%; top: 50%; width: 36em; margin: -2.5em 0 0 -18em }
h1 { font-weight: normal; font-size: 300%; line-height: 150%; text-align: center }

    /* ]]> */ </style><?php echo $extra; ?>
</head>

<body>
    <div>
        <h1><?php echo $msg; ?></h1>
    </div>
</body>

</html><?php }

function draw_editor($fname,$content) { ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo LANG; ?>">

<head>
    <title><?php echo _Page_Editing; ?></title>
    <style type="text/css"> /* <![CDATA[ */

body { margin: 0; padding: 10px; color: WindowText; background: Window }
form { margin: 0; padding: 0 }
textarea { width: 100%; padding: 0; margin: 0; border: thin solid }
#toolbar { padding: 10px 0 0 0; margin: 0; text-align: right }

    /* ]]> */ </style>
    <script type="text/javascript"> /* <![CDATA[ */

function fit_size() {
    toolbar_height=document.getElementById('toolbar').clientHeight
    textarea_height=(window.innerHeight-toolbar_height-30)+'px'
    document.getElementById('content').style.height=textarea_height
}

if(document.getElementById) {
    window.onload=function() {
        document.getElementById('content').focus()
        fit_size()
    }
    window.onresize=fit_size
}

    /* ]]> */ </script>
</head>

<body>
    <form method="post" action="<?php echo basename(__FILE__); ?>">
        <div><textarea name="content" id="content" rows="20" cols="73"><?php
            echo htmlspecialchars($content);
        ?></textarea></div>
        <div id="toolbar">

            <input type="hidden" name="file" value="<?php
                echo htmlspecialchars($fname); ?>" />
            <input type="hidden" name="referrer" value="<?php
                echo htmlspecialchars($_SERVER["HTTP_REFERER"]); ?>" />
            <input type="submit" name="save" value="<?php
                echo _Save; ?>" accesskey="0" />
        </div>
    </form>
</body>

</html><?php }

////// Functions ///////////////////////////////////////////////////////////

function authenticate() {
    header('WWW-Authenticate: Basic realm="'.basename(__FILE__).'"');
    header('HTTP/1.0 401 Unauthorized');
    draw_message(_Forbidden,_Forbidden);
    die();
}

function reject($msg) {
    draw_message(_Error.$msg,$msg);
    die();
}

function redirect($url) {
    // FIXME: to be correct, we must use full URL
    if( !headers_sent() ) {
        header("Location: $url");
    }
    $head_code = '<meta http-equiv="Refresh" content="1;URL='.$url.'">';
    $message = '<a href="'.$url.'">'._Continue.'</a>';
    draw_message(_Continue,$message,$head_code);
    die();
}

/* Copyright (c) 2005 by Dmitry 'gray' Kolesnikov, kastaneda@gmail.com */ ?>


Думаю, объяснять в коде ничего особо и не требуется — всё и так понятно. Редактировать можно только то, на что у веб-сервера прав хватит, и только в текущем каталоге. Никаких сложных систем безопасности (пофиг, что редактировать: html, css, php или самого себя).
Tags: webdev
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded  

  • 3 comments