|
3 | 3 | namespace BookStack\Permissions; |
4 | 4 |
|
5 | 5 | use BookStack\App\Model; |
| 6 | +use BookStack\Entities\EntityProvider; |
6 | 7 | use BookStack\Entities\Models\Entity; |
7 | 8 | use BookStack\Entities\Models\Page; |
8 | 9 | use BookStack\Permissions\Models\EntityPermission; |
|
11 | 12 | use BookStack\Users\Models\User; |
12 | 13 | use Illuminate\Database\Eloquent\Builder; |
13 | 14 | use Illuminate\Database\Query\Builder as QueryBuilder; |
| 15 | +use Illuminate\Database\Query\JoinClause; |
14 | 16 | use InvalidArgumentException; |
15 | 17 |
|
16 | 18 | class PermissionApplicator |
@@ -147,6 +149,42 @@ public function restrictEntityRelationQuery(Builder $query, string $tableName, s |
147 | 149 | }); |
148 | 150 | } |
149 | 151 |
|
| 152 | + /** |
| 153 | + * Filter out items that have related entity relations where |
| 154 | + * the entity is marked as deleted. |
| 155 | + */ |
| 156 | + public function filterDeletedFromEntityRelationQuery(Builder $query, string $tableName, string $entityIdColumn, string $entityTypeColumn): Builder |
| 157 | + { |
| 158 | + $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn]; |
| 159 | + $entityProvider = new EntityProvider(); |
| 160 | + |
| 161 | + $joinQuery = function ($query) use ($entityProvider) { |
| 162 | + $first = true; |
| 163 | + /** @var Builder $query */ |
| 164 | + foreach ($entityProvider->all() as $entity) { |
| 165 | + $entityQuery = function ($query) use ($entity) { |
| 166 | + /** @var Builder $query */ |
| 167 | + $query->select(['id', 'deleted_at']) |
| 168 | + ->selectRaw("'{$entity->getMorphClass()}' as type") |
| 169 | + ->from($entity->getTable()) |
| 170 | + ->whereNotNull('deleted_at'); |
| 171 | + }; |
| 172 | + |
| 173 | + if ($first) { |
| 174 | + $entityQuery($query); |
| 175 | + $first = false; |
| 176 | + } else { |
| 177 | + $query->union($entityQuery); |
| 178 | + } |
| 179 | + } |
| 180 | + }; |
| 181 | + |
| 182 | + return $query->leftJoinSub($joinQuery, 'deletions', function (JoinClause $join) use ($tableDetails) { |
| 183 | + $join->on($tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'], '=', 'deletions.id') |
| 184 | + ->on($tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'], '=', 'deletions.type'); |
| 185 | + })->whereNull('deletions.deleted_at'); |
| 186 | + } |
| 187 | + |
150 | 188 | /** |
151 | 189 | * Add conditions to a query for a model that's a relation of a page, so only the model results |
152 | 190 | * on visible pages are returned by the query. |
|
0 commit comments