1

I got a page that loads html code from a text file into an textarea and I need to be able to save the contents of it using a script.

I'm using a PHP script to load the code from a file and echo it out to the textarea, but how can I send back the contents to the script and save it either to the same file or to a file with a new name?

I was thinking if getElementById would help me but I'm not sure how.

The load script(it has the ability to delete files too)

// The file hierarchy:
//
//Web root - admin - This file
//         - pages - in here are the page text files

// The variable pagesList is the filename chosen in a dropdown list earlier
$page = $_GET["pagesList"];
$action = $_GET["action"];
//get the path to the page( all pages are in a folder named 'pages')
$filename = dirname(dirname(__FILE__))."/pages/".$page;

if(file_exists($filename) and is_file($filename)){

    //If I want to load a file
    if($action == "open"){
        $f = fopen($filename,"rt");
        $content = fread($f, filesize($filename));
        echo $content;
        @fclose($f);

    //If I want to delete a file
    }elseif($action == "delete" && is_file($filename)){
        //move the working directory to where the file is
        $old = getcwd();
        chdir(dirname(dirname(__FILE__))."/pages/");
        //----
        if(unlink($filename)) 
            echo "File deleted,".$filename;
        else
            echo "Error deleting file!";
        //change back the working directory to where it was
        chdir($old);

    //If I want to save a file
    }elseif($action == "save"){
        if(file_exists($filename)){

            //Unknown script, need help!

        }else{

        }
    }
}    

The textarea is only one line with an include in it:

   <textarea id="html_content" style="width:600;height:200;"><?php include("loader.php") ?></textarea>

To sum it up: I need help getting the contents of an textarea to a script for saving later.

EDIT: Thanks to davidkonrad I just had to add a few POST receives in the script and add file_put_content with the content sent to it.

The problem that arised is that jQuery apparently puts \ before each " or '. That messes up all the html code that is supposed to be clean and valid. I'll have to replace the \" with " somehow, str_replace wont cut it. Any ideas?

EDIT2: Thanks again to davidkonrad that fixed it by using encodeURIComponent(jQuery) clientside and urldecode(PHP) serverside.

Patrick Dahlin
  • 286
  • 2
  • 5
  • 19

2 Answers2

5

Update, OK if you just are in doubt how to submit a textarea to your loader.php :

<form method="post" action="loader.php">
<input type="hidden" name="filename" value="test.html">
<input type="hidden" name="action" value="save">
<textarea name="html_content"></textarea>
<input type="submit" value="save">
</form>

loader.php, now you have

$filename=$_POST['filename']; 
$action=$_POST['action'];
$html_content=$_POST['html_content'];

Which here is "test.html", "save" and any text typed into the textarea. use those variables in your if .. else loop as above, eg

} elseif($action == "save"){
   if(file_exists($filename)){
        //Unknown script, need help!
        file_put_contents($filename, $html_content); //or how you want to do it
   }
}

The disadvantages is

  • the page needs to be reloaded on each action
  • you need to echo the inserted content again, between <textarea> .. </textarea> once it is inserted (as I understand, the HTML is part of loader.php)
  • likewise keeping track of the current filename is more complicated

NB : Unless there is a particular reason, you dont have to check if a file already exists before writing to it. And still thinks travelling around in the directories just makes it complicated :) Is /pages/ not just a relative path?


It does not need to be so complicated. I would use a more simple and structured approach, consisting of

  • A PHP class that performs each task by simple file_put_contents, file_get_contents and unlink, including some small error handling
  • A system of $.ajax calls (jQuery) calling the above PHP class

The following working example performs save, load and delete of HTML files to a directoty /files, which you must give RW permissions.

file.php

class File {
    private $filename;
    private $dir = 'files/';

