comment + link extraction
[stapibas.git] / src / stapibas / Content / Extractor / Base.php
1 <?php
2 namespace stapibas;
3
4 class Content_Extractor_Base
5 {
6     public function __construct(Logger $log)
7     {
8         $this->log = $log;
9     }
10
11     protected function extractAuthorData($hentry, $xpath, &$data, $source)
12     {
13         $data['author_name']  = null;
14         $data['author_image'] = null;
15         $data['author_url']   = null;
16
17         $authors = $xpath->evaluate(
18             './/*[' . $this->xpc('p-author') . ']'
19         );
20         if ($authors->length != 1) {
21             //no p-author, so use page author data
22             $data['author_name'] = $this->getFirst(
23                 '/*[self::html or self::h:html]/*[self::head or self::h:head]'
24                 . '/*[(self::meta or self::h:meta) and @name="author"]',
25                 'content', $hentry, $xpath
26             );
27         
28             $data['author_url'] = 
29                 $this->absUrl(
30                     $this->getFirst(
31                         '/*[self::html or self::h:html]/*[self::head or self::h:head]'
32                         . '/*[(self::link or self::h:link) and @rel="author"]',
33                         'href', $hentry, $xpath
34                     ),
35                     $source
36                 );
37             return;
38         }
39
40         $author = $authors->item(0);
41
42         $data['author_name'] = $this->getFirst(
43             './/*[' . $this->xpc('p-name') . ' or ' . $this->xpc('fn') . ']',
44             null, $author, $xpath
45         );
46         $data['author_image'] = $this->getFirst(
47             './/*[' . $this->xpc('u-photo') . ']',
48             'src', $author, $xpath
49         );
50         $data['author_url'] = $this->absUrl(
51             $this->getFirst(
52                 './/*[' . $this->xpc('u-url') . ']',
53                 'href', $author, $xpath
54             ),
55             $source
56         );
57     }
58
59     protected function getFirst($xpathExpr, $attrName, $elem, $xpath)
60     {
61         $items = $xpath->evaluate($xpathExpr, $elem);
62         if (!$items instanceof \DOMNodeList || $items->length == 0) {
63             return null;
64         }
65
66         if ($attrName === false) {
67             return $items->item(0);
68         } else if ($attrName == null) {
69             return $items->item(0)->nodeValue;
70         } else {
71             return $items->item(0)->attributes->getNamedItem($attrName)->nodeValue;
72         }
73     }
74
75     protected function innerHtml($element)
76     {
77         $innerHTML = '';
78         $children = $element->childNodes;
79         foreach ($children as $child) {
80             $tmp_dom = new \DOMDocument();
81             $tmp_dom->appendChild($tmp_dom->importNode($child, true));
82             $innerHTML .= rtrim($tmp_dom->saveHTML(), "\n");
83         }
84         return trim($innerHTML);
85     }
86
87     protected function getXpath($node)
88     {
89         $xpath = new \DOMXPath($node);
90         $xpath->registerNamespace('h', 'http://www.w3.org/1999/xhtml');
91         return $xpath;
92     }
93
94     protected function xpc($class)
95     {
96         return 'contains('
97             . 'concat(" ", normalize-space(@class), " "),'
98             . '" ' . $class . ' "'
99             . ')';
100     }
101
102     protected function xpq($str)
103     {
104         return '"' . htmlspecialchars($str, ENT_QUOTES) . '"';
105     }
106
107     protected function absUrl($url, $source)
108     {
109         if ($url === null) {
110             return null;
111         }
112         $sourceUrl = new \Net_URL2($source);
113         return (string)$sourceUrl->resolve($url);
114     }
115
116 }
117 ?>