'Save a filter, responds to POST filter.json
@param r: the S3Request
@param attr: additional controller parameters'

def _save(self, r, **attr):

    auth = current.auth
    if auth.s3_logged_in():
        pe_id = current.auth.user.pe_id
    else:
        pe_id = None
    if (not pe_id):
        r.unauthorised()
    source = r.body
    source.seek(0)
    try:
        data = json.load(source)
    except ValueError:
        r.error(501, current.ERROR.BAD_SOURCE)
    db = current.db
    s3db = current.s3db
    table = s3db.pr_filter
    record_id = data.get('id')
    record = None
    if record_id:
        query = ((table.id == record_id) & (table.pe_id == pe_id))
        record = db(query).select(table.id, limitby=(0, 1)).first()
        if (not record):
            r.error(404, current.ERROR.BAD_RECORD)
    filter_data = {'pe_id': pe_id, 'controller': r.controller, 'function': r.function, 'resource': self.resource.tablename, 'deleted': False}
    title = data.get('title')
    if (title is not None):
        filter_data['title'] = title
    description = data.get('description')
    if (description is not None):
        filter_data['description'] = description
    query = data.get('query')
    if (query is not None):
        filter_data['query'] = json.dumps(query)
    url = data.get('url')
    if (url is not None):
        filter_data['url'] = url
    onaccept = None
    form = Storage(vars=filter_data)
    if record:
        success = db((table.id == record_id)).update(**filter_data)
        if success:
            current.audit('update', 'pr', 'filter', form, record_id, 'json')
            info = {'updated': record_id}
            onaccept = s3db.get_config(table, 'update_onaccept', s3db.get_config(table, 'onaccept'))
    else:
        success = table.insert(**filter_data)
        if success:
            record_id = success
            current.audit('create', 'pr', 'filter', form, record_id, 'json')
            info = {'created': record_id}
            onaccept = s3db.get_config(table, 'update_onaccept', s3db.get_config(table, 'onaccept'))
    if (onaccept is not None):
        form.vars['id'] = record_id
        callback(onaccept, form)
    xml = current.xml
    if success:
        msg = xml.json_message(**info)
    else:
        msg = xml.json_message(False, 400)
    current.response.headers['Content-Type'] = 'application/json'
    return msg
