Избавляемся от лишних уведомлений на электронную почту

Заметил, что при комментировании какого либо объекта на почту приходит несколько одинаковых уведомлений, что неправильно... Пользователь должен получать одно уведомление за один новый коммент, не больше, но разработчики написали код выборки получателей таким образом, что пользователь получит столько уведомлений, сколько он оставил комментариев к этому же объекту. То есть если пользователь ранее написал, скажем семь комментариев к фотографии, то при появлении нового коммента (от другого пользователя), автор семи комментов получит семь уведомлений.

Я на скорую руку профиксил этот недочет. Открываю: "module/comment/include/service/comment.class.php" и правлю функцию "massMail" вот так:
	public function massMail($module, $itemId, $ownerUserId, $message = [])
	{
		$rows = $this->database()
			->select('c.*')
			->from($this->table, 'c')
			->where('c.type_id = \'' . $this->database()->escape($module) . '\' AND item_id = ' . (int) $itemId . ' AND view_id = 0')
			->execute('getSlaveRows');

		// Массив для содержания только уникальных "user_id"
		$uniquely = [];

		foreach ($rows as $row)
		{
			if ($row['user_id'] == $ownerUserId || in_array($row['user_id'], $uniquely))
			{
				continue;
			}

			$uniquely[] = $row['user_id'];

			phpfox::getLib('mail')
				->to($row['user_id'])
				->subject($message['subject'])
				->message($message['message'])
				->notification('comment.add_new_comment')
				->send();

			phpfox::getService('notification.process')->add('comment_' . $module, $itemId, $row['user_id']);
		}
	}

В функцию добавил пустой массив, куда в дальнейшем будут добавляться уникальные id пользователей:
		// Массив для содержания только уникальных "user_id"
		$uniquely = [];

Дальше, в существующее условие добавил проверку на существование элемента в массиве:
			if ($row['user_id'] == $ownerUserId || in_array($row['user_id'], $uniquely))
			{
				continue;
			}

			$uniquely[] = $row['user_id'];

Если в массиве уже есть id пользователя, которому предстоит отправил письмо, то итерация цикла будет пропущена. Если же id еще нет, то в массив добавляется новая запись и отправляется письмо.

Теперь на почту приходит не более одного уведомления за один коммент.

До того, как я пришел к этому решению, я добавил в запрос ->group('user_id'), но к сожалению не помогло, скорее наоборот - уведомления вообще не приходили. Видимо группировать необходимо не только поле user_id, но и еще какие то (SELECT list is not in GROUP BY clause and contains nonaggregated column 'название поля' which is not functionally dependent on columns in GROUP BY clause), пока не выесню какие именно, решение останется таким.

Похожие темы

Сегодня я разобрался, какие поля необходимо было добавить, это "comment_id" и "user_id":
			->group('comment_id, user_id')

Но это не исправляет ситуацию с несколькими одинаковыми уведомлениями...

Проблема решина при помощи DISTINCT в запросе:
		$rows = $this->database()
			->select('DISTINCT user_id')
			->from($this->table)
			->where('type_id = \'' . $this->database()->escape($module) . '\' AND item_id = ' . (int) $itemId . ' AND view_id = 0')
			->execute('getSlaveRows');

Вся функция, на данный момент, у меня выглядит так:
	public function massMail($module, $itemId, $ownerUserId, $message = [])
	{
		$rows = $this->database()
			->select('DISTINCT user_id')
			->from($this->table)
			->where('type_id = \'' . $this->database()->escape($module) . '\' AND item_id = ' . (int) $itemId . ' AND view_id = 0')
			->execute('getSlaveRows');

		foreach ($rows as $row)
		{
			if ($row['user_id'] == $ownerUserId)
			{
				continue;
			}

			phpfox::getLib('mail')
				->to($row['user_id'])
				->subject($message['subject'])
				->message($message['message'])
				->notification('comment.add_new_comment')
				->send();

			phpfox::getService('notification.process')->add('comment_' . $module, $itemId, $row['user_id']);
		}
	}

На мой взгляд это решение лучше предыдущего.

Возможно, будет интересно: Выборка уникальных значений из таблицы.