1<?php
2require_once('ZoteroEntryNotFoundException.php');
3
4class TextZoteroRepository extends ZoteroRepository
5{
6	const COLUMN_ID = 1;
7	const COLUMN_SHORT_TITLE = 2;
8	const COLUMN_TITLE = 3;
9	const COLUMN_AUTHOR = 4;
10	const COLUMN_DATE = 5;
11
12	const HEADER = "|**Zotero ID**|**Short Name**|**Title**|**Author**|**Date**|**Info**|";
13
14	private $fileName;
15	private $config;
16
17	public function __construct($fileName, ZoteroConfig $config)
18	{
19		$this->fileName = $fileName;
20		$this->config = $config;
21		$fileContents = file_get_contents($fileName);
22		$this->parseEntries($fileContents);
23	}
24
25	private function parseEntries($fileContents)
26	{
27		foreach (explode("\n", $fileContents) as $line)
28		{
29			$e = $this->parseLine($line);
30			if ($e != null)
31			{
32				$this->entries[$e->getZoteroId()] = $e;
33			}
34		}
35	}
36
37	/**
38	 * @return ZoteroEntry
39	 */
40	private function parseLine($line)
41	{
42		$line = trim($line);
43
44		if ($line == "" || $line == self::HEADER)
45		{
46			return null;
47		}
48
49		$line = $this->extractZoteroKey($line);
50		$columns = explode("|", $line);
51
52		if (count($columns) != 8)
53		{
54			return null;
55		}
56
57		$e = new ZoteroEntry($columns[self::COLUMN_ID]);
58		$e->setAuthor($columns[self::COLUMN_AUTHOR]);
59		$e->setCiteKey($columns[self::COLUMN_SHORT_TITLE]);
60		$e->setDate($columns[self::COLUMN_DATE]);
61		$e->setTitle($columns[self::COLUMN_TITLE]);
62		return $e;
63	}
64
65	private function extractZoteroKey($text)
66	{
67		$matches = array();
68		if (preg_match("/\[\[.*\|(.*)\]\]/", $text, $matches))
69		{
70			$text = str_replace($matches[0], $matches[1], $text);
71		}
72		return $text;
73	}
74
75	public function updateAndSaveEntries(array $newEntries)
76	{
77		foreach ($newEntries as $id => $newEntry)
78		{
79			$this->entries[$id] = $newEntry;
80		}
81
82		$allEntries = array();
83		foreach ($this->entries as $entry)
84		{
85			$allEntries[$entry->getCiteKey()] = $entry;
86		}
87		ksort($allEntries);
88		$this->saveAllEntriesToFile($allEntries);
89	}
90
91	private function saveAllEntriesToFile($entries)
92	{
93		$text = self::HEADER . "\n";
94		foreach ($entries as $e)
95		{
96			$text .= $this->serializeEntry($e);
97		}
98		file_put_contents($this->fileName, $text);
99	}
100
101	private function serializeEntry(ZoteroEntry $e)
102	{
103		$problem = "";
104		$title = preg_replace("/[\n\r\t ]{2,}/", " ", $e->getTitle());
105		if ($title != $e->getTitle()) { $problem .= "White space in title. "; }
106		$citeKey = trim($e->getCiteKey()) . ($e->getCiteKey() == "" ? " " : "");
107		if ($citeKey === "") { $problem .= "Empty short title/cite key. "; }
108		$citeKeyCount = $this->countCiteKey($e);
109		if ($citeKeyCount > 1) { $problem .= "Multiple usages of short title/cite key (" . $citeKeyCount . "). "; }
110
111		if ($problem != "")
112		{
113			 $problem = "Problem(s): " . $problem;
114		}
115		else
116		{
117			$problem = " ";
118		}
119		$entryUrl = $this->config->getUrlForEntry($e);
120
121		return
122			"|" .
123			"[[" . $entryUrl . "|" . $e->getZoteroId() . "]]" . "|" .
124			$citeKey . "|" .
125			$title . "|" .
126			$e->getAuthor() . "|" .
127			$e->getDate() . ($e->getDate() == "" ? " " : "") . "|" .
128			$problem .
129			"|\n";
130	}
131
132	private function countCiteKey(ZoteroEntry $e)
133	{
134		$count = 0;
135		foreach ($this->entries as $entry)
136		{
137			if ($entry->getCiteKey() === $e->getCiteKey())
138			{
139				$count++;
140			}
141		}
142		return $count;
143	}
144}
145?>
146