©Sergey Emelyanov 2025 | Alle Rechte vorbehalten
Im Entwicklungsalltag mit der Vtiger CRM API kommt es häufig zu der unangenehmen Situation, dass beim Löschen eines Datensatzes die zugehörigen Verknüpfungen nicht automatisch entfernt werden. Dies führt dazu, dass verwandte Datensätze in separaten Abfragen gelöscht werden müssen – ein mühsamer und ineffizienter Prozess. Um diesen Umstand zu umgehen, habe ich eine Hilfsfunktion entwickelt, die es ermöglicht, verknüpfte Datensätze automatisch zu löschen. Die Funktion vtws_delete_related nimmt als Parameter die ID des übergeordneten (Source) und des untergeordneten (Related) Datensatzes sowie optional ein User-Modell zur Kontrolle der Zugriffsrechte entgegen.
Im Folgenden wird der Code der Funktion erläutert und präsentiert. Sie können diese Funktion beispielsweise in die Datei include/Webservices/DeleteRelatedRecords.php
einfügen.
function vtws_delete_related($sourceRecordId, $relatedRecordId, $user = false)
{
global $log, $adb;
// Zerlegung der Quell-ID in Modul- und Elementkomponenten
list($moduleSourceId, $elementSourceId) = vtws_getIdComponents($sourceRecordId);
$webserviceObject = VtigerWebserviceObject::fromId($adb, $moduleSourceId);
// Ermitteln des Handler-Pfads und der Handler-Klasse
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject, $user, $adb, $log);
$meta = $handler->getMeta();
// Ermitteln des Modulnamens des Quell-Datensatzes
$sourceModuleName = $meta->getObjectEntityName($sourceRecordId);
// Prüfung der Benutzerrechte: Liste der erlaubten Module abrufen
$types = vtws_listtypes(null, $user);
if (!in_array($sourceModuleName, $types['types'])) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, 'Permission to perform the operation is denied');
}
// Sicherstellen, dass der Quell-Datensatz zum erwarteten Modul gehört
if ($sourceModuleName !== $webserviceObject->getEntityName()) {
throw new WebServiceException(WebServiceErrorCode::$INVALIDID, 'Id specified is incorrect');
}
if (!$meta->hasPermission(EntityMeta::$UPDATE, $sourceRecordId)) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, 'Permission to read given object is denied');
}
// Prüfung, ob der Quell-Datensatz existiert
if (!$meta->exists($elementSourceId)) {
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND, 'Record you are trying to access is not found');
}
// Prüfung der Schreibrechte
if ($meta->hasWriteAccess() !== true) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, 'Permission to write is denied');
}
// Zerlegung der Related-ID in Modul und Element
list($moduleRelatedId, $elementRelatedId) = vtws_getIdComponents($relatedRecordId);
// Instanz des verknüpften Datensatzes abrufen
$relatedRecordInstance = Vtiger_Record_Model::getInstanceById($elementRelatedId);
$relatedModuleName = $relatedRecordInstance->getModuleName();
// Instanz des Quellmoduls holen
$sourceModuleFocus = CRMEntity::getInstance($sourceModuleName);
if ($sourceModuleFocus && $relatedRecordInstance) {
// Abhängig von den Modulen (z.B. Potentials mit Products oder Contacts)
if ($sourceModuleName == 'Potentials' && $relatedModuleName == 'Products') {
$query = 'DELETE FROM vtiger_seproductsrel WHERE crmid=? AND productid=? AND setype=?';
$adb->pquery($query, [$elementSourceId, $elementRelatedId, 'Potentials']);
} elseif ($sourceModuleName == 'Potentials' && $relatedModuleName == 'Contacts') {
$query = 'DELETE FROM vtiger_contpotentialrel WHERE potentialid=? AND contactid=?';
$adb->pquery($query, [$elementSourceId, $elementRelatedId]);
} else {
// Standardmethode zum Aufheben der Verknüpfung
$sourceModuleFocus->delete_related_module($sourceModuleName, $elementSourceId, $relatedModuleName, $elementRelatedId);
}
}
// Zwischenspeicher leeren
VTWS_PreserveGlobal::flush();
return true;
}
Funktionsweise und Erläuterung
Fazit
Mithilfe der Funktion vtws_delete_related können Sie verknüpfte Datensätze automatisiert über die Vtiger CRM Webservices löschen. Dieses universelle Lösungsbeispiel vereinfacht den Löschvorgang erheblich, da es nicht mehr erforderlich ist, jeden verbundenen Datensatz einzeln über weitere Anfragen zu entfernen. Administratoren und Entwickler profitieren von einer vereinfachten, einheitlichen Methode, die Prozesse zu beschleunigen und den Wartungsaufwand zu reduzieren.
©Sergey Emelyanov 2025 | Alle Rechte vorbehalten