<?php namespace Depicter\Services; use Averta\Core\Utility\Arr; use Averta\WordPress\Utility\Sanitize; class DocumentFontsV1Service { /** * @var array[] */ private $fonts = []; /** * Get font families * * @param int $documentId The document ID to get belonging faces * @param string $type Repository type of the font. `google`, `typescript`, .. * * @return int[]|string[] */ public function getFamilies( $documentId, $type = 'google' ) { return array_keys( $this->getFontsInfo( $documentId, $type ) ); } /** * Get collected fonts list * * @param int $documentId The document ID to get belonging faces * @param string $type Repository type of the font. `google`, `typescript`, .. * * @return int[]|string[] */ public function getFontsInfo( $documentId, $type = 'google' ) { return ! empty( $this->fonts[ $documentId ][ $type ] ) ? $this->fonts[ $documentId ][ $type ] : []; } /** * Get font faces * * @param int $documentId The document ID to get belonging faces * @param string $type Repository type of the font. `google`, `typescript`, .. * * @return array */ public function getFontsLinkQuery( $documentId, $type = 'google' ) { if( empty( $this->fonts[ $documentId ][ $type ] ) ){ return []; } $fontFaces = []; foreach ( $this->fonts[ $documentId ][ $type ] as $fontNameSlug => $fontInfo ) { if ( $fontNameSlug == 'inherit' ) { continue; } if( 'google' === $type && isset( $this->fonts[ $documentId ]['local'][ $fontNameSlug ] ) ){ continue; } $weights = []; foreach ( $fontInfo['weights'] as $key => $weight ) { $weight = 'regular' == strtolower($weight) ? '400' : $weight; $weights[ $key ] = $weight; } // Sort weight number ascending ksort( $weights ); // Make weight query string for current font $weightQuery = ''; foreach ( $weights as $weightKey => $weight ){ $weightQuery .= $weight . ','; } $weightQuery = rtrim($weightQuery, ','); // Collect font name and weights in a query string $fontFaces[] = $fontInfo['face'] . ':' . $weightQuery; } return $fontFaces; } /** * Add a font to fonts list * * @param int $documentId The document ID that the font belongs to * @param string $fontName Font family name * @param string|array $fontWeight Font weight * @param string $type Repository type of the font. `google`, `typescript`, .. */ public function addFont( $documentId, $fontName, $fontWeight, $type = 'google' ) { if ( empty( $fontName ) ) { return; } $systemFonts = $this->systemFonts(); if ( in_array( $fontName, $systemFonts ) ) { $type = 'system'; } $fontName = str_replace( ['\"', '"'], ['', ''], trim( $fontName ) ); $fontNameSlug = Sanitize::slug( $fontName ); $fontWeight = (array) $fontWeight; $this->initFontForDocument( $documentId ); if ( isset( $this->fonts[ $documentId ][ $type ][ $fontNameSlug ] ) ) { foreach ( $fontWeight as $weight ) { if ( !in_array( $weight, $this->fonts[ $documentId ][ $type ][ $fontNameSlug ]['weights'] ) ) { $this->fonts[ $documentId ][ $type ][ $fontNameSlug ]['weights'][] = $weight; } } } else { $this->fonts[ $documentId ][ $type ][ $fontNameSlug ] = [ 'family' => $fontName, 'face' => str_replace( ' ', '+', $fontName ), 'weights' => $fontWeight ]; } } public function addLocalFont( $documentId, $fontName, $variants = [] ) { if ( empty( $fontName ) ) { return; } $fontName = str_replace( ['\"', '"'], ['', ''], trim( $fontName ) ); $fontNameSlug = Sanitize::slug( $fontName ); $variants = (array) $variants; if ( isset( $this->fonts[ $documentId ][ 'local' ][ $fontNameSlug ] ) ) { $this->fonts[ $documentId ][ 'local' ][ $fontNameSlug ]['variants'] = Arr::merge( $this->fonts[ $documentId ][ 'local' ][ $fontNameSlug ]['variants'], $variants ); } else { $this->fonts[ $documentId ][ 'local' ][ $fontNameSlug ] = [ 'family' => $fontName, 'variants' => $variants ]; } } /** * Generate Css for loading local css fonts * * @param $documentId * * @return string */ public function getLocalFontsCss( $documentId ){ $fontsCss = ""; if( ! empty( $this->fonts[ $documentId ][ 'local' ] ) && is_array( $this->fonts[ $documentId ][ 'local' ] ) ){ foreach( $this->fonts[ $documentId ][ 'local' ] as $key => $fontInfo ){ // Generate font face css style only for local/website fonts which used in the document if ( ! empty( $this->fonts[ $documentId ]['google'] ) && ! in_array( $key, array_keys( $this->fonts[ $documentId ]['google'] ) ) ) { continue; } if( is_array( $fontInfo['variants'] ) ){ foreach( $fontInfo['variants'] as $fontVariant ){ $fontsCss .= "@font-face{\n"; $fontsCss .= !empty( $fontInfo['family'] ) ? "\tfont-family:\"" . $fontInfo['family'] ."\";\n" : ""; $fontsCss .= !empty( $fontVariant['style'] ) ? "\tfont-style:" . $fontVariant['style'] .";\n" : ""; $fontsCss .= !empty( $fontVariant['weight'] ) ? "\tfont-weight:" . $fontVariant['weight'] .";\n" : ""; $fontsCss .= "\tfont-display:fallback;\n"; $fontsCss .= !empty( $fontVariant['src'] ) ? "\tsrc:". str_replace( '"', "'", $fontVariant['src'] ) .";\n" : ""; $fontsCss .= "\tfont-stretch:normal;\n}\n"; } } } } return $fontsCss; } protected function initFontForDocument( $documentId ){ if( ! isset( $this->fonts[ $documentId ] ) ){ $this->fonts[ $documentId ] = [ 'google' => [] ]; } } /** * Add list of fonts to fonts list * * @param int $documentId The document ID that fonts belong to * @param array $fontList * @param string $type */ public function addFonts( $documentId, $fontList, $type = 'google' ) { if ( empty( $fontList ) ) { return; } foreach ( $fontList as $fontName => $fontWeight ){ $this->addFont( $documentId, $fontName, $fontWeight, $type ); } } /** * Get system Fonts * * @return array */ public function systemFonts() { return [ 'Arial', 'Helvetica', 'Times New Roman', 'Georgia', 'Courier New', 'Verdana', 'Tahoma' ]; } /** * Get fonts load link * * @param int $documentId The document ID to get belonging faces * @param string $type Repository type of the font. `google`, `typescript`, .. * * @return bool|string */ public function getFontsLink( $documentId, $type = 'google' ) { if ( $fontsQuery = $this->getFontsLinkQuery( $documentId, $type = 'google' ) ) { $fontsQuery = implode( "|", $fontsQuery ); return 'https://fonts.googleapis.com/css?family=' . $fontsQuery . '&display=swap'; } return ''; } }