Source_extract() version2, envío y extracción de datos desde PHP como si fuera un navegador

source extractLos retos se amplían y source_extract() necesitaba un nuevo enfoque para madurar y ser mas versátil, de manera que, frente a la anterior version que solo enviaba POST y usaba Cookies suplantando un navegador, esta nueva version mejora el soporte, permitiendo enviar datos por GET y POST, pudiendo enviar no solo textos si no a demás poder hacer upload de archivos, con opción de mostrar la cabecera HTTP y todo sin perder la opcion de usar cookies. El único problema es que la reestructuración de variables ha echo que no sean igual que en la anterior versión ya que se ha re-escrito casi entera.

function source_extract(
		$url, 
		$POSTdata='', 
		$GETdata='', 
		$file_upload='', 
		$header=false, 
		$cookie=false
	){
	$user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.0.9) Gecko/20061206 Firefox/1.5.0.9';
	
	#get
	if(is_array($GETdata)){
		foreach($GETdata as $k => $v){	$GETdata[$k] = $k.'='.urlencode($v);	}
		$GETdata = implode('&', $GETdata);
	}
	if($GETdata!='') $url .= strpos($url, '?') ? '&'.$GETdata : '?'.$GETdata;
	
	#post+files
	if(is_array($POSTdata)&&!is_array($file_upload)){
		foreach($POSTdata as $k => $v){	$POSTdata[$k] = $k.'='.$v;	}
		$POSTdata = implode('&', $POSTdata);
	} elseif(count($POSTdata)==0){
		$POSTdata = array();
	}
	if(is_array($file_upload)){	
		foreach($file_upload as $k=>$v){
			$v					= (substr($v,0,1)!='.'&&substr($v,0,1)!='/') ? './'.$v : ''.$v;
			$path_v				= realpath(dirname($v));
			$file_v				= basename($v);
			$file_upload[$k]	= '@'.$path_v.(substr($path_v,-1)!='/' ? '/' : '').$file_v;
		}
		$file_upload = array_merge($POSTdata, $file_upload);
	}
	
	$ch = curl_init($url);
	if(is_array($file_upload)|| $POSTdata!=''){
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, (is_array($file_upload) ? $file_upload : $POSTdata));
	}
	if($cookie){
		curl_setopt ($ch, CURLOPT_COOKIEJAR, $cookie);
		curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookie);
	}
	if($header){
		curl_setopt ($ch, CURLOPT_HEADER, 1);
	}
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (substr($url,0,5)=='https'));
	curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
	$_url_content = $url_content = curl_exec ($ch);
	curl_close($ch);
		$url_content = array(
			'url'		=>$url,
			'post'		=>$file_upload ? $file_upload : $POSTdata,
			'content'	=>$_url_content
		);
	if($header){
		$_url_content = explode("\r\n\r\n", $_url_content,3);
		
		$url_content['header']	= (count($_url_content)>2) ? $_url_content[0]."\r\n".$_url_content[1] : $_url_content[0];
		
		$url_content['header']	= explode("\r\n", $url_content['header']);
		foreach($url_content['header'] as $k=>$v){	$o[$k] = explode(': ', $v,2); $o[$o[$k][0]] = $o[$k][1]; unset($o[$k]);	}
		$url_content['header'] = $o;
		
		$url_content['content']	= (count($_url_content)>2) ? $_url_content[2] : $_url_content[1];
	}
	return $url_content;
}

El primer parámetro es la URL de referencia donde queremos hacer la consulta o extraer el texto.
El segundo, y tercero son arrays que respectivamente introducen los datos a enviar por POST y GET. En ambos casos se pueden introducir tanto texto en formato campo=valor&campo2=valor o siendo un array en el que las key son los nombres de los campos a enviar y los valores los textos a enviar. Si se pretende enviar algún archivo en la petición es obligatorio que los valores que se envíen por POST estén en formato array.
El cuarto parámetro es un array de archivo/s a subir por POST a la URL de destino. El array debe tener como key los nombres de campo y como valor las direcciones donde se encuentran los archivos. Los archivos tienen que estar dentro del servidor, si se redireccióna alguno externo no se enviará correctamente.
El quinto parametro es un valor boleano de true o false, que tiene false por defecto. Si se pone a true mostrara un valor en el array de salida llamado header que contiene una array de las distintas propiedades devueltas en la consulta HTTP.
El sexto y ultimo parámetro indica la utilización de cookies. Por defecto esta en false para no ser utilizado pero si se le indica la ruta de un archivo, este actúa como un cache de cookies entre consultas almacenando valores entre estas.

