diff --git a/README.rst b/README.rst index d58a05b..f8fed2b 100644 --- a/README.rst +++ b/README.rst @@ -62,6 +62,14 @@ Mark user 123 as active and has played a song: ->mark('active', 123) ->mark('song:played', 123) ; + +Or... + +.. code-block:: php + + $bitter + ->mark(['active', 'song:played'], 123) + ; **Note**: Please don't use huge ids (e.g. 2^32 or bigger) cause this will require large amounts of memory. diff --git a/src/FreeAgent/Bitter/Bitter.php b/src/FreeAgent/Bitter/Bitter.php index 3ec82a2..6051796 100644 --- a/src/FreeAgent/Bitter/Bitter.php +++ b/src/FreeAgent/Bitter/Bitter.php @@ -55,28 +55,35 @@ public function setRedisClient($redisClient) /** * Marks an event for hours, days, weeks and months * - * @param string $eventName The name of the event, could be "active" or "new_signups" + * @param string|array $eventName The name of the event, could be "active" or "new_signups" * @param integer $id An unique id, typically user id. The id should not be huge, read Redis documentation why (bitmaps) * @param DateTime $dateTime Which date should be used as a reference point, default is now */ - public function mark($eventName, $id, DateTime $dateTime = null) + public function mark($eventNames, $id, DateTime $dateTime = null) { + $eventNames = is_array($eventNames) ? $eventNames : array($eventNames); $dateTime = is_null($dateTime) ? new DateTime : $dateTime; - $eventData = array( - new Year($eventName, $dateTime), - new Month($eventName, $dateTime), - new Week($eventName, $dateTime), - new Day($eventName, $dateTime), - new Hour($eventName, $dateTime), - ); - - foreach ($eventData as $event) { - $key = $this->prefixKey . $event->getKey(); - $this->getRedisClient()->setbit($key, $id, 1); - $this->getRedisClient()->sadd($this->prefixKey . 'keys', $key); + $pipe = $this->getRedisClient()->pipeline(); + + foreach ($eventNames as $key => $eventName) { + $eventData = array( + new Year($eventName, $dateTime), + new Month($eventName, $dateTime), + new Week($eventName, $dateTime), + new Day($eventName, $dateTime), + new Hour($eventName, $dateTime), + ); + + foreach ($eventData as $event) { + $key = $this->prefixKey . $event->getKey(); + $pipe->setbit($key, $id, 1); + $pipe->sadd($this->prefixKey . 'keys', $key); + } } + $pipe->execute(); + return $this; } diff --git a/tests/units/Bitter.php b/tests/units/Bitter.php index baa0a60..85a3f21 100644 --- a/tests/units/Bitter.php +++ b/tests/units/Bitter.php @@ -133,6 +133,90 @@ public function testMarkUnitOfTime($redisClient) $this->removeAll($redisClient); } + /** + * @dataProvider dataProviderTestedClients + */ + public function testMultipleMarks($redisClient) + { + $bitter = new TestedBitter($redisClient, $this->getPrefixKey(), $this->getPrefixTempKey()); + + $this->removeAll($redisClient); + + $dateTime = DateTime::createFromFormat('Y-m-d H:i:s', '2012-11-06 15:30:45'); + + $events = array( + 'drink_a_bitter_beer', + 'drink_another_bitter_beer', + 'pass_out', + ); + + foreach ($events as $event) { + $day = new Day($event, $dateTime); + + $this + ->integer($bitter->count($day)) + ->isIdenticalTo(0) + ; + $this + ->boolean($bitter->in(404, $day)) + ->isFalse() + ; + } + + + $this + ->object($bitter->mark($events, 404, $dateTime)) + ->isIdenticalTo($bitter) + ; + + foreach ($events as $event) { + $day = new Day($event, $dateTime); + + $this + ->integer($bitter->count($day)) + ->isIdenticalTo(1) + ; + $this + ->boolean($bitter->in(404, $day)) + ->isTrue() + ; + } + + + // Adding it a second time with the same dateTime ! + $this + ->object($bitter->mark($events, 404, $dateTime)) + ->isIdenticalTo($bitter) + ; + + foreach ($events as $event) { + $day = new Day($event, $dateTime); + $this + ->integer($bitter->count($day)) + ->isIdenticalTo(1) + ; + $this + ->boolean($bitter->in(404, $day)) + ->isTrue() + ; + } + + $this->removeAll($redisClient); + + $day = new Day('drink_a_bitter_beer', new DateTime()); + $this + ->boolean($bitter->in(13, $day)) + ->isFalse() + ; + $bitter->mark('drink_a_bitter_beer', 13); + $this + ->boolean($bitter->in(13, $day)) + ->isTrue() + ; + + $this->removeAll($redisClient); + } + /** * @dataProvider dataProviderTestedClients */