1<?php
2require_once('ZoteroRepository.php');
3require_once('ZoteroEntryNotFoundException.php');
4require_once('ZoteroFeedReader.php');
5require_once('ZoteroConfig.php');
6
7class FeedZoteroRepository extends ZoteroRepository
8{
9	/**
10	 * @var DomDocument
11	 */
12	private $dom;
13
14	/**
15	 * @var DomXPath
16	 */
17	private $xpath;
18
19	/**
20	 * @var ZoteroConfig
21	 */
22	private $config;
23
24	public function __construct(ZoteroFeedReader $feedReader, ZoteroConfig $config)
25	{
26		$this->config = $config;
27		$this->parseEntries($feedReader->getFeed());
28	}
29
30	private function parseEntries($feed)
31	{
32		$this->dom = new DomDocument();
33    	$this->dom->loadXml($feed);
34		$this->createXPath();
35
36		$r = $this->xpath->query('//atom:feed/atom:entry');
37		foreach ($r as $node)
38		{
39			$itemType = $this->parseItemType($node);
40			if ($itemType == "note" || $itemType == "attachment")
41			{
42				continue;
43			}
44			$e = $this->createEntry($node);
45			if ($e->getZoteroId() !== "" && $e->getAuthor() !== "" && $e->getTitle() !== "")
46			{
47				$this->entries[$e->getZoteroId()] = $e;
48			}
49		}
50	}
51
52	private function createXPath()
53	{
54		$this->xpath = new DomXPath($this->dom);
55		$this->xpath->registerNameSpace("atom", "http://www.w3.org/2005/Atom");
56		$this->xpath->registerNameSpace("zapi", "http://zotero.org/ns/api");
57	}
58
59	/**
60	 * @return ZoteroEntry
61	 */
62	private function createEntry($node)
63	{
64		$zoteroId = $this->parseId($node);
65		$e = new ZoteroEntry($zoteroId);
66		$this->parseData($node, $e);
67		return $e;
68	}
69
70	private function parseItemType($node)
71	{
72		$item = $this->xpath->query("./zapi:itemType", $node)->item(0);
73		if ($item == null)
74		{
75			throw new ZoteroParserException("Zotero item type could not be found in node " . $node);
76		}
77		return $item->nodeValue;
78	}
79
80	private function parseId($node)
81	{
82		$item = $this->xpath->query("./zapi:key", $node)->item(0);
83		if ($item == null)
84		{
85			throw new ZoteroParserException("Zotero ID could not be found in node " . $node);
86		}
87		return $item->nodeValue;
88	}
89
90	private function parseData($node, ZoteroEntry $e)
91	{
92		$item = $this->xpath->query("./atom:content", $node)->item(0);
93		if ($item == null)
94		{
95			throw new ZoteroParserException("Entry content could not be found in node " . $node);
96		}
97		$json = $item->nodeValue;
98		$data = json_decode($json);
99
100		$e->setAuthor($this->parseAuthor($data));
101		if (isset($data->title)) { $e->setTitle(html_entity_decode($data->title)); }
102		if (isset($data->shortTitle)) { $e->setCiteKey(html_entity_decode($data->shortTitle)); }
103		if (isset($data->date)) { $e->setDate(html_entity_decode($data->date)); }
104	}
105
106	private function parseAuthor($data)
107	{
108		if (count($data->creators) == 0)
109		{
110			return "Author not specified";
111		}
112		$authorName = "";
113		$author = $data->creators[0];
114		if (isset($author->firstName) && isset($author->lastName))
115		{
116			$firstName = $author->firstName;
117			$lastName =$author->lastName;
118			$authorFormat = $this->config->getConfig("SourceEntries", "authorFormat");
119			$authorName = str_replace("FIRSTNAME", $firstName, $authorFormat);
120			$authorName = str_replace("LASTNAME", $lastName, $authorName);
121		}
122		elseif (isset($author->name))
123		{
124			$authorName = $author->name;
125		}
126		if ($authorName == "")
127		{
128			return "Author not specified";
129		}
130		if (count($data->creators) > 1)
131		{
132			$authorName .= " et.al.";
133		}
134		return $authorName;
135	}
136}
137?>
138