public static function multiResponse($options, $overrideFormat = false) { $format = $overrideFormat ? $overrideFormat : $options['requestParams']['format']; if (empty($options['results'])) { $options['results'] = ['results' => [], 'total' => 0]; } if ($options['results'] && isset($options['results']['results'])) { $totalResults = $options['results']['total']; $options['results'] = $options['results']['results']; if ($options['requestParams']['v'] >= 3) { header("Total-Results: {$totalResults}"); } } switch ($format) { case 'atom': case 'csljson': case 'json': case 'keys': case 'versions': $link = Zotero_API::buildLinkHeader($options['action'], $options['uri'], $totalResults, $options['requestParams']); if ($link) { header($link); } break; } if (!empty($options['head'])) { return; } switch ($format) { case 'atom': $t = microtime(true); $response = Zotero_Atom::createAtomFeed($options['action'], $options['title'], $options['uri'], $options['results'], $totalResults, $options['requestParams'], $options['permissions'], isset($options['fixedValues']) ? $options['fixedValues'] : null); StatsD::timing("api." . $options['action'] . ".multiple.createAtomFeed." . implode("-", $options['requestParams']['content']), (microtime(true) - $t) * 1000); return $response; case 'csljson': $json = Zotero_Cite::getJSONFromItems($options['results'], true); echo Zotero_Utilities::formatJSON($json); break; case 'json': echo Zotero_API::createJSONResponse($options['results'], $options['requestParams'], $options['permissions']); break; case 'keys': echo implode("\n", $options['results']) . "\n"; break; case 'versions': if (!empty($options['results'])) { echo Zotero_Utilities::formatJSON($options['results']); } else { echo Zotero_Utilities::formatJSON(new stdClass()); } break; case 'writereport': echo Zotero_Utilities::formatJSON($options['results']); break; default: throw new Exception("Unexpected format '" . $options['requestParams']['format'] . "'"); } }
public function groupUsers() { if (($this->method == 'POST' || $this->method == 'PUT') && !$this->body) { $this->e400("{$this->method} data not provided"); } // For now, only allow root and user access if (!$this->permissions->isSuper()) { $this->e403(); } $groupID = $this->scopeObjectID; $userID = $this->objectID; $group = Zotero_Groups::get($groupID); if (!$group) { $this->e404("Group {$groupID} does not exist"); } // Add multiple users to group if ($this->method == 'POST') { if ($userID) { $this->e400("POST requests cannot end with a userID (did you mean PUT?)"); } // Body can contain multiple <user> blocks, so stuff in root element try { $xml = @new SimpleXMLElement("<root>" . $this->body . "</root>"); } catch (Exception $e) { $this->e400("{$this->method} data is not valid XML"); } $addedUserIDs = array(); Zotero_DB::beginTransaction(); foreach ($xml->user as $user) { $id = (int) $user['id']; $role = (string) $user['role']; if (!$id) { $this->e400("User ID not provided in '" . $user->asXML() . "'"); } if (!$role) { $this->e400("Role not provided in '" . $user->asXML() . "'"); } try { $added = $group->addUser($id, $role); } catch (Exception $e) { if (strpos($e->getMessage(), "Invalid role") === 0) { $this->e400("Invalid role '{$role}' in " . $user->asXML() . "'"); } $this->e500($e->getMessage()); } if ($added) { $addedUserIDs[] = $id; } } // Response after adding $entries = array(); foreach ($addedUserIDs as $addedUserID) { $entries[] = $group->memberToAtom($addedUserID); } $title = "Users added to group '{$group->name}'"; $this->responseXML = Zotero_Atom::createAtomFeed($title, $this->uri, $entries, null, $this->queryParams, $this->apiVersion, $this->permissions); Zotero_DB::commit(); $this->end(); } // Add a single user to group if ($this->method == 'PUT') { if (!$userID) { $this->e400("PUT requests must end with a userID (did you mean POST?)"); } try { $user = @new SimpleXMLElement($this->body); } catch (Exception $e) { $this->e400("{$this->method} data is not valid XML"); } $id = (int) $user['id']; $role = (string) $user['role']; // User id is optional, but, if it's there, make sure it matches if ($id && $id != $userID) { $this->e400("User ID {$id} does not match user ID {$userID} from URI"); } if (!$role) { $this->e400("Role not provided in '{$this->body}'"); } Zotero_DB::beginTransaction(); $changedUserIDs = array(); try { if ($role == 'owner') { if ($userID != $group->ownerUserID) { $changedUserIDs[] = $group->ownerUserID; $group->ownerUserID = $userID; $group->save(); $changedUserIDs[] = $userID; } } else { if ($group->hasUser($userID)) { try { $updated = $group->updateUser($userID, $role); } catch (Exception $e) { switch ($e->getCode()) { case Z_ERROR_CANNOT_DELETE_GROUP_OWNER: $this->e400($e->getMessage()); default: $this->e500($e->getMessage()); } } if ($updated) { $changedUsersIDs[] = $userID; } } else { $added = $group->addUser($userID, $role); if ($added) { $changedUserIDs[] = $userID; } } } } catch (Exception $e) { if (strpos($e->getMessage(), "Invalid role") === 0) { $this->e400("Invalid role '{$role}' in '{$this->body}'"); } $this->e500($e->getMessage()); } // Response after adding $entries = array(); foreach ($changedUserIDs as $changedUserID) { $entries[] = $group->memberToAtom($changedUserID); } $title = "Users changed in group '{$group->name}'"; $this->responseXML = Zotero_Atom::createAtomFeed($title, $this->uri, $entries, null, $this->queryParams, $this->apiVersion, $this->permissions); Zotero_DB::commit(); $this->end(); } if ($this->method == 'DELETE') { if (!$userID) { $this->e400("DELETE requests must end with a userID"); } Zotero_DB::beginTransaction(); try { $group->removeUser($userID); } catch (Exception $e) { switch ($e->getCode()) { case Z_ERROR_CANNOT_DELETE_GROUP_OWNER: $this->e400($e->getMessage()); case Z_ERROR_USER_NOT_GROUP_MEMBER: $this->e404($e->getMessage()); default: $this->e500($e->getMessage()); } } Zotero_DB::commit(); header("HTTP/1.1 204 No Content"); exit; } // Single user if ($userID) { $this->responseXML = $group->memberToAtom($userID); $this->end(); } // Multiple users $title = "Members of '{$group->name}'"; $entries = array(); $memberIDs = array_merge(array($group->ownerUserID), $group->getAdmins(), $group->getMembers()); foreach ($memberIDs as $userID) { $entries[] = $group->memberToAtom($userID); } $totalResults = sizeOf($entries); $this->responseXML = Zotero_Atom::createAtomFeed($title, $this->uri, $entries, $totalResults, $this->queryParams, $this->apiVersion, $this->permissions); $this->end(); }