1 <?php
2 require_once('ZoteroEntryNotFoundException.php');
3 
4 class 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