Esta vez pondré en otro articulo un ejemplo mas real, por ahora aquí os va un ejemplo para probar todas las propiedades..

Creamos en la misma carpeta un archivo que se llame cookie.txt, y subimos en el mismo sitio una imagen JPG a la que cambiaremos el nombre por “imagen.jpg”. Esta imagen va a ser la que vamos a “transmitir”.
A continuacion creamos otro que se llame receptor.php, y en este escribimos lo siguiente.

<?php
//archivo creado para comprobar si se obtienen bien los datos de get, post y files
echo '////////// INICIO DEL CONTENIDO DE LA PAGINA /////////////////';
$data = array(
			'_GET'		=> $_GET,
			'_POST'		=> $_POST,
			'_FILES'	=> $_FILES
);
echo '////////// FIN DEL CONTENIDO DE LA PAGINA ////////////////////';
print_r($data);
?>

Este archivo nos servirá como receptor de la prueba con la que vamos a poder comprobar que datos llegan..

Por ultimo hacemos el código de la pagina propia, con el que vamos a hacer la consulta.
Ponemos el nombre que queramos a la pagina y insertamos el código a continuación.

<?php
$url = 'receptor.php';
$post = array('ejemplo_post'=>'Ejemplo de datos enviados por post', 'otro_ejemplo'=>32486245378934);
$get = array('ejemplo_get'=>'Ejemplo de datos enviados por get', 'otro_ejemplo_por_get'=>37827489237);
$file_upload = array('Nombre_de_archivo'=> './imagen.jpg');
print_r(source_extract($url, $post, $get, $file_upload, true, './cookie.txt'));

/*Esta parte debeis sustituirla por el codigo de la funcion que aparece en la parte de arriba*/
?>

Hay que tener muy en cuenta que hay q sustituir el ultimo comentario por la función de arriba del todo para que el ultimo archivo se ejecute correctamente.

Cuanto tengamos todo y abramos el ultimo archivo desde el navegador veremos que nos aparecen varios datos entre los que se encontrara la cabecera, un array con todos los datos contenidos de la pagina receptor.php y los datos enviados por post, url…

Pronto tendremos un ejemplo más tangible..
A peticion del publico he realizado una corrección en la linea 78 del código de la función que activa automáticamente el soporte de SSL para las paginas web HTTPS. Si alguien tiene algún problema o incompatibilidad con esa corrección q me lo comente

Función de extracción de datos Youtube() en PHP version3

Youtube()A estas alturas supongo que los que lean este blog seguramente sepan que hace esta función. Es una función que a partir de una ID de youtube extrae el resto de datos del mismo video…
El motivo de esta actualización es el aviso de @pablo que me indicaba que en la versión 1 se la función si que se obtener el usuario que ha subido el video, asi que esa ha sido la primera corrección.
Revisando el código a demás me di cuenta que la fecha también fallaba, así como el debug de fecha, y como guinda.. mucha gente esta usando la direccion de youtube completa para obtener el ID y para los usuarios menos expertos es un coñazo el extraerlo.. así que he incorporado el metodo que el genio Alex Barros diseño en Boozox y uno de sus lectores @Javier compartieron para que ahora podamos ver los vídeos no solo con la ID si no que también con la URL.

