1 ) { $keep[] = $w; } } if ( ! $keep ) { // a title made only of filler words ("About", "Contact us") is still the best guess $keep = array_slice( sxseo_words( $title ), 0, 4 ); } return implode( ' ', array_slice( $keep, 0, 4 ) ); } /** * Keyword list for the legacy keywords meta (and hashtags / schema): focus phrase, tags, categories, then the * most frequent meaningful words of the page. Short, unique, lower-case. Search engines that still read the tag * get relevant terms; none of it is stuffed. */ public static function keywords( $title, $content, array $terms = array(), $focus = '', $limit = 10 ) { $out = array(); $add = function ( $k ) use ( &$out ) { $k = trim( sxseo_lower( wp_strip_all_tags( (string) $k ) ) ); if ( '' !== $k && ! in_array( $k, $out, true ) ) { $out[] = $k; } }; if ( '' !== $focus ) { $add( $focus ); } foreach ( $terms as $t ) { $add( $t ); } $stop = sxseo_stopwords(); $freq = array(); $words = sxseo_words( $title . ' ' . $title . ' ' . sxseo_plain( $content ) ); foreach ( $words as $w ) { if ( isset( $stop[ $w ] ) || sxseo_len( $w ) < 4 || is_numeric( $w ) ) { continue; } $freq[ $w ] = ( $freq[ $w ] ?? 0 ) + 1; } arsort( $freq ); foreach ( array_keys( $freq ) as $w ) { if ( count( $out ) >= $limit ) { break; } if ( $freq[ $w ] >= 2 || count( $out ) < 3 ) { $add( $w ); } } return array_slice( $out, 0, $limit ); } /** First image src in the content (for the social image fallback). */ public static function first_image( $content ) { if ( preg_match( '/]+src=["\']([^"\']+)["\']/i', (string) $content, $m ) ) { $src = $m[1]; if ( 0 === strpos( $src, '//' ) ) { return set_url_scheme( $src ); } return 0 === strpos( $src, '/' ) ? home_url( $src ) : $src; } return ''; } /** Fill %vars% in a title template; unknown vars vanish, repeated separators collapse. */ public static function render_template( $tpl, array $vars ) { $vars += array( 'sitename' => get_bloginfo( 'name' ), 'tagline' => get_bloginfo( 'description' ), 'sep' => sxseo_opt( 'sep', '–' ), ); $out = preg_replace_callback( '/%%?([a-z_]+)%%?/i', function ( $m ) use ( $vars ) { $k = sxseo_lower( $m[1] ); return isset( $vars[ $k ] ) ? (string) $vars[ $k ] : ''; }, (string) $tpl ); $sep = preg_quote( (string) $vars['sep'], '/' ); $out = preg_replace( '/\s+/u', ' ', $out ); $out = preg_replace( '/(\s*' . $sep . '\s*){2,}/u', ' ' . $vars['sep'] . ' ', $out ); $out = trim( $out, " \t\n\r\0\x0B" ); $out = preg_replace( '/^' . $sep . '\s*|\s*' . $sep . '$/u', '', $out ); return trim( $out ); } }