2009-11-30

LABjs, cargando javascript más rápidamente

Ya hemos visto en muchas ocasiones técnicas para mejorar el tiempo de carga del javascript de nuestras páginas. Todas pasan por generar dinámicamente las llamadas a los scripts desde el propio Javascript, de esta forma estamos haciendo que los ficheros se carguen de forma simultánea haciendo que la carga total de la página se reduzca.

Versión HTML

figure11
(Ver Imagen)

Versión LABjs

figure31
(Ver Imagen)

LABjs, es una librería que nos permitirá gestionar de forma muy intuitiva permitiéndonos cargar nuestros ficheros javascript en paralelo, minimizando el tiempo de carga.

// LABjs
$LAB
.script("framework.js").wait()
.script("plugin.framework.js")
.script("myplugin.framework.js").wait()
.script("init.js");

Como podemos ver, disponemos de una serie de métodos que nos permitirán gestionar la carga de ficheros, haciendo que unos carguen después para que las dependencias estén cargadas a la hora de usarse.

Metodos de la API

  • $LAB.setGlobalDefaults():Método que nos permite definir los valores por defecto para la carga de ficheros.
  • $LAB.setOptions(): Indicamos opciones que serán pasadas en la cadena de carga.
  • $LAB.script(): Método usado para cargar los ficheros Javascript, permite encadenar varios.
  • $LAB.wait(): Método que detiene la ejecución y que permite ejecutar una funcionalidad (o cargar otro fichero).
Fuente: anieto2k.com

PHPUnit y como documentar para autogenerar codigo de test.

PHPUnit nos permite poner comentarios delante de la funciones enre los /***/ el cual se lee cuando generamos el proyecto de testing. Dandonos la posibilidad de crear de esta manera muy simple los testing de la funciones o class.
Acá les dejo un ejemplo para dejar todo mas claro:


class Calculator
{
/**
* @assert (0, 0) == 0
* @assert (0, 1) == 1
* @assert (1, 0) == 1
* @assert (1, 1) == 2
*/
public function add($a, $b)
{
return $a + $b;
}
}


Anotaciones @assert para PHPUnit

Anotación
Lo transforma automáticamente en
@assert (...) == XassertEquals(X, method(...))
@assert (...) != XassertNotEquals(X, method(...))
@assert (...) === XassertSame(X, method(...))
@assert (...) !== XassertNotSame(X, method(...))
@assert (...) > XassertGreaterThan(X, method(...))
@assert (...) >= XassertGreaterThanOrEqual(X, method(...))
@assert (...) <>assertLessThan(X, method(...))
@assert (...) <= Xclass="literal">assertLessThanOrEqual(X, method(...))
@assert (...) throws X@expectedException X

Para mas informacion aca esta el link oficial de PHPUnit sobre el tema: Link Oficial en Ingles

2009-11-28

Prey – Para recuperar un ordenador robado

prey

Presentado en Pio.la esta semana, PreyProyect es un proyecto chileno que nos permite conocer en todo momento la localización de nuestro ordenador, reduciendo los riesgos de perderlo en un robo.

Prey funciona en Mac, Linux y Windows, siendo de Código Abierto y completamente gratuito.

Prey te ayuda a localizar tu laptop enviándote reportes con un montón de información acerca de su paradero actual. Esto incluye el estátus general del PC, un listado de los programas en ejecución y las conexiones activas, información detallada de red y conexión wifi, un pantallazo del escritorio y — en caso de que el laptop tenga una cámara webcam — una foto del ladrón.

Prey usa un sistema de activación remoto, manteniéndose en silencio para que el ladrón no sepa que está siendo monitoreado.

Una excelente herramienta que puede ayudarnos a recuperarnos de un susto.

Como conectarce a SQL Server 2000 MSDE (Desktop Edition) desde un equipo remoto.

Conectarse a SQL Server MSDE 2000 con Aqua Data Studio requiere que tenga conexiones remotas permitió aceptar conexiones TCP / IP. Una vez que haya conexiones TCP / IP habilitado, puede conectarse a SQL Server MSDE utilizando el nombre y el nombre de la instancia en la hostia: parámetro.

1. Instalación de MSDE con conexiones de red habilitada: El primer paso es instalar MSDE con conexiones de red habilitada. De forma predeterminada, MSDE se instala con conexiones de red con discapacidad. Para instalar MSDE con con conexiones de red, debe ejecutar el setup.exe desde la línea de comandos y especificando el DISABLENETWORKPROTOCOLS = 0. Como se describe en la documentación de instalación de MSDE ...

Parámetros de configuración

Docs de instalación:
Instrucciones de instalación de MSDE

MSDE SupeSocketNetLib Registry
MSDE SupeSocketNetLib Registry
MSDE TCP Registry
MSDE TCP Registry

2. Verifing TCP / IP de las conexiones remotas: Para comprobar que la instalación de MSDE se ha permitido a las conexiones remotas puede ejecutar "regedit" para ver la configuración del Registro. Compruebe que las claves siguientes ...

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\
MSDE\MSSQLServer\SuperSocketNetLib\ProtocolList=[tcp np]

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\
MSDE\MSSQLServer\SuperSocketNetLib\Tcp\TcpPort=[Port]

Registration - Advanced SQL Server
Registration - SQL Server

3. Registro de Conexiones: Ahora, registro de una conexión de servidor en Aqua Data Studio usando "Hostname \ SQLEXPRESS 'como parámetro el nombre de host, donde hostname es el nombre de host o dirección IP del servidor SQL y SQLEXPRESS es el nombre de instancia.

TAMBIÉN MIRAR ESTE LINK: Microsoft MSDE hay mas informacion

2009-11-27

SQLite y .NET Un ejemplo de como utilizarlo.

En este primer artículo comentaré de forma general las características de SQLite y cómo comenzar a crear bases de datos bajo esta plataforma.

¿Qué es SQLite?

SQLite es, como indican en un artículo de su propia web oficial, una base de datos de código libre con las siguientes características distintivas:

  • No necesita configuración, ni tras la instalación inicial ni para el posterior mantenimiento.
  • No utiliza servidor. Se puede utilizar embebida dentro de otra aplicación o gestionar los ficheros de datos a través de una pequeña aplicación de consola descargable desde su web.
  • Utiliza un sólo fichero para almacenar los datos. Una base de datos de SQLite se compone de un único fichero que puede almacenarse en cualquier ruta de la máquina.
  • Los ficheros de datos son multiplataforma. Una base de datos creada en una máquina y sistema operativo concreto puede copiarse y utilizarse bajo cualquier otra plataforma.
  • Es muy compacta. La librería que se integra con otras aplicaciones ocupa unos 200 KBytes.
  • Utiliza tipado dinámico (Manifest Typing). SQLite permite almacenar cualquier valor de cualquier tipo en cualquier registro de una tabla de la base de datos, independientemente del tipo declarado al crear la tabla.
  • Utiliza registros de longitud variable. Cada dato almacenado en la base de datos ocupará su tamaño real y no el reservado según su tipo.

A estas características me gustaría añadir un par más que me parecen interesantes:

  • Proporciona un muy buen rendimiento, muy por encima de bases de datos como Access.
  • Se integra muy fácilmente con aplicaciones .NET ya que existe su proveedor ADO.NET 2.0, también de código libre.

¿Qué necesitamos descargar?

Para gestionar y utilizar bases de datos SQLite tan sólo deberemos descargar la aplicación de gestión en modo consola que nos servirá para crear el fichero de base de datos y crear todas las entidades necesarias (tablas, índices…), y el proveedor ADO.NET para su utilización desde nuestra aplicación .NET.

  1. Página de descarga de SQLite.
  2. Página de descarga de SQLite for ADO.NET 2.0.

¿Cómo crear una base de datos en SQLite?

La base de datos se creará mediante la aplicación de consola “sqlite3.exe” pasándole como parámetro el nombre deseado para nuestra base de datos:

c:\> sqlite3 basedatos.db
SQLite version 3.5.6
Enter “.help” for instructions
sqlite>

Una vez iniciada la aplicación se podrán ejecutar todas las sentencias SQL necesarias para crear las tablas que queramos que formen parte de nuestra base de datos.

  1. CREATE TABLE tabla1(
  2. campo1 INTEGER PRIMARY KEY,
  3. campo2 TEXT,
  4. campo3 NUMERIC,
  5. campo4 INTEGER,
  6. campo5 REAL
  7. );

Los tipos de datos declarados al crear una tabla serán meramente informativos y no impedirán que posteriormente se inserte cualquier valor de cualquier tipo en estos campos, siempre con las siguientes matizaciones:

  • Si en un campo TEXT se inserta un valor numérico este valor se convertirá a texto antes de ser almacenado.
  • Si en un campo NUMERIC se inserta un valor de tipo texto éste se intentará convertir a un valor numérico entero o real antes de su almacenamiento y si no es posible la conversión se almacenará directamente como texto.
  • Los campos de tipo INTEGER se comportan de igual forma que NUMERIC salvo que si se inserta un valor real sin decimales o un valor textual que pueda convertirse a éste último se almacenará como entero.
  • Los campos de tipo REAL se comportan de igual forma que NUMERIC salvo que se almacenará el dato siempre como valor de tipo real.
  • Los campos INTEGER PRIMARY KEY servirán para crear un campo autonumérico o autoincremental (el campo se autoincrementa al realizar inserciones en la tabla con este campo nulo).

Lo primero que haremos será crear el proyecto en Visual Studio o cualquier otro IDE de desarrollo .NET y añadir a las referencias del proyecto el proveedor ADO.NET 2.0 para SQLite (en el artículo anterior comentamos dónde podíamos conseguir este proveedor). La librería DLL a añadir como referencia, y que habrá que distribuir con nuestra aplicación, será la denominada System.Data.SQLite.DLL que encontraremos dentro del fichero ZIP que descargamos. Una vez referenciado el proveedor para ADO.NET de SQLite ya podemos comenzar a escribir el código de nuestra aplicación. Para ello, deberemos añadir la directiva using correspondiente a la librería que acabamos de añadir:

  1. using System.Data.SQLite;

A partir de este momento el código necesario para acceder y gestionar nuestra base de datos SQLite será completamente análogo al ya tradicional que utilizamos para el acceso a cualquier otro tipo de bases de datos, salvo que los nombres de las clases comenzarán con el prefijo “SQLite”. Así, por ejemplo, tendremos a nuestra disposición las siguientes clases:

SQLiteConnection
SQLiteTransaction
SQLiteCommand
SQLiteParameter
SQLiteDataReader

Conexión con la base de datos

La conexión con la base de datos se realizará mediante la clase SQLiteConnection. Para el caso de SQLite, el único parámetro obligatorio de la cadena de conexión será el nombre del fichero de datos:

  1. SQLiteConnection con =
  2. new SQLiteConnection("Data Source=index.bd");

Otros parámetros que pueden especificarse dentro de la cadena de conexión son la contraseña en caso de existir, el timeout por defecto para las operaciones sobre la base de datos, etc. Para ver todos los parámetros que podemos especificar en la conexión con la base de datos SQLite puede consultarse la ayuda proporcionada con el proveedor ADO.NET en el fichero SQLite.NET.chm

Consulta de datos

Para realizar una consulta parametrizada sobre la base de datos haremos uso de las clases SQLiteCommand, SQLiteParameter y SQLiteDataReader. Veamos cómo quedaría un método sencillo de consulta sobre una tabla especificando un parámetro de búsqueda:

  1. public SQLiteDataReader selectClave(int clave)
  2. {
  3. SQLiteConnection con =
  4. new SQLiteConnection("Data Source=basedatos.bd");

  5. SQLiteParameter param = new SQLiteParameter();
  6. param.Value = clave;

  7. string cmdStr =
  8. "SELECT campo2 FROM tabla1 WHERE campo1 = ?;";

  9. SQLiteCommand cmd =
  10. new SQLiteCommand(cmdStr, con);

  11. cmd.Parameters.Add(param);

  12. SQLiteDataReader reader = cmd.ExecuteReader();

  13. return reader;
  14. }

Inserción de datos

La ejecución de una operación INSERT simple será análoga a la consulta descrita en el apartado anterior, salvo que el método de ejecución será ahora ExecuteNonQuery() ya que no se devolverá ningún valor:

  1. public void insertClave(string campo1, int campo2)
  2. {
  3. SQLiteConnection con =
  4. new SQLiteConnection("Data Source=basedatos.bd");

  5. SQLiteParameter param1 = new SQLiteParameter();
  6. Param1.Value = campo1;

  7. SQLiteParameter param2 = new SQLiteParameter();
  8. Param2.Value = campo2;

  9. string cmdStr =
  10. "INSERT INTO tabla1 (campo1, campo2) VALUES (?,?);";

  11. SQLiteCommand cmd =
  12. new SQLiteCommand(cmdStr, con);

  13. cmd.Parameters.Add(param1);
  14. cmd.Parameters.Add(param2);

  15. SQLiteDataReader reader = cmd.ExecuteNonQuery();

  16. return reader;
  17. }

Si en nuestra tabla existe un campo autonumérico y queremos recuperar su valor después de ejecutar la operación de INSERT, tendremos que modificar la instrucción ejecutada para añadir al final una llamada a la función last_insert_rowid() de SQLite y cambiar el método de ejecución por ExecuteScalar() para recuperar el valor devuelto:

  1. string cmdStr =
  2. "INSERT INTO tabla1 (campo1, campo2) VALUES (?,?);" +
  3. "SELECT last_insert_rowid();";

  4. ...

  5. int res = Convert.ToInt32(cmd.ExecuteScalar());

