canonical redirect for entries with trailing slash
[mdref/mdref] / mdref / Repo.php
1 <?php
2
3 namespace mdref;
4
5
6 /**
7 * A reference repo
8 */
9 class Repo implements \IteratorAggregate {
10 /**
11 * The name of the repository
12 * @var string
13 */
14 private $name;
15
16 /**
17 * The path to the repository
18 * @var string
19 */
20 private $path;
21
22 /**
23 * The edit url template
24 * @var string
25 */
26 private $edit;
27
28 /**
29 * Path to the repository containing the name.mdref file
30 * @param string $path
31 * @throws \InvalidArgumentException
32 */
33 public function __construct($path) {
34 if (!($mdref = current(glob("$path/*.mdref")))) {
35 throw new \InvalidArgumentException(
36 sprintf("Not a reference, could not find '*.mdref': '%s'",
37 $path));
38 }
39
40 $this->path = realpath($path);
41 $this->name = basename($mdref, ".mdref");
42 $this->edit = trim(file_get_contents($mdref));
43 }
44
45 /**
46 * Get the repository's name
47 * @return string
48 */
49 public function getName() {
50 return $this->name;
51 }
52
53 /**
54 * Get the path of the repository or a file in it
55 * @param string $file
56 * @return string
57 */
58 public function getPath($file = "") {
59 return $this->path . "/$file";
60 }
61
62 /**
63 * Get the edit url for a ref entry
64 * @param string $entry
65 * @return string
66 */
67 public function getEditUrl($entry) {
68 return sprintf($this->edit, $entry);
69 }
70
71 /**
72 * Get the file path of an entry in this repo
73 * @param string $entry
74 * @return string file path
75 */
76 public function hasEntry($entry, &$canonical = null) {
77 $trim = rtrim($entry, "/");
78 $file = $this->getPath("$trim.md");
79 if (is_file($file)) {
80 if ($trim !== $entry) {
81 $canonical = $trim;
82 }
83 return $file;
84 }
85 $file = $this->getPath($this->getName()."/$entry.md");
86 if (is_file($file)) {
87 $canonical = $this->getName() . "/" . $entry;
88 return $file;
89 }
90 }
91
92 /**
93 * Get the canonical entry name of a file in this repo
94 * @param string $file
95 * @return string entry
96 */
97 public function hasFile($file) {
98 if (($file = realpath($file))) {
99 $path = $this->getPath();
100 $plen = strlen($path);
101 if (!strncmp($file, $path, $plen)) {
102 $dirname = dirname(substr($file, $plen));
103 $basename = basename($file, ".md");
104
105 if ($dirname === ".") {
106 return $basename;
107 }
108
109 return $dirname . "/". $basename;
110 }
111 }
112 }
113
114 /**
115 * Get an Entry instance
116 * @param string $entry
117 * @return \mdref\Entry
118 * @throws \OutOfBoundsException
119 */
120 public function getEntry($entry) {
121 return new Entry($entry, $this);
122 }
123
124 /**
125 * Get the root Entry instance
126 * @return \mdref\Entry
127 */
128 public function getRootEntry() {
129 return new Entry($this->name, $this);
130 }
131
132 /**
133 * Implements \IteratorAggregate
134 * @return \mdref\Tree
135 */
136 public function getIterator() {
137 return new Tree($this->path, $this);
138 }
139 }