1<?php 2 3if (!defined('DOKU_INC')) { 4 define('DOKU_INC', __DIR__ . '/../../'); 5} 6require_once(DOKU_INC . 'inc/init.php'); 7 8class Manifest { 9 public function run() { 10 $manifest = retrieveConfig('manifest', [$this, 'jsonToArray']); 11 12 global $conf; 13 14 if (empty($manifest['name'])) { 15 $manifest['name'] = $conf['title']; 16 } 17 18 if (empty($manifest['short_name'])) { 19 $manifest['short_name'] = $conf['title']; 20 } 21 22 if (empty($manifest['description'])) { 23 $manifest['description'] = $conf['tagline']; 24 } 25 26 if (empty($manifest['start_url'])) { 27 $manifest['start_url'] = DOKU_REL; 28 } 29 30 $styleUtil = new \dokuwiki\StyleUtils(); 31 $styleIni = $styleUtil->cssStyleini($conf['template']); 32 $replacements = $styleIni['replacements']; 33 34 if (empty($manifest['background_color'])) { 35 $manifest['background_color'] = $replacements['__background__']; 36 } 37 38 if (empty($manifest['theme_color'])) { 39 $manifest['theme_color'] = !empty($replacements['__theme_color__']) ? $replacements['__theme_color__'] : $replacements['__background_alt__']; 40 } 41 42 if (empty($manifest['icons'])) { 43 $manifest['icons'] = []; 44 $look = [ 45 ':wiki:logo.png', 46 ':logo.png', 47 'images/logo.png', 48 ':wiki:apple-touch-icon.png', 49 ':apple-touch-icon.png', 50 'images/apple-touch-icon.png', 51 ':wiki:favicon.svg', 52 ':favicon.svg', 53 'images/favicon.svg', 54 ':wiki:favicon.ico', 55 ':favicon.ico', 56 'images/favicon.ico', 57 ':wiki:logo', 58 ]; 59 60 $abs = true; 61 foreach($look as $img) { 62 if($img[0] === ':') { 63 $file = mediaFN($img); 64 $ismedia = true; 65 } else { 66 $file = tpl_incdir().$img; 67 $ismedia = false; 68 } 69 70 if (file_exists($file)) { 71 $imginfo = getimagesize($file); 72 if($ismedia) { 73 $url = ml($img, '', true, '', $abs); 74 } else { 75 $url = tpl_basedir().$img; 76 if($abs) $url = DOKU_URL.substr($url, strlen(DOKU_REL)); 77 } 78 $manifest['icons'][] = [ 79 'src' => $url, 80 'sizes' => $imginfo[0] . 'x' . $imginfo[1], 81 'type' => $imginfo['mime'], 82 ]; 83 }; 84 } 85 } 86 87 trigger_event('MANIFEST_SEND', $manifest); 88 89 header('Content-Type: application/manifest+json'); 90 echo json_encode($manifest); 91 } 92 93 public function jsonToArray($file) 94 { 95 $json = file_get_contents($file); 96 97 $conf = json_decode($json, true); 98 99 $jsonError = json_last_error(); 100 if (!is_array($conf) && $jsonError !== JSON_ERROR_NONE) { 101 102 switch ($jsonError) { 103 case JSON_ERROR_DEPTH: 104 $jsonErrorText = 'The maximum stack depth has been exceeded'; 105 break; 106 case JSON_ERROR_STATE_MISMATCH: 107 $jsonErrorText = 'Invalid or malformed JSON'; 108 break; 109 case JSON_ERROR_CTRL_CHAR: 110 $jsonErrorText = 'Control character error, possibly incorrectly encoded'; 111 break; 112 case JSON_ERROR_SYNTAX: 113 $jsonErrorText = 'Syntax error'; 114 break; 115 case JSON_ERROR_UTF8: 116 $jsonErrorText = 'Malformed UTF-8 characters, possibly incorrectly encoded'; 117 break; 118 case JSON_ERROR_RECURSION: 119 $jsonErrorText = 'One or more recursive references in the value to be encoded'; 120 break; 121 case JSON_ERROR_INF_OR_NAN: 122 $jsonErrorText = 'One or more NAN or INF values in the value to be encoded'; 123 break; 124 case JSON_ERROR_UNSUPPORTED_TYPE: 125 $jsonErrorText = 'A value of a type that cannot be encoded was given'; 126 break; 127 case JSON_ERROR_INVALID_PROPERTY_NAME: 128 $jsonErrorText = 'A property name that cannot be encoded was given'; 129 break; 130 case JSON_ERROR_UTF16: 131 $jsonErrorText = 'Malformed UTF-16 characters, possibly incorrectly encoded'; 132 break; 133 default: 134 $jsonErrorText = 'Unknown Error Code'; 135 } 136 137 trigger_error('JSON decoding error "' . $jsonErrorText . '" for file ' . $file, E_USER_WARNING); 138 return []; 139 } 140 141 return $conf; 142 } 143} 144 145$manifest = new Manifest(); 146$manifest->run(); 147