7 * Micropub endpoint URL
14 * Micropub media endpoint URL
21 * Access token endpoint URL
28 * Authorization endpoint URL
32 public $authorization;
34 public function incomplete()
36 return $this->authorization === null
37 || $this->token === null
38 || $this->micropub === null;
41 public function discover($server)
43 //TODO: discovery via link headers
44 $baseUrl = new \Net_URL2($server);
46 $doc = new \DOMDocument();
47 @$doc->loadHTMLFile($server);
48 $sx = simplexml_import_dom($doc);
50 Log::err('Error loading URL: ' . $server);
53 //$sx->registerXPathNamespace('h', 'http://www.w3.org/1999/xhtml');
56 '/html/head/link[@rel="authorization_endpoint" and @href]'
59 Log::err('No authorization endpoint found at ' . $server);
62 $this->authorization = (string) $baseUrl->resolve(
63 (string) $auths[0]['href']
67 '/html/head/link[@rel="token_endpoint" and @href]'
69 if (!count($tokens)) {
70 Log::err('No token endpoint found');
73 $this->token = (string) $baseUrl->resolve(
74 (string) $tokens[0]['href']
78 '/html/head/link[@rel="micropub" and @href]'
81 Log::err('No micropub endpoint found');
84 $this->micropub = (string) $baseUrl->resolve(
85 (string) $mps[0]['href']
89 public function discoverMedia($accessToken)
91 $configUrl = $this->micropub;
92 if (strpos($configUrl, '?') === false) {
93 $configUrl .= '?q=config';
95 $configUrl .= '&q=config';
98 $ctx = stream_context_create(
102 'Accept: application/json',
103 'Authorization: Bearer ' . $accessToken
108 $json = @file_get_contents($configUrl, false, $ctx);
109 if ($json === false) {
113 $configData = json_decode($json);
114 if ($configData === null) {
115 //json could not be decoded
116 Log::err('micropub configuration is invalid');
119 if (isset($configData->{'media-endpoint'})) {
120 $configUrlObj = new \Net_URL2($configUrl);
121 $this->media = (string) $configUrlObj->resolve(
122 $configData->{'media-endpoint'}
127 public function load($server)
129 $file = $this->getCacheFilePath($server, false);
130 if ($file === false || !file_exists($file)) {
133 $data = parse_ini_file($file);
134 foreach ($data as $prop => $val) {
135 if (!property_exists($this, $prop)) {
136 Log::err('Invalid cache config key "' . $prop . '"');
144 public function save($server)
146 $file = $this->getCacheFilePath($server, true);
147 if ($file === false) {
153 'micropub=' . Config::quoteIniValue($this->micropub) . "\n"
154 . 'media=' . Config::quoteIniValue($this->media) . "\n"
155 . 'token=' . Config::quoteIniValue($this->token) . "\n"
157 . Config::quoteIniValue($this->authorization) . "\n"
161 public function getCacheFilePath($server, $create = false)
163 if (isset($_SERVER['XDG_CACHE_HOME'])
164 && $_SERVER['XDG_CACHE_HOME'] != ''
166 $cacheBaseDir = $_SERVER['XDG_CACHE_HOME'];
168 if (!isset($_SERVER['HOME']) || $_SERVER['HOME'] == '') {
169 Log::err('Cannot determine home directory');
172 $cacheBaseDir = $_SERVER['HOME'] . '/.cache';
175 $cacheDir = $cacheBaseDir . '/shpub';
176 if (!is_dir($cacheDir) && $create) {
177 mkdir($cacheDir, 0700, true);
179 $file = $cacheDir . '/' . urlencode($server) . '.ini';