*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
if(!defined('DOKU_LF')) define('DOKU_LF', "\n");
require_once(DOKU_PLUGIN.'action.php');
/**
* All DokuWiki plugins to interfere with the event system
* need to inherit from this class
*/
class action_plugin_fontface extends DokuWiki_Action_Plugin {
public function __construct() {
$this->fontSysDir = DOKU_INC.'lib/plugins/fontface/fonts/';
$this->fontDir = DOKU_BASE.'lib/plugins/fontface/fonts/';
}
// register hook
function register(Doku_Event_Handler $controller) {
$controller->register_hook('TPL_METAHEADER_OUTPUT','BEFORE', $this, '_addFontCode');
}
/**
* Add font code (JS and CSS) depending on chosen technique
*
* @param unknown_type $event
* @param unknown_type $param
*/
function _addFontCode(&$event, $param) {
$technique = $this->getConf('technique');
$fontFileName = $this->getConf('fontFile');
$fontFileName2 = $this->getConf('fontFile2');
$fontName = $this->getConf('fontName');
$fontName2 = $this->getConf('fontName2');
// config option 'elements' used to be called 'headings', fallback to old option for backwards-compatibility
$headings = $this->getConf('headings');
$elements = !empty($headings) ? $headings : $this->getConf('elements');
$elements2 = $this->getConf('elements2');
$CSSfiles = array();
$CSSembed = '';
// don't apply anything if no technique is chosen
if (empty($technique)) {
return false;
}
// incomplete sanity check
if (empty($fontName) && empty($fontFileName) && empty($fontName2) && empty($fontFileName2)) {
msg("The FontFace plugin is missing some config settings.", -1);
return false;
}
// prepare CSS and JS to embed depending on the technique
switch ($technique) {
case 'fontface':
$CSSembed .= $this->_getFontFaceCode($fontName, $fontFileName);
$CSSembed .= $this->_getFontFaceCode($fontName2, $fontFileName2);
break;
case 'google':
$CSSfiles[] = $this->_getGoogleFontPath($fontFileName);
$CSSfiles[] = $this->_getGoogleFontPath($fontFileName2);
break;
}
// add styles automatically if elements are given, otherwise set them through CSS as usual
if ( !empty($elements) && !empty($fontName) ) {
$CSSembed .= $elements." { font-family: '".$fontName."', ".$this->getConf('genericFamily')."; }".NL;
}
if ( !empty($elements2) && !empty($fontName2) ) {
$CSSembed .= $elements2." { font-family: '".$fontName2."', ".$this->getConf('genericFamily2')."; }".NL;
}
// include all relevant CSS files
if (!empty($CSSfiles)){
foreach($CSSfiles as $CSSfile) {
$event->data['link'][] = array(
'type' => 'text/css',
'rel' => 'stylesheet',
'media' => 'screen',
'href' => $CSSfile
);
}
}
// embed all relevant CSS code
if (!empty($CSSembed)){
$event->data['style'][] = array(
'type' => 'text/css',
'media' => 'screen',
'_data' => $CSSembed
);
}
}
/**
* Check if file option is set and if it exists
*
* @param string $file File to check (path to system directory)
* @param string $fileDisplay File to display in error message (path to web directory)
* @param string $fileConfig Name of config option
* @return bool If file is okay
*/
function _isFileOk($file, $fileDisplay, $fileConfig) {
if (empty($file)) {
msg("The '".$fileConfig."' config setting is not set.", -1);
return false;
} else if (!file_exists($file)) {
msg("The file ".$fileDisplay." (".$fileConfig.") does not exist.", -1);
return false;
}
return true;
}
/**
* Get code to embed local uploaded font via @font-face
*
* @param string $fontName Name of the font as used in CSS
* @param string $fontFileName File name of the font without extension
* @return mixed String of CSS to embed or Bool if there is nothing to embed
*/
function _getFontFaceCode($fontName, $fontFileName) {
if (empty($fontName) || empty($fontFileName)) {
return false;
}
$fontSysDir = $this->fontSysDir;
$fontDir = $this->fontDir;
$fontEOT = $fontFileName.'.eot';
$fontWOFF = $fontFileName.'.woff';
$fontWOFF2 = $fontFileName.'.woff2';
$fontTTF = $fontFileName.'.ttf';
$fontSVG = $fontFileName.'.svg';
// check if at least ttf and woff files exist
if (!$this->_isFileOk($fontSysDir.$fontWOFF, $fontDir.$fontWOFF, 'fontFile') ||
!$this->_isFileOk($fontSysDir.$fontTTF, $fontDir.$fontTTF, 'fontFile')) {
return false;
}
$CSSembed = "@font-face {".NL.
" font-family: '".$fontName."';".NL;
if (file_exists($fontSysDir.$fontEOT)) {
$CSSembed .= " src: url('".$fontDir.$fontEOT."');".NL;
}
$CSSembed .= " src: ";
if (file_exists($fontSysDir.$fontEOT)) {
$CSSembed .= " url('".$fontDir.$fontEOT."?#iefix') format('embedded-opentype'),".NL;
}
if (file_exists($fontSysDir.$fontWOFF2)) {
$CSSembed .= " url('".$fontDir.$fontWOFF2."') format('woff2'),".NL;
}
$CSSembed .= " url('".$fontDir.$fontWOFF."') format('woff'),".NL;
$CSSembed .= " url('".$fontDir.$fontTTF."') format('truetype')";
if (file_exists($fontSysDir.$fontSVG)) {
$CSSembed .= ",".NL;
$CSSembed .= " url('".$fontDir.$fontSVG."#".str_replace(' ', '', $fontName)."') format('svg')";
}
$CSSembed .= ";".NL.
" font-weight: normal;".NL.
" font-style: normal;".NL.
"}".NL;
return $CSSembed;
}
/**
* Get path to Google font
*
* @param string $fontFileName File name of the font without extension
* @return mixed String of CSS file path to embed or Bool if there is nothing to embed
*/
function _getGoogleFontPath($fontFileName) {
// check if required option is set
if (empty($fontFileName)) {
return false;
}
return 'https://fonts.googleapis.com/css?family='.str_replace(' ', '+', $fontFileName);
}
}
// vim:ts=4:sw=4: