Customizing SMF > SMF Coding Discussion

<br/> when saving edit

(1/5) > >>

Yoshi:
Next problem.

I have this code as the saving process when editing:

--- Code: ---function BugTrackerSubmitEdit()
{
global $smcFunc, $context, $sourcedir, $scripturl;

// Then, is the required is_fxt POST set?
if (!isset($_POST['is_fxt']) || empty($_POST['is_fxt']))
fatal_lang_error('save_failed');

// Load the tracker?
$result = $smcFunc['db_query']('', '
SELECT
tracker
FROM {db_prefix}bugtracker_entries
WHERE id = {int:id}',
array(
'id' => $_POST['entry_id'],
)
);

if ($smcFunc['db_num_rows']($result) == 0)
fatal_lang_error('entry_no_exist', false);

// What's our tracker?
$tracker = $smcFunc['db_fetch_assoc']($result);

// Not ours, and we have no permission to edit someone else's entry?
if (!allowedTo('bt_edit_any') && (allowedTo('bt_edit_own') && $context['user']['id'] != $tracker))
fatal_lang_error('edit_entry_else_noaccess');


// Load Subs-Post.php, will need that!
include($sourcedir . '/Subs-Post.php');

// Pour over these variables, so they can be altered and done with.
$entry = array(
'title' => $_POST['entry_title'],
'type' => $_POST['entry_type'],
'private' => !empty($_POST['entry_private']),
'description' => $_POST['entry_desc'],
'mark' => $_POST['entry_mark'],
'attention' => !empty($_POST['entry_attention']),
'id' => $_POST['entry_id']
);

// Check if the title, the type or the description are empty.
if (empty($entry['title']))
fatal_lang_error('no_title', false);

// Type...
if (empty($entry['type']) || !in_array($entry['type'], array('issue', 'feature')))
fatal_lang_error('no_type', false);

// And description.
if (empty($entry['description']))
fatal_lang_error('no_description', false);

// Are we submitting a valid mark? (rare condition)
if (!in_array($entry['mark'], array('new', 'wip', 'done', 'reject')))
fatal_lang_error('save_failed');

// No entry?
if (empty($entry['id']))
fatal_lang_error('save_failed');

// Preparse the message.
preparsecode($entry['description']);

// Okay, lets prepare the entry data itself! Create an array of the available types.
$fentry = array(
'title' => $smcFunc['htmlspecialchars']($entry['title']),
'type' => strtolower($entry['type']),
'private' => (int) $entry['private'],
'description' => $entry['description'], // No htmlspecialchars here because it'll fail to parse <br />s correctly!
'mark' => strtolower($entry['mark']),
'attention' => (int) $entry['attention'],
'id' => (int) $entry['id']
);

// Assuming we have everything ready now, update!
$smcFunc['db_query']('', '
UPDATE {db_prefix}bugtracker_entries
SET
name = {string:title},
type = {string:type},
private = {int:private},
description = {string:description},
status = {string:mark},
attention = {int:attention}
WHERE id = {int:id}',
array(
'id' => $fentry['id'],
'title' => $fentry['title'],
'type' => $fentry['type'],
'private' => $fentry['private'],
'description' => $fentry['description'],
'mark' => $fentry['mark'],
'attention' => $fentry['attention']
)
);

// Then we're ready to opt-out!
redirectexit($scripturl . '?action=bugtracker;sa=view;entry=' . $fentry['id']);
}
--- End code ---

I know it is really really really messy.

This is my template:

--- Code: ---function template_BugTrackerEdit()
{
// Globalling.
global $context, $scripturl, $txt;

// Types a bit quicker.
$entry = $context['bugtracker']['entry'];

// Start our form.
echo '
<form action="', $scripturl, '?action=bugtracker;sa=edit2" method="post">';

// Then, for the general information.
echo '
<div class="cat_bar">
<h3 class="catbg">
', $txt['entry_edit'], '
</h3>
</div>
<div class="windowbg">
<span class="topslice"><span></span></span>
<div style="margin-left:10px">
<table class="fullwidth">';

// The entry title. Lets start with that.
echo '
<tr>
<td class="halfwidth">
<strong>', $txt['title'], '</strong>
</td>
<td class="halfwidth">
<input type="text" style="width: 98%" name="entry_title" value="', $entry['name'], '" />
</td>
</tr>';

// To what should we mark this?
echo '
<tr>
<td class="halfwidth"></td>
<td class="halfwidth">
<select name="entry_mark">
<option value="new"', ($entry['status'] == 'new' ? ' selected="selected"' : ''), '>', $txt['mark_new'], '</option>
<option value="wip"', ($entry['status'] == 'wip' ? ' selected="selected"' : ''), '>', $txt['mark_wip'], '</option>
<option value="done"', ($entry['status'] == 'done' ? ' selected="selected"' : ''), '>', $txt['mark_done'], '</option>
<option value="reject"', ($entry['status'] == 'reject' ? ' selected="selected"' : ''), '>', $txt['mark_reject'], '</option>
</select>
</td>
</tr>';

// What kind of thing is this? Set the type, please.
echo '
<tr>
<td class="halfwidth"></td>
<td class="halfwidth">
<select name="entry_type">
<option value="" disabled="disabled" selected="selected">', $txt['type'], '</option>
<option value="issue"', ($entry['type'] == 'issue' ? ' selected="selected"' : ''), '>', $txt['bugtracker_issue'], '</option>
<option value="feature"', ($entry['type'] == 'feature' ? ' selected="selected"' : ''), '>', $txt['bugtracker_feature'], '</option>
</select>
</td>
</tr>';

// Does this entry need to be private?
echo '
<tr>
<td class="halfwidth"></td>
<td class="halfwidth">
<input type="checkbox" name="entry_private" value="true"', ($entry['private'] ? ' checked="checked"' : ''), ' /> ', $txt['entry_private'], '
</td>
</tr>';

// Or does it need attention?
echo '
<tr>
<td class="halfwidth"></td>
<td class="halfwidth">
<input type="checkbox" name="entry_attention" value="true"', ($entry['attention'] ? ' checked="checked"' : ''), ' /> ', $txt['mark_attention'], '
</td>
</tr>';

// Close everything. And start the editor.
echo '
</table>

<hr />

<div id="bbcBox_message"></div>
<div id="smileyBox_message"></div>
', template_control_richedit($context['post_box_name'], 'smileyBox_message', 'bbcBox_message') . '<br /><hr />';

// Some hidden stuff.
echo '
<input type="hidden" name="entry_id" value="', $entry['id'], '" />
<input type="hidden" name="is_fxt" value="true" />';

// And our submit button and closing stuff.
echo '
<div class="floatright" style="margin-right:10px">
<input type="submit" value="', $txt['entry_submit'], '" class="button_submit" />
</div>
<br class="clear" />
</div>
<span class="botslice"><span></span></span>
</div>';

// Close the form.
echo '
</form>';

// Because content will break otherwise.
echo '
<br class="clear" />';
}
--- End code ---

