<?php /*

 Composr
 Copyright (c) ocProducts, 2004-2016

 See text/EN/licence.txt for full licencing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license    http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright  ocProducts Ltd
 * @package    core_form_interfaces
 */

/**
 * Build up a preview based on what was submitted.
 *
 * @param  boolean $multi_return Whether to return additional data
 * @return mixed Either Tempcode for the preview, or a tuple of details
 */
function build_preview($multi_return = false)
{
    require_code('input_filter_2');
    modsecurity_workaround_enable();

    require_css('forms');
    require_javascript('checking');

    // Check CAPTCHA if it is passed
    if (addon_installed('captcha')) {
        if (((array_key_exists('post', $_POST)) && ($_POST['post'] != '')) && (array_key_exists('captcha', $_POST))) {
            require_code('captcha');
            enforce_captcha(false);
        }
    }

    require_code('attachments2');
    $hooks = find_all_hooks('systems', 'preview');
    $output = null;
    $new_post_value = null;
    $attachment_type = null;
    $forum_db = false;
    $limit_to = null;
    foreach (array_keys($hooks) as $hook) {
        require_code('hooks/systems/preview/' . $hook);
        $object = object_factory('Hook_preview_' . $hook, true);
        if (is_null($object)) {
            continue;
        }
        $apply_bits = $object->applies();
        $applies = $apply_bits[0];
        if ($applies) {
            $attachment_type = $apply_bits[1];
            $forum_db = array_key_exists(2, $apply_bits) ? $apply_bits[2] : false;
            $limit_to = array_key_exists(3, $apply_bits) ? $apply_bits[3] : null;

            if (method_exists($object, 'run')) {
                list($output, $new_post_value) = $object->run();
            }

            break;
        }
    }
    $webstandards = new Tempcode();
    $keyword_density = new Tempcode();
    $spelling = new Tempcode();
    $meta_keywords = post_param_string('meta_keywords', '');
    $spellcheck = post_param_integer('perform_spellcheck', 0) == 1;
    $keywordcheck = (post_param_integer('perform_keywordcheck', 0) == 1) && ($meta_keywords != '');
    if (post_param_integer('perform_webstandards_check', 0) != 0) {
        foreach ($_POST as $key => $val) {
            if (!is_string($val)) {
                continue;
            }

            $val = post_param_string($key, ''); // stripslashes, and WYSIWYG output handling

            $tempcodecss = (post_param_integer('tempcodecss__' . $key, 0) == 1);
            $supports_comcode = (post_param_integer('comcode__' . $key, 0) == 1);

            if ($supports_comcode) {
                $temp = $_FILES;
                $_FILES = array();
                $valt = comcode_to_tempcode($val);
                $_FILES = $temp;

                require_code('view_modes');
                require_code('obfuscate');
                require_code('webstandards');
                $webstandards->attach(check_xhtml_webstandards($valt->evaluate(), false, post_param_integer('perform_webstandards_check', 0), true));
            } elseif ($tempcodecss) {
                $i = 0;
                $color = post_param_string(strval($i), '');
                while ($color != '') {
                    $val = str_replace('<color-' . strval($i) . '>', '#' . $color, $val);
                    $i++;

                    $color = post_param_string(strval($i), '');
                }
                $_val_orig = $val;

                require_lang('webstandards');
                require_code('view_modes');
                require_code('obfuscate');
                require_code('webstandards');
                require_code('webstandards2');
                $error = check_css($_val_orig);
                $show = (count($error['errors']) != 0);
                if ($show) {
                    $webstandards->attach(display_webstandards_results($_val_orig, $error, true, true));
                }
            }
        }
    }
    if ($spellcheck) {
        require_code('spelling');
    }
    $db = $forum_db ? $GLOBALS['FORUM_DB'] : $GLOBALS['SITE_DB'];
    $map_table_map = array();
    require_code('templates_map_table');
    $attachment_field = 'post';
    foreach ($_POST as $key => $val) {
        if (!is_string($val)) {
            continue;
        }

        if ((!is_null($limit_to)) && (!in_array($key, $limit_to))) {
            continue;
        }

        // Read in value, and will it be hidden?...

        $val = post_param_string($key, ''); // stripslashes, and WYSIWYG output handling
        if ($val == '0') {
            $val = do_lang('NO');
        }
        if ($val == '1') {
            $val = do_lang('YES');
        }

        if ((substr($key, 0, 14) == 'review_rating') || (substr($key, 0, 7) == 'rating')) {
            $val .= '/10';
        }

        $is_hidden =
            in_array($key, array(
                'stub',
                'from_url',
                'password',
                'confirm_password',
                'edit_password',
                'MAX_FILE_SIZE',
                'perform_webstandards_check',
                '_validated',
                'id',
                'posting_ref_id',
                'f_face',
                'f_colour',
                'f_size',
                'http_referer',
                'session_id',
                'csrf_token',
                'y' . md5(get_site_name() . ': antispam'),
            )) ||
            (strpos($key, 'hour') !== false) ||
            (strpos($key, 'access_') !== false) ||
            (strpos($key, 'minute') !== false) ||
            (strpos($key, 'confirm') !== false) ||
            (strpos($key, 'pre_f_') !== false) ||
            (strpos($key, 'label_for__') !== false) ||
            (strpos($key, 'wysiwyg_version_of_') !== false) ||
            (strpos($key, 'is_wysiwyg') !== false) ||
            (strpos($key, 'require__') !== false) ||
            (strpos($key, 'tempcodecss__') !== false) ||
            (strpos($key, 'comcode__') !== false) ||
            (strpos($key, '_parsed') !== false) ||
            (substr($key, 0, 1) == '_') ||
            (substr($key, 0, 9) == 'hidFileID') ||
            (substr($key, 0, 11) == 'hidFileName') ||
            (($key[0] == 'x') && (strlen($key) == 33));
        if (substr($key, 0, 14) == 'tick_on_form__') {
            if (post_param_integer(substr($key, 14), 0) == 1) {
                $is_hidden = true;
            } else {
                $key = substr($key, 14);
            }
        }

        // TODO: Do a better job with this using proper hooks, #2994
        $fields_filter = null;
        switch ('_WILD:' . get_page_name() . ':' . get_param_string('type', 'browse')) {
            case '_WILD:warnings:add':
            case '_WILD:warnings:_edit':
                $fields_filter = array('explanation', 'message');
                break;

            case '_WILD:cms_galleries:add_category':
            case '_WILD:cms_galleries:_edit_category':
                $fields_filter = array('fullname', 'name', 'description');
                break;

            case '_WILD:cms_downloads:add_category':
            case '_WILD:cms_downloads:_edit_category':
                $fields_filter = array('category', 'description');
                break;

            case '_WILD:cms_catalogues:add_catalogue':
            case '_WILD:cms_catalogues:_edit_catalogue':
                $fields_filter = array('title', 'description');
                break;

            case '_WILD:cms_catalogues:add_category':
            case '_WILD:cms_catalogues:_edit_category':
                $fields_filter = array('title', 'description');
                break;

            case '_WILD:cms_calendar:add':
            case '_WILD:cms_calendar:_edit':
                $fields_filter = array('title', 'post');
                break;

            case '_WILD:admin_ecommerce:add':
            case '_WILD:admin_ecommerce:_edit':
                $fields_filter = array('title', 'description', 'mail_start', 'mail_end', 'mail_uhoh');
                if (post_param_string('subject_0', '') != '') {
                    $fields_filter = array_merge($fields_filter, array('subject_0', 'body_0'));
                }
                if (post_param_string('subject_1', '') != '') {
                    $fields_filter = array_merge($fields_filter, array('subject_1', 'body_1'));
                }
                if (post_param_string('subject_2', '') != '') {
                    $fields_filter = array_merge($fields_filter, array('subject_2', 'body_2'));
                }
                break;

            case '_WILD:admin_cns_post_templates:add':
            case '_WILD:admin_cns_post_templates:_edit':
                $fields_filter = array('title', 'text');
                break;

            case '_WILD:admin_cns_multi_moderations:add':
            case '_WILD:admin_cns_multi_moderations:_edit':
                $fields_filter = array('name', 'post_text');
                break;

            case '_WILD:admin_cns_customprofilefields:add':
            case '_WILD:admin_cns_customprofilefields:_edit':
                $fields_filter = array('name', 'description');
                break;

            case '_WILD:admin_chat:add':
            case '_WILD:admin_chat:_edit':
                $fields_filter = array('room_name', 'c_welcome');
                break;

            case '_WILD:admin_awards:add':
            case '_WILD:admin_awards:_edit':
                $fields_filter = array('title', 'description');
                break;
        }
        switch ('_WILD:' . get_page_name()) {
            case '_WILD:recommend':
                $fields_filter = array('subject', 'message');
                break;
        }
        if (($fields_filter !== null) && (!in_array($key, $fields_filter))) {
            $is_hidden = true;
        }

        if (substr($key, -4) == '_day') {
            $key = substr($key, 0, strlen($key) - 4);
            $timestamp = post_param_date($key);
            if (is_null($timestamp)) {
                $is_hidden = true;
            } else {
                $val = get_timezoned_date($timestamp, false, true, false, true);
            }
        } elseif ((substr($key, -6) == '_month') || (substr($key, -5) == '_year')) {
            $is_hidden = true;
        }

        $key_nice = post_param_string('label_for__' . $key, titleify($key));
        if ($key_nice == '') {
            $is_hidden = true;
        }

        // Checking...

        if (!$is_hidden) {
            if ($spellcheck) {
                require_code('comcode_from_html');
                $mispellings = run_spellcheck(strip_comcode(semihtml_to_comcode($val, true)), null, false);
                $_misspellings = array();
                foreach ($mispellings as $word_bad => $words_good) {
                    $_misspellings[] = array('WORD' => $word_bad, 'CORRECTIONS' => implode(', ', $words_good));
                }
                if (count($_misspellings) != 0) {
                    $spelling->attach(do_template('PREVIEW_SCRIPT_SPELLING', array('_GUID' => '9649572982c01995a8f47c58d16fda39', 'FIELD' => $key_nice, 'MISSPELLINGS' => $_misspellings)));
                }
            }
            if (($keywordcheck) && ((strpos($val, ' ') !== false) || ($key == 'title'))) {
                $keyword_explode = explode(',', $meta_keywords);
                $keywords = array();
                $word_count = str_word_count($val);
                if ($word_count != 0) {
                    foreach ($keyword_explode as $meta_keyword) {
                        $meta_keyword = trim($meta_keyword);
                        if ($meta_keyword != '') {
                            $density = substr_count($val, $meta_keyword) / $word_count;
                            $ideal_density = 1.0 / (9.0 * count($keyword_explode)); // Pretty rough -- common sense is needed
                            $keywords[] = array('sort' => $ideal_density, 'KEYWORD' => $meta_keyword, 'IDEAL_DENSITY' => strval(intval(round($ideal_density * 100))), 'DENSITY' => strval(intval(round($density * 100))));
                        }
                    }
                    sort_maps_by($keywords, 'sort');
                    foreach ($keywords as $ti => $meta_keyword) {
                        unset($keywords[$ti]['sort']);
                    }
                    if (count($keywords) != 0) {
                        $keyword_density->attach(do_template('PREVIEW_SCRIPT_KEYWORD_DENSITY', array('_GUID' => '4fa05e9f52023958a3594d1610b00747', 'FIELD' => $key_nice, 'KEYWORDS' => $keywords)));
                    }
                }
            }
        }

        // Display...

        if (is_null($output)) {
            $attachment_supporting_field = false;
            if (($attachment_type !== null) && ($key == 'post')) {
                $attachment_supporting_field = true;
                $attachment_field = $key;
            } elseif ((in_array($key, array('post', 'description'))) && (strpos($val, '[attachment') !== false)) {
                $attachment_supporting_field = true;
                if (!isset($_POST['post'])) {
                    $attachment_field = $key;
                }
            }

            if (!$attachment_supporting_field) {
                $tempcodecss = (post_param_integer('tempcodecss__' . $key, 0) == 1);
                $supports_comcode = (post_param_integer('comcode__' . $key, 0) == 1);
                $preformatted = (post_param_integer('pre_f_' . $key, 0) == 1);

                if ($is_hidden) {
                    continue;
                }

                if ($preformatted) {
                    $valt = with_whitespace($val);
                } elseif ($supports_comcode) {
                    $valt = comcode_to_tempcode($val);
                } elseif ($tempcodecss) {
                    $i = 0;
                    $color = post_param_string(strval($i), '');
                    while ($color != '') {
                        $val = str_replace('<color-' . strval($i) . '>', '#' . $color, $val);
                        $i++;

                        $color = post_param_string(strval($i), '');
                    }
                    $_val_orig = $val;
                    $valt = comcode_to_tempcode("[code=\"CSS\"]" . $val . "[/code]");
                } else {
                    $valt = make_string_tempcode(escape_html($val));
                }

                $map_table_map[$key_nice] = $valt;
            } else { // An attachment-supporting field
                $tempcodecss = false;
                $posting_ref_id = post_param_integer('posting_ref_id', null);
                if ($posting_ref_id < 0) {
                    fatal_exit(do_lang_tempcode('INTERNAL_ERROR'));
                }
                $post_bits = do_comcode_attachments($val, ($attachment_type === null) ? 'null' : $attachment_type, ($posting_ref_id === null) ? '' : strval(-$posting_ref_id), true, $db);
                $new_post_value = $post_bits['comcode'];

                $map_table_map[$key_nice] = $post_bits['tempcode'];

                $val = $post_bits['tempcode'];
                $supports_comcode = true;
            }
        }
    }

    // Make attachments temporarily readable without any permission context
    require_code('comcode_compiler');
    global $COMCODE_ATTACHMENTS;
    $posting_ref_id = post_param_integer('posting_ref_id', null);
    if (!is_null($posting_ref_id)) {
        if (array_key_exists(strval(-$posting_ref_id), $COMCODE_ATTACHMENTS)) {
            foreach ($COMCODE_ATTACHMENTS[strval(-$posting_ref_id)] as $attachment) {
                $db->query_delete('attachment_refs', array('r_referer_type' => 'null', 'r_referer_id' => strval(-$posting_ref_id), 'a_id' => $attachment['id']), '', 1);
                $db->query_insert('attachment_refs', array('r_referer_type' => 'null', 'r_referer_id' => strval(-$posting_ref_id), 'a_id' => $attachment['id']));
            }
        }
    }

    if (is_null($output)) {
        if (count($map_table_map) == 1) {
            $output = array_pop($map_table_map);
        } else {
            $map_table_fields = new Tempcode();
            foreach ($map_table_map as $key => $val) {
                $map_table_fields->attach(map_table_field($key, $val, true));
            }
            $output = do_template('MAP_TABLE', array('_GUID' => '3f548883b9eb37054c500d1088d9efa3', 'FIELDS' => $map_table_fields));
        }
    }

    if (get_param_integer('js_only', 0) == 1) {
        $output = new Tempcode();
    }

    // This is to get the Comcode attachments updated to the new IDs
    if (!is_null($new_post_value)) {
        $_new_post_value_html = comcode_to_tempcode($new_post_value, null, false, null, null, $db, true);

        require_code('comcode_from_html');
        $new_post_value_html = wysiwygify_media_set($_new_post_value_html->evaluate());

        if (strpos($new_post_value_html, '<!-- CC-error -->') === false) {
            $output->attach(do_template('PREVIEW_SCRIPT_CODE', array('_GUID' => 'bc7432af91e1eaf212dc210f3bf2f756', 'ATTACHMENT_FIELD' => $attachment_field, 'NEW_POST_VALUE_HTML' => $new_post_value_html, 'NEW_POST_VALUE' => $new_post_value)));
        }
    }

    if ($multi_return) {
        return array($output, $webstandards, $keyword_density, $spelling);
    }
    return $output;
}
