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