How to properly store CKEditor HTML input - php

Im using CKEditor to store HTML input. Its working fine the one way. Data goes into the database exactly as I input it.
However, when I try to retrieve it in JSON, I get all sorts of parsing errors.
Here is a simple string which screws up
<p>This is my text</p>
<span style="font-size:14px">More test</span>
The JSON gets hung up on the double quotes, and the spaces. So I implemented this function in PHP before it gets inserted.
function parseline($string){
$string = str_replace(chr(10), "//n", $string);
$string = str_replace(chr(13), "//n", $string);
$string = str_replace(chr(34), "'", $string);
$string = str_replace("'","\'", $string);
return $string;
}
That line then becomes
<p>This is a test and more content</p>//n<span style=\'font-size:72px\'>
However. This still hangs up the JSON parsing.
How do I correctly store data from CKEditor, and then how to parse it back from the database, so that it can be parsed correctly as JSON??
Ideally I want to store it properly. And then I'll need to reverse parse the //n out to display back in the editor properly. Because right now, if I get valid data, I still get the //n displayed in the editor as actual values.
Ive been on this for 6 hours now. And Im tearing my hair out.
EDIT - Still stuck on this 22 hours later
Here is what is going into the database
<p>qweqweqweqwe</p>
And then Im getting it like this (using Lumen/laravel)
$post = Post::find($id);
return json_encode($post);
Then in Vue Im getting that json
el:'#app',
data : {
post: {}
},
methods: {
getPost: function(id){
var that = this;
$.ajax({
url:'post/'+id,
dataType:'json',
type:'GET'
}).done(function(data){
// Assign the data to Vue
that.post = JSON.parse(data);
}).fail(function(xhr){
});
}
}
This fails, with this exception
Uncaught SyntaxError: Unexpected token
in JSON at position 175
And the json returned is
{"uuid":"0bcb9c59-19da-4dcf-90d6-6dd53adfb449","title":"test","slug":"test","body":"<p>qweqweqweqwe</p>
","created_at":1519529598,"updated_at":1519534639}
So obviously its failing because there is an Enter key after the ending < /p >. But I already tried removing all enter keys and all that before storing. Replacing with new line /n. That works, but then I get //n back, and also things like style="font-size:14px;" from CKeditor, also make it fail, because of the double quotes.
So the issue is. Im storing the data exactly as its entered in the database. Retrieving it properly is just most definitely not working or easy to do at all it seems. At least as valid json.
EDIT 3 - Completeley lost and officially stumped
Im getting this back as json
var data = {
"uuid": "2cd2d954-233a-46d6-8111-29596262d3bc",
"body": "<p>test<\/p>\n",
"cover_img": "https:\/\/static.pexels.com\/photos\/170811\/pexels-photo-170811.jpeg",
"title": "asdf",
"slug": "asdf",
"created_at": 1519536364,
"updated_at": 1519538302
}
If i do
JSON.parse(data);
I consistently get
Uncaught SyntaxError: Unexpected token
in JSON at position 66
Even though if you copy that exact object over to JSONLint.com, its completely valid. Im so stumped. The most stumped I think I have ever been on any issue in my entire career. Which is wierd, because it seems like it would be such an easy bug to find.

Store it directly as HTML in the database. Don't modify, tweak, or otherwise screw with it at all - what's in the database should be exactly what the user submitted. (Stuff like XSS protection, parsing short codes, etc. should be done on display, so you can adjust your algorithms while still having the original HTML to work with.)
Provide it to Vue by running it through json_encode, which will escape it correctly:
$response = ['html' => $html];
return json_encode($response);
(You can also just do json_encode($html), which will return a JS-friendly string instead of a JSON object. Vue'll be happy with that, too.)
The resulting JSON will be:
{"html":"<p>This is my text<\/p>\n\n<span style=\"font-size:14px\">More test<\/span>"}
which Vue will be just fine with when you JSON.parse it.

Assuming a CKEditor instance named editor1, get CKEditor data, construct an object with it, stringify it and send it to database without PHP manipulation (JSON.stringify will take care of escaping characters):
JSON.stringify({'ckdata': editor1.getData()})
Retrieve data from database as text without PHP manipulation and parse it as JSON object:
JSON.parse(databasedata).ckdata;
EDIT: ceejayoz gave a better answer, since data is stored unmodified in database

Related

PHP Json Malformed When Posted From jQuery Ajax

I am having a weird issue, when i use json_decode() on some json from a jquery ajax call it's coming back always saying that the json is malformed (JSON_ERROR_SYNTAX).
I say this is weird because if i take a copy of the raw posted json from the developer console and manually push it through json_decode() then it decodes perfectly fine.
I have uploaded a txt file of the example json here : https://drive.google.com/file/d/1IZ5RkpFK7KLUNYeZe4dPdxGWZXinmFSJ/view?usp=sharing which works manually parsing it but not from posted data. Another weird issue is if i save the json string to a longtext field in a mysql database and then pull it out again, it then decodes fine; but this isn't ideal, it needs to validate it before going to the database and i'm unsure why this would allow it to decode anyway.
Any ideas?
This might be happeing due to new line code added in your code. You can add below code and try to decode the code again it might work.
$content = preg_replace('/[\r\n\t\s]+/s', ' ', $content);#new lines, multiple spaces/tabs/newlines
$content = preg_replace('#/\*.*?\*/#', '', $content);#comments
$content = preg_replace('/^\s+/', '', $content);#spaces on the begining

Angular http.get error to retrieve backslash stored in mysql

I'm so frustrated with this.
I'm using Angular from CDN and I'm calling a $http.get request to a PHP file that prints all the result set (mysql) in JSON format, which is "well done".
But, I have stored some backslashes into the database as part of the value of a field. E.G:
{"Field 1":"user1"},{"Field 2":"some_data\2"}
That crashes the entire page and the data in the view is not being displayed. It's printed in the raw JSON file this way:
{"Field 2":"some_data�2"}
Currently I'm printing the resultant json "manually":
$outp = '{"Field 2":"'.$resultset['field_data'].'"}';
echo $outp;
I've tried everything I know: addslashes(), stripslashes(), htmlspecialchars(), json_encode()... Error is:
SyntaxError: Unexpected token in JSON at position 138742
Can anyone help me, please?

Can't get data from json

I need to get brand: "hello world"
When I send using post data with json and get it with
$input = Input::all();
then with
die(print_r($input));
this is written
Array ([[], {brand: "hello world"}, [], 1427154586016])1
And
I tryed using json_encode and get with
die(print_r($encode));
this
{data: "{"brand":"Hello world"}", dc: "142715"}1
now if I do
$brand = $encode['data'] or $brand = $encode['brand']
I get an error.
How do I get Hello world to var $brand
It looks like you're using json_encode() when you should be using json_decode(). But like kamlesh pointed out, it appears that your original JSON data is not valid JSON to begin with, so this would not help you. This wiki article has an example of valid syntax.
Also, if you're using laravel, you can use the helper function dd(), which will die() and var_dump() automatically for you, saving you a bit of time.
Hopefully this solves your problem, but if not, read the docs for the Input. There should be something there to get you on the right track.

JSON array to PHP / MySQL JSON.parse JSON.stringify how to store double quotes and single quotes

I have a form with fields and a text-area that allows any characters to be entered. I can't just submit the form, because the form is being recycled many times over, so the form values are being stored in associative arrays:
<form name='Theform'>
<input type="text" id="VISITOR_DETAILS_NAME" value="Joe">
<input type="text" id="VISITOR_DETAILS_SIZE" value="Large">
<textarea id='VISITOR_DETAILS_INFO'>
User can enter anything here including double " and single ' quotes
</textarea>
<input type="hidden" name="package" id="package" value="" />
</form>
The text-area value are stored in a JavaScript array along with the other form values:
myArray[0]['VISITOR_DETAILS_NAME'] = document.getElementById('VISITOR_DETAILS_NAME').value;
myArray[0]['VISITOR_DETAILS_SIZE'] = document.getElementById('VISITOR_DETAILS_SIZE').value;
myArray[0]['VISITOR_DETAILS_INFO'] = document.getElementById('VISITOR_DETAILS_INFO').value;
I end up with an array something like this:
{
VISITOR_DETAILS_NAME : "Joe",
VISITOR_DETAILS_SIZE : "Large",
VISITOR_DETAILS_INFO : "User can enter anything here including double " and single ' quotes"
};
I then pass this JavaScript array to the hidden form field using JSON.stringify and then POST this to PHP:
document.getElementById('package').value = JSON.stringify(myArray[0]);
Theform.submit();
(For now I'm just posting to an iframe to test that the JSON is passing the JavaScript arrays properly through POST).
When I get it on the PHP side - it seems good to go. It looks like the JSON.stringify has added the backslash to the double quote (\" ) - and now I want to store the values in MySQL. But I want to first test that I can send/reconstruct the JSON back to the javascript as an array - so I try this:
parent.myArray[0] = JSON.parse('<?php echo $_POST['package']; ?>');
I get an ERROR: SyntaxError: Expected token ')' OR SyntaxError: missing ) after argument list
This is strange to me - because when I try it without POSTING - It seems to work fine like this:
document.getElementById('package').value = JSON.stringify(myArray[0]);
now if I try to just pass back the stringified value back to the array
myArray[0] = JSON.parse(document.getElementById('package').value);
- it seems to work fine - no errors
QUESTIONS:
Why am I getting this error when trying to reconstruct the ARRAY from the
POSTED JSON.stringify() value?
Do I save this JSON.stringify() value in MySQL as is?
Or do I PHP json_decode() it first?
I want to grab the form data - handle it properly - store it in MySQL and then read it back into the form when I need it.
Thanks All :)
parent.myArray[0] = JSON.parse('<?php echo $_POST['package']; ?>');
Here you are are trying to convert a JSON text into an HTML representation of a JavaScript string representation of a JSON text, but you aren't doing anything to escape it for either.
If you have any ' characters in the JSON data, then they will terminate the JavaScript string.
If you have any " characters in the JSON data, then they will be represented as \", but \" is a JavaScript string representation of ". Since you don't do anything to escape the text you put in the JS string, the slash character will be consumed by the JavaScript parser and will be gone before it reached the JSON parser.
If you want to convert data for placing in a JavaScript string then you need to escape it.
However, JSON is a subset (almost) of JavaScript. So the process of converting a JSON text to a JavaScript string so it can be parsed into a JavaScript object is over-complicated. You can skip that can just go straight to:
<script>
var foo = <?php echo $json; ?>
</script>
However, since you are taking in the JSON from the client, echoing out directly will expose you to XSS attacks. In order to deal with this you should filter the data on the server.
This will:
Fail to parse any invalid JSON and so not output bad JSON (but it might output nothing, giving you a JSON syntax error, you should apply tests to see if the parse was successful and output a sensible default case if it fails).
Convert any </script> in the data to <\/script> making it safe to place in a script element (because that is how PHP's json_encode works
Such:
<!-- I don't do PHP, this is untested -->
<script>
var foo = <?php
$unsafe_json = $_POST['package'];
$data_structure = json_parse($unsafe_json);
$safe_json = json_encode($data_structure);
echo $safe_json;
?>;
</script>
Do I save this JSON.stringify() value in MySQL as is? Or do I PHP json_decode() it first?
That depends on what you intend to do with the data. In general when putting things into a database it is a good idea to extra the data from the data format and normalize it. That way you can run queries over it.
If you are only going to store the data and then retrieve it, you might be able to get away with not doing that and storing strings of JSON in the database. That loses you a lot of flexibility though and might bite you in the future.

json_encode won't escape newlines

Firstly, I have search Stack Overflow for the answer, but I have not found a solution that works.
I am using an MVC framework (yii) to generate some views and throw them in an array. Each view is a card, and I have an array of cards ($deck) as well as an array of arrays of cards ($hands, the list of hands for each player). I'm simply trying to set a javascript variable on the front-end to store the hands created in PHP. My view has, it is worth noting, multiple lines. In fact, my current test view consists only of:
test
test
I therefore used json_encode, but it's giving me the following error when I use $.parseJSON():
Uncaught SyntaxError: Unexpected token t
I read elsewhere that it is required (for whatever reason) to use json_encode twice. I have tried this, but it does not help.
With a single json_encode, the output of echoing $hands (followed by an exit) looks pretty healthy:
[["test\ntest","test\ntest","test\ntest","test\ntest", etc...
But when I do not exit, I get a syntax error every time.
Edit: Here is a sample of my code. Note that $cards is an array of HTML normally, but in my simplified case which still errors, includes only the two lines of 'test' as mentioned above.
$deck = array();
foreach ($cards as $card) {
$deck[] = $this->renderPartial('/gamePieces/cardTest',
array('card'=>$card), true);
}
$hands = Cards::handOutCards($deck, $numCards , $numPlayers);
$hands = json_encode($hands);
echo $hands; exit;
With JavaScript, I am doing the following:
var hands = $.parseJSON('<?php echo json_encode($hands); ?>');
It errors on page load.
Any help would be appreciated!
Thanks,
ParagonRG
var hands = $.parseJSON('<?php echo json_encode($hands); ?>');
This will result in something like:
var hands = $.parseJSON('{"foobar":"baz'"}');
If there are ' characters in the encoded string, it'll break the Javascript syntax. Since you're directly outputting the JSON into Javacript, just do:
var hands = <?php echo json_encode($hands); ?>;
JSON is syntactically valid Javascript. You only need to parse it or eval it if you receive it as a string through AJAX for instance. If you're directly generating Javascript source code, just embed it directly.

Categories