ex . "/s", $content, $matches ); if( is_array( $matches ) && is_array( $matches[1] ) && ( ! empty( $matches[1] ) ) ) { $matches = $matches[1]; } else { return false; } /** * We take the first valid name as key - or filename if user has started filename with $this->custom_font_prefix */ $first_name = ''; $first_file = ''; /** * Split file info and store in array */ foreach( $matches as $file_info ) { // $file_info = str_replace( array( '{', '}' ), '', $file_info ); $lines = preg_split( '/\n|\r/', $file_info, -1, PREG_SPLIT_NO_EMPTY ); $info = array( 'name' => '', 'style' => 'normal', 'weight' => 400, 'filename' => '', 'full_name' => '', 'files' => array() // 'ttf' => 'filename' ); foreach ( $lines as $line ) { $line = explode( ':', $line ); $key = trim( str_replace( array( '"', '\'' ), '', $line[0] ) ); if( empty( $key ) || ! isset( $info[ $key ] ) ) { continue; } $info[ $key ] = isset( $line[1] ) ? trim( str_replace( array( '"', '\'' ), '', $line[1] ) ) : ''; if( 'filename' == $key ) { $info[ $key ] = strtolower( $info[ $key ] ); } } if( empty( $info['filename'] ) ) { continue; } $orig_file = trailingslashit( $path ) . $info['filename']; if( ! file_exists( $orig_file ) ) { continue; } /** * Set the font name */ if( ( $info['name'] != '' ) && ( '' == $first_name ) ) { $first_name = $info['name']; } $path_parts = pathinfo( $orig_file ); if( '' == $first_file ) { $first_file = $path_parts['filename']; } /** * Get all allowed font files */ $fs = glob( trailingslashit( $path ) . $path_parts['filename'] . '.*' ); foreach ( $fs as $f ) { $fp = pathinfo( $f ); if( in_array( $fp['extension'], $this->file_ext ) ) { $info['files'][ $fp['extension'] ] = $fp['basename']; } } $meta[] = $info; } if( '' == $first_name ) { $first_name = ucfirst( $first_file ); } /** * Set first entry to */ foreach ( $meta as $key => &$value ) { if( ( 0 == $key ) || ( '' == $value['name'] ) ) { $value['name'] = $first_name; } if( '' == $value['full_name'] ) { $value['full_name'] = $value['name']; } } unset( $value ); $meta['key'] = AviaHelper::save_string( strtolower( $first_name ), '-' ); return $meta; } /** * Scans the files in given directory and creates the metadata info array for DB * * @since 4.3 * @param string $temp_path * @param string $font_name * @return array|false */ protected function scan_font_files( $temp_path, $font_name ) { $meta = array(); $fonts = array(); $files = scandir( $temp_path ); if( false === $files ) { return false; } $files = array_diff( $files, array( '..', '.' ) ); foreach( $files as $file ) { $split = pathinfo( $file ); if( isset( $fonts[ $split['filename'] ] ) ) { $fonts[ $split['filename'] ][ $split['extension'] ] = $split['basename']; } else { $fonts[ $split['filename'] ] = array( $split['extension'] => $split['basename'] ); } } foreach( $fonts as $font => $files ) { $pos = strrpos( $font, '-' ); $style = ( $pos !== false ) ? substr( $font, $pos + 1 ) : ''; $style_info = isset( $this->google_fonts_def[ $style ] ) ? $this->google_fonts_def[ $style ] : array( 400, 'normal' ); $filename = isset( $files['ttf'] ) ? $files['ttf'] : ''; if( empty( $filename ) ) { foreach ($files as $fn ) { $filename = $fn; break; } } $meta[] = array( 'name' => $font_name, 'style' => $style_info[1], 'weight' => $style_info[0], 'filename' => $filename, 'full_name' => $font_name, 'files' => $files // 'ttf' => 'filename' ); } $meta['key'] = AviaHelper::save_string( strtolower( $font_name ), '-' ); return $meta; } /** * Add a font to the options array of uploaded fonts * * @since 4.3 * @param array $font_info */ protected function add_font( array $font_info ) { $fonts = $this->get_font_list(); $fonts[ $font_info['key'] ] = array( 'folder' => trailingslashit( $this->upload_paths['fonts'] ) . $font_info['key'], 'config' => $font_info, 'origin_url' => trailingslashit( $this->upload_paths['baseurl'] ), 'origin_dir' => trailingslashit( $this->upload_paths['basedir'] ) ); /** * Sort array by font name */ $names = array(); foreach ( $fonts as $key => $value ) { $names[ $key ] = $value['config'][0]['name']; } asort( $names ); $sorted = array(); foreach ($names as $key => $name ) { $sorted[ $key ] = $fonts[ $key ]; } $this->update_font_list( $sorted ); } /** * Remove the font from font list and from server - remove the directory * * @since 4.3 * @param string $font_id * @return boolean */ protected function remove_font( $font_id ) { $fonts = $this->get_font_list(); if( ! isset( $fonts[ $font_id ] ) ) { return true; } avia_backend_delete_folder( $fonts[ $font_id ]['origin_dir'] . $fonts[ $font_id ]['folder'] ); unset( $fonts[ $font_id ] ); $this->update_font_list( $fonts ); return true; } /** * Add additional info about added fonts and a delete link below standard upload button * * @since 4.3 * @param string $output * @param array $element * @return string */ public function handler_add_font_manager_upload( $output, array $element ) { if( $element['id'] != 'typefont_upload' ) { return $output; } $fonts = $this->get_font_list(); $output .= "
"; foreach( $fonts as $font_info ) { $output .= $this->backend_font_info( $font_info['config'] ); } $output .= "
"; return $output; } /** * Returns the HTML div for a custom type font to display below upload button list * * @since 4.3 * @param array $font_info * @return string */ protected function backend_font_info( array $font_info ) { $fonts = array(); $font_key = ''; $font_name = ''; foreach( $font_info as $key => $info ) { if( 'key' === $key ) { $font_key = $info; continue; } if( 0 === $key ) { $font_name = $info['name']; } if( ! isset( $fonts[ $info['style'] ] ) ) { $fonts[ $info['style'] ] = array(); } $fonts[ $info['style'] ][] = $info['weight']; } foreach( $fonts as $style => $values ) { $values = array_unique( $values ); sort( $values, SORT_NATURAL | SORT_FLAG_CASE ); $fonts[ $style ] = $values; } $html = ''; $html .= "
"; $html .= '
'; $html .= '' . __( 'Font: ', 'avia_framework' ) . $font_name . ''; $html .= ' ( font-family: ' . $font_key . ' )'; $html .= '
'; $html .= '
'; foreach( $fonts as $style => $values ) { $html .= '
'; $html .= '' . $style . ': '; $html .= '' . implode( ', ', $values ) . ''; $html .= '
'; } $html .= '
'; $html .= '
'; $html .= "" . __( 'Delete', 'avia_framework' ) . ""; $html .= '
'; $html .= '
'; return $html; } /** * Returns a list of Google Fonts that can be merged in the select box for selecting fonts * * For enhancements see: https://fonts.google.com/ * @since 4.3 * @return array */ public function google_fonts_select_list() { $fonts = array( 'Advent Pro' => 'Advent Pro:100,400,600', 'Alice' => 'Alice', 'Allerta' => 'Allerta', 'Arvo' => 'Arvo', 'Arimo' => 'Arimo:400,700', 'Antic' => 'Antic', 'Audiowide' => 'Audiowide', 'Bad Script' => 'Bad Script', 'Baumans' => 'Baumans', 'Bangers' => 'Bangers', 'Barlow' => 'Barlow:400,500,600,700', 'Bitter' => 'Bitter', 'Cabin' => 'Cabin', 'Cardo' => 'Cardo', 'Carme' => 'Carme', 'Caveat' => 'Caveat:400,700', 'Coda' => 'Coda', 'Codystar' => 'Codystar:300,400', 'Cormorant Garamond' => 'Cormorant Garamond:300,400,700', 'Comfortaa' => 'Comfortaa:300,400,700', 'Coustard' => 'Coustard', 'Gruppo' => 'Gruppo', 'Damion' => 'Damion', 'Dancing Script' => 'Dancing Script', 'Droid Sans' => 'Droid Sans', 'Droid Serif' => 'Droid Serif', 'EB Garamond' => 'EB Garamond', 'Exo' => 'Exo:900,700,400,100', 'Finger Paint' => 'Finger Paint', 'Fira Sans' => 'Fira Sans:100,400,700', 'Fjord One' => 'Fjord One', 'Flamenco' => 'Flamenco:400,300', 'Great Vibes' => 'Great Vibes', 'Heebo' => 'Heebo:100,400,700', 'Herr Von Muellerhoff' => 'Herr Von Muellerhoff', 'IBM Plex Serif' => 'IBM Plex Serif:300,400,700', 'Inconsolata' => 'Inconsolata', 'Josefin Sans' => 'Josefin Sans', 'Josefin Slab' => 'Josefin Slab', 'Kameron' => 'Kameron', 'Karla' => 'Karla:400,700', 'Kreon' => 'Kreon', 'Lato' => 'Lato:300,400,700', 'Lobster' => 'Lobster', 'Lora' => 'Lora', 'League Script' => 'League Script', 'Mate SC' => 'Mate SC', 'Marck Script' => 'Marck Script', 'Mako' => 'Mako', 'Megrim' => 'Megrim', 'Merienda' => 'Merienda:400,700', 'Merriweather' => 'Merriweather:300,400,700', 'Metrophobic' => 'Metrophobic', 'Molengo' => 'Molengo', 'Montserrat' => 'Montserrat', 'Muli' => 'Muli', 'Nixie One' => 'Nixie One', 'Nobile' => 'Nobile', 'News Cycle' => 'News Cycle', 'Open Sans' => 'Open Sans:400,600', 'Open Sans Condensed' => 'Open Sans Condensed:300,700', 'Orbitron' => 'Orbitron', 'Oregano' => 'Oregano', 'Oswald' => 'Oswald', 'Pacifico' => 'Pacifico', 'Parisienne' => 'Parisienne', 'Petit Formal Script' => 'Petit Formal Script', 'Pinyon Script' => 'Pinyon Script', 'Playfair Display' => 'Playfair Display:400,700', 'Podkova' => 'Podkova', 'Poiret One' => 'Poiret One', 'Poly' => 'Poly', 'Press Start 2P (Retro Pixelfont)' => 'Press Start 2P', 'PT Sans' => 'PT Sans', 'Quattrocento' => 'Quattrocento', 'Questrial' => 'Questrial', 'Quicksand' => 'Quicksand:400,600', 'Raleway' => 'Raleway', 'Righteous' => 'Righteous', 'Roboto' => 'Roboto:100,400,700', 'Sacramento' => 'Sacramento', 'Salsa' => 'Salsa', 'Signika Negative' => 'Signika Negative', 'Source Serif Pro' => 'Source Serif Pro:400,600,700', 'Sunshiney' => 'Sunshiney', 'Special Elite' => 'Special Elite', 'Tangerine' => 'Tangerine', 'Terminal Dosis' => 'Terminal Dosis', 'Tenor Sans' => 'Tenor Sans', 'Varela Round' => 'Varela Round', 'Work Sans' => 'Work Sans:700,400,100', 'Yellowtail' => 'Yellowtail', ); /** * Kept for backwards compatibility - will be replaced by next filter */ $fonts = apply_filters('avf_google_heading_font', $fonts ); /** * @since 4.3 * @return array */ $fonts = apply_filters('avf_available_google_fonts', $fonts ); return $fonts; } /** * Returns a list of websafe fonts that can be merged in the select box for selecting fonts * Keys are extended by -websave at the end to be able to recognise them before the array is returned * * For enhancements see https://www.cssfontstack.com/ * * @since 4.3 * @return array */ public function websafe_fonts_select_list() { $fonts = array( 'Arial' => 'Arial', 'Arial Black' => 'Arial-Black', 'Arial Narrow' => 'Arial-Narrow', 'Helvetica' => 'Helvetica', 'Helvetica Neue' => 'Helvetica-Neue,Helvetica', 'Lucida Sans' => 'Lucida-Sans,Lucida-Grande,Lucida-Sans-Unicode', 'Tahoma' => 'Tahoma', 'Trebuchet MS' => 'Trebuchet-MS', 'Verdana' => 'Verdana', 'Georgia' => 'Georgia', 'Lucida Bright' => 'Lucida-Bright', 'Palatino' => 'Palatino', 'Times New Roman' => 'Times-New-Roman', 'Courier New' => 'Courier-New', 'Lucida Sans Typewriter' => 'Lucida-Sans-Typewriter', 'Copperplate' => 'Copperplate', 'Papyrus' => 'Papyrus', 'Brush Script MT' => 'Brush-Script-MT' ); /** * @since 4.3 */ $fonts = apply_filters('avf_available_websafe_fonts', $fonts ); foreach( $fonts as $key => $value ) { if( false === ( strpos( $value, '-websafe' ) ) ) { $value .= '-websave'; } $fonts[ $key ] = $value; } return $fonts; } /** * Returns a list of custom uploaded fonts that can be merged in the select box for selecting fonts * Keys are extended by -customfont at the end to be able to recognise them before the array is returned * * @since 4.3 * @return array */ public function custom_font_select_list() { $fonts = array(); $uploaded = $this->get_font_list(); /** * Sort alphabetically */ $keys = array_keys( $uploaded ); sort( $keys, SORT_STRING ); foreach( $keys as $font_key ) { /** * framework\php\class-htmlhelper.php function select() eliminates fonts with the same name (= key). * To avoid this we add the uploaded font weights to the name of the font. */ $weight = array(); foreach( $uploaded[ $font_key ]['config'] as $key => $desc ) { if( isset( $desc['weight'] ) ) { $weight[] = $desc['weight']; } } $weight = array_unique( $weight ); sort( $weight ); $name = isset( $uploaded[ $font_key ]['config'][0]['name'] ) ? $uploaded[ $font_key ]['config'][0]['name'] : $font_key; $name .= ' (' . implode( ', ', $weight ) . ')'; $fonts[ $name ] = $font_key; } /** * @since 4.3 */ $fonts = apply_filters('avf_available_custom_fonts', $fonts ); foreach( $fonts as $key => &$value ) { if( false === ( strpos( $value, '-custom' ) ) ) { $value .= '-custom'; } } return $fonts; } /** * Returns the options array for a font select box. Adds optgroup so the user knows what type of font he selects. * * @since 4.3 * @param array $source 'all' | 'websafe' | 'custom' | 'google' * @param string $cache 'cache' | 'no_cache' * @param string|array $default 'add_default' | 'no_default' | array ( 'value' => 'key' ) * @return array */ public function get_font_select_options_list( array $source = array( 'all' ), $cache = 'cache', $default = 'add_default' ) { if( ! empty( $this->select_options_font_list ) && ( 'cache' == $cache ) ) { return $this->select_options_font_list; } $font_types = apply_filters( 'avf_font_select_options_order', array( 'websafe', 'google', 'custom' ) ); $options = array(); if( 'add_default' == $default ) { $options[ __( 'Default', 'avia_framework' ) ] = ''; } else if( is_array( $default ) && ! empty( $default ) ) { $options = $default; } foreach( $font_types as $font_type ) { $intersect = array_intersect( array( 'all', $font_type ), $source ); if( ! empty( $intersect ) ) { $fonts = array(); switch( $font_type ) { case 'custom': $fonts = $this->custom_font_select_list(); $optgroup = __( 'Uploaded Fonts (located at Enfold -> Import/Export)', 'avia_framework' ); break; case 'websafe'; $fonts = $this->websafe_fonts_select_list(); $optgroup = __( 'Websafe Fonts', 'avia_framework' ); break; case 'google'; $fonts = $this->google_fonts_select_list(); $optgroup = __( 'Google Fonts', 'avia_framework' ); break; } if( ! empty( $fonts ) ) { $options[ $optgroup ] = $fonts; } } } if( 'cache' == $cache ) { $this->select_options_font_list = $options; } return $options; } /** * Returns the CSS for a single font. * $font must have the stucture from an entry of $this->add_font * * @since 4.3 * @param array $font_info * @return sting */ public function get_css_custom_font_face( array $font_info ) { $font = $font_info['config']; $css = ''; foreach( $font as $key => $info ) { if( ! is_numeric( $key ) ) { continue; } $urls = array(); foreach( $info['files'] as $ext => $file ) { if( ! array_key_exists( $ext, $this->css_formats ) ) { continue; } $url = trailingslashit( $font_info['origin_url'] . $font_info['folder'] ) . $file; switch( $ext ) { case 'eot': $iefix = $url . "?#iefix"; // IE6-IE8 $urls[] = " url('{$url}') {$this->css_formats[ $ext ]}"; $urls[] = " url('{$iefix}') {$this->css_formats[ $ext ]}"; break; case 'svg': $urls[] = " url('{$url}#{$font['key']}') {$this->css_formats[ $ext ]}"; break; default: $urls[] = " url('{$url}') {$this->css_formats[ $ext ]}"; break; } } if( empty( $urls ) ) { continue; } /** * Allow to change default behaviour of browsers when loading external fonts * https://developers.google.com/web/updates/2016/02/font-display * * @since 4.5.6 * @return string auto | block | swap | fallback | optional */ $font_display = apply_filters( 'avf_font_display', 'auto', $font['key'] ); $css .= "@font-face { \r\n"; $css .= " font-family: '{$font['key']}';\r\n"; $css .= " src: "; $css .= implode( ",\r\n ", $urls ); $css .= ";\r\n"; $css .= " font-style: {$info['style']};\r\n"; $css .= " font-weight: {$info['weight']};\r\n"; $css .= " font-display: {$font_display};\r\n"; $css .= "}\r\n"; } return $css; } /** * Output styles for custom uploaded fonts * * @since 4.3 */ public function handler_wp_print_styles() { $uploaded = $this->get_font_list(); $out = '' . "\r\n"; echo $out; } /** * Output styles for custom uploaded fonts to dynamic stylesheet * * @param string $output * @param avia_style_generator $style_generator * @param string $context 'before' | 'after' * @return string */ public function handler_create_dynamic_stylesheet( $output, avia_style_generator $style_generator, $context = '' ) { if( ! in_array( $context, array( 'before' ) ) ) { return $output; } $uploaded = $this->get_font_list(); $output .= "\r\n"; foreach( $uploaded as $font_info ) { $output .= $this->get_css_custom_font_face( $font_info ); } $output .= "\r\n"; return $output; } /** * Splits the selected font string (option value from font selectbox) * * @since 4.3 * @param string $selection * @return array */ public function split_font_info( $selection ) { /** * Split font sizes for Google fonts */ $info = explode( ':', $selection ); $font = array( 'family' => trim( $info[0] ), 'weight' => isset( $info[1] ) ? trim( $info[1] ) : '' ); return $font; } /** * Returns the type of font selected from a selectbox * * @since 4.3 * @param array $font_info * @return string 'websave' | 'custom' | 'google' */ public function get_selected_font_type( array $font_info ) { if( strpos( $font_info['family'], '-websave' ) !== false ) { return 'websave'; } if( strpos( $font_info['family'], '-custom' ) !== false ) { return 'custom'; } return 'google'; } /** * Removes any font type mark from first font name, removes ",' and returns the fontname in lowercase * * @since 4.3 * @param array $font_info * @return array */ public function set_font_family( array $font_info ) { $type = $this->get_selected_font_type( $font_info ); switch( $type ) { case 'websave': case 'custom': $replace = '-' . $type; break; default: return $font_info; } /** * In case we have several fonts we only take the first one */ $font_family = explode( ',', $font_info['family'] ); $font_family = strtolower( $font_family[0] ); $font_family = str_replace( array( '"', "'" ), '', $font_family ); $font_info['family'] = str_replace( $replace, '', $font_family ); return $font_info; } }