Skip to content

Commit

Permalink
Merge branch 'MDL-70048-master' of git://github.com/peterRd/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewnicols committed Jan 28, 2021
2 parents 34dec1d + 663c84a commit bf69831
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 17 deletions.
57 changes: 45 additions & 12 deletions repository/dropbox/classes/dropbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
*/
class dropbox extends \oauth2_client {

/**
* @var array Custom continue endpoints that differ from the standard.
*/
private $mappedcontinueoverides = [
'files/search_v2' => 'files/search/continue_v2'
];

/**
* Create the DropBox API Client.
*
Expand Down Expand Up @@ -87,14 +94,37 @@ protected function get_content_endpoint($endpoint) {
return new \moodle_url('https://api-content.dropbox.com/2/' . $endpoint);
}

/**
* Get the continue endpoint for the provided endpoint.
*
* @param string $endpoint The original endpoint
* @return string $endpoint The generated/mapped continue link
*/
protected function get_endpoint_for_continue(string $endpoint) {
// Any API endpoint returning 'has_more' will provide a cursor, and also have a matching endpoint suffixed
// with /continue which takes that cursor.
if (preg_match('_/continue$_', $endpoint) === 0) {
// First check if the API call uses a custom mapped continue endpoint.
if (isset($this->mappedcontinueoverides[$endpoint])) {
$endpoint = $this->mappedcontinueoverides[$endpoint];
} else {
// Only add /continue if it is not already present.
$endpoint .= '/continue';
}
}

return $endpoint;
}

/**
* Make an API call against the specified endpoint with supplied data.
*
* @param string $endpoint The endpoint to be contacted
* @param array $data Any data to pass to the endpoint
* @param string $resultnode The name of the node that contains the data
* @return object Content decoded from the endpoint
*/
protected function fetch_dropbox_data($endpoint, $data = []) {
protected function fetch_dropbox_data($endpoint, $data = [], string $resultnode = 'entries') {
$url = $this->get_api_endpoint($endpoint);
$this->cleanopt();
$this->resetHeader();
Expand All @@ -114,20 +144,15 @@ protected function fetch_dropbox_data($endpoint, $data = []) {
$this->check_and_handle_api_errors($result);

if ($this->has_additional_results($result)) {
// Any API endpoint returning 'has_more' will provide a cursor, and also have a matching endpoint suffixed
// with /continue which takes that cursor.
if (preg_match('_/continue$_', $endpoint) === 0) {
// Only add /continue if it is not already present.
$endpoint .= '/continue';
}
$endpoint = $this->get_endpoint_for_continue($endpoint);

// Fetch the next page of results.
$additionaldata = $this->fetch_dropbox_data($endpoint, [
'cursor' => $result->cursor,
]);
], $resultnode);

// Merge the list of entries.
$result->entries = array_merge($result->entries, $additionaldata->entries);
$result->$resultnode = array_merge($result->$resultnode, $additionaldata->$resultnode);
}

if (isset($result->has_more)) {
Expand Down Expand Up @@ -240,10 +265,18 @@ public function get_listing($path = '') {
* @return object The returned directory listing, or null on failure
*/
public function search($query = '') {
$data = $this->fetch_dropbox_data('files/search', [
'path' => '',
// There is nothing to be searched. Return an empty array to mimic the response from Dropbox.
if (!$query) {
return [];
}

$data = $this->fetch_dropbox_data('files/search_v2', [
'options' => [
'path' => '',
'filename_only' => true,
],
'query' => $query,
]);
], 'matches');

return $data;
}
Expand Down
6 changes: 6 additions & 0 deletions repository/dropbox/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,12 @@ protected function process_entries(array $entries) {
// We only use the consistent parts of the file, folder, and metadata.
$entrydata = $entrydata->metadata;
}

// Due to a change in the api, the actual content is in a nested metadata tree.
if ($entrydata->{".tag"} == "metadata" && isset($entrydata->metadata)) {
$entrydata = $entrydata->metadata;
}

if ($entrydata->{".tag"} === "folder") {
$dirslist[] = [
'title' => $entrydata->name,
Expand Down
10 changes: 5 additions & 5 deletions repository/dropbox/tests/api_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,9 @@ public function test_fetch_dropbox_data_recurse_on_additional_records() {
$mock->expects($this->exactly(3))
->method('request')
->will($this->onConsecutiveCalls(
json_encode(['has_more' => true, 'cursor' => 'Example', 'entries' => ['foo', 'bar']]),
json_encode(['has_more' => true, 'cursor' => 'Example', 'entries' => ['baz']]),
json_encode(['has_more' => false, 'cursor' => '', 'entries' => ['bum']])
json_encode(['has_more' => true, 'cursor' => 'Example', 'matches' => ['foo', 'bar']]),
json_encode(['has_more' => true, 'cursor' => 'Example', 'matches' => ['baz']]),
json_encode(['has_more' => false, 'cursor' => '', 'matches' => ['bum']])
));

// We automatically adjust for the /continue endpoint.
Expand All @@ -437,14 +437,14 @@ public function test_fetch_dropbox_data_recurse_on_additional_records() {
$rc = new \ReflectionClass(\repository_dropbox\dropbox::class);
$rcm = $rc->getMethod('fetch_dropbox_data');
$rcm->setAccessible(true);
$result = $rcm->invoke($mock, $endpoint, null);
$result = $rcm->invoke($mock, $endpoint, null, 'matches');

$this->assertEquals([
'foo',
'bar',
'baz',
'bum',
], $result->entries);
], $result->matches);

$this->assertFalse(isset($result->cursor));
$this->assertFalse(isset($result->has_more));
Expand Down

0 comments on commit bf69831

Please sign in to comment.