    public function __construct() {
        $action = isset($_POST['action']) ? $_POST['action'] : false;
        $this->filename = isset($_POST['filename']) ? $_POST['filename'] : false;
        if ((!$action) || (!$this->filename)) return;
        switch ($action) {
            case 'save' : 
                $this->save(); break;
            case 'load' : 
                $this->load(); break;
            case 'delete' : 
                $this->delete(); break;
            default :
                return;
                break;
        }
    }
    private function save() {
        $content = isset($_POST['content']) ? $_POST['content'] : '';
        file_put_contents($this->dir.$this->filename, urldecode($content));
    }
    private function load() {
        $content = @file_get_contents($this->dir.$this->filename);
        echo $content;
    }
    private function delete() {
        unlink($this->dir.$this->filename);
    }
}
$file = new File();

file.html, markup

<input type="text" id="filename" value="test.txt"><br>
<textarea id="html_content" style="width:600;height:200;"></textarea>
<br>
<button id="save">save</button>
<button id="load">load</button>
<button id="delete">delete</button>

file.html, script :

var url = 'file.php';
$("#save").click(function() {
    $.ajax({
        url : url,
        type: 'post',
        data : {
            filename : $("#filename").val(),
            action : 'save',
            content : encodeURIComponent($('#html_content').val())
        }
    });
});
$("#delete").click(function() {
    $.ajax({
        url : url,
        type: 'post',
        data : {
            filename : $("#filename").val(),
            action : 'delete'
        }
    });
});
$("#load").click( function() {
    $.ajax({
        url : url,
        type: 'post',
        data : {
            filename : $("#filename").val(),
            action : 'load'
        },
        success : function(html) {
            $("#html_content").val(html);
        }
    });
});

The HTML content (tags, HTML entities) is maintained upon save by the use of encodeURIComponent and urldecode. Try it out yourself, and consider this as the base for a more complex system. If you want to create a new file, just enter a new filename in the filename box. If you want to load a file, enter that filename in the filename box. I think file_put_contents etc is by far more robust than dealing with file handles, chdir(dirname(dirname(__FILE__))."/pages/"); (??) and so on.

davidkonrad
  • 83,997
  • 17
  • 205
  • 265
  • Wow, thanks, but the main problem I got is about transferring the text inside the textarea to a php script. I got the loading and deleting done already as you can see. Theres nothing wrong with the way you made the code but I'd prefer to continue on with the way I started it. And I see you use POST to handle the content, I'd use GET though, for more flexibility. – Patrick Dahlin Feb 23 '14 at 13:57
  • OK, dont quite understand - why cant you pass the content of the textarea to the PHP script by normal form/submit? The reason for using POST instead of GET have a reason : GET has some ver narrow limitations, on a normal PHP with suhosin patch the default limit of a $_GET field is 512 bytes. For browsers the total max length for a GET (all fields inclusive) is about 2000 chars. Not much when editing HTML files - See http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers - I think you will end up using POST in the end :) – davidkonrad Feb 23 '14 at 14:11
  • Ah, theres a limit.. Well, is it possible to have a textarea in a form and submit its contents through POST? And I meant that I'd like to continue with the script I already have, not using JQuery or a second completely new script to handle what I already have. – Patrick Dahlin Feb 23 '14 at 14:17
  • Now when I realized you edited your answer I made it about the same trying it out myself and its just what I needed :). Now the jQuery POST function apparently puts a \ before all " and ' characters, which invalidates all the html I try to save, and on each save the slashes duplicate making the line really long in the end. I tried to replace the \ using str_replace without any luck... I'm really loosing my temperament on this jQuery "feature". – Patrick Dahlin Feb 23 '14 at 21:11
  • Hey @PatrickDahlin - do as in my first suggestion, clientside `encodeURIComponent`, serverside `urldecode`. This is rather normal, escaping (look it up) - dont ever try to "solve" it manually by str_replace or anything else. Both languages, javascript and PHP, is designed to deal with that through the mentioned functions and others. – davidkonrad Feb 23 '14 at 21:23
  • @PatrickDahlin, why dont you consult the docs? http://dk1.php.net/file_put_contents ?? – davidkonrad Feb 23 '14 at 21:35
  • `if (!file_put_contents(x,y)) {` - looks pretty straight forward to me – davidkonrad Feb 23 '14 at 21:36
0

try using php fputs function to save file