function youtube($id, $debug = false) {
	$_id = parse_url($id);
	parse_str($_id['query']);
	unset($_id);
	$id = empty($v) ? $id : $v;

	$url = 'http://es.youtube.com/watch?v='.$id;
	$query = @file_get_contents($url);
	
	$exp_info = '!&t=(.+)&!U';
	preg_match_all($exp_info,$query,$t);
	
	$exp_info = "!<meta name=\"title\" content=\"(.+)\">!U";
	preg_match_all($exp_info,$query,$titulo);
	
	$exp_info = "!<meta name=\"description\" content=\"(.+)\">!U";
	preg_match_all($exp_info,$query,$descripcion);
		
	$exp_info = "!<span class=\"watch-video-added post-date\">(.+) de (.+) de (.+)</span>!U";
	preg_match_all($exp_info,$query,$fecha);
	
	$exp_info = "<meta name=\"keywords\" content=\"(.+)\">";
	preg_match_all($exp_info,$query,$tags);
	
	$exp_info = "!href=\"/user/(.+)\"!U";
	preg_match_all($exp_info,$query,$user);
	
	$t				= $t[1][0];
	$titulo			= $titulo[1][0]; 
	$descripcion	= $descripcion[1][0];
	$fecha			= ($fecha[1][0]&&$fecha[2][0]&&$fecha[3][0]) ? $fecha[1][0].' de '.$fecha[2][0].' de '.$fecha[3][0] : '';
	$tags			= $tags[1][0];
	$user			= $user[1][0];
			
	$salida["id"]			= $id;
    $salida["t"]			= $t;
    $salida["url"]			= $url;
    $salida["iurl"]			= "http://img.youtube.com/vi/".$id."/2.jpg";
    $salida["reproductor"]	= "http://www.youtube.com/p.swf?video_id=".$id."&iurl=http://img.youtube.com/vi/".$id."/2.jpg&t=".$t;
    $salida["video"]		= "http://youtube.com/get_video.php?video_id=".$id."&t=".$t;
    $salida["html"]			= "<object width=\"425\" height=\"350\"><param name=\"movie\" value=\"http://www.youtube.com/v/".$id."\"></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/v/".$id."\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"425\" height=\"350\"></embed></object>";
    $salida["title"]		= $titulo;
    $salida["descripcion"]	= $descripcion;
    $salida["fecha"]		= $fecha;
	$salida["tags"]			= $tags;
	$salida["usuario"]		= $user;

	if($debug){
		//sistema de diagnostico
		$salida['debug']				= $query;
		$s['la url de lectura es']		= $url;
		$s['lectura de video']			= ($query		)	? 'si' : 'no' ;
		$s['t encontrado']				= ($t			)	? 'si' : 'no' ;
		$s['titulo encontrado']			= ($titulo		)	? 'si' : 'no' ;
		$s['descripcion encontrada']	= ($descripcion	)	? 'si' : 'no' ;
		$s['fecha encontrada']			= ($fecha		)	? 'si' : 'no' ;
		$s['tags encontrados']			= ($tags		)	? 'si' : 'no' ;
		$s['usuario encontrado']		= ($user		)	? 'si' : 'no' ;
		$s['contenido para debug']		= $salida;
		return	$s;
	}
	if($t == ""){ //Error de conexion
		return false;
	} else { // todo OK
		return $salida;
	}
}

Un ejemplo con ID:

$datos = youtube('aWCD69urAqQ');
print_r($datos);

El mismo ejemplo de antes pero esta vez con la URL completa:

$datos = youtube('http://es.youtube.com/watch?v=aWCD69urAqQ&fmt=18');
print_r($datos);

He sacado una nueva version que corrige errores de peticion y caracteres. la podeis encontrar en Función de extracción de datos Youtube() en PHP version4

Tierra0 en rediseño..

