/** * Add a Newsfeed item. * * @static * @param Model_User $user * @param string $class e.g. 'user' * @param string $type e.g. 'login' * @param array $data Data to be user with item * @return boolean */ protected static function add(Model_User $user, $class, $type, array $data = null) { $item = new Model_NewsfeedItem(); // Update item if previous added less than time window specified time $update = DB::update($item->get_table_name())->set(array('stamp' => time()))->where('user_id', '=', $user->id)->and_where('class', '=', $class)->and_where('type', '=', $type)->and_where('stamp', '>', strtotime(Newsfeed::UPDATE_WINDOW)); $data ? $update->and_where('data', '=', @json_encode($data)) : $update->and_where('data', 'IS', null); // Update any? if ($update->execute()) { return true; } // No new enough item found, insert $item->set_fields(array('user_id' => $user->id, 'class' => $class, 'type' => $type, 'data' => $data, 'stamp' => time())); $item->save(); return $item->loaded(); }
/** * Aggregate repeating items, daily. * * @param Model_NewsfeedItem[] $items * @return Model_NewsfeedItem[] */ protected function aggregate($items = null) { $aggregated = array(); $aggregate_types = array(); foreach ($items as $item) { // Check if item type is aggregateable $class = 'Newsfeeditem_' . $item->class; if (!isset($aggregate_types[$class])) { $aggregate_types[$class] = class_exists($class) ? Arr::get(get_class_vars($class), 'aggregate', array()) : array(); } if (!in_array($item->type, $aggregate_types[$class])) { // Not aggregateable $aggregated[] = $item; continue; } // Generate key $key = $item->user_id . $item->class . $item->type . date('Ymd', $item->stamp); if (isset($aggregated[$key])) { // Aggregate to existing key /** @var Model_NewsfeedItem $aggregate */ $aggregate = clone $aggregated[$key]; // Make it aggregated pseudo item if necessary if (!$aggregate->is_aggregate()) { $_aggregate = new Model_NewsfeedItem(); $_aggregate->is_aggregate(true); $_aggregate->set_fields(array('user_id' => $aggregate->user_id, 'stamp' => $aggregate->stamp, 'class' => $aggregate->class, 'type' => $aggregate->type, 'data' => array(clone $aggregate))); $aggregate = $_aggregate; } // Add current item $data = $aggregate->data; $duplicate = false; foreach ($data as $_item) { if ($_item->data == $item->data) { $duplicate = true; break; } } if (!$duplicate) { $data[] = $item; $aggregate->data = $data; $aggregated[$key] = $aggregate; } } else { // New aggregateable key $aggregated[$key] = $item; } } return $aggregated; }