/** * Get an article(s). * * @param string $id Article id. * @param bool $idlib True if the Id library should be used (False for MongoIds) * @param bool $justOne True if only one entry should be returned. * @param bool $fixUTF8 True if UTF8 should be decoded. * * @return mixed The article/articles as an array, or an error string. */ protected function get($id, $idlib = true, $justOne = false, $fixUTF8 = true, $page = 1, $limit = self::PER_PAGE) { $query = array('published' => true, 'ghosted' => false); if ($idlib) { $keys = Id::dissectKeys($id, 'article'); $query['date'] = array('$gte' => $keys['date'], '$lte' => $keys['date'] + $keys['ambiguity']); } else { $query['_id'] = $this->_toMongoId($id); } $results = $this->db->find($query)->skip(($page - 1) * self::PER_PAGE)->sort(array('date' => -1)); $total = $results->count(); $valid = array(); if ($limit != null) { $results->limit($limit); } if ($idlib) { foreach ($results as $result) { if (!Id::validateHash($id, array('ambiguity' => $keys['ambiguity'], 'reportedDate' => $keys['date'], 'date' => $result['date'], 'title' => $result['title']), 'news')) { continue; } array_push($valid, $result); } } else { $valid = iterator_to_array($results); } if ($justOne) { $valid = array(reset($valid)); } if (empty($valid)) { return array('Invalid id.', 0); } $comments = new comments(ConnectionFactory::get('mongo')); foreach ($valid as $key => $entry) { $this->resolveUser($valid[$key]['user']); if ($fixUTF8) { $this->resolveUTF8($valid[$key]); } $valid[$key]['rating'] = $this->getScore($entry['_id']); $valid[$key]['comments'] = $comments->getCount($entry['_id']); } if ($justOne) { return reset($valid); } return array($valid, $total); }
/** * Gets a bug. * * @param string $id Bug id. * @param bool $idlib True if the Id library should be used (False for MongoIds) * @param bool $justOne True if only one entry should be returned. * @param bool $fixUTF8 True if UTF8 should be decoded. * * @return mixed The bug/bugs as an array, or an error string. */ protected function get($id, $idlib = true, $justOne = false, $fixUTF8 = true, $page = 1, $limit = self::PER_PAGE) { $query = array('ghosted' => false); if ($idlib) { $keys = Id::dissectKeys($id, 'bugs'); $query['created'] = (int) $keys['time']; } else { $query['_id'] = $this->_toMongoId($id); } $results = $this->db->find($query)->skip(($page - 1) * self::PER_PAGE); $total = $results->count(); $valid = array(); if ($limit != null) { $results->limit($limit); } if ($idlib) { foreach ($results as $result) { if (!Id::validateHash($id, array('_id' => $result['_id'], 'created' => $result['created']), 'bugs')) { continue; } array_push($valid, $result); } } else { $valid = iterator_to_array($results); } if ($justOne) { $valid = array(reset($valid)); } if (empty($valid) || $total == 0) { return array('Invalid id.', 0); } foreach ($valid as $key => $entry) { $this->resolveUser($valid[$key]['reporter']); if ($fixUTF8) { $this->resolveUTF8($valid[$key]); } } if ($justOne) { return reset($valid); } return array($valid, $total); }
/** * Id validation * * Used for validating a piece of content directly maps to a given id. * * @param string $hash Id to test against. * @param array $data Content to test with. * @param string $type Type of content/id being used. * * @return bool True if the given content directly maps to the given id. */ protected static function validateHash($hash, $data, $type) { switch ($type) { case 'news': $realHash = self::create($data, $type); return $realHash == $hash || $data['date'] >= $data['reportedDate'] && $data['date'] <= $data['reportedDate'] + $data['ambiguity']; break; case 'bugs': $hash = explode('-', $hash); $time = base_convert($hash[0], 36, 10); $last = base_convert($hash[1], 36, 10); return $time == $data['_id']->getTimestamp() && $last == $data['_id']->getInc(); break; case 'user': return $hash == $data['username']; break; case 'article': return Id::validateHash($hash, $data, 'news'); break; } return false; }