public function FlagCountManager::decrementFlagCounts in Flag 8.4
Decrements count of flagged entities.
Parameters
\Drupal\flag\Event\UnflaggingEvent $event: The unflagging event.
File
- src/
FlagCountManager.php, line 221
Class
- FlagCountManager
- Class FlagCountManager.
Namespace
Drupal\flagCode
public function decrementFlagCounts(UnflaggingEvent $event) {
$flaggings_count = [];
$flag_ids = [];
$entity_ids = [];
$flaggings = $event
->getFlaggings();
// Attempt to optimize the amount of queries that need to be executed if
// a lot of flaggings are deleted. Build a list of flags and entity_ids
// that will need to be updated. Entity type is ignored since one flag is
// specific to a given entity type.
foreach ($flaggings as $flagging) {
$flag_id = $flagging
->getFlagId();
$entity_id = $flagging
->getFlaggableId();
$flag_ids[$flag_id] = $flag_id;
$entity_ids[$entity_id] = $entity_id;
if (!isset($flaggings_count[$flag_id][$entity_id])) {
$flaggings_count[$flag_id][$entity_id] = 1;
}
else {
$flaggings_count[$flag_id][$entity_id]++;
}
$this
->resetLoadedCounts($flagging
->getFlaggable(), $flagging
->getFlag());
}
// Build a query that fetches the count for all flag and entity ID
// combinations.
$result = $this->connection
->select('flag_counts')
->fields('flag_counts', [
'flag_id',
'entity_type',
'entity_id',
'count',
])
->condition('flag_id', $flag_ids, 'IN')
->condition('entity_id', $entity_ids, 'IN')
->execute();
$to_delete = [];
foreach ($result as $row) {
// The query above could fetch combinations that are not being deleted
// skip them now.
// Most cases will either delete flaggings of a single flag or a single
// entity where that does not happen.
if (!isset($flaggings_count[$row->flag_id][$row->entity_id])) {
continue;
}
if ($row->count <= $flaggings_count[$row->flag_id][$row->entity_id]) {
// If all flaggings for the given flag and entity are deleted, delete
// the row.
$to_delete[$row->flag_id][] = $row->entity_id;
}
else {
// Otherwise, update the count.
$this->connection
->update('flag_counts')
->expression('count', 'count - :decrement', [
':decrement' => $flaggings_count[$row->flag_id][$row->entity_id],
])
->condition('flag_id', $row->flag_id)
->condition('entity_id', $row->entity_id)
->execute();
}
}
// Execute a delete query per flag.
foreach ($to_delete as $flag_id => $entity_ids) {
$this->connection
->delete('flag_counts')
->condition('flag_id', $flag_id)
->condition('entity_id', $entity_ids, 'IN')
->execute();
}
}