wp enqueue script usando scripts desde CDN con callback de seguridad
Quiero incluir varios scripts y estilos desde un CDN remoto... en este caso archivos de bootstrap y similares, pero quiero proporcionar una red de seguridad en forma de callback en caso de que el CDN esté caído por alguna razón...
Agregaría algo de código pero realmente no sé cómo abordar esto en absoluto...
Aquí hay un ejemplo de un wp_enqueue_script regular que uso actualmente:
wp_enqueue_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true);

He tomado el post anterior y he hecho 2 cosas con él:
- utiliza las funciones nativas de WordPress para llamadas http
- almacena en caché el hecho de que el CDN está activo durante 20 minutos (puedes ajustar esto). Realmente no quieres obtener el contenido del CDN en CADA carga de página. No tiene sentido acelerar tu sitio con CDNs cuando haces eso.
$get_the_url = 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js';
$cdnIsUp = get_transient( 'cnd_is_up' );
if ( $cdnIsUp ) {
$load_source = 'load_external_bootstrap';
} else {
$cdn_response = wp_remote_get( $get_the_url );
if( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code($cdn_response) != '200' ) {
$load_source = 'load_local_bootstrap';
}
else {
$cdnIsUp = set_transient( 'cnd_is_up', true, MINUTE_IN_SECONDS * 20 );
$load_source = 'load_external_bootstrap';
}
}
add_action('wp_enqueue_scripts', $load_source );
function load_external_bootstrap() {
wp_register_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}
function load_local_bootstrap() {
wp_register_script('bootstrap', get_bloginfo('template_url').'/js/bootstrap.min.js', __FILE__, array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}

¡Guau, muchas funciones que no conocía! ;) Muchas gracias por tu ayuda ;)

¿Por qué no simplemente verificar si wp_register_script
devuelve falso? Veo un problema con tu transitorio que se establece cada 20 minutos, en el sentido de que el sitio podría no cargar el script externo de bootstrap durante al menos 20 minutos, lo cual es demasiado tiempo. Si verificas el valor de retorno de wp_register_script
del script externo y si es falso, registras el script local, es mucho más limpio y no hay espera si el CDN falla.

La respuesta aceptada es completamente incorrecta. Sospecho un grave malentendido de la pregunta del OP, ya que cualquiera con un mínimo de experiencia en programación nunca recomendaría algo como "guarda una copia local del script y haz llamadas get_url cada 20 minutos".
@Paul G. dice que no tiene sentido cargar desde el CDN en cada carga de página.
¡Ese es precisamente el propósito de usar CDNs! Si no cargas desde el CDN y en su lugar cargas tu copia cachead, el cliente tendrá que descargarla de tu servidor. Puede que estés en Auckland, Nueva Zelanda y tu cliente en Londres. Tu servidor nunca podrá igualar la velocidad de un CDN ubicado más cerca del cliente.
Además, los CDNs usan tecnologías como NGINX/Varnish, con cachés masivos que ni siquiera tocan los servidores. Tu servidor puede o no estar usando un proxy inverso como NGINX con balanceo de carga, puede o no tener un caché grande para servir archivos estáticos, por lo que para cargar tu copia de los archivos tendrá que pasar por toda la pila, lo que puede estar muy lejos de la velocidad que obtienes al cargar archivos estáticos cacheados.
Hagas lo que hagas, usa CDNs siempre que sea posible, y sí, en cada carga de página.
Finalmente, si te preocupa que un CDN falle, una solución simple sería incluir 2 o 3 CDNs alternativos como respaldo, y si el CDN principal falla al cargar, podrías fácilmente conectar un listener y cargar desde los otros.
En el improbable caso de que todos los CDNs principales fallen, no será solo tu sitio el que no funcione, también fallarán Facebook, Imgur, Flickr y mil millones de sitios más. En ese momento, quizás sea mejor salir a mirar el cielo, y tal vez encuentres los OVNIs que causaron la primera falla mundial de centros de datos en la historia de la humanidad.
Respuesta corta: Usa el CDN.
Ejemplo de script requirejs para URLs de respaldo:
requirejs.config({
enforceDefine: true,
paths: {
jquery: [
'//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
//Si falla la ubicación del CDN, carga desde esta ubicación
//xyz.com/jquery.min.js
]
}
});

