Skip to content

Commit

Permalink
Merge pull request #2 from dennisinteractive/28103_handle_mutiple_fields
Browse files Browse the repository at this point in the history
28103 handle mutiple fields
  • Loading branch information
tashaharrison authored Jun 30, 2017
2 parents 51fb19e + 0ee166f commit b0ea27f
Show file tree
Hide file tree
Showing 30 changed files with 1,094 additions and 521 deletions.
15 changes: 13 additions & 2 deletions dennis_link_checker.module
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use Dennis\Link\Checker\LinkLocalisation;
use Dennis\Link\Checker\Processor;
use Dennis\Link\Checker\EntityHandler;
use Dennis\Link\Checker\Analyzer;
use SystemQueue as Queue;
use Dennis\Link\Checker\Throttler;
use Dennis\Link\Checker\Database;
use Dennis\Link\Checker\Queue;

/**
* PSR-4 autoloader
Expand Down Expand Up @@ -37,11 +39,20 @@ function dennis_link_checker_setup(array $nids) {
->setMaxRedirects(10)
->setInternalOnly(TRUE)
->setLocalisation(LinkLocalisation::ORIGINAL)
->setFieldNames(variable_get('dennis_link_checker_fields', array('body')))
->setNodeList($nids);

$queue = new Queue('dennis_link_checker');
$entity_handler = new EntityHandler($config);
$analyzer = new Analyzer($config);

// Make sure we don't request more than one page per second.
$curl_throttler = new Throttler(1);

// Database object that allows interaction with the DB.
$database = new Database();

$analyzer = new Analyzer($config, $curl_throttler, $database);

return new Processor($config, $queue, $entity_handler, $analyzer);
}

Expand Down
56 changes: 48 additions & 8 deletions src/Dennis/Link/Checker/Analyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,38 @@
* @package Dennis\Link\Checker
*/
class Analyzer implements AnalyzerInterface {

protected $host;

/**
* @var ConfigInterface
*/
protected $config;

/**
* @var number of redirects in current chain.
*/
protected $redirectCount;

/**
* @var int maximum number of seconds to spend resolving links.
*/
protected $linkTimeLimit = 480;

/**
* @var Throttler
*/
protected $curlThrottler;

/**
* @var Database
*/
protected $database;

/**
* @inheritDoc
*/
public function __construct(ConfigInterface $config) {
public function __construct(ConfigInterface $config, Throttler $curl_throttler, Database $database) {
$this->config = $config;
$this->curlThrottler = $curl_throttler;
$this->database = $database;
}

/**
Expand All @@ -45,8 +65,17 @@ public function getSiteHost() {
* @inheritDoc
*/
public function multipleLinks($links) {
foreach ($links as &$link) {
$link = $this->link($link);
$timeout = $this->linkTimeLimit + time();

foreach ($links as $link) {
if (time() >= $timeout) {
throw new TimeoutException(sprintf('Could not process %s links within %s seconds',
count($links),
$this->linkTimeLimit));
}
$this->link($link);
// Keep the DB connection alive whilst we are processing external links.
$this->database->keepConnectionAlive();
}

return $links;
Expand All @@ -56,6 +85,9 @@ public function multipleLinks($links) {
* @inheritDoc
*/
public function link(LinkInterface $link) {
// Make sure we only process one link per configured number of seconds.
$this->curlThrottler->throttle();

// Only redirect 301's so cannot use CURLOPT_FOLLOWLOCATION
$this->redirectCount = 0;

Expand All @@ -75,7 +107,8 @@ public function link(LinkInterface $link) {
->setNumberOfRedirects($this->redirectCount);

} catch (ResourceFailException $e) {
$link->setError($e->getMessage(), $e->getCode());
$link->setNumberOfRedirects($this->redirectCount)
->setError($e->getMessage(), $e->getCode());
}

return $link;
Expand All @@ -90,8 +123,13 @@ public function link(LinkInterface $link) {
*/
protected function followRedirects($url) {
$info = $this->getInfo($url);

if (!empty($info['redirect_url'])) {
if ($info['http_code'] == 301) {
// Throw exception if we have reached our redirect limit.
if ($this->redirectCount > $this->config->getMaxRedirects()) {
throw new ResourceFailException(sprintf('Maximum of %s redirects reached.', $this->config->getMaxRedirects()));
}
// Do the redirect
$this->redirectCount++;
return $this->followRedirects($info['redirect_url']);
Expand Down Expand Up @@ -123,8 +161,10 @@ protected function getInfo($url) {
return $info;
}
else {
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
throw new ResourceFailException(curl_error($ch), curl_errno($ch));
throw new ResourceFailException($error, $errno);
}

}
Expand Down
5 changes: 4 additions & 1 deletion src/Dennis/Link/Checker/AnalyzerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ interface AnalyzerInterface {

/**
* AnalyzerInterface constructor.
*
* @param ConfigInterface $config
* @param Throttler $curl_throttler
* @param Database $database
*/
public function __construct(ConfigInterface $config);
public function __construct(ConfigInterface $config, Throttler $curl_throttler, Database $database);

/**
* Checks the link.
Expand Down
19 changes: 19 additions & 0 deletions src/Dennis/Link/Checker/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class Config implements ConfigInterface {

protected $nids = FALSE;

protected $fieldNames = [];

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -136,4 +138,21 @@ public function setNodeList(array $nids) {
public function getNodeList() {
return $this->nids;
}

/**
* @inheritDoc
*/
public function setFieldNames(array $field_names) {
$this->fieldNames = $field_names;

return $this;
}

/**
* @inheritDoc
*/
public function getFieldNames() {
return $this->fieldNames;
}

}
15 changes: 15 additions & 0 deletions src/Dennis/Link/Checker/ConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,19 @@ public function setNodeList(array $nids);
* @return array
*/
public function getNodeList();

/**
* The names of fields to check for links in.
*
* @param array $field_names
* @return self
*/
public function setFieldNames(array $field_names);

/**
* The names of fields to check for links in.
*
* @return array
*/
public function getFieldNames();
}
35 changes: 35 additions & 0 deletions src/Dennis/Link/Checker/Database.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
/**
* @file
* Database
*/
namespace Dennis\Link\Checker;

/**
* Class Database
* @package Dennis\Link\Database
*/
class Database implements DatabaseInterface {
/**
* How often the DB should be pinged in seconds.
*/
const interval = 15;

/**
* @var int last time the DB was pinged.
*/
protected $pingTime = 0;

/**
* @inheritDoc
*/
public function keepConnectionAlive() {
$now = time();
// If it's been more than 15 seconds... Ping!
if (($now - $this->pingTime) > self::interval) {
db_query('SELECT CURTIME()');
// Set the ping time.
$this->pingTime = $now;
}
}
}
17 changes: 17 additions & 0 deletions src/Dennis/Link/Checker/DatabaseInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
/**
* @file
* DatabaseInterface
*/
namespace Dennis\Link\Checker;

/**
* Interface DatabaseInterface
* @package Dennis\Link\Checker
*/
interface DatabaseInterface {
/**
* Keep database connection alive.
*/
public function keepConnectionAlive();
}
64 changes: 64 additions & 0 deletions src/Dennis/Link/Checker/Entity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* @file
* Entity
*/
namespace Dennis\Link\Checker;

/**
* Class Entity
* @package Dennis\Link\Checker
*/
class Entity implements EntityInterface {
/**
* @var string
*/
protected $entityType;

/**
* @var int
*/
protected $entityId;

/**
* @var ConfigInterface
*/
protected $config;

/**
* @inheritDoc
*/
public function __construct($config, $entity_type, $entity_id) {
$this->config = $config;
$this->entityType = $entity_type;
$this->entityId = $entity_id;
}

/**
* @inheritDoc
*/
public function getConfig() {
return $this->config;
}

/**
* @inheritDoc
*/
public function entityId() {
return $this->entityId;
}

/**
* @inheritDoc
*/
public function entityType() {
return $this->entityType;
}

/**
* @inheritDoc
*/
public function getField($field_name) {
return new Field($this, $field_name);
}
}
Loading

0 comments on commit b0ea27f

Please sign in to comment.