Created
June 22, 2016 14:18
-
-
Save langemike/ba4f3dea8fe0a1546f81549d4448d10b to your computer and use it in GitHub Desktop.
Validation class for validating dead links through a whitelist function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use BadMethodCallException; | |
trait LinkCheckerTrait { | |
/** | |
* The failed links. | |
* | |
* @var array | |
*/ | |
protected $diffLinks = []; | |
/** | |
* Resolved links from classes. | |
* | |
* @var array | |
*/ | |
protected static $resolvedLinks = []; | |
/** | |
* Validate links | |
* @param string $attribute | |
* @param string $value | |
* @param array $parameters | |
* @param \Validator $validator | |
* @return bool | |
**/ | |
public function validateLinks($attribute, $value, $parameters, $validator) | |
{ | |
$this->requireParameterCount(1, $parameters, 'link'); | |
if (! isset($this->customMessages['links'])) { | |
$this->setCustomMessages(['links' => 'De volgende links bestaan niet :links']); | |
} | |
$whitelist = array(); | |
foreach ($parameters as $class) { | |
$whitelist = array_unique(array_merge($whitelist, $this->fetchLinksFromClass($class))); | |
} | |
$links = $this->fetchLinks($value); | |
$this->diffLinks = array_diff($links, $whitelist); | |
if (count($this->diffLinks) > 0) { | |
//dd($links); | |
} | |
return count($this->diffLinks) === 0; | |
} | |
/** | |
* Nice validation messages with failed links | |
* @param string $message | |
* @param string $attribute | |
* @param string $rule | |
* @param array $parameters | |
* @return string | |
**/ | |
public function replaceLinks($message, $attribute, $rule, $parameters) | |
{ | |
return str_replace([':links'], implode(', ', $this->diffLinks), $message); | |
} | |
/** | |
* Get URLs from a mixed value | |
* @param mixed $value | |
* @return array | |
*/ | |
protected function fetchLinks($value) | |
{ | |
$links = array(); | |
if (is_string($value)) { | |
$links = $this->fetchLinksFromString($value); | |
} else if (is_array($value)) { | |
$links = $this->fetchLinksFromArray($value); | |
} | |
return array_filter($links, array($this, 'disallowedUrl')); | |
} | |
/** | |
* Fetch links from array | |
* @param array $value | |
* @return array | |
**/ | |
protected function fetchLinksFromArray($value) | |
{ | |
$links = array_filter($value, function($value) { | |
return preg_match('/^(http|\/)/', $value) !== 0; | |
}); | |
return array_map(array($this, 'normalizeUrl'), $links); | |
} | |
/** | |
* Fetch links from string | |
* @param string $value | |
* @return array | |
**/ | |
protected function fetchLinksFromString($value) | |
{ | |
$matches = preg_match_all('/<a.*?href\s*=\s*[\'\"](.*?)[\'\"]/', $value, $links); | |
return array_map(array($this, 'normalizeUrl'), $links[1]); | |
} | |
/** | |
* Get URLs from a class instance | |
* @param string $class | |
* @return array | |
*/ | |
protected function fetchLinksFromClass($class) | |
{ | |
if (array_key_exists($class, static::$resolvedLinks)) { | |
return static::$resolvedLinks[$class]; | |
} | |
$instance = new $class; | |
if (method_exists($instance, 'getValidatorLinks') === false) { | |
throw new BadMethodCallException("Method [getValidatorLinks] does not exist on [$class]."); | |
} | |
// Collect links from class | |
static::$resolvedLinks[$class] = array_map(array($this, 'normalizeUrl'), $instance->getValidatorLinks()); | |
return static::$resolvedLinks[$class]; | |
} | |
/** | |
* Disallowed URLs | |
* @param string $url | |
* @return bool | |
*/ | |
protected function disallowedUrl($url) | |
{ | |
return strpos($url, 'http') === false; | |
} | |
/** | |
* Transform URLs into consistent format | |
* - Base URL removed | |
* - Remove query string | |
* - Consitent trailing slash | |
* @param string $url | |
* @return string | |
*/ | |
protected function normalizeUrl($url) | |
{ | |
if (strpos($url, 'http') === 0) { | |
$url = str_replace($this->getBaseUrl(), '', $url); | |
} | |
return rtrim(preg_replace('/\?.*/', '', $url), '/'); | |
} | |
/** | |
* Get Base URL of application | |
* @return string | |
**/ | |
protected function getBaseUrl() | |
{ | |
return $this->container['config']->get('app.url'); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment