crea un sistema de frases para facebook

Hola, antes que nada lamento no escribir tan seguido…

He pasado un fin de semana en casa aburrido y se me ocurrio crear uno de esos populares sistemitas para poner frases en tu facebook, pueden descargarlo desde aqui;

http://www.mediafire.com/?ctjst16e221y53x

Pruebenlo y despues me cuentan!

Anuncios

cakephp y los campos de tipo enum

Actualmente como sabran cakephp no soporta los campos del tipo enum, por que al importar los fixtures en los tests podemos encontrarnos con algunos problemas.

Cree un simple patch para que transforme el enum a un campo de texto, voy abrir un ticket a ver si lo pueden agregar al datasources dbo.

Mientras tanto si alguno de tus modelos usa campos enum puedes agregar lo siguiente en el fixture;

class ModelnameFixture extends CakeTestFixture {
	function create(&$db) {
		// enum support in test fixture, by Eugenio Fage
		foreach ($this->fields as $field) {
			if(substr($field['type'],0,4)=='enum') $db->columns[$field['type']] = $db->columns['string'];
		}

		return parent::create($db);
	}
}

Saludos!

megusta / fblike script

EL REPOSITORIO HA SIDO CAMBIADO, PUEDES DESCARGAR LA NUEVA VERSION DESDE AQUI http://www.mediafire.com/?ctjst16e221y53x

Desarrolle una pequeña script para script para crear frases en facebook, pueden descargarla desde;
http://code.google.com/p/fblike/

Pueden ver una pequeña demostracion aqui

Que es?

Fblike es una simple script para que los usuarios de facebook puedan crear frases y compartirlas con sus amigos. Puedes ver una demo del sistema en;

Inspiracion

fblike fue inspirado en base a estos sitios;

Como instalar fblike

  1. crea la base de datos y la tabla, las sentencias sql para crear las tablas se encuentran en base.sql
  2. configura los datos para conectarte a la base de datos en app/config/database.php
  3. crea una aplicacion en facebook http://developers.facebook.com/setup/
    • ingresa a la configuracion de la aplicacion que recien creaste
    • ve a la pestaña que dice Facebook integration
    • elige una direccion dentro de facebook (opcion Página de trabajo)
    • en canvas URL escribe direccion_donde_esta_fblike/fbapp
    • en canvas type seleccion iframe
  4. configura los datos para usar la facebook app en app/config/fb-config.php
  5. una vez que la probaste y funciona no olvides ponerlo en modo de produccion, para ello vea a app/config/core.php busca Configure::write(‘debug’, 3); y cambialo por Configure::write(‘debug’, 0);

DESCARGAR

http://code.google.com/p/fblike/downloads/detail?name=fblike.zip

cacheando queries de forma facil

Idea original tomada de: http://www.endyourif.com/caching-queries-in-cakephp/

Una optimizacion comun es cachear queries… navegando por ahi me encontre con un articulo donde simplemente reescriben el metodo find de los modelos para cachear las queries, lo modifique un poquito y asi quedo;

app_model.php

class AppModel extends Model {
	/**
	 * 
	 * Cache find queries
	 */ 
    function find($conditions = null, $fields = array(), $order = null, $recursive = null) {
    	if (!empty($fields['cacheKey'])) {
    		$cacheConfig = 'query';
			if (!empty($fields['cacheConfig'])){
      			$cacheConfig = $fields['cacheConfig'];
    		}
    		
    		$cacheName = $this->name . '-' . $fields['cacheKey'];
			
    		if (($data = Cache::read($cacheName, $cacheConfig)) === false) {
				$data = parent::find($conditions, $fields, $order, $recursive);
				Cache::write($cacheName, $data, $cacheConfig);
			}
    	}else{
    		$data = parent::find($conditions, $fields, $order, $recursive);
    	}
    	
    	return $data;
    }
}

Como veran por defecto usa la configuracion de cache llamada ‘query’, asi que vamos a tener que agregar esto en;

