소스 검색

Rework the funding info parsing to avoid requiring graphql permissions

Jordi Boggiano 5 년 전
부모
커밋
c4f19e51d8
1개의 변경된 파일67개의 추가작업 그리고 18개의 파일을 삭제
  1. 67 18
      src/Composer/Repository/Vcs/GitHubDriver.php

+ 67 - 18
src/Composer/Repository/Vcs/GitHubDriver.php

@@ -167,7 +167,6 @@ class GitHubDriver extends VcsDriver
                 if (!isset($composer['abandoned']) && $this->isArchived) {
                     $composer['abandoned'] = true;
                 }
-
                 if (!isset($composer['funding']) && $funding = $this->getFundingInfo()) {
                     $composer['funding'] = $funding;
                 }
@@ -193,28 +192,78 @@ class GitHubDriver extends VcsDriver
             return $this->fundingInfo = false;
         }
 
-        $graphql = 'query{repository(owner:"'.$this->owner.'",name:"'.$this->repository.'"){fundingLinks{platform,url}}}';
-        try {
-            $result = $this->remoteFilesystem->getContents($this->originUrl, 'https://api.github.com/graphql', false, array(
-                'http' => array(
-                    'method' => 'POST',
-                    'content' => json_encode(array('query' => $graphql)),
-                    'header' => array('Content-Type: application/json'),
-                ),
-                'retry-auth-failure' => false,
-            ));
-        } catch (TransportException $e) {
+        foreach (array($this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/.github/FUNDING.yml', $this->getApiUrl() . '/repos/'.$this->owner.'/.github/contents/FUNDING.yml') as $file) {
+
+            try {
+                $result = $this->remoteFilesystem->getContents($this->originUrl, $file, false, array(
+                    'retry-auth-failure' => false,
+                ));
+                $response = json_decode($result, true);
+            } catch (TransportException $e) {
+                continue;
+            }
+            if (empty($response['content']) || $response['encoding'] !== 'base64' || !($funding = base64_decode($response['content']))) {
+                continue;
+            }
+        }
+        if (empty($funding)) {
             return $this->fundingInfo = false;
         }
-        $result = json_decode($result, true);
 
-        if (empty($result['data']['repository']['fundingLinks'])) {
-            return $this->fundingInfo = false;
+        $result = array();
+        $key = null;
+        foreach (preg_split('{\r?\n}', $funding) as $line) {
+            $line = preg_replace('{#.*}', '', $line);
+            $line = trim($line);
+            if (preg_match('{^(\w+)\s*:\s*(.+)$}', $line, $match)) {
+                if (preg_match('{^\[.*\]$}', $match[2])) {
+                    foreach (array_map('trim', preg_split('{[\'"]?\s*,\s*[\'"]?}', substr($match[2], 1, -1))) as $item) {
+                        $result[] = array('type' => $match[1], 'url' => trim($item, '"\''));
+                    }
+                } else {
+                    $result[] = array('type' => $match[1], 'url' => $match[2]);
+                }
+                $key = null;
+            } elseif (preg_match('{^(\w+)\s*:$}', $line, $match)) {
+                $key = $match[1];
+            } elseif ($key && preg_match('{^-\s*(.+)$}', $line, $match)) {
+                $result[] = array('type' => $key, 'url' => $match[1]);
+            }
+        }
+
+        foreach ($result as $key => $item) {
+            switch ($item['type']) {
+                case 'tidelift':
+                    $result[$key]['url'] = 'https://tidelift.com/funding/github/' . $item['url'];
+                    break;
+                case 'github':
+                    $result[$key]['url'] = 'https://github.com/' . basename($item['url']);
+                    break;
+                case 'patreon':
+                    $result[$key]['url'] = 'https://www.patreon.com/' . basename($item['url']);
+                    break;
+                case 'otechie':
+                    $result[$key]['url'] = 'https://otechie.com/' . basename($item['url']);
+                    break;
+                case 'open_collective':
+                    $result[$key]['url'] = 'https://opencollective.com/' . basename($item['url']);
+                    break;
+                case 'liberapay':
+                    $result[$key]['url'] = 'https://liberapay.com/' . basename($item['url']);
+                    break;
+                case 'ko_fi':
+                    $result[$key]['url'] = 'https://ko-fi.com/' . basename($item['url']);
+                    break;
+                case 'issuehunt':
+                    $result[$key]['url'] = 'https://issuehunt.io/r/' . $item['url'];
+                    break;
+                case 'community_bridge':
+                    $result[$key]['url'] = 'https://funding.communitybridge.org/projects/' . basename($item['url']);
+                    break;
+            }
         }
 
-        return $this->fundingInfo = array_map(function ($link) {
-            return array('type' => strtolower($link['platform']), 'url' => $link['url']);
-        }, $result['data']['repository']['fundingLinks']);
+        return $this->fundingInfo = $result;
     }
 
     /**