Transacciones en SQLite

Tal y como aconsejan en la ayuda del propio proveedor de ADO.NET para SQLite, en caso de ejecutar varias operaciones sobre una base de datos es recomendable hacerlas dentro de una misma transacción, algo que aumentará muchísimo el rendimiento de la base de datos y por tanto reducirá considerablemente el tiempo necesario para ejecutar las operaciones. Para comenzar una transacción bastará con llamar al método BeginTransaction() del objeto SQLiteConnection una vez creada la conexión, y para finalizar la transacción haciendo COMMIT o ROLLBACK de todas las operaciones llamaremos a los métodos Commit() o Rollback() respectivamente:

  1. SQLiteConnection con =
  2. new SQLiteConnection("Data Source=basedatos.bd");

  3. SQLiteTransaction tran = con.BeginTransaction();

  4. ...

  5. tran.Commit();

Espero que este pequeño tutorial de SQLite sobre .NET les sea de ayuda.

Fuente: sgoliver.net

Air - ActionScript3 Clase para manejar SQLite.

Voy compartir una clase que desarrollé que podría ser muy útil para todos los que trabajan con Air y SQLite (base local) o quieran hacerlo, ya que entre todos tenemos que hacer a esta maravillosa aplicacion conocida y destruir a Silverlight jaja (bromilla).. (o no..)

He estado rompiéndome la cabeza un poco para pasar los métodos que tengo de conexión de PHP a ActionScript 3, para poder manejar registros simples, como UPDATE, INSERT y SELECT desde una sola clase y lo he conseguido!!.

Voy a tratar de ser breve..
Desde ActionScript 3 la implementación es muuuuy simple.. en este caso trabajo desde Flex 3, vamos por pasos.

Primero, importamos la clase y hacemos la conexión, la clase automáticamente creará la base de datos si no existe:
import phoxer.DataManager.AirSqlManager;

private var database:AirSqlManager;
private function onComplete():void{
database = new AirSqlManager("test.db");
}

----------------------------------------------

Segundo, creamos las tablas:
//CREAR LA TABLA
var campos:Object= new Object();
campos.id="INTEGER PRIMARY KEY NOT NULL";
campos.titulo="TEXT";
campos.fecha="TEXT";

var tableTareasToCreate:Object= new Object();
tableTareasToCreate.tabla="tareas";
tableTareasToCreate.campos=campos;
database.createTable(tableTareasToCreate,insertTarea);

El metodo createTable(); utiliza 3 parametros.
1-El objeto con la información para crear la tabla.
2-La función a la que llama si se pudo crear la tabla o si ya existe.
3-La función a la que llama si se genero algun error en la creación de la tabla.
Terminaria devolviendo un query asi:
CREATE TABLE IF NOT EXISTS tareas (`titulo` TEXT,`id` INTEGER PRIMARY KEY NOT NULL,`fecha` TEXT)

----------------------------------------------

Tercero, Incertando un registro
//INSERTAR REGISTRO
var campos:Object= new Object();
campos.titulo="Registro 1";
campos.fecha="20/08/2009";

var dataToInsert:Object = new Object();
dataToInsert.tabla="tareas";
dataToInsert.datos=campos;
database.setInsert(dataToInsert,consultar);

el metodo setInsert(); utiliza 3 parametros.
1-El objeto con la información para hacer el insert.
2-La función a la que llama si se pudo hacer. (todabía no se como recuperar el ultimo id)
3-La función a la que llama si se genero algun error.
Terminaria devolviendo un query asi:
INSERT INTO tareas (titulo,fecha) VALUES ('Registro 1','20/08/2009')

----------------------------------------------

Cuarto, haciendo una consulta
//HACER UNA CONSULTA
var tableToConsult:Object= new Object();
tableToConsult.tabla="tareas";
tableToConsult.principal="id";
tableToConsult.orden="DESC";
database.setSelect(tableToConsult,leerDatos,onError);


private function leerDatos(dts:Array):void{
for each(var dt:Object in dts){
trace(dt.id+" "+dt.titulo+" "+dt.fecha);
}
}

private function onError():void{
trace("no se pudo hacer la consulta");
}

el metodo setSelect(); utiliza 3 parametros.
1-El objeto con la información para hacer la consulta.
2-La función a la que llama si se pudo hacer. devuelve un array de objetos con el resultado
3-La función a la que llama si se genero algun error.
Terminaria devolviendo un query asi:
SELECT * FROM tareas ORDER BY id DESC