config/core.php

Cache::config('query', array(
 'engine' => 'File',
 'duration'=> '+20 minutes',
 'probability'=> 100,
 'path' => CACHE . 'queries' . DS,
 ));

Ademas tendremos que crear en el directorio de cache el directorio queries, alli se salvaran todas las queries, si en vez de usar el file engine podemos cambiarlo por memcache tocando la configuracion (lo que recien escribimos en core.php).

USO

Cuando queremos cachear un find solo agregamos lo siguiente al array options;

$this->Modelo->find('all',array('cacheKey'=>'llave','conditions'=>2));
$this->Modelo->find('all',array('cacheKey'=>'llave','cacheConfig'=>'memcached','conditions'=>2));

PAZ!

Lograr que cakephp soporte subdominios

Hola a todos, por si algunos no lo sabian cakePHP no es muy bueno a la hora de manejar urls con subdominio, en este post voy a escribir sobre como hacer posible manejar subdominios haciendo la menor cantidad de modificaciones posibles.

Basicamente la idea es que pase el subdominio por el named parameter subdomain. Todo esto sin tocar el .htaccess

Para esta solucion necesitamos poner unas pocas lineas en el config/bootstrap.php , otras en el config/routes.php (ya que hay que agregar el domain a las rutas), luego agregamos una constante en webroot/index.php y finalmente usar un nuevo htmlhelper para hacer links correctamente que por supuesto extiende de htmlhelper

Primero:

En el archivo config/bootstrap.php agrega al final:
(Recuerda cambiar test.domain.com por el nombre de tu dominio ejemplo: miweb.com tambien puedes usar un subdominio, es importante que siempre lo escribas en minusculas)

// sub domain in lower
define('MYDOMAIN','test.larompe.com.ar');

if(!isset($_GET['url']))$_GET['url']='';

$token=parse_url($_SERVER['SERVER_NAME']);
if((($pos=strpos($token['path'],MYDOMAIN))>0)){
$subdomain=strtolower(substr($token['path'],0,$pos-1));

}else{
$subdomain='www'

}
$_GET['url']=$subdomain.'/'.$_GET['url'];

Segundo

Vas a tener que modificar las rutas de tu aplicacion, estas se encuentran en config/routes.php

Ejemplo;

La ruta;
Router::connect(‘/’, array(‘controller’ => ‘pages’, ‘action’ => ‘display’, ‘home’));

Pasa a llamarse;
Router::connect(‘/:subdomain/’, array(‘controller’ => ‘pages’, ‘action’ => ‘display’, ‘home’),array(‘subdomain’));

