function churchcal_updateEvent($params, $source = null)
{
    $arr = array();
    // Store all Exception and Addition changes for communication to other modules
    $changes = array();
    // Nur Rechte pr�fen, wenn ich source bin, denn sonst hat das das Ursprungsmodul schon erledigt
    if ($source == null) {
        // Pr�fe, ob ich auf neue Kategorie schrieben darf
        if (!churchcal_isAllowedToEditCategory($params["category_id"])) {
            return CTNoPermission("AllowedToEditCategory[" . $params["category_id"] . "]", "churchcal");
        }
        // Pr�fe, ob ich auf die vorhandene Kategorie schreiben darf
        $old_cal = db_query("select category_id, startdate from {cc_cal} where id=:id", array(":id" => $params["id"]))->fetch();
        if (!churchcal_isAllowedToEditCategory($old_cal->category_id)) {
            return CTNoPermission("AllowedToEditCategory[" . $old_cal->category_id . "]", "churchcal");
        }
    }
    // Wenn es nur eine Verschiebung auf dem Kalender ist
    if (!isset($params["repeat_id"])) {
        $i = new CTInterface();
        $i->setParam("startdate", false);
        $i->setParam("enddate", false);
        $i->setParam("bezeichnung", false);
        $i->setParam("category_id", false);
        if (count($i->getDBInsertArrayFromParams($params)) > 0) {
            db_update("cc_cal")->fields($i->getDBInsertArrayFromParams($params))->condition("id", $params["id"], "=")->execute();
        }
    } else {
        $arr[":event_id"] = $params["id"];
        $arr[":startdate"] = $params["startdate"];
        $arr[":enddate"] = $params["enddate"];
        $arr[":bezeichnung"] = $params["bezeichnung"];
        $arr[":ort"] = $params["ort"];
        $arr[":intern_yn"] = $params["intern_yn"];
        $arr[":notizen"] = str_replace('\\"', '"', $params["notizen"]);
        $arr[":link"] = $params["link"];
        $arr[":category_id"] = $params["category_id"];
        if (isset($params["repeat_id"])) {
            $arr[":repeat_id"] = $params["repeat_id"];
        } else {
            $arr[":repeat_id"] = null;
        }
        if (isset($params["repeat_until"])) {
            $arr[":repeat_until"] = $params["repeat_until"];
        } else {
            $arr[":repeat_until"] = null;
        }
        if (isset($params["repeat_frequence"])) {
            $arr[":repeat_frequence"] = $params["repeat_frequence"];
        } else {
            $arr[":repeat_frequence"] = null;
        }
        if (isset($params["repeat_option_id"])) {
            $arr[":repeat_option_id"] = $params["repeat_option_id"];
        } else {
            $arr[":repeat_option_id"] = null;
        }
        db_query("update {cc_cal} set startdate=:startdate, enddate=:enddate, bezeichnung=:bezeichnung, ort=:ort,\n      notizen=:notizen, link=:link, category_id=:category_id, intern_yn=:intern_yn, category_id=:category_id, \n      repeat_id=:repeat_id, repeat_until=:repeat_until, repeat_frequence=:repeat_frequence,\n      repeat_option_id=:repeat_option_id \n        where id=:event_id", $arr);
        // Hole alle Exceptions aus der DB
        $exc = churchcore_getTableData("cc_cal_except", null, "cal_id=" . $params["id"]);
        // Vergleiche erst mal welche schon in der DB sind oder noch nicht in der DB sind.
        if (isset($params["exceptions"])) {
            foreach ($params["exceptions"] as $exception) {
                if ($exception["id"] > 0) {
                    $exc[$exception["id"]]->vorhanden = true;
                } else {
                    $add_exc = array("cal_id" => $params["id"], "except_date_start" => $exception["except_date_start"], "except_date_end" => $exception["except_date_end"]);
                    churchcal_addException($add_exc);
                    $changes["add_exception"][] = $add_exc;
                }
            }
        }
        // L�sche nun alle, die in der DB sind, aber nicht mehr vorhanden sind.
        if ($exc != false) {
            foreach ($exc as $e) {
                if (!isset($e->vorhanden)) {
                    $del_exc = array("id" => $e->id, "except_date_start" => $e->except_date_start, "except_date_end" => $e->except_date_end);
                    churchcal_delException($del_exc);
                    $changes["del_exception"][] = $del_exc;
                }
            }
        }
        // Hole alle Additions aus der DB
        $add = churchcore_getTableData("cc_cal_add", null, "cal_id=" . $params["id"]);
        // Vergleiche erst mal welche schon in der DB sind oder noch nicht in der DB sind.
        if (isset($params["additions"])) {
            foreach ($params["additions"] as $addition) {
                if ($addition["id"] > 0) {
                    $add[$addition["id"]]->vorhanden = true;
                } else {
                    $add_add = array("cal_id" => $params["id"], "add_date" => $addition["add_date"], "with_repeat_yn" => $addition["with_repeat_yn"]);
                    churchcal_addAddition($add_add);
                    $changes["add_addition"][] = $add_add;
                }
            }
        }
        // L�sche nun alle, die in der DB sind, aber nicht mehr vorhanden sind.
        if ($add != false) {
            foreach ($add as $a) {
                if (!isset($a->vorhanden)) {
                    $del_add = array("id" => $a->id, "add_date" => $a->add_date);
                    churchcal_delAddition($del_add);
                    $changes["del_addition"][] = $del_add;
                }
            }
        }
    }
    // MeetingRequest
    if (isset($params["meetingRequest"])) {
        churchcal_handleMeetingRequest($params["id"], $params);
    }
    // BENACHRICHTIGE ANDERE MODULE
    $modules = churchcore_getModulesSorted(false, false);
    if (in_array("churchresource", $modules) && ($source == null || $source != "churchresource")) {
        include_once CHURCHRESOURCE . '/churchresource_db.php';
        if ($source == null) {
            $source = "churchcal";
        }
        $params["cal_id"] = $params["id"];
        churchresource_updateResourcesFromChurchCal($params, $source, $changes);
    }
    if (in_array("churchservice", $modules) && ($source == null || $source != "churchservice")) {
        include_once CHURCHSERVICE . '/churchservice_db.php';
        $cs_params = array_merge(array(), $params);
        $cs_params["cal_id"] = $params["id"];
        $cs_params["id"] = null;
        $cs_params["old_startdate"] = $old_cal->startdate;
        if ($source == null) {
            $source = "churchcal";
        }
        churchservice_updateEventFromChurchCal($cs_params, $source);
    }
}
/**
 * Store all Exception and Addition changes for communication to other modules
 *
 * @param array $params
 * @param string $sourc; controls cooperation between modules if event comes from another modulee
 * @param boolean $withoutPerm If permission will be checked.
 */