Para hacer una consulta mas rigurosa:
//HACER UNA CONSULTA
var tableToConsult:Object= new Object();
tableToConsult.tabla="tareas";
tableToConsult.principal="id";
tableToConsult.orden="DESC";
tableToConsult.filtro="titulo";
tableToConsult.same="Registro";
database.setSelect(tableToConsult,leerDatos,onError);


private function leerDatos(dts:Array):void{
for each(var dt:Object in dts){
trace(dt.id+" "+dt.titulo+" "+dt.fecha);
}
}

private function onError():void{
trace("no se pudo hacer la consulta");
}

Si ven se agregaron dos opciones mas "filtro y same", esto nos va a devolver los registros cuando ejemplo: "titulo" sea igual a "Registro".
Terminaria devolviendo un query asi:
SELECT * FROM tareas WHERE titulo ='Registro' ORDER BY id DESC

----------------------------------------------

Quinto, haciendo una modificación:
//MODIFICAR UN REGISTRO
var datos:Object=new Object();
datos.titulo="Modificado";
datos.fecha="1/09/2009";

var registroAModificar:Object = new Object();
registroAModificar.tabla="tareas";
registroAModificar.datos=datos;
registroAModificar.campo="id";
registroAModificar.valor="3";
database.setUpdate(registroAModificar);

el metodo setUpdate(); utiliza 3 parametros.
1-El objeto con la información del registro que se va a modificar.
2-La función a la que llama si se pudo hacer.
3-La función a la que llama si se genero algun error.
Terminaria devolviendo un query asi:
UPDATE `tareas` SET `titulo`='Modificado',`fecha`='1/09/2009' WHERE id='3'

----------------------------------------------

Bien como vemos con esta clase se nos resulta muyyy facil conectarnos a una base de datos SQLite y manejarla, que les parece??..
Me faltan mas metodos a medida que voy mejorandola la voy subiendo.

haaa me olvidaba, aca esta la la clase AirSqlManager:
/**
Air SQLite Manager
By ::[PHOXER]::
http://www.phoxer.com
v 1.2;
*/

