Microsoft da otro paso más para acercarse a PHP con la nueva versión de FastCGI para IIS.
FastCGI es una herramienta que con la colaboración entre Microsoft y Zend, intentan mejorar el rendimiento y la estabilidad a PHP en un entorno Windows. Microsoft’s PHP initiative
VÃa / PHPDeveloper.org
No entiendo por qué no hay un filter o un action cuando se trata de los contenidos de los widgets. A no ser que el autor los haya metido, no hay forma de modificar ni el form del widget ni su contenido.
Me he encontrado en la necesidad de tener que indicar en el footer el tamaño de columnas de Bootstrap para cada uno de los widgets de un sidebar, para lo cual es necesario modificar la salida de cada widget e incluir en el form un campo que indique el ancho y en el html del widget el código de Bootstrap para indicar el ancho de la columna:
En el function.php meteremos el siguiente código:
Primero modificaremos los datos del widget para que añada el nuevo campo que vamos a meter (widget_bootstrap_columns), milagrosamente sí hay un filtro para ello:
// Modificamos los datos enviados al guardar el widget
add_filter( 'widget_update_callback', 'sw_widget_update');
function sw_widget_update($instance, $new_instance, $old_instance, $obj ) {
if (isset($_POST['widget_bootstrap_columns'])) $instance['widget_bootstrap_columns'] = $_POST['widget_bootstrap_columns'];
return $instance;
}
Después vamos a modificar la variable global $wp_registered_widgets que contiene la llamada a la función widget del widget (la que escribe el HTML). Encapsularemos esta llamada dentro de una función anónima para realizar las tareas que sean necesarias, en mi caso dibujar un div con el class col-sm-N:
// Modifico el display del widget para meterle el código de bootstrap
add_action('dynamic_sidebar_before', 'sw_modify_widgets_display', 10, 2);
function sw_modify_widgets_display($index, $bool) {
global $wp_registered_widgets;
$sidebars_widgets = wp_get_sidebars_widgets();
foreach ( (array) $sidebars_widgets[$index] as $id ) {
if ( !isset($wp_registered_widgets[$id]) ) continue;
$wp_registered_widgets[$id]['_callback'] = $wp_registered_widgets[$id]['callback'];
$wp_registered_widgets[$id]['callback'] = function($args, $widget_args) use ($id) {
global $wp_registered_widgets;
// Recuperamos los datos del widget
$instance = get_option($wp_registered_widgets[$id]['_callback'][0]->option_name);
$bootstrap = isset($instance[$wp_registered_widgets[$id]['_callback'][0]->number]['widget_bootstrap_columns'])? $instance[$wp_registered_widgets[$id]['_callback'][0]->number]['widget_bootstrap_columns'] : false;
// Pintamos el tamaño de la columna si así procede
if ($bootstrap) echo '<div class="col-sm-'.$bootstrap.'">';
call_user_func_array($wp_registered_widgets[$id]['_callback'], array($args, $widget_args));
if ($bootstrap) echo '</div>';
};
}
}
Y por último haremos lo mismo para el formulario, modificar la variable global $wp_registered_widget_controls para encapsular la función form del widget y dibujar antes un input donde almacenemos el valor de widget_bootstrap_columns:
// Modifica el form de los widgets
add_action( 'load-widgets.php', 'sw_modificar_widgets_forms' );
function sw_modificar_widgets_forms() {
global $wp_registered_widget_controls;
foreach($wp_registered_widget_controls as $id=>$widget) {
$wp_registered_widget_controls[$id]['_callback'] = $wp_registered_widget_controls[$id]['callback'];
$wp_registered_widget_controls[$id]['callback'] = function($data) use ($id) {
global $wp_registered_widget_controls;
// Recuperamos los datos del widget para incluir el valor de widget_bootstrap_columns
$instance = get_option($wp_registered_widget_controls[$id]['_callback'][0]->option_name);
$widget_bootstrap_columns = isset($instance[$data['number']]) && isset($instance[$data['number']]['widget_bootstrap_columns'])? $instance[$data['number']]['widget_bootstrap_columns']:'';
echo '<div class="widget_added"><p>Número de columnas (col-sm-<input type="number" name="widget_bootstrap_columns" min="1" max="12" value="'.$widget_bootstrap_columns.'" />)</p><hr /></div>';
call_user_func_array($wp_registered_widget_controls[$id]['_callback'], array($data));
};
}
}
MySQL ha pagado 3000 dólares para ser socio de Microsoft’s Visual Studio Industry Partner (VSIP) para poder consolidar su base de datos en el entorno Windows.
Según informan desde MySQl, el 40% de las descargas son desde Windows, y este movimiento permitirá una mayor integración entre en la base de datos y el entorno de desarrollo de Microsoft. Mediante el uso de plugin, los desarrolladores de C# o Visual Basic podrá integrar MySQL en sus aplicaciones de una forma sencilla.
Esta cercanÃa supone un beneficio para ambas compañÃas, para MySQL el que las aplicaciones en Windows puedan desarrollarse usando su base de datos, y para Microsoft, que los desarrolladores seguirán en el entorno Windows al no tener la necesidad de migrar a otro entorno, o usar base de datos como Oracle que son más partidarios de Linux que de Oracle. MySQL gets cosy with Microsoft
Interesante librería que nos permite extraer textos de ficheros PDF, ignora todo aquello que no esté como texto en una capa y soporta ASCIIHexDecode, ASCII85Decode, FlateDecode:
include('class.pdf2text.php');
$a = new PDF2Text();
$a->setFilename('test.pdf');
$a->decodePDF();
echo $a->output();
Para mí, uno de los mayores fracasos de Twitter es su API, una limitación de su uso increíble para algo que le podría dar mucho juego a la aplicación. Ahora mismo no sé en cuánto está el límite, pero la posibilidad de realizar una aplicación basada en Twitter es una pesadilla.
Para aquellos que no quieran sufrir lo que hemos sufrido con TwitterPoster (los espacios en blanco es porque la gente actualiza su imagen y no podemos recuperar la de todos los usuarios por el límite en el API de Twitter), les recomiendo usar Twitter mediante CURL.
Os paso un script sencillito que he realizado:
<?php
// Primer hacemos login
$url ="https://twitter.com/sessions";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
// Por si tienen limitación por navegador
curl_setopt($ch, curlOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)");
// Poned una ruta para las cookies
curl_setopt ($ch, CURLOPT_COOKIEJAR, '/temp/');
curl_setopt ($ch, CURLOPT_COOKIEFILE, '/temp/');
curl_setopt ($ch, CURLOPT_POSTFIELDS, "username_or_email=[usuario]&password=[contraseña]");
// Para que funcione el https
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, curlOPT_SSL_VERIFYHOST, 2);
curl_exec ($ch);
// Cargamos el home, porque Twitter añade dos campos ocultos para poder publicar por web
$url ="http://twitter.com/home";
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec ($ch);
// Recuperamos los campos ocultos
preg_match('//', $result, $match);
$authenticity_token = $match[1];
preg_match('//', $result, $match);
$siv = $match[1];
// Insertamos el texto
$res = $url ="http://twitter.com/status/update";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POSTFIELDS, 'siv='.$siv.'&authenticity_token='.$auth.'&status=[texto]');
curl_exec ($ch);
curl_close ($ch);
unset($ch);
?>
¿Qué fallo tiene este script? pues que si cambian el HTML (campos de formulario, …) o las URLs deja de funcionar, pero al menos no tenemos limitaciones. Eso sí, es más costoso para sus servidores y para los nuestros, porque en vez de hacer una llamada, hacemos 3, y en nuestro caso, a parte parseamos una página para obtener dos campos ocultos.
phc es un compilador de PHP (un poco verde aún) que nos permite crear ejecutables con el código de un script PHP.
Para los desarrolladores de PHP nos ofrece las siguientes posibilidades:
Compilar código PHP en ejecutables optimizados
Compliar aplicaciones web en extensiones optimizadas
Formatear el código PHP de forma “bonita”
Ofuscar el código PHP
Combinar varios scripts PHP en uno solo
Optimizar el código PHP usando optimizaciones de complicación (experimental)
Ahora tengo dos dudas, si todo fuera optimizado y no se tratara de una versión inicial (por ahora no admite programación orientada a objetos):
¿En Apache se pueden ejecutar los compilados en el cgi-bin?, juraría que sí pero no lo tengo muy claro.
¿Qué es más eficiente: Apache preparado para interpretar PHP o ejecutar un compilado? siempre es más eficiente ejecutar que interpretar, pero no estoy tan puesto en Apache para saber qué puede ser más rápido.