Skip to content

Commit

Permalink
Merge pull request #10 from theofidry/bugfix/lazy-fetch
Browse files Browse the repository at this point in the history
Fetch data lazily
  • Loading branch information
c9s authored Feb 5, 2018
2 parents 2d361b3 + dc8695a commit a5d85f5
Showing 1 changed file with 82 additions and 28 deletions.
110 changes: 82 additions & 28 deletions src/PEARX/Channel.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<?php

namespace PEARX;
use PEARX\ChannelParser;

use DOMDocument;
use Exception;
use PEARX\Core;

/**
* ````php
* $channel = new PEARX\Channel( 'pear.php.net', array(
* 'cache' => ....
* ));
*
* $channel->getPackages();
*
* ```
*/
class Channel
{
Expand All @@ -21,11 +22,10 @@ class Channel
public $name;

/**
* @var string suggestedalias
* @var string suggested alias
*/
public $alias;


/**
* @var string summary
*/
Expand All @@ -36,13 +36,11 @@ class Channel
*/
public $primary = array();


/**
* @var string REST version
*/
public $rest; // Latest REST version


public $cache;

public $downloader;
Expand All @@ -58,43 +56,61 @@ class Channel

public $core;

private $host;
private $init = false;

/**
* @param string $host
* @param array $options
*/
public function __construct($host, $options = array() )
{
$this->core = new Core( $options );
$this->channelXml = $this->fetchChannelXml( $host );

$parser = new ChannelParser;
$info = $parser->parse( $this->channelXml );

$this->name = $info->name;
$this->summary = $info->summary;
$this->alias = $info->alias;
$this->primary = $info->primary;
$this->rest = $info->rest;
$this->host = $host;
}

/**
* @return string
*/
public function getBaseUrl()
{
$this->init();

return $this->scheme . '://' . $this->name;
}

/**
* @param string $version
*
* @return string
*/
public function getRestBaseUrl($version = null)
{
if( $version && $this->primary[$version] )
$this->init();

if( $version && $this->primary[$version] ) {
return rtrim($this->primary[ $version ],'/');
}

return rtrim($this->primary[ $this->rest ],'/');
}


/**
* @param string $packageName
* @param string $version
*
* @return DOMDocument
*/
public function fetchPackageReleaseXml($packageName, $version = 'stable')
{
$baseUrl = $this->getRestBaseUrl();
$url = "$baseUrl/r/" . strtolower($packageName);

if( $version === 'stable'
if ( $version === 'stable'
|| $version === 'latest'
|| $version === 'beta' )
{
|| $version === 'beta'
) {
// Get version info
$ret = file_get_contents($url . '/' . $version . '.txt');
if ($ret === false) {
Expand All @@ -116,15 +132,19 @@ public function fetchPackageReleaseXml($packageName, $version = 'stable')

/**
* fetch channel.xml from PEAR channel server.
*
* @param string $host
*
* @return string
*/
public function fetchChannelXml($host)
{
$xmlstr = null;
$xmlstr = $this->core->cache ? $this->core->cache->get( $host ) : null;

// cache not found.
if( null !== $xmlstr )
// Check the cache
if( null !== $xmlstr ) {
return $xmlstr;
}

$httpUrl = 'http://' . $host . '/channel.xml';
$httpsUrl = 'https://' . $host . '/channel.xml';
Expand All @@ -148,19 +168,22 @@ public function fetchChannelXml($host)
throw new Exception('channel.xml fetch failed.');
}

// save cache
// Cache result
if( $this->cache ) {
$this->cache->set($host, $xmlstr );
}
return $xmlstr;
}

/**
* @return Category[]
*/
public function getCategories()
{
$baseUrl = $this->getRestBaseUrl();
$url = $baseUrl . '/c/categories.xml';
$xmlStr = $this->core->request($url);

// libxml_use_internal_errors(true);
$xml = Utils::create_dom();
if( false === $xml->loadXml( $xmlStr ) ) {
Expand Down Expand Up @@ -195,13 +218,44 @@ public function getPackages()
}


/**
* @param string
*
* @return Package|null
*/
public function findPackage($name)
{
foreach( $this->getCategories() as $category ) {
$packages = $category->getPackages();
if( isset($packages[$name]) )
return $packages[ $name ];
if( isset($packages[$name]) ) {
return $packages[$name];
}
}
}

/**
* Initialise the properties necessary to do an HTTP request. This is done lazily as opposed as during
* instantiation to avoid an HTTP request if unnecessary which would otherwise fail if no internet
* connection is available.
*/
private function init()
{
if ($this->init) {
return;
}

$this->channelXml = $this->fetchChannelXml( $this->host );

$parser = new ChannelParser;
$info = $parser->parse( $this->channelXml );

$this->name = $info->name;
$this->summary = $info->summary;
$this->alias = $info->alias;
$this->primary = $info->primary;
$this->rest = $info->rest;

$this->init = true;
}
}

Expand Down

0 comments on commit a5d85f5

Please sign in to comment.