Skip to content

Commit 324000b

Browse files
authored
Merge pull request #213 from fbourigault/v4-api-8962-8877-9674
Projects collection consolidation
2 parents b80d826 + 07ec099 commit 324000b

File tree

5 files changed

+114
-90
lines changed

5 files changed

+114
-90
lines changed

UPGRADE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ See [documentation](doc/customize.md) to know how to customize the client timeou
2727

2828
* The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed.
2929
Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDeployKey` and `enableDeployKey` instead.
30+
* The `ORDER_BY` and `SORT` class constants have been removed.
31+
* The `accessible`, `owned` and `search` methods have been removed. Use `all` method instead.
32+
* The `all` method now take a single argument which is an associative array of query string parameters.
3033

3134
## `Gitlab\Api\Repositories` changes
3235

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"php-http/client-implementation": "^1.0",
2727
"php-http/discovery": "^1.2",
2828
"php-http/httplug": "^1.1",
29-
"php-http/multipart-stream-builder": "^1.0"
29+
"php-http/multipart-stream-builder": "^1.0",
30+
"symfony/options-resolver": "^2.6 || ^3.0"
3031
},
3132
"require-dev": {
3233
"guzzlehttp/psr7": "^1.2",

lib/Gitlab/Api/AbstractApi.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Http\Message\MultipartStream\MultipartStreamBuilder;
77
use Http\Message\StreamFactory;
88
use Psr\Http\Message\ResponseInterface;
9+
use Symfony\Component\OptionsResolver\OptionsResolver;
910

1011
/**
1112
* Abstract class for Api classes
@@ -190,6 +191,29 @@ protected function encodePath($path)
190191
return str_replace('.', '%2E', $path);
191192
}
192193

194+
/**
195+
* Create a new OptionsResolver with page, per_page and sort options.
196+
*
197+
* @return OptionsResolver
198+
*/
199+
protected function createOptionsResolver()
200+
{
201+
$resolver = new OptionsResolver();
202+
$resolver->setDefined('page')
203+
->setAllowedTypes('page', 'int')
204+
->setAllowedValues('page', function ($value) { return $value > 0; })
205+
;
206+
$resolver->setDefined('per_page')
207+
->setAllowedTypes('per_page', 'int')
208+
->setAllowedValues('per_page', function ($value) { return $value > 0 && $value <= 100; })
209+
;
210+
$resolver->setDefined('sort')
211+
->setAllowedValues('sort', ['asc', 'desc'])
212+
;
213+
214+
return $resolver;
215+
}
216+
193217
private function preparePath($path, array $parameters = [])
194218
{
195219
if (count($parameters) > 0) {

lib/Gitlab/Api/Projects.php

Lines changed: 73 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,81 @@
11
<?php namespace Gitlab\Api;
22

3+
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
4+
use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
5+
36
class Projects extends AbstractApi
47
{
5-
const ORDER_BY = 'created_at';
6-
const SORT = 'asc';
7-
8-
/**
9-
* @param int $page
10-
* @param int $per_page
11-
* @param string $order_by
12-
* @param string $sort
13-
* @return mixed
14-
*/
15-
public function all($page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT)
16-
{
17-
return $this->get('projects/all', array(
18-
'page' => $page,
19-
'per_page' => $per_page,
20-
'order_by' => $order_by,
21-
'sort' => $sort
22-
));
23-
}
24-
258
/**
26-
* @param int $page
27-
* @param int $per_page
28-
* @param string $order_by
29-
* @param string $sort
30-
* @return mixed
31-
*/
32-
public function accessible($page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT)
33-
{
34-
return $this->get('projects', array(
35-
'page' => $page,
36-
'per_page' => $per_page,
37-
'order_by' => $order_by,
38-
'sort' => $sort
39-
));
40-
}
41-
42-
/**
43-
* Get projects owned by the current user
44-
* @param int $page
45-
* @param int $per_page
46-
* @param string $order_by
47-
* @param string $sort
48-
* @return mixed
49-
*/
50-
public function owned($page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT)
51-
{
52-
return $this->get('projects?owned=1', array(
53-
'page' => $page,
54-
'per_page' => $per_page,
55-
'order_by' => $order_by,
56-
'sort' => $sort
57-
));
58-
}
59-
60-
/**
61-
* @param string $query
62-
* @param int $page
63-
* @param int $per_page
64-
* @param string $order_by
65-
* @param string $sort
66-
* @return mixed
67-
*/
68-
public function search($query, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT)
69-
{
70-
return $this->get('projects/search/'.$this->encodePath($query), array(
71-
'page' => $page,
72-
'per_page' => $per_page,
73-
'order_by' => $order_by,
74-
'sort' => $sort
75-
));
9+
* @param array $parameters {
10+
*
11+
* @var bool $archived Limit by archived status.
12+
* @var string $visibility Limit by visibility public, internal, or private.
13+
* @var string $order_by Return projects ordered by id, name, path, created_at, updated_at,
14+
* or last_activity_at fields. Default is created_at.
15+
* @var string $sort Return projects sorted in asc or desc order. Default is desc.
16+
* @var string $search Return list of projects matching the search criteria.
17+
* @var bool $simple Return only the ID, URL, name, and path of each project.
18+
* @var bool $owned Limit by projects owned by the current user.
19+
* @var bool $membership Limit by projects that the current user is a member of.
20+
* @var bool $starred Limit by projects starred by the current user.
21+
* @var bool $statistics Include project statistics.
22+
* @var bool $with_issues_enabled Limit by enabled issues feature.
23+
* @var bool $with_merge_requests_enabled Limit by enabled merge requests feature.
24+
* }
25+
*
26+
* @throws UndefinedOptionsException If an option name is undefined
27+
* @throws InvalidOptionsException If an option doesn't fulfill the
28+
* specified validation rules
29+
*
30+
* @return mixed
31+
*/
32+
public function all(array $parameters = [])
33+
{
34+
$resolver = $this->createOptionsResolver();
35+
$booleanNormalizer = function ($value) {
36+
return $value ? 'true' : 'false';
37+
};
38+
$resolver->setDefined('archived')
39+
->setAllowedTypes('archived', 'bool')
40+
->setNormalizer('archived', $booleanNormalizer)
41+
;
42+
$resolver->setDefined('visibility')
43+
->setAllowedValues('visibility', ['public', 'internal', 'private'])
44+
;
45+
$resolver->setDefined('order_by')
46+
->setAllowedValues('order_by', ['id', 'name', 'path', 'created_at', 'updated_at', 'last_activity_at'])
47+
;
48+
$resolver->setDefined('search');
49+
$resolver->setDefined('simple')
50+
->setAllowedTypes('simple', 'bool')
51+
->setNormalizer('simple', $booleanNormalizer)
52+
;
53+
$resolver->setDefined('owned')
54+
->setAllowedTypes('owned', 'bool')
55+
->setNormalizer('owned', $booleanNormalizer)
56+
;
57+
$resolver->setDefined('membership')
58+
->setAllowedTypes('membership', 'bool')
59+
->setNormalizer('membership', $booleanNormalizer)
60+
;
61+
$resolver->setDefined('starred')
62+
->setAllowedTypes('starred', 'bool')
63+
->setNormalizer('starred', $booleanNormalizer)
64+
;
65+
$resolver->setDefined('statistics')
66+
->setAllowedTypes('statistics', 'bool')
67+
->setNormalizer('statistics', $booleanNormalizer)
68+
;
69+
$resolver->setDefined('with_issues_enabled')
70+
->setAllowedTypes('with_issues_enabled', 'bool')
71+
->setNormalizer('with_issues_enabled', $booleanNormalizer)
72+
;
73+
$resolver->setDefined('with_merge_requests_enabled')
74+
->setAllowedTypes('with_merge_requests_enabled', 'bool')
75+
->setNormalizer('with_merge_requests_enabled', $booleanNormalizer)
76+
;
77+
78+
return $this->get('projects', $resolver->resolve($parameters));
7679
}
7780

7881
/**

test/Gitlab/Tests/Api/ProjectsTest.php

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function shouldGetAllProjects()
1212
{
1313
$expectedArray = $this->getMultipleProjectsData();
1414

15-
$api = $this->getMultipleProjectsRequestMock('projects/all', $expectedArray);
15+
$api = $this->getMultipleProjectsRequestMock('projects', $expectedArray);
1616

1717
$this->assertEquals($expectedArray, $api->all());
1818
}
@@ -24,9 +24,9 @@ public function shouldGetAllProjectsSortedByName()
2424
{
2525
$expectedArray = $this->getMultipleProjectsData();
2626

27-
$api = $this->getMultipleProjectsRequestMock('projects/all', $expectedArray, 1, 5, 'name', 'asc');
27+
$api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, ['page' => 1, 'per_page' => 5, 'order_by' => 'name', 'sort' => 'asc']);
2828

29-
$this->assertEquals($expectedArray, $api->all(1, 5, 'name'));
29+
$this->assertEquals($expectedArray, $api->all(['page' => 1, 'per_page' => 5, 'order_by' => 'name', 'sort' => 'asc']));
3030
}
3131

3232
/**
@@ -39,7 +39,7 @@ public function shouldNotNeedPaginationWhenGettingProjects()
3939
$api = $this->getApiMock();
4040
$api->expects($this->once())
4141
->method('get')
42-
->with('projects/all', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE, 'order_by' => Projects::ORDER_BY, 'sort' => Projects::SORT))
42+
->with('projects')
4343
->will($this->returnValue($expectedArray))
4444
;
4545

@@ -53,9 +53,9 @@ public function shouldGetAccessibleProjects()
5353
{
5454
$expectedArray = $this->getMultipleProjectsData();
5555

56-
$api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, 2, 7);
56+
$api = $this->getMultipleProjectsRequestMock('projects', $expectedArray);
5757

58-
$this->assertEquals($expectedArray, $api->accessible(2, 7));
58+
$this->assertEquals($expectedArray, $api->all());
5959
}
6060

6161
/**
@@ -65,27 +65,20 @@ public function shouldGetOwnedProjects()
6565
{
6666
$expectedArray = $this->getMultipleProjectsData();
6767

68-
$api = $this->getMultipleProjectsRequestMock('projects?owned=1', $expectedArray, 3, 50);
68+
$api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, ['owned' => 'true']);
6969

70-
$this->assertEquals($expectedArray, $api->owned(3, 50));
70+
$this->assertEquals($expectedArray, $api->all(['owned' => true]));
7171
}
7272

73-
7473
/**
7574
* @test
7675
*/
7776
public function shouldSearchProjects()
7877
{
7978
$expectedArray = $this->getMultipleProjectsData();
8079

81-
$api = $this->getMultipleProjectsRequestMock('projects/search/a%20project', $expectedArray);
82-
$this->assertEquals($expectedArray, $api->search('a project'));
83-
84-
$api = $this->getMultipleProjectsRequestMock('projects/search/a%2Eproject', $expectedArray);
85-
$this->assertEquals($expectedArray, $api->search('a.project'));
86-
87-
$api = $this->getMultipleProjectsRequestMock('projects/search/a%2Fproject', $expectedArray);
88-
$this->assertEquals($expectedArray, $api->search('a/project'));
80+
$api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, ['search' => 'a project']);
81+
$this->assertEquals($expectedArray, $api->all(['search' => 'a project']));
8982
}
9083

9184
/**
@@ -1008,12 +1001,12 @@ public function shouldRemoveVariable()
10081001
$this->assertEquals($expectedBool, $api->removeVariable(1, 'ftp_password'));
10091002
}
10101003

1011-
protected function getMultipleProjectsRequestMock($path, $expectedArray = array(), $page = 1, $per_page = 20, $order_by = 'created_at', $sort = 'asc')
1004+
protected function getMultipleProjectsRequestMock($path, $expectedArray = array(), $expectedParameters = array())
10121005
{
10131006
$api = $this->getApiMock();
10141007
$api->expects($this->once())
10151008
->method('get')
1016-
->with($path, array('page' => $page, 'per_page' => $per_page, 'order_by' => $order_by, 'sort' => $sort))
1009+
->with($path, $expectedParameters)
10171010
->will($this->returnValue($expectedArray))
10181011
;
10191012

0 commit comments

Comments
 (0)