Librería Tokyo Tyrant para PHP
Cada día suenan más las bases de datos clave-valor, y entre ellas Tokyo Tyrant, por lo que no nos vendrá mal hacer uso de la librería PECL para ella, lástima que sea PECL.
PHP Tokyo Tyrant
Cada día suenan más las bases de datos clave-valor, y entre ellas Tokyo Tyrant, por lo que no nos vendrá mal hacer uso de la librería PECL para ella, lástima que sea PECL.
PHP Tokyo Tyrant
Seguimos con el error 404. Si días atrás hablábamos de cómo personalizarlo desde WordPress, hoy hablaremos de cómo configurarlo de manera general desde el servidor.
Recordemos el 404. Cuando se intenta acceder a una página que no existe, el servidor devuelve un mensaje de error 404. Normalmente los navegadores tienen su propia página que muestra ese error (Firefox incluyó la suya a partir de la version 1.5). Personalizar nuestra propia página de error nos puede dar una mayor funcionalidad y no perder la estética de nuestro sitio.
Hace tiempo hice un script para PHP que permitía postear en WordPress usando Jabber (por ejemplo GTalk). Ahora he mejorado un poco el script para que admita poner categorías (si no las hay, las crea) y subir imágenes mediante una URL (ajustándolo a un ancho máximo).
Existen distintas palabras claves para separar los distintos elementos del post dentro del texto que se envía: titulo, contenido, tags, categorias e image. Las distintas secciones se separan con ‘##’ para diferenciarlas unas de otras y se separarán por dos puntos ‘:’ formando pares clave:valor. Un ejemplo para escribir en el IM sería el siguiente:
titulo:Titulo del post##contenido:Lorem Ipsum... con todo el HTML que querramos##tags:etiqueta1, etiqueta2, etiqueta3##categorías:Categoria1,Categoria2#image:http://servidor.com/ruta/imagen.png
El código principal es el siguiente:
$e";'), explode("\n", $contenido)));
}
if (isset($image)) {
$img_content = file_get_contents($image);
$im = imagecreatefromstring($img_content);
$w = imagesx($im);
$h = imagesy($im);
$imgtype = exif_imagetype($image);
if ($w > $max_width) {
$image_p = imagecreatetruecolor($max_width, intval($h*$max_width/$w));
imagecopyresampled($image_p, $im, 0, 0, 0, 0, $max_width, intval($h*$max_width/$w), $w, $h);
ob_start();
imagepng($image_p);
$img_content = ob_get_contents();
ob_end_clean();
$imgtype = IMAGETYPE_PNG;
$w = $max_width;
$h = intval($h*$max_width/$w);
}
$imgname = "img".time().image_type_to_extension($imgtype);
$f = new xmlrpcmsg('metaWeblog.newMediaObject',
array(php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode(array('name'=>$imgname, 'bits'=>new xmlrpcval($img_content, 'base64'))))
);
$c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
$c->setDebug(0);
$r=&$c->send($f);
if(!$r->faultCode()) {
$v=$r->value();
$datos = simplexml_load_string($v->serialize());
$url = $datos->xpath('//member/name[. ="url"]/following-sibling::*/string');
$contenido = '
'.$contenido;
} else {
return "Error a la hora de subir la imagen: $image [".$r->faultString()."]";
}
}
//$contenido .= mb_convert_encoding($contenido, 'UTF-8');
$f = new xmlrpcmsg('wp.getUsersBlogs',
array(php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña))
);
$c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
$c->setDebug(0);
$r=&$c->send($f);
if(!$r->faultCode()) {
$v=$r->value();
$datos = simplexml_load_string($v->serialize());
$blogid = $datos->xpath('//member/name[. ="blogid"]/following-sibling::*/string');
$blogid = is_array($blogid) ? (string) $blogid[0] : (string) $blogid;
$f = new xmlrpcmsg('metaWeblog.newPost',
array(php_xmlrpc_encode($blogid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode(array('title'=>$titulo, 'description'=>$contenido, 'mt_keywords'=>$tags)), php_xmlrpc_encode(1))
);
$c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
$c->request_charset_encoding = 'UTF-8';
$c->setDebug(0);
$r=&$c->send($f);
if($r->faultCode()) {
return "Ha habido un error al intentar crear un nuevo post [".$r->faultString()."]";
} else {
$datos = simplexml_load_string($r->serialize());
$postid = $datos->xpath('//value/string');
$postid = is_array($postid) ? (string) $postid[0] : (string) $postid;
$f = new xmlrpcmsg('metaWeblog.getPost',
array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña))
);
$c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
$c->setDebug(0);
$r=&$c->send($f);
if($r->faultCode()) {
return "Ha habido un error al intentar recuperar información sobre el post insertado [".$r->faultString()."]";
} else {
$datos = simplexml_load_string($r->serialize());
$permalink = $datos->xpath('//member/name[. ="permaLink"]/following-sibling::*/string');
$permalink = is_array($permalink) ? (string) $permalink[0] : (string) $permalink;
$title = $datos->xpath('//member/name[. ="title"]/following-sibling::*/string');
$title = is_array($title) ? (string) $title[0] : (string) $title;
if (isset($categorias)) {
$f = new xmlrpcmsg('mt.getCategoryList',
array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña))
);
$c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
$c->setDebug(0);
$r=&$c->send($f);
if(!$r->faultCode()) {
$datos = simplexml_load_string($r->serialize());
$catsblog = $datos->xpath('//struct');
foreach(explode(',', $categorias) as $cat) {$cats[$cat] = null;}
foreach($catsblog as $cat) {
foreach($cats as $_cat=>$val) {
if (strtolower((string) $cat->member[1]->value->string) == strtolower($_cat)) {
$cats[$_cat] = (string) $cat->member[0]->value->string;
}
}
}
foreach($cats as $cat=>$val) {
if (!$val) {
$f = new xmlrpcmsg('wp.newCategory',
array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode(array('name'=>$cat, 'slug'=>str_replace(' ', '_', strtolower($cat)), 'parent_id'=>1, 'description'=>'')))
);
$c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
$c->setDebug(0);
$r=&$c->send($f);
if(!$r->faultCode()) {
$datos = simplexml_load_string($r->serialize());
$catid = (string) $datos->xpath('//int');
$cats[$cat] = $catid;
} else {
return "Ha habido un error a la hora de crear la categoría $cat";
}
}
}
foreach($cats as $val) {
$catlist[] = array('categoryId'=>$val);
}
$f = new xmlrpcmsg('mt.setPostCategories',
array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode($catlist))
);
$c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
$c->setDebug(0);
$r=&$c->send($f);
if($r->faultCode()) {
return "Hubo un error a la hora de modificar las categorías del post";
}
} else {
return "Ha habido un error al intentar recuperar las categorias del blog";
}
}
return "Se ha publicado '$title': $permalink";
}
}
} else {
return "Ha habido un error al intentar recuperar información sobre el blog [".$r->faultString()."]";
}
}
//Use XMPPHP_Log::LEVEL_VERBOSE to get more logging for error reports
//If this doesn't work, are you running 64-bit PHP with < 5.2.6?
$conn = new XMPPHP_XMPPOld($jabber_host, $jabber_puerto, $jabber_usuario, $jabber_contraseña, 'xmpphp', $jabber_host, false,
XMPPHP_Log::LEVEL_ERROR);
$conn->autoSubscribe();
$conn->useEncryption(false);
try {
$conn->connect();
while(!$conn->isDisconnected()) {
$payloads = $conn->processUntil(array('message', 'presence', 'end_stream', 'session_start'));
foreach($payloads as $event) {
$pl = $event[1];
switch($event[0]) {
case 'message':
if (trim($pl['body']) == '') break;
$conn->message($pl['from'], $body=post($pl['body']), $type=$pl['type']);
if($pl['body'] == 'quit') $conn->disconnect();
if($pl['body'] == 'break') $conn->send("");
break;
case 'presence':
// print "Presence: {$pl['from']} [{$pl['show']}] {$pl['status']}\n";
break;
case 'session_start':
//print "Empezamos\n";
$conn->getRoster();
$conn->presence($status="Asonesss jefeeeeeee!");
break;
}
}
}
} catch(XMPPHP_Exception $e) {
echo 'ERROR:';
die($e->getMessage());
}
Podéis bajaros el código aquí.
Sigo en mi evangelización de CodeIgniter, y en este caso se trata de un mini tutoria que explica cómo crear un carrito de la compra usando la librería Shopping Chart Class que ofrece CodeIgniter. Quizás sea mejor utilizar aplicaciones específicas para crear tiendas, pero en algunos casos no nos queda otra que implementarlo nosotros mismos.
Building a Shopping Cart using CodeIgniter’s Shopping Cart Class
Vía / PHPDeveloper.org
Un script en PHP para poder autenticarse en Google Reader API, para aquel que quiera realizar aplicaciones que necesiten de este servicio. El script es muy sencillo y quizás sea para que gente experimentada lo utilice.
Authenticating the Google Reader API
Vía / Script & Style
En mi blog personal, me ocurre que cuando quiero mostrar código en un post tengo que modificarlo para que quede bonito, poniéndole estilos, etc… La verdad es que es bastante aburrido y no es algo que me guste mucho hacer, me da mucha pereza.
Supongo que hay más gente que se encuentra en mi situación y me entenderán. La solución es usar unas librerías que me modifiquen el código y lo muestre con colores y tabulado. No me he puesto a buscar en Google, pero habrá ya alguna, de todas formas, siempre está bien saber cómo se podría hacer.
En este caso vamos a explicar como realizar un pequeño parser de código PHP, con tan solo unas funcionalidades: reconoce comentarios, palabras reservadas, funciones, variables y texto entrecomillado, a parte de realizar una mínima tabulación. No reconoce código HTML, ni realiza otras cosas, aunque las ampliaciones son posibles.
phpMyFAQ es un sistema multi-idioma para la gestión de FAQs, requiere PHP 4.3 o superior y admite diferentes sistemas de bases de datos (MySQL, PostgreSQL, SQLite, Sybase, MS SQL Server, MaxDB, IBM DB2, IBM Cloudscape, Apache Derby, Oracle, Interbase y Firebird).
También ofrece un CMS con editor WYSIWYG y un gestor de imágenes. Soporte para multi usuarios con usuarios y grupos basados en permisos en categorÃas y registros. Además añade revisión de tipo wiki, sistema de noticias, user tracking, plantillas, soporte a XML, PDF, sistema de backup, artÃculos relacionados, etiquetado, RSS, protección anti-spam, LDAP y scripts de instalación.
phpMyFAQ
VÃa / International PHP Magazine
Comments are closed.
Hola, he dado un vistazo a la documentación de Tokyo Tyrant y no acabo de entender del todo para que sirve una base de datos clave-valor..
Me lo podÃas aclarar?
Saludos.
Hola
Normalmente las BD son relacionales, tal tabla se relaciona con tal otra, … Pero esto no siempre es necesario ya que muchas veces sólo se realizan accesos mediante el ID de la tabla. ¿Para qué usar una BD relacional si vas a tirar únicamente de ID?
Una de las caracterÃsticas más importantes de las BD clave-valor es su rapidez, son mucho más rápidas que las BD relacionales.
ImagÃnate que tienes una BD que controla el spam de una web y necesitas saber si una IP está aceptada o rechazada. En este caso no necesitarÃas una BD relacional, solo saber si span[‘ip’] es true o false.
Espero haberte despejado las dudas.
Saludos