Now, whenever I save something, say this in the entry description:

--- Quote ---Test

ing
--- End quote ---

And edit the thing again, the description shows up like this:

--- Quote ---Test<br /><br />ing
--- End quote ---

Which obviously is not normal.

I tried looking in Post.php. No cake for me, except for this piece which looked interesting:

--- Code: --- // If we came from WYSIWYG then turn it back into BBC regardless.
if (!empty($_REQUEST['message_mode']) && isset($_REQUEST['message']))
{
require_once($sourcedir . '/Subs-Editor.php');

$_REQUEST['message'] = html_to_bbc($_REQUEST['message']);

// We need to unhtml it now as it gets done shortly.
$_REQUEST['message'] = un_htmlspecialchars($_REQUEST['message']);

// We need this for everything else.
$_POST['message'] = $_REQUEST['message'];
}
--- End code ---

But which didn't help me any further.

Am I missing something?

SMF 2.0.2.

Arantor:
Ah, you fell foul of that. Not surprising, it's a minefield.

Let's deal with that last bit first, the message_mode stuff. That's for the WYSIWYG editor. What happens is that the WYSIWYG editor sends back the actual HTML that it made, which gets intercepted before everything else, and all that code - most importantly html_to_bbc - converts it to bbcode before going on to the usual saving code.

Now, as to your core issue. Your saving routine passed it to preparsecode() to properly sanitise it and you saved it after that, great. Before you pass that back to be edited, you need to un_preparsecode() it. I forget what other functions you need to have run, regarding htmlspecialchars, but as ever SimpleDesk does cover this ;)

Yoshi:

--- Quote from: Arantor on July 26, 2012, 10:12:40 AM ---Ah, you fell foul of that. Not surprising, it's a minefield.

Let's deal with that last bit first, the message_mode stuff. That's for the WYSIWYG editor. What happens is that the WYSIWYG editor sends back the actual HTML that it made, which gets intercepted before everything else, and all that code - most importantly html_to_bbc - converts it to bbcode before going on to the usual saving code.

Now, as to your core issue. Your saving routine passed it to preparsecode() to properly sanitise it and you saved it after that, great. Before you pass that back to be edited, you need to un_preparsecode() it. I forget what other functions you need to have run, regarding htmlspecialchars, but as ever SimpleDesk does cover this ;)

--- End quote ---
htmlspecialchars gave me other issues, regarding hte same problem, pretty much.

I'll check what un_preparsecode() can do for me :)

Yoshi:
Arantor: I found this in SimpleDesk at the posting process.


--- Code: ---$smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['shd_message']), ENT_QUOTES)
--- End code ---

That something?

Sorry, 99% of SD's code it too advanced for me ;D

Arantor:
No...

It's un_preparsecode like I already said. Just before it calls the censoring.

What's happening is that you're confusing the two processes, something that SMF does so wonderfully >_<

OK, here's the deal, add, edit and post are essentially three separate processes.

Add: set up a blank form
Edit: load an existing item and prepare the form for that data
Post: save the data from the above processes

Now, Add and Edit are 99% the same, just that add uses a blank form, edit uses a non empty form, you just set up some variables, either with empty values or existing values, and push through to the same form.


Ask yourself: of the code you posted, what exactly does it do? Where exactly is it used? Well, it's in the saving routine, and thus absolutely nothing to do with editing a post.

Your problem isn't how you save it. It's how you load it again to be able to show it back to the user.

Navigation

[0] Message Index

[#] Next page

Go to full version