Finalmente tenemos que atrapar los /controller /controller/action;
Router::connect(‘/:subdomain/:controller/:action/*’, array(‘subdomain’));
Router::connect(‘/:subdomain/:controller/*’, array(‘subdomain’));

Recuerda que por defecto si el subdominio no esta seteado pone www, osea que las rutas para la aplicacion principal es;
Router::connect(‘/www/users/*’, array(‘controller’=>’users’,’action’=>’index’));

Tercero

Agregar la siguiente linea al principio de webroot/index.php

define(‘WEBROOT_DIR’, ‘/’);

Cuarto

Crea el helper HtmlSubdomain, para ello crea el archivo views/helpers/html_subdomain.php


<?php
class HtmlSubdomainHelper extends HtmlHelper{
function link($title, $url = null, $options = array(), $confirmMessage = false) {
$escapeTitle = true;
if ($url !== null) {
$url = $this->url($url);
}
return parent::link($title,$url,$options,$confirmMessage);
}
function url($url=null,$full=false){
if(is_array($url)){
if(!isset($url['subdomain'])) $url['subdomain'] = 'www';
$subdomain=$url['subdomain'];
$url=parent::url($url);
$pos=strpos($url,'/'.$subdomain.'/')+strlen('/'.$subdomain);
$url=substr($url,$pos);
return 'http://'.$subdomain.'.'.MYDOMAIN.$url;
}
return parent::url($url,$full);
}
}

Por ultimo

Debes recordar agregar el Helper HtmlSubdomain para crear los links en tu vista, ejemplo;

echo $this->HtmlSubdomain->link(‘hola’,array(‘controller’=>’pages’,’view’=>’display’,’home’,’subdomain’=>’subdom1′);

cakePHP Bakery: publicaron mi articulo!!!

Hace alrededor de un mes estaba creando una herramienta que usaba consultas muy pesadas y realizaba complejas busquedas. Como con SQL era imposible conseguir ese tipo de consultas de forma eficiente utilice Sphinx

Sphinx viene con un API, de cuasualidad en la “panaderia” de cakePHP me encontre con un comportamiento para los modelos que hacia busquedas utilizando la api de sphinx.

Como todo esto no me bastaba para el proyecto, por cierto pueden verlo aqui; www. gastromap.com.ar es un mapa gastronomico

Yo necesitaba un componente ademas de hacer uso del comportamiento del modelo, por ello cree un componente y le agregue algunas cositas que le faltaban como poder hacer uso de la busqueda geografica de sphinx.

Como me parecio que podia ser util cree un articulo y lo publique en la panaderia, en los ultimos dias habia visto un incremento en el spam, por lo que crei que jamas lo publicarian.

Pero un mes despues… http://bakery.cakephp.org/articles/view/sphinx-component-and-behavior

Que tan ineficiente puede ser incrementar un valor de un modelo

Estoy trabajando para refactorizar el codigo de meneame usando el framework cakephp.

Hoy me encontraba haciendo la logica para votar una noticia y me encontre con el problema de tener que hacer una query simple;
UPDATE `links` AS `Link` SET `Link`.`link_anonymous` = link_anonymous+1 WHERE `link_id` = 1

Esto se logra haciendo desde el modelo;
$this->updateAll(array(‘link_anonymous’=>’link_anonymous+1’),array(‘link_id’=>1));

Pero al hacer en vez de hacer el update simple que escribi mas arriba hace un update con todos los joins de los modelos;
UPDATE `links` AS `Link` LEFT JOIN `users` AS `User` ON (`Link`.`link_author` = `User`.`user_id`) LEFT JOIN `blogs` AS `Blog` ON (`Link`.`link_blog` = `Blog`.`blog_id`) LEFT JOIN `categories` AS `Category` ON (`Link`.`link_category` = `Category`.`category_id`) SET `Link`.`link_anonymous` = link_anonymous+1 WHERE `link_id` = 1 AND `limit` = ‘1’

Este update es muy costoso, intente usando las funciones del modelo saveField y save, pero no entienden el mensaje ‘link_anonymous+1’, lo transforman a 1 y yo quiero que hagan link_anonymous+1

Para solucionar este problemita agregue la funcion update, que elimina las asociaciones entre el modelo que queremos actualizar y luegos las agrega nuevamente, de esta forma el UPDATE vuelve a ser simple.

La funcion fue tomada de http://blog.pepa.info/php-html-css/cakephp/getting-rid-of-joins-in-updateall-query/

agregar a #app_model.php
/**
* A workaround for CakePHP lack of support for recursive
*/
function updateAll($fields, $conditions = true, $recursive = null) {
if (!isset($recursive)) {
$recursive = $this->recursive;
}

if ($recursive == -1) {
$this->unbindModel(array(
‘belongsTo’ => array_keys($this->belongsTo),
‘hasOne’ => array_keys($this->hasOne)
), true);
}

return parent::updateAll($fields, $conditions);
}

Luego hago;
$this->updateAll(array(‘link_anonymous’=>’link_anonymous+1’),array(‘link_id’=>1),-1);

y… voila!
UPDATE `links` AS `Link` SET `Link`.`link_anonymous` = link_anonymous+1 WHERE `link_id` = 1

EDITO: hoy agregue un ticket al equipo de desarrollo de cakephp… a ver que contestan