package phoxer.DataManager{
import flash.data.SQLConnection;
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.errors.SQLError;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.filesystem.File;

public class AirSqlManager{
private var conexion:SQLConnection;
private var BDFile:File;
private var State:SQLStatement = new SQLStatement();
public function AirSqlManager(db:String,asy:Boolean=false){
conexion = new SQLConnection();
conexion.addEventListener(SQLEvent.OPEN,onDbOpen,false,0,true);
conexion.addEventListener(SQLErrorEvent.ERROR,onDbError,false,0,true);
BDFile=File.applicationStorageDirectory.resolvePath(db);
trace("DB PATH: "+BDFile.nativePath)//path actual.
trace("DB EXIST: "+BDFile.exists)//si existe la base.
if(asy){
conexion.openAsync(BDFile);
}else{
conexion.open(BDFile);
}
}
private function onDbOpen(e:SQLEvent):void{
trace("DB CONECTED")
State.sqlConnection = conexion;
}
private function onDbError(e:SQLErrorEvent):void{
trace("DB Error: SqlData: "+e)
}

public function createTable(Obj:Object,bk:Function=null,err:Function=null):void{
var campos:Object=Obj.campos;
var sql:String="CREATE TABLE IF NOT EXISTS "+Obj.tabla+" (";
var cmp:String="";
for(var dt:Object in campos){
cmp+="`"+dt+"` "+campos[dt]+",";
}

cmp=quitarUltimaComa(cmp);
sql+=cmp+")";
trace(sql);
State.text=sql;
try{
State.execute();
if(bk!=null){
bk();
}
}catch (e:SQLError){
trace("CREATE ERROR: "+e);
if(err!=null){
err();
}
}

}

public function setSelect(Obj:Object,bk:Function=null,err:Function=null):void{
var tabla:String=Obj.tabla;
var principal:String=Obj.principal;
var orden:String=Obj.orden;
var filtro:String=Obj.filtro;
var same:String=Obj.same;
var like:String=Obj.like;
var limite:String=Obj.limit;
var select:String=Obj.select;
//-limit
limite=(limite!="" && limite!=null)? String(" LIMIT "+limite):"";
//-Select
select=(select!="" && select!=null)? String("`"+select+"`"):"*";
//-SQL
var sql:String;
if(filtro!="" && filtro!=null && same!="" && same!=null) {
sql="SELECT "+select+" FROM "+tabla+" WHERE "+filtro+" ='"+same+"' ORDER BY "+principal+" "+orden+" "+limite;
}else if(filtro!="" && filtro!=null && like!="" && like!=null){
sql="SELECT "+select+" FROM "+tabla+" WHERE "+filtro+" LIKE '%"+like+"%' ORDER BY "+principal+" "+orden+" "+limite;
}else{
sql="SELECT "+select+" FROM "+tabla+" ORDER BY "+principal+" "+orden+" "+limite;
}
trace(sql);
State.text=sql;
try{
State.execute();
if(bk!=null){
var result:SQLResult = State.getResult();
bk(result.data);
}
}catch (e:SQLError){
trace("SELECT ERROR: "+e);
if(err!=null){
err();
}
}
}

public function setInsert(Obj:Object,bk:Function=null,err:Function=null):void{
var datos:Object=Obj.datos;
var sql:String="INSERT INTO "+Obj.tabla+" (";
var campos:String="";
var valores:String="";
for(var dt:Object in datos){
campos+=dt+",";
valores+="'"+String(datos[dt])+"',";
}
campos=quitarUltimaComa(campos);
valores=quitarUltimaComa(valores);
sql+=campos+") VALUES ("+valores+")";
trace(sql);
State.text=sql;
try{
State.execute();
if(bk!=null){
bk();
}
}catch (e:SQLError){
trace("INSERT ERROR: "+e);
if(err!=null){
err();
}
}
}

public function setUpdate(Obj:Object,bk:Function=null,err:Function=null):void{
var tabla:String=Obj.tabla;
var datos:Object=Obj.datos;
var campo:String=Obj.campo;
var valor:String=Obj.valor;
var sql:String="UPDATE `"+tabla+"` SET "
var sets:String="";
for (var dt:Object in datos){
sets+= "`"+dt+"`='"+String(datos[dt])+"',";
}
sets=quitarUltimaComa(sets);
sql+=sets+" WHERE "+campo+"='"+valor+"'";

trace(sql);
State.text=sql;
try{
State.execute();
if(bk!=null){
bk();
}
}catch (e:SQLError){
trace("INSERT ERROR: "+e);
if(err!=null){
err();
}
}
}

public function setDelete(Obj:Object,bk:Function=null,err:Function=null):void{
var sql:String="DELETE FROM "+Obj.tabla+" WHERE "+Obj.campo+"='"+Obj.valor+"'";
trace(sql);
State.text=sql;
try{
State.execute();
if(bk!=null){
bk();
}
}catch (e:SQLError){
trace("DELETE ERROR: "+e);
if(err!=null){
err();
}
}
}

private function quitarUltimaComa(st:String):String{
return st.substr(0,-1);
}
}
Fuente: phoxer.com

Compartiendo artículos en las redes sociales

No creo que sea necesario informar sobre la importancia que tiene compartir el contenido en las nuevas redes. La enorme cantidad de blogs que han parado su actividad por resultar mucho más cómodo actualizar una cuenta de twitter es símbolo de que el flujo de información está reformulando su camino, por lo que tenemos que estar atentos siempre en las nuevas “carreteras digitales” que se construyen, muchas veces, en pocas semanas.

Un ejemplo que veo a diario: la cuenta de twitter.com/wwwhatsnew, con sus casi 6.000 lectores, muchas veces ofrece más visitas a los enlaces que indico que este blog, con sus 20.000 subscriptores. Ya ha habido casos en los que más de 1000 personas han accedido a una página recomendada en mi twitter, 1000 accesos en menos de diez minutos (tiempo de vida medio de un enlace en una cuenta de microblog).

Si sois responsables por algun sitio web y queréis añadir la posibilidad de que los lectores de vuestros textos puedan facilmente compartirlos en las diferentes redes sociales y agregadores de contenido, leed ahora algunas diferentes opciones muy sencillas de usar y de integrar.

BlogPlay

bllogplay

Compatible con Blogger, Wordpress y HTML incluye la posibilidad de añadir nuestras propias redes sociales, aumentando el conjunto de opciones predefinidas entre las que se encuentra twitter, facebook y envío por email.

Antes era conocido como Sociable, ahora está en manos del imparable equipo de startups.com.

KnxDT

KnxDT

Creado en español, podemos usarlo para compartir contenido en Delicious, Digg, Google, Yahoo, Technorati, Menéame, Fresqui, Enchílame, Blinklist, Simpy, Spurl, Reddit, Autobombéame, etc.

ShareThis

sharethis

Uno de los más conocidos, ofrece un botón que, al pulsarlo, puede mostrar decenas de opciones para compartir el artículo en varias redes de todo el mundo.

AddInto

addinto

Aunque parece estar programado para sitios en inglés, bastarán unos suaves retoques para incluir las redes que consideréis más apropiadas. Permite divulgar en twitter, digg, delicious, facebook.. bien a través de un botón o plugins para vuestra plataforma de blog habitual.

AddToAny

addtoany

Otro clásico inmortal que ofrece una enorme cantidad de redes para compartir el contenido. Un botón abre un panel con todas las opciones elegidas en la sección de adminsitración, ocupando poco espacio en la página web.

Wikio

wikio

Wikio también incluye un sistema universal con las opciones más utilizadas en nuestro idioma, ocupando poco espacio y mostrando un botón en español.

I Love Social Bookmarking plugin

social_bmarking

Muy sencillo de usar, con posibilidad de personalizar la estética y la funcionalidad. Aunque hace tiempo que no se actualiza, usa iconos de buena calidad obtenidos en www.fasticon.com

Fuente: wwwhatsnew.com

Uso DooTranslator para la traducción

DooTranslator salió, apoya "CSV", "gettext", "Array", "ini", por ahora, pronto se llevarán a cabo otros "tipos de archivo". Así, por ejemplo, usted tiene su archivo de traducción con este contenido:

en.svntest;"This is just a test!"

Permite inicializar la clase DooTranslator:$translator = Doo::translator('Csv', $this->_basePath . 'languages/en/LC_MESSAGES/en.csv');echo $translator->translate("test");

Como usted puede ver su muy simple, el primer argumento es el tipo de archivo para la traducción y la segunda es la ruta al archivo, el tercer argumento puede ser opciones de matriz. Para CSV puede configurar opciones como: delimitador, recinto y la longitud. El valor por defecto para delimitador es ";" y para la carcasa es ".

Ahora vamos a añadir algunas opciones a nuestra llamada, digamos que queremos un delimitador de otros entonces "," y queremos añadir algo de almacenamiento en caché.$translator = Doo::translator('Csv', $this->_basePath . 'languages/en/LC_MESSAGES/main.csv', array('cache' => 'apc', 'delimiter' => '|'));

Así que ahora hemos añadido mecanismo de caché que es "APC" y hemos añadido delimitador que es "|", ahora en nuestro en.csv debemos cambiar delimitador:test|"This is just a test!"

De mecanismos de caché compatibles son "APC", "php", "XCache" y "eaccelerator". Ahora vamos a añadir marcadores de posición para traducir método:
$translator->translate("Hello [_1], wellcome to my website!", array("John"));

Esto le mostrará traducida cadena con: "Hola Juan, bienvenido a mi página web!".

Muy bien de eso, si usted tienen alguna pregunta por favor te pido, esto es una simple traducción de su clase aún en fase beta por lo que bugy puede ser poco, probarlo y por favor enviarme comentarios si usted encuentra algunos errores.

WordPress: 10 plugins para aumentar la seguridad de tu sitio

A medida que un blog comienza a crecer y gana popularidad es necesario comenzar a tomar medidas para prevenir problemas y riesgos de seguridad.

Es por eso que en este artículo les brindamos una lista con los 10 mejores plugins WordPress de seguridad para asegurar su blog de posibles hackers y otro tipo de vulnerabilidades.

1. Invisible Defender

Protege los formularios de registración, login y comentarios de spambots añadiendo dos campos extra ocultos por CSS.

Descarga| Página del Plugin

2. AskApache Password Protect

Protege tus contraseñas, los directorios wp-admin, wp-includes, wp-content y los plugins.

Descarga | Página del Plugin

3. Secure WordPress

Asegura tu instalación de WordPress, remueve la información de error en la página de ingreso, añade index.html al directorio de plugins y remueve la wp-version, excepto en el área de administración.

Descarga | Página del Plugin

4. WordPress Database Backup

Crea respaldos para tus tablas centrales de WordPress y para cualquier otra tabla que desees en la misma base de datos.

Descarga | Página del Plugin

5. WP Security Scan

Escanea tu instalación WordPress en busca de vulnerabilidades de instalación y sugiere acciones correctivas. Escanea tu blog y verifica contraseñas, permisos de archivos, seguridad de base de datos y ocultación de la versión de WP.

Descarga | Página del Plugin

6. WordPress File Monitor

Monitorea tu instalación de WordPress en busca de archivos añadidos, editados y borrados. Cuando se detecta un cambio se envía un e-mail de alerta a la dirección que especifiques.

Descarga| Página del Plugin

7. Force SSL

Fuerza una conexión HTTPS con propósitos de seguridad. El SSL forzado simplemente redirige la petición realizada por medio del http regular viejo para solicitar nuevos https confiables, y eso es básicamente todo.

Download | Página del Plugin

8. Admin SSL

Asegura el login de WordPress y las páginas de administración. Soporta todas las configuraciones SLL y encripta contenidos cookie.

Descarga| Página del Plugin

9. Replace WP-Version

Este pequeño plugin asegura tu instalación de WordPress y elimina o reemplaza tu versión de WP y versión de base de datos.

Descarga | Página del Plugin

10. WP-dephorm

Protege a tus usuarios de phorm. Esto se logra programando una cookie para que no opte por la información del phorm minado. Los visitantes de tu blog no tendrán información almacenada ahí y utilizada en campañas de marketing mientras visitan tu sitio.

Descarga | Página del Plugin

Fuente: elwebmaster.com

Memorari – Recibe avisos por chat, email y teléfono

memorari

Memorari es un sistema que nos permite recibir avisos en diferentes canales de comunicación.

Solamente tenemos que indicar el día y hora junto con el mensaje y el medio por el que queremos ser avisados, recibiendo el texto puntualmente para evitar olvidar algo importante.

Muy fácil de usar y bastante práctico.

Fuente: wwwhatsnew.com

SlickPlan – Crea diagramas de flujo y sitemaps en la web

slickplan

SlickPlan es una aplicación que nos permite dibujar diagramas de flujo de estados y mapas para sites sin necesidad de instalar nada en nuestro ordenador.

Se pueden dibujar los elementos representado la transición de estados y exportar los diagramas en PDF, permitiendo compartirlos o usarlos para documentar sistemas.

La funcionalidad de creación de sitemaps es excelente, permitiendo colgar las páginas en orden jerárquico y exportar el resultado en HTML para poder mostrarlo en cualquier sitio web:

paginas

Esta última opción me recuerda bastante a SlickMap CSS, del que os hablé hace unos meses por aquí mismo.

Fuente: wwwhatsnew.com

DooFlashMessenger con DooPHP

Hola chicos, DooFlashMessenger está aquí, en este tutorial voy a explicar cómo se puede utilizar con tan sólo 3 líneas de código. Lo mismo que usted tiene en observaciones de clases.

Bueno te permite empezar, comenzamos con las llamadas de clase:$flash = new DooFlashMessenger();

Ahora tenemos que dar acceso a DooFlashMessenger de la vista, lo hacemos de esta manera:DooController::view()->flashMessenger = $flash;

Cuando se puede acceder desde el fin de flashMessenger podemos mostrar mensajes desde flashMessenger, lo hacemos con displayMesssages() method. Here es el código que necesita tener en su archivo de plantilla:$flash->displayMessages();

Ahora sólo tienes que añadir algún mensaje para Flash Messenger, el mensaje se almacenará en la sesión, con la siguiente ejecución DooFlashMessenger clase de mensajes que se almacenan en la sesión se imprimirá con displayMessages() método. Llamadas displayMessages() método se hará eco de todos los mensajes que se almacenan.

Adición de mensajes a flashMessenger se hace llamando a addMessage método:

$flash->addMessage("This is just test message");

Link en Ingles: link

33 Sitios web para bajar archivos vetoriales

Vector-Images

Adobe

Adobe

Today-Free

Today-Free

Ndesign-studio

Ndesign-studio

Snap2objects

snap2objects

Designers Revolution

designers-revolution

Smashing Magazine

Smashing-magazine

Vector Cartoons

Vector-Cartoons

Vibr8bros

vibr8bros

Free Logotypes

free-logotypes

Deviantart

devianstart

Design Bum

Design-Bum

Magic People

magic-people

Vectorvault

vectorvault

Cool Vectors

cool-vectors

Dr-Depot

dr-depot

Createsk8

createsk8

Vector Stock

Vector-Stock

Vectors Workshop

vectors-workshop

The Pixlpusher

the-pixlpusher

All The Flags of The World

all-the-flags-of-the-world

SVG-Cards

svg-cards

BrainCorp

braincorp

VectorJunky

vectorjunky

Vector Portal

vector-portal

KeepDesigning

keepdesigning

RoundPixel

roundpixel

FreeVectors

freevectors

QVectors

qvectors

Bittbox

bittbox

Vecteezy

vecteezy

Vector4Free

vectors4free

GoMediaZine

gomediazine

Vector Wallpapers

Vector-wallpapers

Fuente: wwwhatsnew.com