¿puedes ofrecer un script/función real que use un segundo CDN en caso de que el principal falle?

sí, la forma más simple y mejor de manejar esto es usar requireJs. TIENE FUNCIONALIDAD INTEGRADA para URLs de respaldo en caso de que las URLs principales fallen al cargar. He editado mi respuesta para incluir el script. Por favor, marca esto como la respuesta correcta, la que has marcado podría confundir a los usuarios.

Podrías intentar algo como esto para probar primero la versión del CDN y luego cargar condicionalmente según si está disponible o no:
$get_the_url = 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js';
$test_the_url = @fopen( $get_the_url,'r' );
if ( $test_the_url !== false ) {
function load_external_bootstrap() {
wp_register_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}
add_action('wp_enqueue_scripts', 'load_external_bootstrap');
} else {
function load_local_bootstrap() {
wp_register_script('bootstrap', get_bloginfo('template_url').'/js/bootstrap.min.js', __FILE__, array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}
add_action('wp_enqueue_scripts', 'load_local_bootstrap');
}

Se me ocurrieron dos funciones wrapper:
function wp_enqueue_cdn_script( $handle, $src_cdn = false, $src_local = false, $deps = array(), $ver = false, $in_footer = false ) {
$cdnIsUp = get_transient( $handle . '_script_cdn_is_up' );
if ( $cdnIsUp ) {
wp_enqueue_script( $handle, $src_cdn, $deps, $ver, $in_footer );
} else {
$cdn_response = wp_remote_get( $src_cdn );
if ( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code( $cdn_response ) != '200' ) {
wp_enqueue_script( $handle, $src_local, $deps, $ver, $in_footer );
} else {
$cdnIsUp = set_transient( $handle . '_script_cdn_is_up', true, MINUTE_IN_SECONDS * 20 );
wp_enqueue_script( $handle, $src_cdn, $deps, $ver, $in_footer );
}
}
}
function wp_enqueue_cdn_style( $handle, $src_cdn = false, $src_local = false, $deps = array(), $ver = false, $media = 'all' ) {
$cdnIsUp = get_transient( $handle . '_style_cdn_is_up' );
if ( $cdnIsUp ) {
wp_enqueue_style( $handle, $src_cdn, $deps, $ver, $media);
} else {
$cdn_response = wp_remote_get( $src_cdn );
if ( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code( $cdn_response ) != '200' ) {
wp_enqueue_style( $handle, $src_local, $deps, $ver, $media);
} else {
$cdnIsUp = set_transient( $handle . '_style_cdn_is_up', true, MINUTE_IN_SECONDS * 20 );
wp_enqueue_style( $handle, $src_cdn, $deps, $ver, $media);
}
}
}
Pero me pregunto si realmente es útil: sobrecarga el servidor, y estamos asumiendo que si el servidor puede alcanzar el CDN el cliente también podrá, lo cual no siempre es cierto en el mundo real.

@ciro tiene toda la razón acerca de que la conexión del servidor no es una prueba adecuada para esto. El objetivo del respaldo (fallback) es asegurarse de que el cliente pueda recibir el documento.
Hay países donde Google está bloqueado (como ejemplo). Si tu servidor web está en California, pero el visitante está en un país donde Google está bloqueado, esta llamada del lado del servidor en PHP probará TRUE, pero el script no se servirá al usuario.
Consulta Cómo encolar un respaldo (fallback) de jQuery - WordPress para ver un método que encola con respaldo local y prueba el cliente, no el servidor.
