/** * Single drop restful api */ public function action_index() { $this->template = ""; if (!$this->admin) { throw new HTTP_Exception_403(); } switch ($this->request->method()) { case "POST": // Get the POST data $drops = json_decode($this->request->body(), TRUE); Kohana::$log->add(Log::DEBUG, ":count Drops received", array(':count' => count($drops))); Model_Droplet::create_from_array($drops); break; } }
/** * @covers Model_Droplet::get_unprocessed_droplets */ public function test_get_unprocessed_droplets() { // Get the unprocessed items $unprocessed = Model_Droplet::get_unprocessed_droplets(); // Verify that $unprocessed is an array $this->assertTrue(is_array($unprocessed)); // Verify that the items are ordered in ascending order if (count($unprocessed) > 1) { $_first = $unprocessed[0]->droplet_pub_date; $_last = end($unprocessed)->droplet_pub_date; // Compare the first and last items // The pub date of the first item should be earlier than that of the last item $this->assertLessThan(strtotime($_last), strtotime($_first), 'The droplets are not in descending order'); } // Garbage collection unset($unprocessed); }
/** * Create a single new drop and publish new ones for meta extraction. * * @return array */ public static function create_drop($drop) { list($drops, $new_drops) = Model_Droplet::create_from_array(array($drop)); if (!empty($new_drops)) { Swiftriver_Event::run('swiftriver.droplet.extract_metadata', $new_drops[0]); Model_Droplet::create_from_array(array($new_drops[0])); } return $drops[0]; }
/** * Gets droplets whose database id is above the specified minimum * * @param int $user_id Logged in user id * @param int $river_id Database ID of the river * @param int $since_id Lower limit of the droplet id * @return array */ public static function get_droplets_since_id($user_id, $river_id, $since_id, $filters = array(), $photos = FALSE) { // Check the cache $request_hash = hash('sha256', $user_id . $river_id . $since_id . var_export($filters, TRUE) . ($photos ? 1 : 0)); $cache_key = 'river_drops_since_' . $request_hash; // If the cache key is available (with default value set to FALSE) if ($droplets = Cache::instance()->get($cache_key, FALSE)) { return $droplets; } $droplets = array('total' => 0, 'droplets' => array()); $river_orm = ORM::factory('river', $river_id); if ($river_orm->loaded()) { $query = DB::select(array('droplets.id', 'id'), array('rivers_droplets.id', 'sort_id'), 'droplet_title', 'droplet_content', 'droplets.channel', 'identity_name', 'identity_avatar', array(DB::expr('DATE_FORMAT(droplets.droplet_date_pub, "%b %e, %Y %H:%i UTC")'), 'droplet_date_pub'), array('user_scores.score', 'user_score'), array('links.url', 'original_url'), 'comment_count')->from('droplets')->join('rivers_droplets', 'INNER')->on('rivers_droplets.droplet_id', '=', 'droplets.id')->join('identities', 'INNER')->on('droplets.identity_id', '=', 'identities.id')->where('droplets.processing_status', '=', Model_Droplet::PROCESSING_STATUS_COMPLETE)->where('rivers_droplets.river_id', '=', $river_id)->where('rivers_droplets.id', '>', $since_id); if ($photos) { $query->where('droplets.droplet_image', '>', 0); } // Apply the river filters Model_Droplet::apply_droplets_filter($query, $filters, $user_id, $river_orm); // Left join for user scores $query->join(array('droplet_scores', 'user_scores'), 'LEFT')->on('user_scores.droplet_id', '=', DB::expr('droplets.id AND user_scores.user_id = ' . $user_id))->join('links', 'LEFT')->on('links.id', '=', 'droplets.original_url'); // Group, order and limit $query->order_by('rivers_droplets.id', 'ASC')->limit(self::DROPLETS_PER_PAGE)->offset(0); $droplets['droplets'] = $query->execute()->as_array(); // Encode content and title as utf8 in case they arent foreach ($droplets['droplets'] as &$droplet) { Model_Droplet::utf8_encode($droplet); } // Populate the metadata Model_Droplet::populate_metadata($droplets['droplets'], $river_orm->account_id); } // Cache the drops if (!empty($droplets['droplets'])) { Cache::instance()->set($cache_key, $droplets); } return $droplets; }
/** * Retrieves the list of droplets that matche the specified filters * * @param array $filters Set of filters to apply to the droplets list * @param int $user_id ID of the user initiating the search * @param int $page Page number - for calculating the offset of the resultset * @param bool $photos - When TRUE, filter out only those droplets with photos */ public static function search($filters, $user_id, $page = 1, $photos = FALSE) { $user_orm = ORM::factory('user', $user_id); $droplets = array(); if ($user_orm->loaded()) { // Sanity check for the page number $page = empty($page) ? 1 : $page; // Build Buckets Query $query = DB::select(array('droplets.id', 'id'), array(DB::expr('UNIX_TIMESTAMP(droplets.droplet_date_add)'), 'sort_id'), 'droplet_title', 'droplet_content', 'droplets.channel', 'identity_name', 'identity_avatar', array(DB::expr('DATE_FORMAT(droplet_date_pub, "%b %e, %Y %H:%i UTC")'), 'droplet_date_pub'), array(DB::expr('SUM(all_scores.score)'), 'scores'), array('user_scores.score', 'user_score'))->from('droplets')->join('identities')->on('droplets.identity_id', '=', 'identities.id')->join(array('droplet_scores', 'all_scores'), 'LEFT')->on('all_scores.droplet_id', '=', 'droplets.id')->join(array('droplet_scores', 'user_scores'), 'LEFT')->on('user_scores.droplet_id', '=', DB::expr('droplets.id AND user_scores.user_id = ' . $user_id))->where('droplets.processing_status', '=', Model_Droplet::PROCESSING_STATUS_COMPLETE)->where('droplets.parent_id', '=', 0); self::apply_droplets_filter($query, $filters, $user_id); if ($photos) { $query->where('droplets.droplet_image', '>', 0); } $query->group_by('droplets.id')->order_by('droplets.droplet_date_add', 'DESC')->limit(20)->offset(20 * ($page - 1)); $droplets = $query->execute()->as_array(); Model_Droplet::populate_metadata($droplets, $user_orm->account->id); } return $droplets; }
/** * Replies restful api */ public function action_reply() { $this->template = ""; $this->auto_render = FALSE; $droplet_id = intval($this->request->param('id', 0)); switch ($this->request->method()) { case "GET": $params = $this->request->query(); if (isset($params['since_id'])) { $since_id = intval($this->request->query('since_id')); $comments = Model_Droplet::get_comments($droplet_id, $since_id, TRUE); } else { $last_id = $this->request->query('last_id') ? intval($this->request->query('last_id')) : PHP_INT_MAX; $comments = Model_Droplet::get_comments($droplet_id, $last_id); if (empty($comments)) { throw new HTTP_Exception_404('The requested page was not found on this server.'); } } echo json_encode($comments); break; case "POST": // Is the logged in user an owner? if (!$this->owner) { throw new HTTP_Exception_403(); } // Get the POST data $body = json_decode($this->request->body(), TRUE); $comment = ORM::factory('droplet_comment'); $comment->comment_text = $body['comment_text']; $comment->droplet_id = intval($this->request->param('id', 0)); $comment->user_id = $this->user->id; $comment->save(); if ($comment->loaded()) { echo json_encode(array('id' => $comment->id, 'droplet_id' => $comment->droplet_id, 'comment_text' => $comment->comment_text, 'identity_user_id' => $this->user->id, 'identity_name' => $this->user->name, 'identity_avatar' => Swiftriver_Users::gravatar($this->user->email, 80), 'deleted' => FALSE, 'date_added' => date_format(date_create($comment->date_added), 'M d, Y H:i') . ' UTC')); } else { $this->response->status(400); } break; case "PUT": $comment_id = intval($this->request->param('id2', 0)); $comment = ORM::factory('droplet_comment', $comment_id); // Does the comment exist? if (!$comment->loaded()) { throw new HTTP_Exception_404(); } // Is owner of the comment logged in? if ($comment->user->id != $this->user->id) { throw new HTTP_Exception_403(); } $comment->deleted = TRUE; $comment->save(); break; } }
/** * Internal helper that performs the search and returns the results * to the invoking controller action * * @param array $parameters An array of search parameters * @return array */ private function _handle_drops_search($parameters) { // Get the page number for the request $page = (isset($parameters['page']) and intval($parameters['page']) > 0) ? intval($parameters['page']) : 1; // Array to store each of the search results items $results = array('droplets' => array(), 'page' => $page); $user_id = $this->user->id; // Query filters for the droplet fetch $query_filters = array('places' => array($this->search_term), 'tags' => array($this->search_term)); // Check the search scope switch ($this->search_scope) { // Global search case 'all': // Get the droplets $results['droplets'] = Model_Droplet::search($query_filters, $user_id, $page, $this->photos); break; // River search // River search case 'river': // Get the river id $river_id = Cookie::get('search_item_id'); $data = Model_River::get_droplets($user_id, $river_id, 0, $page, PHP_INT_MAX, 'DESC', $query_filters, $this->photos); $results['droplets'] = $data['droplets']; break; // Bucket search // Bucket search case 'bucket': // Get the bucket id $bucket_id = Cookie::get('search_item_id'); // Get the droplets $data = Model_Bucket::get_droplets($user_id, $bucket_id, 0, $page, PHP_INT_MAX, $this->photos, $query_filters); $results['droplets'] = $data['droplets']; break; } // Return return $results; }