4acd19f513017b1eff58c1e49b61763c62fdf184
[phinde.git] / src / phinde / LinkExtractor / Html.php
1 <?php
2 namespace phinde\LinkExtractor;
3
4 use phinde\LinkInfo;
5
6 class Html
7 {
8     public function extract(\HTTP_Request2_Response $res)
9     {
10         $url = $res->getEffectiveUrl();
11
12         $linkInfos = array();
13
14         //FIXME: mime type switch for cdata
15         $doc = new \DOMDocument();
16         //@ to hide parse warning messages in invalid html
17         @$doc->loadHTML($res->getBody());
18
19         //FIXME: extract base url from html
20         $base = new \Net_URL2($url);
21
22         $dx = new \DOMXPath($doc);
23
24         $meta = $dx->evaluate('/html/head/meta[@name="robots" and @content]')
25             ->item(0);
26         if ($meta) {
27             $robots = $meta->attributes->getNamedItem('content')->textContent;
28             foreach (explode(',', $robots) as $value) {
29                 if (trim($value) == 'nofollow') {
30                     //we shall not follow the links
31                     return array();
32                 }
33             }
34         }
35
36         $links = $dx->evaluate('//a');
37         //FIXME: link rel, img, video
38
39         $alreadySeen = array();
40
41         foreach ($links as $link) {
42             $linkTitle = $link->textContent;
43             $href = '';
44             foreach ($link->attributes as $attribute) {
45                 if ($attribute->name == 'href') {
46                     $href = $attribute->textContent;
47                 } else if ($attribute->name == 'rel') {
48                     foreach (explode(',', $attribute->textContent) as $value) {
49                         if (trim($value) == 'nofollow') {
50                             //we shall not follow this link
51                             continue 3;
52                         }
53                     }
54                 }
55             }
56             if ($href == '' || $href{0} == '#') {
57                 //link on this page
58                 continue;
59             }
60
61             $linkUrlObj = $base->resolve($href);
62             $linkUrlObj->setFragment(false);
63             $linkUrl    = (string) $linkUrlObj;
64             if (isset($alreadySeen[$linkUrl])) {
65                 continue;
66             }
67
68             switch ($linkUrlObj->getScheme()) {
69             case 'http':
70             case 'https':
71                 break;
72             default:
73                 continue 2;
74             }
75
76             //FIXME: check target type
77             $linkInfos[] = new LinkInfo(
78                $linkUrl, $linkTitle, $url
79             );
80             $alreadySeen[$linkUrl] = true;
81         }
82
83         return $linkInfos;
84     }
85 }
86 ?>