function churchcal_updateEvent($params, $callCS = true, $withoutPerm = false)
{
    global $user, $base_url;
    $changes = array();
    if (!$withoutPerm && !churchcal_isAllowedToEditCategory($params["category_id"])) {
        throw new CTNoPermission("AllowedToEditCategory[" . $params["category_id"] . "] (newCat)", "churchcal");
    }
    $old_cal = db_query("SELECT *\n                       FROM {cc_cal}\n                       WHERE id=:id", array(":id" => $params["id"]))->fetch();
    // can user edit old event category?
    if (!$withoutPerm && !churchcal_isAllowedToEditCategory($old_cal->category_id)) {
        throw new CTNoPermission("AllowedToEditCategory[" . $old_cal->category_id . "] (oldCat)", "churchcal");
    }
    // When empty, load originEvent for later sending Change protocol
    $dummy = churchcal_getCalPerCategory(array("category_ids" => array(0 => $old_cal->category_id)));
    $originEvent = (array) $dummy[$old_cal->category_id][$params["id"]];
    if (isset($params["notizen"])) {
        $params["notizen"] = str_replace('\\"', '"', $params["notizen"]);
    }
    $i = new CTInterface();
    $i->setParam("startdate", false);
    $i->setParam("enddate", false);
    $i->setParam("bezeichnung", false);
    $i->setParam("category_id", false);
    $i->setParam("ort", false);
    $i->setParam("notizen", false);
    $i->setParam("intern_yn", false);
    $i->setParam("link", false);
    $i->setParam("repeat_id", false);
    $i->setParam("repeat_until", false);
    $i->setParam("repeat_frequence", false);
    $i->setParam("repeat_option_id", false);
    if (isset($params["modified_pid"])) {
        $i->setParam("modified_pid");
    }
    // not with ", false" cause this cause an update
    $f = $i->getDBInsertArrayFromParams($params);
    if (count($f)) {
        db_update("cc_cal")->fields($f)->condition("id", $params["id"], "=")->execute();
    }
    // get all exceptions for event
    $exc = churchcore_getTableData("cc_cal_except", null, "cal_id=" . $params["id"]);
    // look which are already in DB
    if (!empty($params["exceptions"])) {
        foreach ($params["exceptions"] as $exception) {
            if ($exception["id"] > 0) {
                $exc[$exception["id"]]->vorhanden = true;
            } else {
                $add_exc = array("cal_id" => $params["id"], "except_date_start" => $exception["except_date_start"], "except_date_end" => $exception["except_date_end"]);
                churchcal_addException($add_exc);
                $changes["add_exception"][] = $add_exc;
            }
        }
    }
    // delete removed exceptions from DB
    if ($exc) {
        foreach ($exc as $e) {
            if (!isset($e->vorhanden)) {
                $del_exc = array("id" => $e->id, "except_date_start" => $e->except_date_start, "except_date_end" => $e->except_date_end);
                churchcal_delException($del_exc);
                $changes["del_exception"][] = $del_exc;
            }
        }
    }
    // get all additions
    $add = churchcore_getTableData("cc_cal_add", null, "cal_id=" . $params["id"]);
    // look which are already in DB.
    if (!empty($params["additions"])) {
        foreach ($params["additions"] as $addition) {
            if ($addition["id"] > 0) {
                $add[$addition["id"]]->vorhanden = true;
            } else {
                $add_add = array("cal_id" => $params["id"], "add_date" => $addition["add_date"], "with_repeat_yn" => $addition["with_repeat_yn"]);
                churchcal_addAddition($add_add);
                $changes["add_addition"][] = $add_add;
            }
        }
    }
    // delete from DB which are deleted.
    if ($add) {
        foreach ($add as $a) {
            if (!isset($a->vorhanden)) {
                $del_add = array("id" => $a->id, "add_date" => $a->add_date);
                churchcal_delAddition($del_add);
                $changes["del_addition"][] = $del_add;
            }
        }
    }
    // meeting request
    if (isset($params["meetingRequest"])) {
        churchcal_handleMeetingRequest($params["id"], $params);
    }
    // Call other modules
    $newBookingIds = null;
    if (churchcore_isModuleActivated("churchresource")) {
        include_once CHURCHRESOURCE . '/churchresource_db.php';
        $newBookingIds = churchresource_operateResourcesFromChurchCal($params);
    }
    $newCSIds = null;
    if ($callCS) {
        if (churchcore_isModuleActivated("churchservice")) {
            include_once CHURCHSERVICE . '/churchservice_db.php';
            $newCSIds = churchservice_operateEventFromChurchCal($params);
        }
    }
    // Notification
    $data = db_query("select * from {cc_calcategory} where id=:id", array(":id" => $params["category_id"]))->fetch();
    $txt = $user->vorname . " " . $user->name . " hat einen Termin angepasst im Kalender ";
    if ($data != false) {
        $txt .= $data->bezeichnung;
    } else {
        $txt .= $params["category_id"];
    }
    $txt .= " auf:<br>";
    $txt .= churchcore_CCEventData2String($params);
    ct_notify("category", $params["category_id"], $txt);
    // Inform creator when I am allowed and when it is not me!
    if ($callCS && getVar("informCreator", "true") == "true" && $originEvent["modified_pid"] != $user->id) {
        $data = (array) churchcal_getEventChangeImpact(array("newEvent" => $params, "originEvent" => $originEvent, "pastEvent" => null));
        if (!empty($data["bookings"]) || !empty($data["cal"])) {
            $data["new"] = false;
            $data["caption"] = $params["bezeichnung"];
            $data["startdate"] = churchcore_stringToDateDe($params["startdate"]);
            $data["eventUrl"] = $base_url . "?q=churchcal&category_id=" . $params["category_id"] . "&id=" . $params["id"];
            $p = db_query("SELECT name, vorname, IF(spitzname, spitzname, vorname) AS nickname\n                      FROM {cdb_person}\n                      WHERE id=:id", array(":id" => $originEvent["modified_pid"]))->fetch();
            $data["p"] = $p;
            // get populated template and send email
            $lang = getUserLanguage($params["modified_pid"]);
            $content = getTemplateContent('email/informCreator', 'churchcal', $data, null, $lang);
            churchcore_sendEMailToPersonIDs($originEvent["modified_pid"], "[" . getConf('site_name') . "] " . t2($lang, 'information.for.your.event'), $content, null, true);
        }
    }
    return array("cseventIds" => $newCSIds, "bookingIds" => $newBookingIds);
}