<commit_before><?php

/*
 * This file is part of Composer.
 *
 * (c) <NAME> <<EMAIL>>
 *     <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Repository;

use Composer\IO\IOInterface;
use Composer\Package\Loader\ArrayLoader;
use Composer\Util\RemoteFilesystem;
use Composer\Downloader\TransportException;

/**
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 */
class PearRepository extends ArrayRepository
{
    private static $channelNames = array();

    private $url;
    private $channel;
    private $io;
    private $rfs;

    public function __construct(array $config, IOInterface $io, RemoteFilesystem $rfs = null)
    {
        if (!preg_match('{^https?://}', $config['url'])) {
            $config['url'] = 'http://'.$config['url'];
        }

        if (function_exists('filter_var') && !filter_var($config['url'], FILTER_VALIDATE_URL)) {
            throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$config['url']);
        }

        $this->url = rtrim($config['url'], '/');
        $this->channel = !empty($config['channel']) ? $config['channel'] : null;
        $this->io = $io;
        $this->rfs = $rfs ?: new RemoteFilesystem($this->io);
    }

    protected function initialize()
    {
        parent::initialize();

        $this->io->write('Initializing PEAR repository '.$this->url);
        $this->fetchFromServer();
    }

    protected function fetchFromServer()
    {
        $channelXML = $this->requestXml($this->url . "/channel.xml");
        if (!$this->channel) {
            $this->channel = $channelXML->getElementsByTagName("suggestedalias")->item(0)->nodeValue
                                    ?: $channelXML->getElementsByTagName("name")->item(0)->nodeValue;
        }
        self::$channelNames[$channelXML->getElementsByTagName("name")->item(0)->nodeValue] = $this->channel;

        $categoryXML = $this->requestXml($this->url . "/rest/c/categories.xml");
        $categories = $categoryXML->getElementsByTagName("c");

        foreach ($categories as $category) {
            $link = '/' . ltrim($category->getAttribute("xlink:href"), '/');
            try {
                $packagesLink = str_replace("info.xml", "packagesinfo.xml", $link);
                $this->fetchPear2Packages($this->url . $packagesLink);
            } catch (TransportException $e) {
                if (false === strpos($e->getMessage(), '404')) {
                    throw $e;
                }
                $categoryLink = str_replace("info.xml", "packages.xml", $link);
                $this->fetchPearPackages($this->url . $categoryLink);
            }

        }
    }

    /**
     * @param   string $categoryLink
     * @throws  TransportException
     * @throws  InvalidArgumentException<commit_msg>Detect PEAR repos that support composer via Pirum<commit_after><?php

/*
 * This file is part of Composer.
 *
 * (c) <NAME> <<EMAIL>>
 *     <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Repository;

use Composer\IO\IOInterface;
use Composer\Package\Loader\ArrayLoader;
use Composer\Util\RemoteFilesystem;
use Composer\Json\JsonFile;
use Composer\Downloader\TransportException;

/**
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 */
class PearRepository extends ArrayRepository
{
    private static $channelNames = array();

    private $url;
    private $channel;
    private $io;
    private $rfs;

    public function __construct(array $config, IOInterface $io, RemoteFilesystem $rfs = null)
    {
        if (!preg_match('{^https?://}', $config['url'])) {
            $config['url'] = 'http://'.$config['url'];
        }

        if (function_exists('filter_var') && !filter_var($config['url'], FILTER_VALIDATE_URL)) {
            throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$config['url']);
        }

        $this->url = rtrim($config['url'], '/');
        $this->channel = !empty($config['channel']) ? $config['channel'] : null;
        $this->io = $io;
        $this->rfs = $rfs ?: new RemoteFilesystem($this->io);
    }

    protected function initialize()
    {
        parent::initialize();

        $this->io->write('Initializing PEAR repository '.$this->url);
        $this->initializeChannel();
        $this->io->write('Packages names will be prefixed with: pear-'.$this->channel.'/');

        // try to load as a composer repo
        try {
            $json     = new JsonFile($this->url.'/packages.json', new RemoteFilesystem($this->io));
            $packages = $json->read();

            if ($this->io->isVerbose()) {
                $this->io->write('Repository is Composer-compatible, loading via packages.json instead of PEAR protocol');
            }

            $loader = new ArrayLoader();
            foreach ($packages as $data) {
                foreach ($data['versions'] as $rev) {
                    $rev['name'] = 'pear-'.$this->channel.'/'.$rev['name'];
                    $this->addPackage($loader->load($rev));
                }
            }

            return;
        } catch (\Exception $e) {
        }

        $this->fetchFromServer();
    }

    protected function initializeChannel()
    {
        $channelXML = $this->requestXml($this->url . "/channel.xml");
        if (!$this->channel) {
            $this->channel = $channelXML->getElementsByTagName("suggestedalias")->item(0)->nodeValue
                                    ?: $channelXML->getElementsByTagName("name")->item(0)->nodeValue;
        }

        self::$channelNames[$channelXML->getElementsByTagName("name")->item(0)->nodeValue] = $this->channel;
    }

    protected function fetchFromServer()
    {
        $categoryXML = $this->requestXml($this->url . "/rest/c/categories.xml");
        $categories = $categoryXML->getElementsByTagName("c");

        foreach ($categories as $category) {
            $link = '/' . ltrim($category->getAttribute("xlink:href"), '/');
            try {
                $packagesLink = str_replace("info.xml", "packagesinfo.xml", $link);
                $this->fetchPear2Packages($this->url . $packagesLink);
            } catch (TransportException $e) {
                if (false === strpos($e->getMessage(), '404')) {
                    throw $e;
                }
                $categoryLink = str_replace("info.xml", "packages.xml", $link);
                $this->fetchPearPackages($this->url . $categoryLink);
            }

        }
    }

    /**
     * @param   string $categoryLink
     * @throws  TransportException
     * @throws  InvalidArgumentException
{'fraction_non_alphanumeric': 0.16221796195251437, 'fraction_numerical': 0.0020645922430320013, 'mean_word_length': 2.435663627152989, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6975633', 'n_tokens_mistral': 1939, 'n_tokens_neox': 1888, 'n_words': 392}