function opf_save()
{
    global $database;
    $types = opf_get_types();
    // get values
    $id = opf_fetch_post('id', 0, 'int');
    // id is set from opf_edit_filter() only
    $type = opf_fetch_post('type', '', 'unchanged');
    $name = opf_fetch_post('name', '', 'unchanged');
    $func = opf_fetch_post('func', '', 'unchanged');
    $funcname = opf_fetch_post('funcname', '', 'unchanged');
    $desc = opf_fetch_post('desc', '', 'unchanged');
    $active = opf_fetch_post('active', 0, 'int');
    $modules = opf_fetch_post('modules', array(), 'unchanged');
    //$pages  = opf_fetch_post( 'pages', array(), 'unchanged');
    $pages_parent = opf_fetch_post('pages_parent', array(), 'unchanged');
    $searchres = opf_fetch_post('searchresult', FALSE, 'exists');
    $backend = opf_fetch_post('backend', FALSE, 'exists');
    if ($searchres !== FALSE) {
        $pages_parent[] = '0';
    }
    if ($backend !== FALSE) {
        $pages_parent[] = 'backend';
    }
    // cleanup
    $desc = trim($desc);
    $func = trim($func);
    $name = trim($name);
    $funcname = trim($funcname);
    $type = array_key_exists($type, $types) ? $type : key($types);
    $file = '';
    $additional_values = serialize('');
    // move single-page values from $pages_parent to $pages
    $tmp_pages_parent = $tmp_pages = array();
    foreach ($pages_parent as $pid) {
        if (strpos($pid, 's') === 0) {
            $tmp_pages[] = substr($pid, 1);
        } else {
            $tmp_pages_parent[] = $pid;
        }
    }
    $pages_parent = $tmp_pages_parent;
    $pages = $tmp_pages;
    // add additional data
    $filter_old = array();
    if ($id > 0 && opf_db_query_vars("SELECT TRUE FROM " . TABLE_PREFIX . "mod_outputfilter_dashboard" . " WHERE `id`=%d", $id)) {
        // comes from edit, so fetch old data from DB
        $filter_old = opf_db_query("SELECT *" . " FROM " . TABLE_PREFIX . "mod_outputfilter_dashboard" . " WHERE `id`=%d", $id);
        if (!empty($filter_old)) {
            $filter_old = $filter_old[0];
            $userfunc = $filter_old['userfunc'];
            $plugin = $filter_old['plugin'];
            $allowedit = $filter_old['allowedit'];
            $allowedittarget = $filter_old['allowedittarget'];
            $configurl = $filter_old['configurl'];
            $helppath = unserialize($filter_old['helppath']);
            $csspath = $filter_old['csspath'];
            $file = $filter_old['file'];
        }
    } else {
        // comes from add, add default values for inline-filters
        $userfunc = 1;
        $plugin = '';
        $allowedit = 1;
        $allowedittarget = 1;
        $configurl = '';
        $csspath = '';
        $helppath = array();
    }
    // do we have to handle additional data?
    if ($id > 0 && !empty($filter_old)) {
        // comes from edit, so check additional_fields
        $additional_fields = unserialize($filter_old['additional_fields']);
        if (!empty($additional_fields)) {
            $additional_values = array();
            foreach ($additional_fields as $field) {
                if (isset($_POST[$field['name']])) {
                    if (($field['type'] == 'textarea' || $field['type'] == 'editarea') && is_array($field['value'])) {
                        $a = array();
                        preg_match_all("~^\\s*'(.*?)'\\s*=>\\s*'(.*?)'\\s*,?\\s*\$~ms", opf_fetch_post($field['name'], '', 'unchanged'), $matches, PREG_SET_ORDER);
                        if (isset($matches) && $matches) {
                            foreach ($matches as $match) {
                                $a[$match[1]] = $match[2];
                            }
                        }
                        $additional_values[$field['variable']] = $a;
                    } elseif ($field['type'] == 'array') {
                        $a = array();
                        $i = 0;
                        while (isset($_POST[$field['name']]['k'][$i])) {
                            // we can't use opf_fetch_post() because we need to read from $_POST[$field['name']]['k'][$i]
                            $a[opf_fetch_clean($_POST[$field['name']]['k'][$i], '', 'unchanged', FALSE, TRUE)] = opf_fetch_clean($_POST[$field['name']]['v'][$i], '', 'unchanged', FALSE, TRUE);
                            $i++;
                        }
                        $additional_values[$field['variable']] = $a;
                    } else {
                        $additional_values[$field['variable']] = opf_fetch_post($field['name'], '', 'unchanged');
                    }
                } else {
                    $additional_values[$field['variable']] = FALSE;
                }
            }
        }
    }
    // use old values if we come from edit and allowedit is 0
    if ($id > 0 && !empty($filter_old)) {
        if ($allowedit == 0) {
            $name = $filter_old['name'];
            $funcname = $filter_old['funcname'];
            $func = $filter_old['func'];
            $type = $filter_old['type'];
            $desc = unserialize($filter_old['desc']);
            if ($allowedittarget == 0) {
                $modules = unserialize($filter_old['modules']);
                $pages = unserialize($filter_old['pages']);
                $pages_parent = unserialize($filter_old['pages_parent']);
            }
        }
    }
    // prevent inline-filters from overwriting a different filter with same name
    if ($id == 0) {
        // we come from add-filter
        while (opf_is_registered($name)) {
            $name .= mt_rand(0, 9);
        }
    } else {
        // we come from edit-filter: allow to overwrite old one (same $id)
        if (opf_check_name($id) != $name) {
            while (opf_is_registered($name)) {
                $name .= mt_rand(0, 9);
            }
        }
    }
    // register or update filter
    $res = opf_register_filter(array('id' => $id, 'type' => $type, 'name' => $name, 'func' => $func, 'file' => $file, 'funcname' => $funcname, 'modules' => $modules, 'pages' => $pages, 'pages_parent' => $pages_parent, 'desc' => $desc, 'userfunc' => $userfunc, 'plugin' => $plugin, 'active' => $active, 'allowedit' => $allowedit, 'allowedittarget' => $allowedittarget, 'configurl' => $configurl, 'csspath' => $csspath, 'helppath' => $helppath, 'force' => TRUE, 'filter_installed' => FALSE, 'additional_values' => $additional_values));
    if ($res) {
        if ($id == 0) {
            return $database->getLastInsertId();
        } else {
            return $id;
        }
    }
    return $res;
}
function opf_register_filter($filter, $serialized = FALSE)
{
    $now = time();
    $sql_where = '';
    // get variables
    if ($serialized) {
        $filter = unserialize($filter);
    }
    if (isset($filter['id'])) {
        $id = opf_fetch_clean($filter['id'], 0, 'int');
    } else {
        $id = 0;
    }
    // id is set from opf_edit_filter() only
    if (isset($filter['type'])) {
        $type = opf_fetch_clean($filter['type'], '', 'string');
    } else {
        $type = '';
    }
    if (isset($filter['name'])) {
        $name = opf_fetch_clean($filter['name'], '', 'string');
    } else {
        $name = '';
    }
    if (isset($filter['file'])) {
        $file = opf_fetch_clean($filter['file'], '', 'string');
    } else {
        $file = '';
    }
    if (isset($filter['func'])) {
        $func = opf_fetch_clean($filter['func'], '', 'unchanged');
    } else {
        $func = '';
    }
    if (isset($filter['funcname'])) {
        $funcname = opf_fetch_clean($filter['funcname'], '', 'string');
    } else {
        $funcname = '';
    }
    if (isset($filter['userfunc'])) {
        $userfunc = opf_fetch_clean($filter['userfunc'], 0, 'int');
    } else {
        $userfunc = 0;
    }
    if (isset($filter['plugin'])) {
        $plugin = opf_fetch_clean($filter['plugin'], '', 'string');
    } else {
        $plugin = '';
    }
    if (isset($filter['active'])) {
        $active = opf_fetch_clean($filter['active'], 0, 'int');
    } else {
        $active = 1;
    }
    if (isset($filter['allowedit'])) {
        $allowedit = opf_fetch_clean($filter['allowedit'], 0, 'int');
    } else {
        $allowedit = 0;
    }
    if (isset($filter['allowedittarget'])) {
        $allowedittarget = opf_fetch_clean($filter['allowedittarget'], 0, 'int');
    } else {
        $allowedittarget = 1;
    }
    if (isset($filter['configurl'])) {
        $configurl = opf_fetch_clean($filter['configurl'], '', 'string');
    } else {
        $configurl = '';
    }
    if (isset($filter['csspath'])) {
        $csspath = opf_fetch_clean($filter['csspath'], '', 'string');
    } else {
        $csspath = '';
    }
    if (isset($filter['force']) && $filter['force']) {
        $force = TRUE;
    } else {
        $force = FALSE;
    }
    if (isset($filter['filter_installed']) && !$filter['filter_installed']) {
        $filter_installed = FALSE;
    } else {
        $filter_installed = TRUE;
    }
    if (isset($filter['modules'])) {
        $modules = $filter['modules'];
    } else {
        $modules = array();
    }
    if (isset($filter['targets'])) {
        $targets = $filter['targets'];
    } else {
        $targets = array();
    }
    // allow "targets" as alias for "modules"
    if (isset($filter['pages'])) {
        $pages = $filter['pages'];
    } else {
        $pages = array('all');
    }
    if (isset($filter['pages_parent'])) {
        $pages_parent = $filter['pages_parent'];
    } else {
        $pages_parent = array('all');
    }
    if (isset($filter['additional_fields_languages'])) {
        $additional_fields_languages = $filter['additional_fields_languages'];
    }
    // else unset
    if (isset($filter['additional_fields'])) {
        $additional_fields = $filter['additional_fields'];
    }
    // else unset
    if (isset($filter['additional_values'])) {
        $additional_values = $filter['additional_values'];
    } else {
        $additional_values = serialize('');
    }
    // description may be an array of different languages
    if (!isset($filter['desc']) || empty($filter['desc'])) {
        $desc = array();
    } elseif (is_string($filter['desc'])) {
        $desc = array('EN' => $filter['desc']);
    } else {
        $desc = $filter['desc'];
    }
    $desc = serialize($desc);
    if (!isset($filter['helppath']) || empty($filter['helppath'])) {
        $helppath = array();
    } elseif (is_string($filter['helppath'])) {
        $helppath = array('EN' => $filter['helppath']);
    } else {
        $helppath = $filter['helppath'];
    }
    $helppath = serialize($helppath);
    // prepare modules-list
    if (!opf_type_uses_sections($type)) {
        // not a section-filter - no need to check for modules
        $modules = array();
    } else {
        // section-filter
        if (!isset($modules) && isset($targets)) {
            $modules = $targets;
        } elseif (!isset($modules)) {
            $modules = array();
        }
        if (!is_array($modules)) {
            $modules = explode(',', $modules);
        }
        $tmp = array();
        foreach ($modules as $module) {
            $tmp[] = trim($module);
        }
        $modules = $tmp;
        if (in_array('all', $modules)) {
            $all_modules = TRUE;
        } else {
            $all_modules = FALSE;
        }
        foreach (opf_modules_categories('relations') as $m_type => $m_list) {
            if ($all_modules || in_array($m_type, $modules)) {
                $modules = array_merge($modules, $m_list);
            }
        }
        $modules = array_unique($modules);
    }
    // fix some values
    if ($userfunc) {
        $allowedit = 1;
    }
    $modules = serialize($modules);
    if (!is_array($pages)) {
        $pages = explode(',', $pages);
    }
    if (!is_array($pages_parent)) {
        $pages_parent = explode(',', $pages_parent);
    }
    if (empty($pages) && empty($pages_parent)) {
        $pages = array('9999999');
        $pages_parent = array('9999999');
    }
    $tmp = array();
    foreach ($pages as $page) {
        $tmp[] = trim($page);
    }
    $pages = $tmp;
    $tmp = array();
    foreach ($pages_parent as $page) {
        $tmp[] = trim($page);
    }
    $pages_pages = $tmp;
    $pages = serialize($pages);
    $pages_parent = serialize($pages_parent);
    if (isset($additional_fields_languages) && !empty($additional_fields_languages)) {
        $additional_fields_languages = serialize($additional_fields_languages);
    } else {
        $additional_fields_languages = serialize('');
    }
    if ($filter_installed) {
        if (isset($additional_fields) && !empty($additional_fields)) {
            $additional_values = array();
            foreach ($additional_fields as $field) {
                switch ($field['type']) {
                    case 'text':
                    case 'textarea':
                    case 'editarea':
                    case 'array':
                        $additional_values[$field['variable']] = $field['value'];
                        break;
                    case 'checkbox':
                    case 'radio':
                        if (isset($field['checked']) && $field['checked']) {
                            $additional_values[$field['variable']] = $field['value'];
                        } else {
                            if (!isset($additional_values[$field['variable']]) || !$additional_values[$field['variable']]) {
                                $additional_values[$field['variable']] = FALSE;
                            }
                        }
                        break;
                    case 'select':
                        if (isset($field['checked']) && isset($field['value'][$field['checked']])) {
                            $additional_values[$field['variable']] = $field['checked'];
                        } else {
                            $additional_values[$field['variable']] = FALSE;
                        }
                        break;
                }
            }
        } else {
            $additional_values = '';
        }
    }
    if (isset($additional_fields) && !empty($additional_fields)) {
        $additional_fields = serialize($additional_fields);
    } else {
        $additional_fields = serialize('');
    }
    $additional_values = serialize($additional_values);
    // check some variables
    if ($type == '' || $name == '' || $funcname == '') {
        trigger_error('Needed Argument missing or empty', E_USER_WARNING);
        if ($force) {
            // store it nevertheless, but set it inactive
            $active = 0;
            if ($name == '') {
                $name = uniqid('filter_');
            }
            if ($funcname == '') {
                $funcname = uniqid('opff_');
            }
        } else {
            return FALSE;
        }
    }
    $fileCheck = str_replace('{SYSVAR:WB_PATH}', WB_PATH, $file);
    $fileCheck = str_replace('{OPF:PLUGIN_PATH}', OPF_PLUGINS_PATH . $plugin, $fileCheck);
    if ($fileCheck == '' && $func == '' || $fileCheck != '' && $func != '') {
        trigger_error('File OR Function needed', E_USER_WARNING);
        if ($force) {
            // store it nevertheless, but set it inactive
            $active = 0;
            if ($func == '') {
                $func = '// Please enter a function.';
            }
        } else {
            return FALSE;
        }
    }
    if ($fileCheck && (!file_exists($fileCheck) || !is_file($fileCheck) || !is_readable($fileCheck))) {
        trigger_error("Can\\'t read file ({$file})", E_USER_WARNING);
        return FALSE;
    }
    if ($func != '' && !preg_match("~{$funcname}\\s*\\(~", $func)) {
        trigger_error('wrong funcname', E_USER_WARNING);
        if ($force) {
            // store it nevertheless, but set it inactive
            $active = 0;
            $func = preg_replace('/\\?>\\s*<\\?php/', '', "<?php // ATTN: given funcname and used name differ.\n?>" . $func);
        } else {
            return FALSE;
        }
    }
    if ($func != '' && preg_match("/{$funcname}\\s*\\(/", $func)) {
        // remove warning again when funcname is corrected
        $func = preg_replace('/\\s*\\/\\/\\s*ATTN: given funcname and used name differ.\\s*/', "\n", $func);
    }
    // insert values into DB
    // get next free position for type
    $position = opf_db_query_vars("SELECT MAX(`position`) FROM `" . TABLE_PREFIX . "mod_outputfilter_dashboard` WHERE `type`='%s'", $type);
    if (!$position) {
        $position = 0;
    } else {
        ++$position;
    }
    // new entry or update?
    if ($id > 0) {
        $update = opf_is_registered($id);
    } else {
        $update = opf_is_registered($name);
    }
    if ($update) {
        // update, fetch some old values from db
        $sql_action = 'UPDATE';
        if ($id > 0) {
            $sql_where = "WHERE `id`=" . (int) $id;
        } else {
            $sql_where = "WHERE `name`='" . addslashes($name) . "'";
        }
        // keep this addslashes()-call!
        $old = opf_db_query("SELECT * FROM `" . TABLE_PREFIX . "mod_outputfilter_dashboard` {$sql_where}");
        if ($old === FALSE) {
            return FALSE;
        }
        $old = $old[0];
        $old_type = $old['type'];
        $old_pos = $old['position'];
        if ($type == $old_type) {
            // type unchanged, so keep position
            $position = $old_pos;
        } else {
            // change of type
            // correct positions for old type
            opf_db_run_query("UPDATE `" . TABLE_PREFIX . "mod_outputfilter_dashboard` SET `position`=`position`-1 WHERE `type`='%s' AND `position`>%d", $old_type, $old_pos);
        }
        if ($force == FALSE) {
            // update - keep some old values
            $active = (int) $old['active'];
            $modules = $old['modules'];
            $pages = $old['pages'];
            $pages_parent = $old['pages_parent'];
        }
        if (!$filter_installed) {
            // filter from edit. Fetch old values from DB
            $additional_fields_languages = $old['additional_fields_languages'];
            $additional_fields = $old['additional_fields'];
        }
    } else {
        $sql_action = 'INSERT INTO';
    }
    $res = opf_db_run_query("{$sql_action} `" . TABLE_PREFIX . "mod_outputfilter_dashboard` SET\n                                             `userfunc`=%d,\n                                             `plugin`='%s',\n                                             `position`=%d,\n                                             `active`=%d,\n                                             `type`='%s',\n                                             `name`='%s',\n                                             `file`='%s',\n                                             `func`='%s',\n                                             `funcname`='%s',\n                                             `modules`='%s',\n                                             `desc`='%s',\n                                             `pages`='%s',\n                                             `pages_parent`='%s',\n                                             `allowedit`=%d,\n                                             `allowedittarget`=%d,\n                                             `configurl`='%s',\n                                             `csspath`='%s',\n                                             `helppath`='%s',\n                                             `additional_values`='%s',\n                                             `additional_fields`='%s',\n                                             `additional_fields_languages`='%s'\n                                             {$sql_where}", $userfunc, $plugin, $position, $active, $type, $name, $file, $func, $funcname, $modules, $desc, $pages, $pages_parent, $allowedit, $allowedittarget, $configurl, $csspath, $helppath, $additional_values, $additional_fields, $additional_fields_languages);
    return $res;
}
if (!(include get_module_language_file($mod_dir))) {
    return;
}
// load outputfilter-functions
require_once dirname(__FILE__) . '/functions.php';
// This file will be included from tool.php
// prevent this file from being accessed directly
if (!defined('WB_PATH')) {
    die(header('Location: ../index.php'));
}
// check if user is allowed to use admin-tools (to prevent this file to be called by an unauthorized user e.g. from a code-section)
if (!$admin->get_permission('admintools')) {
    die(header('Location: ../../index.php'));
}
// get filter-data
if (!($filters = opf_db_query("SELECT * FROM `" . TABLE_PREFIX . "mod_outputfilter_dashboard` WHERE `id`={$id}"))) {
    return;
}
$filter = $filters[0];
$types = opf_get_types();
$name = $filter['name'];
$active = $filter['active'] == 1 ? 1 : 0;
$userfunc = $filter['userfunc'] == 1 ? 1 : 0;
$plugin = $filter['plugin'];
$type = array_key_exists($filter['type'], $types) ? $filter['type'] : key($types);
$file = $filter['file'];
$modules = unserialize($filter['modules']);
$desc = opf_fetch_entry_language(unserialize($filter['desc']));
$helppath = opf_fetch_entry_language(unserialize($filter['helppath']));
$helppath = str_replace('{SYSVAR:WB_URL}', WB_URL, $helppath);
$helppath = str_replace('{OPF:PLUGIN_URL}', OPF_PLUGINS_URL . $filter['plugin'], $helppath);