1<?php 2/** 3 * DokuWiki Action Plugin FontFace 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Anika Henke <anika@selfthinker.org> 7 */ 8// must be run within Dokuwiki 9if(!defined('DOKU_INC')) die(); 10 11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 12if(!defined('DOKU_LF')) define('DOKU_LF', "\n"); 13 14require_once(DOKU_PLUGIN.'action.php'); 15 16/** 17 * All DokuWiki plugins to interfere with the event system 18 * need to inherit from this class 19 */ 20class action_plugin_fontface extends DokuWiki_Action_Plugin { 21 22 public function __construct() { 23 $this->fontSysDir = DOKU_INC.'lib/plugins/fontface/fonts/'; 24 $this->fontDir = DOKU_BASE.'lib/plugins/fontface/fonts/'; 25 } 26 27 // register hook 28 function register(Doku_Event_Handler $controller) { 29 $controller->register_hook('TPL_METAHEADER_OUTPUT','BEFORE', $this, '_addFontCode'); 30 } 31 32 /** 33 * Add font code (JS and CSS) depending on chosen technique 34 * 35 * @param unknown_type $event 36 * @param unknown_type $param 37 */ 38 function _addFontCode(&$event, $param) { 39 40 $technique = $this->getConf('technique'); 41 $fontFileName = $this->getConf('fontFile'); 42 $fontFileName2 = $this->getConf('fontFile2'); 43 $fontName = $this->getConf('fontName'); 44 $fontName2 = $this->getConf('fontName2'); 45 // config option 'elements' used to be called 'headings', fallback to old option for backwards-compatibility 46 $headings = $this->getConf('headings'); 47 $elements = !empty($headings) ? $headings : $this->getConf('elements'); 48 $elements2 = $this->getConf('elements2'); 49 50 $CSSfiles = array(); 51 $CSSembed = ''; 52 53 // don't apply anything if no technique is chosen 54 if (empty($technique)) { 55 return false; 56 } 57 58 // incomplete sanity check 59 if (empty($fontName) && empty($fontFileName) && empty($fontName2) && empty($fontFileName2)) { 60 msg("The FontFace plugin is missing some config settings.", -1); 61 return false; 62 } 63 64 // prepare CSS and JS to embed depending on the technique 65 switch ($technique) { 66 case 'fontface': 67 $CSSembed .= $this->_getFontFaceCode($fontName, $fontFileName); 68 $CSSembed .= $this->_getFontFaceCode($fontName2, $fontFileName2); 69 break; 70 71 case 'google': 72 $CSSfiles[] = $this->_getGoogleFontPath($fontFileName); 73 $CSSfiles[] = $this->_getGoogleFontPath($fontFileName2); 74 break; 75 } 76 77 // add styles automatically if elements are given, otherwise set them through CSS as usual 78 if ( !empty($elements) && !empty($fontName) ) { 79 $CSSembed .= $elements." { font-family: '".$fontName."', ".$this->getConf('genericFamily')."; }".NL; 80 } 81 if ( !empty($elements2) && !empty($fontName2) ) { 82 $CSSembed .= $elements2." { font-family: '".$fontName2."', ".$this->getConf('genericFamily2')."; }".NL; 83 } 84 85 // include all relevant CSS files 86 if (!empty($CSSfiles)){ 87 foreach($CSSfiles as $CSSfile) { 88 $event->data['link'][] = array( 89 'type' => 'text/css', 90 'rel' => 'stylesheet', 91 'media' => 'screen', 92 'href' => $CSSfile 93 ); 94 } 95 } 96 // embed all relevant CSS code 97 if (!empty($CSSembed)){ 98 $event->data['style'][] = array( 99 'type' => 'text/css', 100 'media' => 'screen', 101 '_data' => $CSSembed 102 ); 103 } 104 105 } 106 107 /** 108 * Check if file option is set and if it exists 109 * 110 * @param string $file File to check (path to system directory) 111 * @param string $fileDisplay File to display in error message (path to web directory) 112 * @param string $fileConfig Name of config option 113 * @return bool If file is okay 114 */ 115 function _isFileOk($file, $fileDisplay, $fileConfig) { 116 if (empty($file)) { 117 msg("The '<strong>".$fileConfig."</strong>' config setting is <strong>not set</strong>.", -1); 118 return false; 119 } else if (!file_exists($file)) { 120 msg("The file <strong>".$fileDisplay."</strong> (".$fileConfig.") <strong>does not exist</strong>.", -1); 121 return false; 122 } 123 return true; 124 } 125 126 /** 127 * Get code to embed local uploaded font via @font-face 128 * 129 * @param string $fontName Name of the font as used in CSS 130 * @param string $fontFileName File name of the font without extension 131 * @return mixed String of CSS to embed or Bool if there is nothing to embed 132 */ 133 function _getFontFaceCode($fontName, $fontFileName) { 134 if (empty($fontName) || empty($fontFileName)) { 135 return false; 136 } 137 138 $fontSysDir = $this->fontSysDir; 139 $fontDir = $this->fontDir; 140 $fontEOT = $fontFileName.'.eot'; 141 $fontWOFF = $fontFileName.'.woff'; 142 $fontWOFF2 = $fontFileName.'.woff2'; 143 $fontTTF = $fontFileName.'.ttf'; 144 $fontSVG = $fontFileName.'.svg'; 145 146 // check if at least ttf and woff files exist 147 if (!$this->_isFileOk($fontSysDir.$fontWOFF, $fontDir.$fontWOFF, 'fontFile') || 148 !$this->_isFileOk($fontSysDir.$fontTTF, $fontDir.$fontTTF, 'fontFile')) { 149 return false; 150 } 151 152 $CSSembed = "@font-face {".NL. 153 " font-family: '".$fontName."';".NL; 154 if (file_exists($fontSysDir.$fontEOT)) { 155 $CSSembed .= " src: url('".$fontDir.$fontEOT."');".NL; 156 } 157 $CSSembed .= " src: "; 158 if (file_exists($fontSysDir.$fontEOT)) { 159 $CSSembed .= " url('".$fontDir.$fontEOT."?#iefix') format('embedded-opentype'),".NL; 160 } 161 if (file_exists($fontSysDir.$fontWOFF2)) { 162 $CSSembed .= " url('".$fontDir.$fontWOFF2."') format('woff2'),".NL; 163 } 164 $CSSembed .= " url('".$fontDir.$fontWOFF."') format('woff'),".NL; 165 $CSSembed .= " url('".$fontDir.$fontTTF."') format('truetype')"; 166 if (file_exists($fontSysDir.$fontSVG)) { 167 $CSSembed .= ",".NL; 168 $CSSembed .= " url('".$fontDir.$fontSVG."#".str_replace(' ', '', $fontName)."') format('svg')"; 169 } 170 $CSSembed .= ";".NL. 171 " font-weight: normal;".NL. 172 " font-style: normal;".NL. 173 "}".NL; 174 return $CSSembed; 175 } 176 177 /** 178 * Get path to Google font 179 * 180 * @param string $fontFileName File name of the font without extension 181 * @return mixed String of CSS file path to embed or Bool if there is nothing to embed 182 */ 183 function _getGoogleFontPath($fontFileName) { 184 // check if required option is set 185 if (empty($fontFileName)) { 186 return false; 187 } 188 return 'https://fonts.googleapis.com/css?family='.str_replace(' ', '+', $fontFileName); 189 } 190 191} 192 193// vim:ts=4:sw=4: 194