+ /**
+ * Filter out items that have related entity relations where
+ * the entity is marked as deleted.
+ */
+ public function filterDeletedFromEntityRelationQuery(Builder $query, string $tableName, string $entityIdColumn, string $entityTypeColumn): Builder
+ {
+ $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
+ $entityProvider = new EntityProvider();
+
+ $joinQuery = function ($query) use ($entityProvider) {
+ $first = true;
+ foreach ($entityProvider->all() as $entity) {
+ /** @var Builder $query */
+ $entityQuery = function ($query) use ($entity) {
+ $query->select(['id', 'deleted_at'])
+ ->selectRaw("'{$entity->getMorphClass()}' as type")
+ ->from($entity->getTable())
+ ->whereNotNull('deleted_at');
+ };
+
+ if ($first) {
+ $entityQuery($query);
+ $first = false;
+ } else {
+ $query->union($entityQuery);
+ }
+ }
+ };
+
+ return $query->leftJoinSub($joinQuery, 'deletions', function (JoinClause $join) use ($tableDetails) {
+ $join->on($tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'], '=', 'deletions.id')
+ ->on($tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'], '=', 'deletions.type');
+ })->whereNull('deletions.deleted_at');
+ }
+