File Manager

Current Directory: /home/astoriaah/www/templates/yootheme/vendor/yootheme/theme/modules/styler/src
Viewing File: /home/astoriaah/www/templates/yootheme/vendor/yootheme/theme/modules/styler/src/StyleFontLoader.php
<?php namespace YOOtheme\Theme; use YOOtheme\ContainerTrait; use YOOtheme\Util\Path; class StyleFontLoader { use ContainerTrait; const PREFIX = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 '; /** * @var string */ public $cache; /** * @var array */ public $inject = [ 'http' => 'app.http', ]; /** * @var array */ public $formats = [ 'woff2' => self::PREFIX.'Edge/16.246', 'woff' => self::PREFIX.'Edge/12.246', ]; /** * Constructor. * * @param string $cache */ public function __construct($cache) { // create cache dir if (!is_dir($cache)) { mkdir($cache, 0777, true); } $this->cache = $cache; } /** * Creates CSS markup. * * @param string $url * @param string $basePath * @return string */ public function css($url, $basePath) { $date = date(DATE_W3C); $hash = hash('crc32b', "$url, $basePath"); $file = "{$this->cache}/font-{$hash}.css"; // is already cached? if (file_exists($file)) { return file_get_contents($file); } // load font url $fonts = $this->load($url); $relative = function ($path) use ($basePath) { return Path::relative($path, $basePath); }; // relative font path foreach ($fonts as &$font) { $font['src'] = array_map($relative, $font['src']); } // generate fonts css $data = "/* {$url} generated on {$date} */\n"; $data .= join(array_map([$this, 'cssFontFace'], $fonts)); // save file in cache if ($fonts && @file_put_contents($file, $data)) { return $data; } } /** * Creates a single @font-face CSS markup. * * @param array $font * @return string */ public function cssFontFace(array $font) { $output = '@font-face {'; foreach ($font as $name => $value) { if ($name == 'src') { $urls = []; foreach ($value as $format => $url) { $urls[] = "url({$url}) format('{$format}')"; } $value = join(', ', $urls); } $output .= "{$name}: {$value}; "; } return "$output}\n"; } /** * Loads fonts from url. * * @param string $url * @return string */ public function load($url) { $fonts = []; // load font formats based on user agents foreach ($this->formats as $userAgent) { $options = compact('userAgent'); $response = $this->http->get($url, $options); if ($result = $this->parseFonts($response->getBody())) { $fonts = array_replace_recursive($fonts, $result); } } // load fonts and save them foreach ($fonts as &$font) { $font['src'] = array_map([$this, 'loadFont'], $font['src']); } return $fonts; } /** * Load font file from url. * * @param string $url * @param array $options * @return string */ public function loadFont($url, array $options = []) { $hash = hash('crc32b', $url); $type = pathinfo($url, PATHINFO_EXTENSION); $file = "{$this->cache}/font-{$hash}.{$type}"; // is already cached? if (file_exists($file)) { return $file; } // load font from url $data = $this->http->get($url, $options); // save file in cache if (@file_put_contents($file, $data->getBody())) { return $file; } } /** * Parses font @import from source. * * @param string $source * @return array */ public function parse($source) { return preg_match('/@import\s+url\((https?:\/\/fonts\.googleapis\.com[^)]+)\)\s*;?/i', $source, $matches) ? $matches : []; } /** * Parses fonts url from source. * * @param string $source * @return array */ public function parseFonts($source) { $fonts = []; foreach ($this->parseFontFaces($source) as $fontface) { $font = $src = []; foreach ($this->parseFontProperties($fontface) as $name => $value) { if ($name == 'src') { $src = $this->parseFontSrc($value); } else { $font[$name] = $value; } } if ($src) { $hash = hash('crc32b', json_encode($font)); $fonts[$hash] = array_merge($font, compact('src')); } } return $fonts; } /** * Parses font url from source. * * @param string $source * @return array */ public function parseFontSrc($source) { return preg_match('/url\((https?:\/\/.+?)\)\s*format\(\'?(\w+)/', $source, $matches) ? [$matches[2] => $matches[1]] : []; } /** * Parses @font-face from source. * * @param string $source * @return array */ public function parseFontFaces($source) { return preg_match_all('/@font-face\s*{\s*([^}]+)/', $source, $matches) ? $matches[1] : []; } /** * Parses properties from source. * * @param string $source * @return array */ public function parseFontProperties($source) { return preg_match_all('/([\w-]+)\s*:\s*([^;]+)/', $source, $matches) ? array_combine($matches[1], $matches[2]) : []; } }