This is a second rev of this SE Question.
How can I add more validation to this .ico file downloader?
It works but I need a way to check the integrity of each step:
- Check Default location ( checked length is greater than 20 ) ( broken for test.com ... why ?
- Check Google API ( validation already added )
- Scrape page for ico location and download directly ( last resort )
And of course general feedback. Note I Use a GET request to test the script invoking debug.
<?php
if($_GET)
{
$obj = new FaviconFinder();
$obj->invokeDebug($_GET);
}
class FaviconFinder
{
// domain before and after redirects
private $domain;
private $real_domain;
// the domain and how it was obtained
private $domain_code = '0';
private $domain_file;
// the favicon and how it was obtained
private $favicon_code = 'z';
private $favicon_file;
private $ext;
// paths local to server and on the internet (URL)
private $path_local_server = "../../favicons/";
private $name_db;
private $path_internet;
/****************************************************************************************************
* invoke
****************************************************************************************************/
public function invoke( $pipe )
{
$domain = $pipe['domain'];
$this->domain = $domain;
if ( $this->googleAPIFound($domain) )
{
$pipe = $this->saveFavicon($pipe, true);
$pipe['favicon'] = 'NULL';
$pipe['favicon_local'] = $this->name_db;
} else if ( $this->defaultFound($domain) )
{
$pipe = $this->saveFavicon($pipe, true);
$pipe['favicon'] = 'NULL';
$pipe['favicon_local'] = $this->name_db;
} else if ( $this->pageFound($domain) && $this->linkFound() && $this->getFavicon($this->path_internet) )
{
$pipe = $this->saveFavicon($pipe);
$pipe['favicon'] = $this->path_internet;
$pipe['favicon_local'] = $this->name_db;
} else {
$pipe['favicon'] = 'NULL';
$pipe['favicon_local'] = 'image_generic.png';
}
$pipe['method'] = $this->domain_code . $this->favicon_code;
return $pipe;
}
/****************************************************************************************************
* defaultFound
****************************************************************************************************/
private function defaultFound ($domain) {
$default_location = 'http://www.' . $domain . '/favicon.ico';
if( $this->getFavicon( $default_location) )
{
$this->domain_code = 'default - 1';
$this->path_internet = $default_location;
return true;
}
return false;
}
/****************************************************************************************************
* googleAPIFound
****************************************************************************************************/
private function googleAPIFound ($domain) {
$favicon = @file_get_contents('https://plus.google.com/_/favicon?domain=' . $domain);
// remove this
$favicon64 = base64_encode($favicon);
if ( hash('md5', $favicon64) == '99fd8ddc4311471625e5756986002b6b' ) {
return false;
}
else {
$this->domain_code = 'google - 1';
$this->favicon_file = $favicon;
return true;
}
}
/****************************************************************************************************
* pageFound
****************************************************************************************************/
private function pageFound ($domain)
{
return $this->pageFoundGet($domain) || $this->pageFoundCurl($domain);
}
private function pageFoundCurl ($domain)
{
$types = array(
"curl - 1"=>$domain,
"curl - 2"=>'www.' . $domain,
"curl - 4"=>'https://www.' . $domain,
"curl - 3"=>'http://www.' . $domain,
"curl - 6"=>'https://' . $domain,
"curl - 5"=>'http://' . $domain
);
foreach ($types as $key => $value) {
$this->domain_file = $this->curlExec($value, true);
if ($this->domain_file)
{
$this->domain_code = $key;
return true;
}
}
return false;
}
private function pageFoundGet( $domain )
{
$types = array(
"file_get - 1"=>$domain,
"file_get - 2"=>'www.' . $domain,
"file_get - 3"=>'http://www.' . $domain,
"file_get - 4"=>'https://www.' . $domain,
"file_get - 5"=>'http://' . $domain,
"file_get - 6"=>'https://' . $domain
);
foreach ($types as $key => $value) {
if ($this->domain_file = $this->fileGetContents( $value ))
{
$this->domain_code = $key;
return true;
}
}
return false;
}
/****************************************************************************************************
* linkFound
****************************************************************************************************/
private function linkFound()
{
$domain = $this->real_domain;
$regex = '#<link\s+(?=[^>]*rel=(?:\'|")(?:shortcut\s)?icon(?:\'|")\s*)(?:[^>]*href=(?:\'|")(.+?)(?:\'|")).*>#i';
$link_found = preg_match( $regex , $this->domain_file, $matches );
if($link_found === 1)
{
$path = $matches[1];
if ( $path[0] === '/' && $path[1] === '/' )
{
$this->favicon_code = 'a';
$this->path_internet = 'http:' . $path;
}
else if( $path[0] === '/' )
{
$this->favicon_code = 'b';
$this->path_internet = 'http://www.' . $domain . $path;
}
else if ( substr($path, 0, 4) === 'http' )
{
$this->favicon_code = 'c';
$this->path_internet = $path;
}
else
{
$this->favicon_code = 'd';
$this->path_internet = 'http://www.' . $domain . '/' . $path;
}
}
else
{
return false;
}
return true;
}
/****************************************************************************************************
* getFavicon
****************************************************************************************************/
private function getFavicon($url)
{
return $this->getFaviconCurl($url) ;
}
private function getFaviconCurl($url)
{
$temp = $this->curlExec( $url, false );
if($temp === false)
{
return false;
}
if(strlen($temp) < 20)
{
return false;
}
$this->favicon_file = $temp;
return true;
}
/****************************************************************************************************
* saveFavicon
****************************************************************************************************/
public function saveFavicon( $pipe, $switch )
{
if ($switch) {
$this->ext = "ico";
} else {
$arr = parse_url($this->path_internet);
$this->ext = pathinfo($arr['path'], PATHINFO_EXTENSION);
}
$name = str_replace('.', '_', $this->domain);
if ($this->ext) {
$name = $name . "." . $this->ext;
}
file_put_contents($this->path_local_server . $name, $this->favicon_file);
$this->name_db = $name;
return $pipe;
}
/****************************************************************************************************
* wrapper functions
****************************************************************************************************/
private function curlExec ($url, $set)
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
));
$temp = curl_exec($curl);
if ($set) {
$url = curl_getinfo( $curl )['url'];
$url = parse_url($url);
$url = $url['host'];
$this->real_domain = preg_replace('#^www\.(.+\.)#i', '$1', $url);
}
curl_close($curl);
return $temp;
}
private function fileGetContents ($value)
{
$opts = array(
'http'=>array(
'follow_location' => true,
'max_redirects' => 20
)
);
$context = stream_context_create($opts);
return @file_get_contents( $value, false, $context );
}
/****************************************************************************************************
* invokeDebug
****************************************************************************************************/
public function invokeDebug($pipe)
{
if ($pipe['domain'])
{
$pipe = $this->invoke($pipe);
echo "<br> domain | " . $pipe['domain'] . "";
echo "<br> domain_code | " . $this->domain_code;
echo "<br> favicon_code | " . $this->favicon_code;
}
if ($this->favicon_file)
{
echo "<br> favicon_file type | " . gettype($this->favicon_file);
echo "<br> favicon_file length | " . strlen($this->favicon_file);
echo "<br> favicon_file | " . $this->favicon_file;
$file64 = base64_encode($this->favicon_file);
echo "<br> <img src= 'data:image/" . $this->ext . ";base64," . $file64 . "'></img>";
}
}
}