예제 #1
0
 private function updateGitHubInfo(RemoteFilesystem $rfs, Package $package, $owner, $repo, VcsRepository $repository)
 {
     $baseApiUrl = 'https://api.github.com/repos/' . $owner . '/' . $repo;
     $driver = $repository->getDriver();
     if (!$driver instanceof GitHubDriver) {
         return;
     }
     $repoData = $driver->getRepoData();
     try {
         $opts = ['http' => ['header' => ['Accept: application/vnd.github.v3.html']]];
         $readme = $rfs->getContents('github.com', $baseApiUrl . '/readme', false, $opts);
     } catch (\Exception $e) {
         if (!$e instanceof \Composer\Downloader\TransportException || $e->getCode() !== 404) {
             return;
         }
         // 404s just mean no readme present so we proceed with the rest
     }
     if (!empty($readme)) {
         $elements = array('p', 'br', 'small', 'strong', 'b', 'em', 'i', 'strike', 'sub', 'sup', 'ins', 'del', 'ol', 'ul', 'li', 'h1', 'h2', 'h3', 'dl', 'dd', 'dt', 'pre', 'code', 'samp', 'kbd', 'q', 'blockquote', 'abbr', 'cite', 'table', 'thead', 'tbody', 'th', 'tr', 'td', 'a[href|target|rel|id]', 'img[src|title|alt|width|height|style]');
         $config = \HTMLPurifier_Config::createDefault();
         $config->set('HTML.Allowed', implode(',', $elements));
         $config->set('Attr.EnableID', true);
         $config->set('Attr.AllowedFrameTargets', ['_blank']);
         $purifier = new \HTMLPurifier($config);
         $readme = $purifier->purify($readme);
         $dom = new \DOMDocument();
         $dom->loadHTML('<?xml encoding="UTF-8">' . $readme);
         // Links can not be trusted, mark them nofollow and convert relative to absolute links
         $links = $dom->getElementsByTagName('a');
         foreach ($links as $link) {
             $link->setAttribute('rel', 'nofollow noopener external');
             if ('#' === substr($link->getAttribute('href'), 0, 1)) {
                 $link->setAttribute('href', '#user-content-' . substr($link->getAttribute('href'), 1));
             } elseif ('mailto:' === substr($link->getAttribute('href'), 0, 7)) {
                 // do nothing
             } elseif (false === strpos($link->getAttribute('href'), '//')) {
                 $link->setAttribute('href', 'https://github.com/' . $owner . '/' . $repo . '/blob/HEAD/' . $link->getAttribute('href'));
             }
         }
         // convert relative to absolute images
         $images = $dom->getElementsByTagName('img');
         foreach ($images as $img) {
             if (false === strpos($img->getAttribute('src'), '//')) {
                 $img->setAttribute('src', 'https://raw.github.com/' . $owner . '/' . $repo . '/HEAD/' . $img->getAttribute('src'));
             }
         }
         // remove first title as it's usually the project name which we don't need
         if ($dom->getElementsByTagName('h1')->length) {
             $first = $dom->getElementsByTagName('h1')->item(0);
             $first->parentNode->removeChild($first);
         } elseif ($dom->getElementsByTagName('h2')->length) {
             $first = $dom->getElementsByTagName('h2')->item(0);
             $first->parentNode->removeChild($first);
         }
         $readme = $dom->saveHTML();
         $readme = substr($readme, strpos($readme, '<body>') + 6);
         $readme = substr($readme, 0, strrpos($readme, '</body>'));
         $package->setReadme($readme);
     }
     if (!empty($repoData['language'])) {
         $package->setLanguage($repoData['language']);
     }
     if (isset($repoData['stargazers_count'])) {
         $package->setGitHubStars($repoData['stargazers_count']);
     }
     if (isset($repoData['subscribers_count'])) {
         $package->setGitHubWatches($repoData['subscribers_count']);
     }
     if (isset($repoData['network_count'])) {
         $package->setGitHubForks($repoData['network_count']);
     }
     if (isset($repoData['open_issues_count'])) {
         $package->setGitHubOpenIssues($repoData['open_issues_count']);
     }
 }
예제 #2
0
 private function updateGitHubInfo(RemoteFilesystem $rfs, Package $package, $owner, $repo)
 {
     $baseApiUrl = 'https://api.github.com/repos/' . $owner . '/' . $repo;
     try {
         $repoData = JsonFile::parseJson($rfs->getContents('github.com', $baseApiUrl, false), $baseApiUrl);
     } catch (\Exception $e) {
         return;
     }
     try {
         $opts = ['http' => ['header' => ['Accept: application/vnd.github.v3.html']]];
         $readme = $rfs->getContents('github.com', $baseApiUrl . '/readme', false, $opts);
     } catch (\Exception $e) {
         if (!$e instanceof \Composer\Downloader\TransportException || $e->getCode() !== 404) {
             return;
         }
         // 404s just mean no readme present so we proceed with the rest
     }
     if (!empty($readme)) {
         $config = \HTMLPurifier_Config::createDefault();
         $config->set('HTML.Allowed', 'a[href|target|rel|id],strong,b,em,i,strike,pre,code,p,ol,ul,li,br,h1,h2,h3,img[src|title|alt|width|height|style]');
         $config->set('Attr.EnableID', true);
         $config->set('Attr.AllowedFrameTargets', ['_blank']);
         $purifier = new \HTMLPurifier($config);
         $readme = $purifier->purify($readme);
         $dom = new \DOMDocument();
         $dom->loadHTML('<?xml encoding="UTF-8">' . $readme);
         // Links can not be trusted
         $links = $dom->getElementsByTagName('a');
         foreach ($links as $link) {
             $link->setAttribute('rel', 'nofollow');
             if ('#' === substr($link->getAttribute('href'), 0, 1)) {
                 $link->setAttribute('href', '#user-content-' . substr($link->getAttribute('href'), 1));
             } elseif (false === strpos($link->getAttribute('href'), '//')) {
                 $link->setAttribute('href', 'https://github.com/' . $owner . '/' . $repo . '/blob/HEAD/' . $link->getAttribute('href'));
             }
         }
         // remove first title as it's usually the project name which we don't need
         if ($dom->getElementsByTagName('h1')->length) {
             $first = $dom->getElementsByTagName('h1')->item(0);
             $first->parentNode->removeChild($first);
         } elseif ($dom->getElementsByTagName('h2')->length) {
             $first = $dom->getElementsByTagName('h2')->item(0);
             $first->parentNode->removeChild($first);
         }
         $readme = $dom->saveHTML();
         $readme = substr($readme, strpos($readme, '<body>') + 6);
         $readme = substr($readme, 0, strrpos($readme, '</body>'));
         $package->setReadme($readme);
     }
     if (!empty($repoData['language'])) {
         $package->setLanguage($repoData['language']);
     }
     if (!empty($repoData['stargazers_count'])) {
         $package->setGitHubStars($repoData['stargazers_count']);
     }
     if (!empty($repoData['subscribers_count'])) {
         $package->setGitHubWatches($repoData['subscribers_count']);
     }
     if (!empty($repoData['network_count'])) {
         $package->setGitHubForks($repoData['network_count']);
     }
     if (!empty($repoData['open_issues_count'])) {
         $package->setGitHubOpenIssues($repoData['open_issues_count']);
     }
 }