@@ -96,6 +96,7 @@ public function createRepository(string $owner, string $repositoryName, bool $pr
9696
9797 /**
9898 * Search repositories for GitHub App
99+ * @param string $installationId ID of the installation
99100 * @param string $owner Name of user or org
100101 * @param int $page page number
101102 * @param int $per_page number of results per page
@@ -104,24 +105,87 @@ public function createRepository(string $owner, string $repositoryName, bool $pr
104105 *
105106 * @throws Exception
106107 */
107- public function searchRepositories (string $ owner , int $ page , int $ per_page , string $ search = '' ): array
108+ public function searchRepositories (string $ installationId , string $ owner , int $ page , int $ per_page , string $ search = '' ): array
108109 {
109- $ url = '/search/repositories ' ;
110+ // Find whether installation has access to all (or) specific repositories
111+ $ url = '/app/installations/ ' . $ installationId ;
112+ $ response = $ this ->call (self ::METHOD_GET , $ url , ['Authorization ' => "Bearer $ this ->jwtToken " ]);
113+ $ hasAccessToAllRepositories = ($ response ['body ' ]['repository_selection ' ] ?? '' ) === 'all ' ;
114+
115+ // Installation has access to all repositories, use the search API which supports filtering.
116+ if ($ hasAccessToAllRepositories ) {
117+ $ url = '/search/repositories ' ;
118+
119+ $ response = $ this ->call (self ::METHOD_GET , $ url , ['Authorization ' => "Bearer $ this ->accessToken " ], [
120+ 'q ' => "{$ search } user: {$ owner } fork:true " ,
121+ 'page ' => $ page ,
122+ 'per_page ' => $ per_page ,
123+ 'sort ' => 'updated '
124+ ]);
125+
126+ if (!isset ($ response ['body ' ]['items ' ])) {
127+ throw new Exception ("Repositories list missing in the response. " );
128+ }
129+
130+ return [
131+ 'items ' => $ response ['body ' ]['items ' ],
132+ 'total ' => $ response ['body ' ]['total_count ' ],
133+ ];
134+ }
110135
111- $ response = $ this ->call (self ::METHOD_GET , $ url , ['Authorization ' => "Bearer $ this ->accessToken " ], [
112- 'q ' => "{$ search } user: {$ owner } fork:true " ,
113- 'page ' => $ page ,
114- 'per_page ' => $ per_page ,
115- 'sort ' => 'updated '
116- ]);
136+ // Installation has access to specific repositories, we need to perform client-side filtering.
137+ $ url = '/installation/repositories ' ;
138+ $ repositories = [];
117139
118- if (!isset ($ response ['body ' ]['items ' ])) {
119- throw new Exception ("Repositories list missing in the response. " );
140+ // When no search query is provided, delegate pagination to the GitHub API.
141+ if (empty ($ search )) {
142+ $ repositories = $ this ->call (self ::METHOD_GET , $ url , ['Authorization ' => "Bearer $ this ->accessToken " ], [
143+ 'page ' => $ page ,
144+ 'per_page ' => $ per_page ,
145+ ]);
146+
147+ if (!isset ($ repositories ['body ' ]['repositories ' ])) {
148+ throw new Exception ("Repositories list missing in the response. " );
149+ }
150+
151+ return [
152+ 'items ' => $ repositories ['body ' ]['repositories ' ],
153+ 'total ' => $ repositories ['body ' ]['total_count ' ],
154+ ];
120155 }
121156
157+ // When search query is provided, fetch all repositories accessible by the installation and filter them locally.
158+ $ currentPage = 1 ;
159+ while (true ) {
160+ $ response = $ this ->call (self ::METHOD_GET , $ url , ['Authorization ' => "Bearer $ this ->accessToken " ], [
161+ 'page ' => $ currentPage ,
162+ 'per_page ' => 100 , // Maximum allowed by GitHub API
163+ ]);
164+
165+ if (!isset ($ response ['body ' ]['repositories ' ])) {
166+ throw new Exception ("Repositories list missing in the response. " );
167+ }
168+
169+ // Filter repositories to only include those that match the search query.
170+ $ filteredRepositories = array_filter ($ response ['body ' ]['repositories ' ], fn ($ repo ) => stripos ($ repo ['name ' ], $ search ) !== false );
171+
172+ // Merge with result so far.
173+ $ repositories = array_merge ($ repositories , $ filteredRepositories );
174+
175+ // If less than 100 repositories are returned, we have fetched all repositories.
176+ if (\count ($ response ['body ' ]['repositories ' ]) < 100 ) {
177+ break ;
178+ }
179+
180+ // Increment page number to fetch next page.
181+ $ currentPage ++;
182+ }
183+
184+ $ repositoriesInRequestedPage = \array_slice ($ repositories , ($ page - 1 ) * $ per_page , $ per_page );
185+
122186 return [
123- 'items ' => $ response [ ' body ' ][ ' items ' ] ,
124- 'total ' => $ response [ ' body ' ][ ' total_count ' ] ,
187+ 'items ' => $ repositoriesInRequestedPage ,
188+ 'total ' => \count ( $ repositories ) ,
125189 ];
126190 }
127191
0 commit comments