Imagen antigua tierra0Entre ayer y hoy he logrado sacar un poco de tiempo para terminar de dar otro pequeño toque a Tierra0 así que puede que se experimenten algunos cambios inesperados en la web esta mañana.. (los cambios van a ser pequeños así que no creo que tengáis muchos problemas..

Si alguien quiere ver los cambios he echo una captura del theme actual para que podáis comparar..

colorselect(), Selecciona entre colores predefinidos en tus formularios con jquery

crayonsA veces necesitamos ofrecer unos cuantos colores predefinidos a un usuario para que pueda seleccionar cual de todos prefiere para pintar un objeto o dejar como color predeterminado de una parte de nuestra pagina.

Jquery nos ayuda mucho en esto así que he terminado de ayudarnos haciendo una función propia de jquery llamada colorselect().

$.fn.colorselect = function(colores, campo, tamanio) {
	if(tamanio==''){	tamanio	= 20;		}
	if(campo==''){		campo	= 'color';	}
	var o = '<input type="hidden" value="" name="campo" id="color_'+campo+'"/>';
	for(i=0;i<colores.length;i++){
		o += '<div style="height:'+tamanio+'px;width:'+tamanio+'px;margin:2px;float:left;background:'+colores[i]+'" onclick="'+
			 '$(\'.color_selector\').css({\'border\':\'0px solid transparent\', \'magin\':\'2px\'}); '+
			 '$(\'#color_'+campo+'\').attr({value: \''+colores[i]+'\'}); '+
			 '$(this).css({\'border\':\'2px solid '+colores[i]+'\', \'magin\':\'0px\'});'+
			 '" class="color_selector"> </div>\n';
	}
	$(this).html(o);
};



Esta función no se diferencia mucho de las que solemos ver en PHP, también tiene varios valores opcionales.
El primer valor es un array con los nombres de los colores en tipo css (nombres predeterminados como “black” o “red” y nombres en hexadecimales como “#000″), el segundo el nombre del campo que almacenará el color seleccionado y el tercero el tamaño del cubo de selección.

Ejemplo para el ID “color_select”:


$(document).ready(function(){
	$("#color_select").colorselect(Array('black', 'green', 'yellow', 'orange', 'red', 'blue'), 'color', 20);
});



A continuación dejo un ejemplo de una pequeña pagina para probarlo..

<html>
	<head>
		<title>LiveCuadricula</title>
		<script src="http://code.jquery.com/jquery.js"								type="text/javascript"></script>
		<script src="http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js"	type="text/javascript"></script>
		<script type="text/javascript">
$.fn.colorselect = function(colores, campo, tamanio) {
	if(tamanio==''){	tamanio	= 20;		}
	if(campo==''){		campo	= 'color';	}
	var o = '<input type="hidden" value="" name="campo" id="color_'+campo+'"/>';
	for(i=0;i<colores.length;i++){
		o += '<div style="height:'+tamanio+'px;width:'+tamanio+'px;margin:2px;float:left;background:'+colores[i]+'" onclick="'+
			 '$(\'.color_selector\').css({\'border\':\'0px solid transparent\', \'magin\':\'2px\'}); '+
			 '$(\'#color_'+campo+'\').attr({value: \''+colores[i]+'\'}); '+
			 '$(this).css({\'border\':\'2px solid '+colores[i]+'\', \'magin\':\'0px\'});'+
			 '" class="color_selector"> </div>\n';
	}
	$(this).html(o);
};
$(document).ready(function(){
	$("#color_select").colorselect(Array('black', 'green', 'yellow', 'orange', 'red', 'blue'), 'color', 20);
});
		</script>
	</head>
	<body>
		<div id="color_select">contenido por si el Javascript está desactivado</div>
	</body>
</html>

Slife, gestiona tu tiempo

Slife iconHoy no toca ningún código, hoy os presentare uno de los programas que a partir de ahora me va a acompañar a partir de ahora.
Todos los que trabajamos en algo de informática deberíamos tener la inquietud de saber en que se nos va el tiempo y actuar en consecuencia, y para esto ha nacido Slife, programa que genera un informe de tallado de cuanto tiempo estas en cada programa y en que documento trabajas reflejando históricamente en gráficos de tiempo fáciles de interpretar y valorar..slife captura
Es totalmente gratuito, tiene una función adicional para gestionar la información de grupos o empresas compartiendo los datos online y compatible con Mac y Windows… que mas se puede pedir… Os dejo un Link a su web y otro a un video que muestra como funciona.