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;
}
    if (opf_fetch_post('submit_return', FALSE, 'exists')) {
        $force_edit = TRUE;
    }
}
// save edited css file
if ($css_save && $doSave) {
    if (!empty($_POST)) {
        $tmp = opf_css_save();
        if (is_numeric($tmp)) {
            $id = $tmp;
        }
        // overwrite $id
    }
    // in case we come from add/edit check if user pressed "save" instead of "save and exit"
    if (opf_fetch_post('submit_return', FALSE, 'exists')) {
        $force_csspath = opf_fetch_post('csspath', NULL, 'string');
    }
}
// Now, determine what to do: add filter, edit filter, edit css, open help, show overview
$add = opf_fetch_get('add', FALSE, 'exists');
$edit = opf_fetch_get('edit', FALSE, 'exists');
$csspath = opf_fetch_get('csspath', NULL, 'string');
if (isset($force_edit)) {
    $edit = TRUE;
}
if (isset($force_csspath)) {
    $csspath = $force_csspath;
}
if ($add && $doSave) {
    //================================================ add =====
    require WB_PATH . "/modules/{$ModDir}/add_filter.php";