<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>Jorge Iván Meza Martínez &#187; CodeIgniter</title>
	<atom:link href="http://blog.jorgeivanmeza.com/tag/codeigniter/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jorgeivanmeza.com</link>
	<description>The Fire Within Me: &#34;knowledge will set you free&#34;</description>
	<lastBuildDate>Thu, 22 Jul 2010 06:31:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3397</generator>
		<item>
		<title>Integración de una autenticación externa con los foros de Simple Machines 1.1.11</title>
		<link>http://blog.jorgeivanmeza.com/2010/05/integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11</link>
		<comments>http://blog.jorgeivanmeza.com/2010/05/integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11/#comments</comments>
		<pubDate>Mon, 10 May 2010 20:59:12 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Autenticación]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Foros]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[Integración]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=2429</guid>
		<description><![CDATA[Introducción. La situación es la siguiente, se cuenta con un CMS desarrollado en PHP bajo el framework de CodeIgniter con su propio sistema de autenticación en el que se almacenan los usuarios de la siguiente manera. CREATE TABLE IF NOT EXISTS `core_usuario` ( `id_usuario` int(11) unsigned NOT NULL auto_increment, `estado` enum(&#8216;activo&#8217;,'inactivo&#8217;) NOT NULL, `_username` varbinary(16) [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>La situación es la siguiente, se cuenta con un CMS desarrollado en <a href="http://php.net/" target="_blank">PHP</a> bajo el <em>framework</em> de <a href="http://codeigniter.com/" target="_blank">CodeIgniter</a> con su propio sistema de autenticación en el que se almacenan los usuarios de la siguiente manera.</p>
<p><span style="font-family: courier new,courier;">CREATE TABLE IF NOT EXISTS `<strong>core_usuario</strong>` (<br />
<strong> `id_usuario` int(11) unsigned NOT NULL auto_increment,</strong><br />
<strong>`estado` enum(&#8216;activo&#8217;,'inactivo&#8217;) NOT NULL,<br />
</strong><strong> `_username` varbinary(16) NOT NULL,<br />
`_password` varbinary(32) NOT NULL,<br />
`nombres` varchar(50) NOT NULL,<br />
`apellidos` varchar(50) NOT NULL,<br />
</strong>`fecha_nacimiento` date default NULL,<br />
`tipo_documento` enum(&#8216;cc&#8217;,'ce&#8217;,'ti&#8217;,'nit&#8217;) NOT NULL,<br />
`documento_identidad` varchar(12) NOT NULL,<br />
`genero` enum(&#8216;m&#8217;,'f&#8217;) NOT NULL,<br />
`correo` varchar(255) NOT NULL,<br />
`pagina` varchar(255) default NULL,<br />
`observaciones` varchar(255) default NULL,<br />
`fecha_creacion` datetime NOT NULL,<br />
`fecha_actualizacion` datetime NOT NULL,<br />
PRIMARY KEY  (`id_usuario`),<br />
);</span></p>
<p>En el sitio se ha instalado un foro basado en la versión 1.1.11 de <a href="http://www.simplemachines.org/" target="_blank">Simple Machines</a> el cual comparte la base de datos con el CMS.  Se necesita encontrar la forma de unificar los nombres de los usuarios y las contraseñas para tener una única identificación para la autenticación en los dos sistemas.</p>
<p>Para hacer esto se utiliza el API de <a href="http://docs.simplemachines.org/index.php?topic=400.0" target="_blank">SSI</a> de SMF de la siguiente manera.</p>
<h2>Hooks de integración.</h2>
<p>SMF provee una facilidad para alterar el ciclo de flujo del software mediante la manipulación de <em>hooks</em> que se agregan a etapas específicas del programa para modificar su comportamiento por defecto.  En este caso nos interesa crear un <em>hook</em> sobre el punto <a href="http://www.simplemachines.org/community/index.php?topic=173483.msg1106028#msg1106028" target="_blank"><span style="font-family: courier new,courier;">integrate_validate_login</span></a> ya que ese es el punto exacto en que SMF va a realizar la validación de los usuarios durante su autenticación.</p>
<p>Para implementar esto se crea un archivo llamado <span style="font-family: courier new,courier;">jimhook.php</span> (el nombre es arbitrario) con el siguiente contenido inicial.</p>
<pre class="php">&lt;?php
define('SMF_INTEGRATION_SETTINGS', serialize(array(
    'integrate_validate_login' =&gt; 'user_validate',
)));
require_once('SSI.php');
function user_validate()
{
    // Implementación de la lógica de la nueva autenticación.
}
?&gt;</pre>
<p>Estos <em>hooks</em> deben asociarse al sistema de foros agregando la siguiente línea al inicio del archivo <span style="font-family: courier new,courier;">index.php</span>.</p>
<pre class="php">include_once("jimhook.php");</pre>
<h2>Conexión a la base de datos.</h2>
<p>Como se mencionó inicialmente el CMS fue desarrollado en CodeIngniter y en este caso, comparte la base de datos con los foros.  El primer paso es obtener la información de conexión a la base de datos desde los archivos de configuración del CMS.</p>
<pre class="php">define('BASEPATH', 1);
include('../pt/system/application/config/database.php');</pre>
<p>Teniendo esta información se realiza una conexión global a la base de datos utilizando las funciones de PDO.</p>
<pre class="php">$pdo = null;
try
{
    $pdo = new PDO("mysql:host={$db['default']['hostname']};dbname={$db['default']['database']}",
                   $db['default']['username'],
                   $db['default']['password'],
                   array(PDO::MYSQL_ATTR_INIT_COMMAND =&gt; "SET NAMES utf8")
    );
}
catch (PDOException $e)
{
    print "Error!: " . $e -&gt; getMessage() . "&lt;br/&gt;";
    die();
}</pre>
<h2>Funciones de apoyo del CMS.</h2>
<p>Se crean algunas funciones básicas que servirán de soporte para el nuevo procedimiento de autenticación.</p>
<pre class="php">function existeUsuarioEnPlataforma($usuario)
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("SELECT id_usuario FROM `usuarios` WHERE user=?");
    $results = $stmt -&gt; execute(array($usuario));
    return ($stmt -&gt; rowCount() &gt; 0);
}</pre>
<p>Verifica si el usuario identificado por el nombre de usuario (<span style="font-family: courier new,courier;">$usuario</span>) existe o no registrado en el CMS.  Retorna <span style="font-family: courier new,courier;">true</span> o <span style="font-family: courier new,courier;">false</span> según se encuentren o no efectivamente registrados.</p>
<pre class="php">function autenticarUsuarioEnPlataforma($usuario, $contrasena)
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("SELECT id_usuario FROM `usuarios` WHERE user=? AND pass=?");
    $results = $stmt -&gt; execute(array($usuario, MD5($contrasena)));
    return ($stmt -&gt; rowCount() &gt; 0);
}</pre>
<p>Verifica que el usuario identificado con el nombre de usuario (<span style="font-family: courier new,courier;">$usuario</span>) tenga efectivamente a <span style="font-family: courier new,courier;">$contraseña</span> como clave de usuario.  Retorna <span style="font-family: courier new,courier;">true</span> en caso de coincidir, <span style="font-family: courier new,courier;">false</span> de lo contrario.</p>
<p>Nótese como el CMS almacena sus contraseñas en <a href="http://co.php.net/md5" target="_blank">MD5</a> motivo por el cual es necesario realizar esta conversión antes de realizar la comparación en la consulta SQL.</p>
<h2>Funciones de apoyo de los foros.</h2>
<p>De manera análoga, estas funciones facilitan la manipulación de la información en las tablas del sistema de foros, las cuales tienen configurado el prefijo <span style="font-family: courier new,courier;">foros_</span> en sus tablas.</p>
<pre class="php">function existeUsuarioEnForos($usuario)
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("SELECT ID_MEMBER FROM foros_members WHERE memberName = ?");
    $results = $stmt -&gt; execute(array($usuario));
    if($stmt -&gt; rowCount() == 0)
        return false;
    $fuente = $stmt -&gt; fetch();
    return $fuente['ID_MEMBER'];
}</pre>
<p>Verifica si el usuario identificado por el nombre de usuario (<span style="font-family: courier new,courier;">$usuario</span>) existe o no registrado en el foro .  Retorna el identificador del usuario si existe o <span style="font-family: courier new,courier;">false</span> de lo contrario.</p>
<pre class="php">function traerUsuario($usuario, $contrasena)
{
    global $pdo, $sourcedir, $modSettings;
    if(!existeUsuarioEnPlataforma($usuario))
        return false;
    $stmt = $pdo -&gt; prepare("SELECT * FROM `usuarios` WHERE user=?");
    $results = $stmt -&gt; execute(array($usuario));
    $fuente = $stmt -&gt; fetch();
    require_once($sourcedir . '/Subs-Members.php');
    $regOptions = array('username' =&gt; $fuente['user'],
                        'password' =&gt; $contrasena,
                        'password_check' =&gt; $contrasena,
                        'email' =&gt; $fuente['email'],
                        'posts' =&gt; '0',
                        'ID_GROUP' =&gt; '0',
                        'ID_POST_GROUP' =&gt; '4');
    $memberID = registerMember($regOptions);
    return ($memberID &gt; 0);
}</pre>
<p>Obtiene la información del usuario de plataforma identificado por <span style="font-family: courier new,courier;">$usuario</span> y <span style="font-family: courier new,courier;">$contrasena</span>, y lo agrega en la base de datos del foro a través de su API interno.  A este nivel no se realiza ninguna verificación de autenticación.</p>
<pre class="php">function activarUsuarioForo($usuario, $estado='1')
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("UPDATE foros_members SET is_activated = ? WHERE memberName = ?");
    $control = $stmt -&gt; execute(array($estado, $usuario));
    return $control;
}</pre>
<p>Activa al usuario del foro recién creado, el cual por defecto siempre queda en espera de confirmación (<span style="font-family: courier new,courier;">is_activated = 3</span>).</p>
<pre class="php">function actualizarContrasenaForo($usuario, $contrasena)
{
    global $pdo;
    $passwd       = sha1(strtolower($usuario) . $contrasena);
    $passwordSalt = substr(md5(mt_rand()), 0, 4);
    $stmt = $pdo -&gt; prepare("UPDATE foros_members SET passwd = ?, passwordSalt = ? WHERE memberName = ?");
    $control = $stmt -&gt; execute(array($passwd, $passwordSalt, $usuario));
    return $control;
}</pre>
<p>Actualiza la <span style="font-family: courier new,courier;">$contrasena</span> del <span style="font-family: courier new,courier;">$usuario</span> en el sistema de foros.  Nótese como la <span style="font-family: courier new,courier;">$contrasena</span> se recibe de manera plana y se almacena en la base de datos de SMF en <a href="http://co.php.net/sha1" target="_blank">SHA1</a>.</p>
<h2>Acerca del comportamiento del <em>login</em> de SMF.</h2>
<p>Algo que se debe tener en cuenta acerca del comportamiento del <em>login </em>de SMF es que desde el cliente (navegador del usuario) se envía la contraseña ya en su propia representación SHA1 así que si la contraseña con que se va a comparar no está en la misma representación, como en este caso, el CMS la almacena en MD5, se tiene entonces un problema.</p>
<p>Para solventar esto, el sistema de foros permite solicitar nuevamente la contraseña al usuario (<em>retry</em>) y en este segundo intento la envía totalmente plana para su manipulación libre.  En este punto es donde la aprovechamos para verificar la autenticación del usuario contra la información del CMS, crear el usuario en el foro si no existe y actualizar la contraseña en el foro previniendo que haya sido actualizada antes en el CMS.</p>
<h2>Implementación del nuevo proceso de autenticación.</h2>
<pre class="php">function user_validate()
{
    $user = $_REQUEST['user'];
    $id   = 0;
    // Verificar un usuario proveniente de plataforma.
    if(existeUsuarioEnPlataforma($user))
    {
        $id = existeUsuarioEnForos($user);
        // Nueva lógica de autenticación.
    }
    // El usuario no existe en plataforma, verificar los nativos del foro.
    return false;
}</pre>
<p>La base de la nueva autenticación es entonces la definición de la función <span style="font-family: courier new,courier;">user_validate</span> que corresponde con la especificada inicialmente durante la configuración de los <em>hooks</em>.</p>
<p>En ella se verifica inicialmente si el usuario que intenta acceder al sistema (<em>login</em>) se encuentra presente o no en la base de datos de usuarios del CMS.  En caso de no estar presente el control de la autenticación se libera para que el sistema verifique sus usuarios propios, esto permite definir también usuarios internos del foro que no estén presentes en el CMS.</p>
<p>El paso siguiente consiste en determinar si el usuario existe previamente o no en el foro, es decir, no es su primer ingreso al mismo.  A partir de esta respuesta se toma uno de los siguientes caminos.</p>
<ul>
<li>Si no está disponible la contraseña plana (primer <em>login</em>) se solicita nuevamente (segundo <em>login</em>).</li>
<li>Si el usuario no existe en el foro entonces ...
<ul>
<li>Se verifica que el nombre de usuario y la contraseña coincidan.</li>
<li>Se crea el usuario en el foro.</li>
<li>Se activa al nuevo usuario.</li>
</ul>
</li>
<li>Si el usuario ya existía previamente en el foro entonces ...
<ul>
<li>Se verifica que el nombre de usuario y la contraseña coincidan.</li>
<li>Se actualiza la contraseña en el foro por si ha sido actualizada previamente en el CMS.</li>
</ul>
</li>
</ul>
<p>La implementación de estas acciones se detalla a continuación.  En el caso en que el usuario no exista previamente en el foro se ejecuta la siguiente lógica del negocio.</p>
<pre class="php">if($id === false)
{
    // Esta disponible la contrasena (2do. login).
    if(isset($_REQUEST['passwrd']) &amp;&amp; !empty($_REQUEST['passwrd']))
    {
        $auth = autenticarUsuarioEnPlataforma($user, $_REQUEST['passwrd']);
        if($auth)                           // La informacion del usuario es valida.
        {
            $id = traerUsuario($user, $_REQUEST['passwrd']);
            activarUsuarioForo($user);
            return false;                   // La autenticacion tiene EXITO.
        }
        else                                // La informacion del usuario NO es valida.
            return true;                    // La autenticacion FALLA.
    }
    else                                    // No esta disponible la contrasena (1er. login).
        return "retry";                     // Vuelva a solicitar el login para confirmar.
}</pre>
<p>En el caso en que el usuario si exista previamente en el foro, el procedimiento es mas simple y se ejecuta  la siguiente lógica del negocio.</p>
<pre class="php">// El usuario existe en el foro.
if($id !== false)
{
    // Esta disponible la contrasena (2do. login) -&gt; actualizar la contraseña en el foro.
    if(isset($_REQUEST['passwrd']) &amp;&amp; !empty($_REQUEST['passwrd']))
    {
        $auth = autenticarUsuarioEnPlataforma($user, $_REQUEST['passwrd']);
        if($auth)                           // La informacion del usuario es valida.
        {
            actualizarContrasenaForo($user, $_REQUEST['passwrd']);
            return false;                   // La autenticacion tiene EXITO.
        }
        else                                // La informacion del usuario NO es valida.
            return true;                    // La autenticacion FALLA.
    }
    else                                    // No esta disponible la contrasena (1er. login).
        return "retry";                     // Vuelva a solicitar el login para confirmar.
}</pre>
<h2>Conclusiones.</h2>
<p>Hasta ahora, con poca experiencia en su uso, SMF parece ser un sistema de foros útil y práctico.  El proceso de determinar esta unificación de la autenticación fue largo y doloroso debido a la poca documentación que pude encontrar acerca del API, la cual en su mayor parte se encuentra diseminada en los foros de su sitio web.</p>
<p>En términos de su código parece tener un nivel decente de flexibilidad, el concepto de <em>hooks</em> permite realizar modificaciones interesantes al flujo normal del software, sin embargo es difícil formalizarlo al no contar con información suficiente de su lógica de funcionamiento.  Algunas partes del software, en especial los temas, adolecen de separación MVC por lo que se hace necesario editar funciones, entre comillas, que retornan el código HTML que se desea modificar siendo esto molesto, difícil y propenso a errores, sobretodo si se compara con tener archivos PHP separados con la lógica y HTML con la presentación como sería una mejor opción.</p>
<p>Finalmente, después de varios días de luchas y de pruebas, la unificación de la autenticación está funcionando y se ve bien, de todas maneras es mi primer acercamiento a este software por lo que no puedo garantizar que sea la mejor aproximación.  Como siempre, estoy abierto a sugerencias constructivas.</p>
<h2>Enlaces.</h2>
<ul>
<li>Simple Machines.<br />
<a href="http://www.simplemachines.org/" target="_blank">http://www.simplemachines.org/</a></p>
<ul>
<li>A guide to the SMF integration hooks.<br />
<a href="http://www.simplemachines.org/community/index.php?topic=173483.0" target="_blank">http://www.simplemachines.org/community/index.php?topic=173483.0</a></li>
</ul>
</li>
<li>CodeIgniter.<br />
<a href="http://codeigniter.com/" target="_blank">http://codeigniter.com/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2010/05/integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Presentación de Sismos recientes en Colombia</title>
		<link>http://blog.jorgeivanmeza.com/2009/04/presentacion-de-sismos-recientes-en-colombia/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=presentacion-de-sismos-recientes-en-colombia</link>
		<comments>http://blog.jorgeivanmeza.com/2009/04/presentacion-de-sismos-recientes-en-colombia/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 04:58:52 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Proyectos]]></category>
		<category><![CDATA[Sqlite]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1624</guid>
		<description><![CDATA[Sismos recientes en Colombia es una aplicación de agregación de contenido que permite visualizar de manera gráfica en la geografía Colombiana la ubicación de los sismos que han sucedido en el territorio nacional, tanto los [últimos diez] destacados por su intensidad como la actividad sísmica completa de la semana anterior.  Esta información se actualiza casi [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1625" class="wp-caption aligncenter" style="width: 665px"><a href="http://blog.jorgeivanmeza.com/wp-content/uploads/2009/04/sismosrecientesscreenshot.png"><img class="size-full wp-image-1625" title="sismosrecientesscreenshot" src="http://blog.jorgeivanmeza.com/wp-content/uploads/2009/04/sismosrecientesscreenshot.png" alt="Sismos recientes en Colombia" width="655" height="486" /></a><p class="wp-caption-text">Sismos recientes en Colombia</p></div>
<p><a href="http://sismos.jorgeivanmeza.com/" target="_blank">Sismos recientes en Colombia</a> es una aplicación de agregación de contenido que permite visualizar de manera gráfica en la geografía Colombiana la ubicación de los sismos que han sucedido en el territorio nacional, tanto los [últimos diez] destacados por su intensidad como la actividad sísmica completa de la semana anterior.  Esta información se actualiza casi en tiempo real, con una diferencia de al rededor de 3o minutos después del suceso, gracias a los servicios de la <a href="http://seisan.ingeominas.gov.co/RSNC/RSNC.php" target="_blank">Red Sismológica Nacional</a> del <a href="http://www.ingeominas.gov.co/" target="_blank">Instituto Colombiano de Geología y Minería</a>.</p>
<p>La base del proyecto fue desarrollado en una semana de descanso utilizando casi por completo Software Libre.  Se construyó utilizando <a href="http://www.php.net/" target="_blank">PHP</a>, <a href="http://en.wikipedia.org/wiki/XHTML" target="_blank">HTML</a>/<a href="http://en.wikipedia.org/wiki/Css" target="_blank">CSS</a>/<a href="http://en.wikipedia.org/wiki/Javascript" target="_blank">Javascript</a>/<a href="http://en.wikipedia.org/wiki/Ajax_(programming)" target="_blank">AJAX</a>, <a href="http://www.jquery.com/" target="_blank">jQuery</a>, <a href="http://www.codeigniter.com/" target="_blank">CodeIgniter</a>, <a href="http://www.swiftmailer.org/" target="_blank">SwiftMailer</a>, <a href="http://www.sqlite.org/" target="_blank">SQLite</a>,  <a href="http://www.zend.com/en/community/pdt/" target="_blank">Eclipse PDT</a> y<a href="http://maps.google.com/" target="_blank"> Google Maps</a>.  La aplicación aún se encuentra en progreso, alias <em>beta</em>, así que aún tengo pensando hacerle varias mejoras y complementos.</p>
<p>Actualmente el sitio web permite consultar la información de los sismos destacados y de los sismos diarios de la semana en curso, la información georreferenciada se despliega en el mapa gráficamente desde donde se puede acceder a la información disponible del sismo.  El último sismo destacado sucedido cuenta con un enlace a la RSNC donde se amplía su información.  Las fechas y horas hacen referencia al territorio colombiano, es decir, GMT-5.  Adicionalmente la aplicación cuenta con un sistema de <a href="http://en.wikipedia.org/wiki/Cache" target="_blank">caché</a> que permite agilizar la presentación de información cuando esta se encuentra fresca en el sistema y de refrescarla en ciertos intervalos, disminuyendo la consulta a las fuentes de datos y el tiempo de generación del contenido.</p>
<p>He planeado realizar las siguientes mejoras a la aplicación sin ningún orden necesario.</p>
<ul>
<li>Mejorar los colores de la presentación.  Los actuales son de prueba, estoy buscando a alguien que si sepa del tema para que me asesore.</li>
<li>Establecer <em>tooltips</em> informativos para facilitar la utilización del sitio.</li>
<li>Verificar la viabilidad de crear un mapa del sitio (<em>sitemap</em>) que facilite las búsquedas de contenido en el sitio.</li>
<li>Establecer un procedimiento <em>cron</em> que actualice la inforamción aún sin la consulta de visitantes.</li>
<li>Establecer la comunicación con otras aplicaciones como Twitter.</li>
<li>Establecer valores finales para la duración de los <em>cachés</em> de información.</li>
<li>Implementar un módulo de <em>Contáctenos</em>.</li>
<li>Crear una versión móvil que muestre la información resumida.</li>
<li>Implementar un indicador que le muestre al usuario en que sección del sistema se encuentra.</li>
<li>Verificar el cumplimiento [en lo posible] de XHTML.</li>
<li>Establecer la viabilidad de incluír información de sismos de otros lugares del mundo como valor agregado al sitio.</li>
</ul>
<p>La aplicación, [con optimismo] al igual que las cosas buenas del mundo, se encuentra licenciado bajo <a href="http://creativecommons.org/licenses/by-nc-sa/2.5/co/" target="_blank">CC NC-SA</a> así que su código será liberado tan pronto como termine de implementar las principales mejoras y lo documente para dejarlo apto para el consumo humano.</p>
<p>Si alguien tiene alguna sugerencia acerca de como mejorar esta aplicación me gustaría mucho que lo compartiera conmigo.</p>
<h2>Enlaces.</h2>
<ul>
<li>Sismos recientes en Colombia.<br />
<a href="http://sismos.jorgeivanmeza.com/" target="_blank">http://sismos.jorgeivanmeza.com/</a></li>
<li>Registro de cambios.<br />
<a href="http://sismos.jorgeivanmeza.com/site/about/index" target="_blank">http://sismos.jorgeivanmeza.com/site/about/index</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/04/presentacion-de-sismos-recientes-en-colombia/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Remover el index.php de las rutas de CodeIgniter</title>
		<link>http://blog.jorgeivanmeza.com/2009/04/remover-el-indexphp-de-las-rutas-de-codeigniter/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=remover-el-indexphp-de-las-rutas-de-codeigniter</link>
		<comments>http://blog.jorgeivanmeza.com/2009/04/remover-el-indexphp-de-las-rutas-de-codeigniter/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 15:13:46 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[DreamHost]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1613</guid>
		<description><![CDATA[Para hacer esto se hace uso de las capacidades de sobreescritura de URLs de Apache.  Se debe agregar un archivo .htaccess en la raíz del sitio web con el siguiente contenido. RewriteEngine on RewriteCond $1 !^(index\.php&#124;images&#124;robots\.txt) RewriteRule ^(.*)$ index.php/$1 [L] En servidores de Dreamhost he tenido un mejor éxito utilizando la siguiente versión. RewriteEngine on [...]]]></description>
			<content:encoded><![CDATA[<p>Para hacer esto se hace uso de las capacidades de sobreescritura de URLs de Apache.  Se debe agregar un archivo <span style="font-family: courier new,courier;">.htaccess</span> en la raíz del sitio web con el siguiente contenido.</p>
<pre class="javascript">RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]</pre>
<p>En servidores de <a href="http://www.dreamhost.com/">Dreamhost</a> he tenido un mejor éxito utilizando la siguiente versión.</p>
<pre class="javascript">RewriteEngine on
RewriteCond $1 !^(index\.php|public|user_guide|media|robots\.txt)
RewriteRule ^(.*)$ index.php?/$1 [L]</pre>
<p>Adicionalmente es necesario indicarle a CodeIgniter que ya no agregue artificialmente el archivo <span style="font-family: courier new,courier;">index.php</span> a los URL de la siguiente manera.  Edite el archivo <span style="font-family: courier new,courier;">config/config.php</span> y modifique la siguiente llave.</p>
<pre class="javascript">$config['index_page'] = "index.php";</pre>
<p>De forma que quede de la siguiente manera.</p>
<pre class="javascript">$config['index_page'] = "";</pre>
<h2>Enlaces.</h2>
<ul>
<li>CodeIgniter URLs.<br />
<a href="http://codeigniter.com/user_guide/general/urls.html" target="_blank">http://codeigniter.com/user_guide/general/urls.html</a></li>
<li>Dreamhost .htaccess.<br />
<a href="http://codeigniter.com/wiki/Dreamhost_.htaccess/" target="_blank">http://codeigniter.com/wiki/Dreamhost_.htaccess/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/04/remover-el-indexphp-de-las-rutas-de-codeigniter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducción al MVC de CodeIgniter - Parte I</title>
		<link>http://blog.jorgeivanmeza.com/2009/03/introduccion-al-mvc-de-codeigniter-parte-i/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=introduccion-al-mvc-de-codeigniter-parte-i</link>
		<comments>http://blog.jorgeivanmeza.com/2009/03/introduccion-al-mvc-de-codeigniter-parte-i/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 14:29:36 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://www.jorgeivanmeza.com/blog/?p=1555</guid>
		<description><![CDATA[Controladores. Actúa como intermediario entre el requerimiento del usuario y, los modelos, las vistas y otros recursos que generan su respuesta. Su clase base es Controller. Su identificador empieza con minúsculas: user. El nombre de su clase empieza con mayúsculas: User. El nombre de archivo coincide con el identificador y la extensión .php. Se almacenan [...]]]></description>
			<content:encoded><![CDATA[<h2>Controladores.</h2>
<ul>
<li>Actúa como intermediario entre el requerimiento del usuario y, los modelos, las vistas y otros recursos que generan su respuesta.</li>
<li>Su clase base es <span style="font-family: courier new,courier;">Controller</span>.</li>
<li>Su identificador empieza con minúsculas: <span style="font-family: courier new,courier;">user</span>.</li>
<li>El nombre de su clase empieza con mayúsculas: <span style="font-family: courier new,courier;">User</span>.</li>
<li>El nombre de archivo coincide con el identificador y la extensión <span style="font-family: courier new,courier;">.php</span>.</li>
<li>Se almacenan bajo <span style="font-family: courier new,courier;">application/controllers</span>.  Es posible agrupar controladores en subdirectorios, estas rutas se deberán ver reflejadas en el requerimiento del usuario.</li>
<li>Si se define un constructor para el controlador: <span style="font-family: courier new,courier;">__construct</span> para PHP5, su primera instrucción deberá ser invocar al constructor padre: <span style="font-family: courier new,courier;">parent::Controller()</span>.</li>
<li>Las acciones (o funciones) corresponden con los métodos del controlador y es allí donde se implementa su lógica.</li>
<li>Los nombres de las acciones comienzan con minúsculas.</li>
<li>Las acciones pueden recibir información adicional del requerimiento de usuario a través de sus parámetros.</li>
<li>El controlador por defecto es <span style="font-family: courier new,courier;">welcome</span>, esto personalizarse modificando el valor de <span style="font-family: courier new,courier;">$route['default_controller']</span> en <span style="font-family: courier new,courier;">application/config/routes.php</span>.</li>
<li>La acción por defecto es <span style="font-family: courier new,courier;">index</span>.</li>
<li>Los controladores y las acciones por defecto son utilizadas si el usuario no las referencia explícitamente en su requerimiento.</li>
<li>Para definir métodos privados en el controlador que no serán tomados en cuenta como acciones, deberán declararse como <span style="font-family: courier new,courier;">private</span> o <span style="font-family: courier new,courier;">protected</span> (PHP5) y su nombre deberá empezar por un guión-bajo (PHP 4 y 5).</li>
<li>Es posible personalizar la manipulación de las acciones de un controlador sobreescribiendo el método <span style="font-family: courier new,courier;">_remap($method)</span> del último.  No es frecuente hacerlo.</li>
<li>Es posible manipular, como postprocesar, la información que va a ser enviada de regreso al usuario desde un controlador sobreescribiendo su método <span style="font-family: courier new,courier;">_output($output)</span>.  No es frecuente hacerlo.</li>
</ul>
<p>[source='php']<br />
// Archivo application/controllers/user.php</p>
<p>class User extends Controller<br />
{<br />
	public function __construct()<br />
	{<br />
		parent::Controller();<br />
		// Constructor del controlador.<br />
	}</p>
<p>	public function index()<br />
	{<br />
		// Acción por defecto.<br />
	}</p>
<p>	public function changeName($firstName, $lastName)<br />
	{<br />
		// Acción con parámetros enviados desde el requerimiento.<br />
	}</p>
<p>	private function _myInternalMethod()<br />
	{<br />
		// Método privado no acción.<br />
	}<br />
}<br />
[/source]</p>
<h2>Vistas.</h2>
<ul>
<li>Se encarga de preparar y organizar la información resultante que será presentada al usuario como respuesta a su requerimiento.</li>
<li>Son archivos con contenido XHTML y PHP.</li>
<li>No son invocados directamente, son utilizados por los controladores.</li>
<li>El nombre de su identificador puede ser arbitrario.</li>
<li>El nombre del archivo será su identificador junto con la extensión <span style="font-family: courier new,courier;">.php</span>.</li>
<li>Se almacenan bajo <span style="font-family: courier new,courier;">application/views</span>.  Es posible agrupar vistas en subdirectorios, estas rutas se deberán ver reflejadas en su llamado desde el controlador.</li>
<li>Para cargar una vista desde el controlador: <span style="font-family: courier new,courier;">$this -&gt; load -&gt; view(&#8216;ruta/archivo&#8217;)</span>.  La extensión de la vista puede omitirse si se utilizó la extensión por defecto.</li>
<li>Este método envía inmediatamente el contenido de la vista procesada al usuario.</li>
<li>Es posible enviar información desde el controlador hacia la vista modificando su carga: <span style="font-family: courier new,courier;">$this -&gt; load -&gt; view(&#8216;ruta/archivo&#8217;, $data)</span>.</li>
<li><span style="font-family: courier new,courier;">$data</span> puede ser un arreglo relacional o un objeto.  En el primer caso, las celdas del arreglo se convierten en variables de la vista siendo el índice de cada celda el nombre y el contenido su correspondiente valor de la variable.  De igual manera ocurre en el segundo caso, convirtiéndose en variables de la vista a los atributos del objeto.</li>
<li>Es posible cargar una vista y almacenarla en una variable para su posterior uso en lugar de enviarla directamente al usuario: <span style="font-family: courier new,courier;">$myView = $this -&gt; load -&gt; view(&#8216;ruta/archivo&#8217;, $data, <strong>true</strong>)</span>.</li>
</ul>
<p>[source='php']<br />
// Archivo application/controllers/user.php</p>
<p>class User extends Controller<br />
{<br />
	public function index()<br />
	{<br />
		$data['title'] = &#8220;System Administration&#8221;;<br />
		$data['suibtitle'] = &#8220;User management&#8221;;</p>
<p>		$this -> load -> view(&#8216;user/index&#8217;, $data);<br />
	}<br />
}</p>
<p>// Archivo application/views/user/index.php</p>
<p><html><br />
	<head></p>
<p>	</head><br />
	<body></p>
<h1>< ?php echo $subtitle; ?></h1>
<p>	</body><br />
</html></p>
<p>[/source]</p>
<h2>Modelos.</h2>
<ul>
<li>Representan a la lógica del negocio y la información del sistema.</li>
<li>Su clase base es <span style="font-family: courier new,courier;">Model</span>.</li>
<li>Su identificador empieza con minúsculas: <span style="font-family: courier new,courier;">user</span>.</li>
<li>El nombre de su clase corresponde con el identificador empezando con mayúsculas y terminando con el postfijo <span style="font-family: courier new,courier;">_model</span>: <span style="font-family: courier new,courier;">User</span><span style="font-family: courier new,courier;">_model</span>.</li>
<li>El nombre de archivo coincide con el nombre de la clase en minúsculas y la extensión <span style="font-family: courier new,courier;">.php</span>: <span style="font-family: courier new,courier;">user_model.php</span>.</li>
<li>Se almacenan bajo <span style="font-family: courier new,courier;">application/models</span>.  Es posible agrupar modelos en subdirectorios, estas rutas se deberán ver reflejadas en el momento de invocarlos.</li>
<li>Si se define un constructor para el modelo: <span style="font-family: courier new,courier;">__construct</span> para PHP5, su primera instrucción deberá ser invocar al constructor padre: <span style="font-family: courier new,courier;">parent::Model()</span>.</li>
<li>Para cargar un modelo desde el controlador: <span style="font-family: courier new,courier;">$this -&gt; load -&gt; model(&#8216;ruta/Nombre_modelo&#8217;)</span>.  Esto comúnmente se realiza en el constructor de la clase que lo utiliza para garantizar su uso a todo su largo.</li>
<li>Después de cargado el modelo puede utilizarse de la siguiente manera: <span style="font-family: courier new,courier;">$this -&gt; Nombre_modelo -&gt; método()</span>.</li>
<li>Es posible especificar el nombre del objeto donde se cargan los modelos: <span style="font-family: courier new,courier;">$this -&gt; load -&gt; model(&#8216;ruta/Nombre_modelo&#8217;, <strong>&#8216;otroNombre&#8217;</strong>)</span>, esto permite acceder a él de la siguiente manera: <span style="font-family: courier new,courier;">$this -&gt; <strong>otroNombre</strong> -&gt; método()</span>.</li>
<li>Un tercer parámetro enviado durante la carga de un modelo le permite a este <em>autoconectarse</em> a la base de datos del sistema: <span style="font-family: courier new,courier;">$this -&gt; load -&gt; model(&#8216;ruta/Nombre_modelo&#8217;, &#8216;&#8217;, <strong>true</strong>)</span>.</li>
<li>Es posible indicarle al framework que cargue automáticamente una lista de modelos al listarlos en el arreglo <span style="font-family: courier new,courier;">$autoload['model']</span> de <span style="font-family: courier new,courier;">application/config/autoload.php</span>.</li>
</ul>
<p>[source='php']<br />
// Archivo application/controllers/user.php</p>
<p>class User extends Controller<br />
{<br />
	function __construct()<br />
	{<br />
		parent::Controller();<br />
		$this -> load -> model(&#8216;admin/user&#8217;);<br />
	}</p>
<p>	public function index()<br />
	{<br />
		$data['info'] = $this -> User -> miMetodo();</p>
<p>		$this -> load -> view(&#8216;user/index&#8217;, $data);<br />
	}<br />
}</p>
<p>// Archivo application/models/admin/user.php</p>
<p>class User_model extends Model<br />
{<br />
	function __construct()<br />
	{<br />
		parent::Model();<br />
	}</p>
<p>	public function miMetodo()<br />
	{<br />
		// Implementación de la lógica del negocio<br />
	}<br />
}</p>
<p>[/source]</p>
<h2>Requerimiento del usuario.</h2>
<ul>
<li>El requerimiento del usuario incluye la información que encapsula su solicitud, así como todos los datos requeridos interpretarla.</li>
<li>La información proviene desde dos fuentes: el URL (dirección) y el contenido POST (formularios).</li>
<li>El URL por defecto sigue este formato: <span style="font-family: courier new,courier;">server.com/index.php/controller/action/data</span><span style="font-family: courier new,courier;">1/data2</span>.  Cada parte del URL es conocida como un segmento.  Los segmentos <span style="font-family: courier new,courier;">controller</span> y <span style="font-family: courier new,courier;">action</span> corresponden con los identificadores del controlador y de la acción, incluyendo las rutas adicionales si se utilizaron, que son requeridos por el usuario.</li>
<li>Los segmentos adicionales (<span style="font-family: courier new,courier;">data1</span> y <span style="font-family: courier new,courier;">data2</span>) son pasados a la acción como parámetros del método.</li>
<li>La información enviada a través de variables POST, como es el caso de los formularios, es recibida a través de la clase <a href="http://codeigniter.com/user_guide/libraries/input.html" target="_blank"><span style="font-family: courier new,courier;">Input</span></a> de la seiguiente manera: <span style="font-family: courier new,courier;">$this -&gt; input -&gt; post(&#8216;nombreVariable&#8217;, <strong>true</strong>)</span>.  El segundo parámetro (booleano) indica si la variable debe ser o no pasada por el filtro XSS de contenido antes de ser accedida.</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Model, View and Controller.<br />
<a href="http://codeigniter.com/user_guide/overview/mvc.html" target="_blank">http://codeigniter.com/user_guide/overview/mvc.html</a></li>
<li>Controllers.<br />
<a href="http://codeigniter.com/user_guide/general/controllers.html" target="_blank">http://codeigniter.com/user_guide/general/controllers.html</a></li>
<li>Views.<br />
<a href="http://codeigniter.com/user_guide/general/views.html" target="_blank">http://codeigniter.com/user_guide/general/views.html</a></li>
<li>Models.<br />
<a href="http://codeigniter.com/user_guide/general/models.html" target="_blank">http://codeigniter.com/user_guide/general/models.html</a></li>
<li>URLs.<br />
<a href="http://codeigniter.com/user_guide/general/urls.html" target="_blank">http://codeigniter.com/user_guide/general/urls.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/03/introduccion-al-mvc-de-codeigniter-parte-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Instalación de CodeIgniter 1.7.x en Linux</title>
		<link>http://blog.jorgeivanmeza.com/2009/03/instalacion-de-codeigniter-17x-en-linux/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=instalacion-de-codeigniter-17x-en-linux</link>
		<comments>http://blog.jorgeivanmeza.com/2009/03/instalacion-de-codeigniter-17x-en-linux/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 02:44:38 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://www.jorgeivanmeza.com/blog/?p=1550</guid>
		<description><![CDATA[Introducción. CodeIgniter es un framework muy interesante para el desarrollo de aplicaciones web.  Lo he estado utilizando por dos años y ha sido muy útil.  Su curva de aprendizaje no es muy pronunciada lo que ha facilitado que desarrolladores no muy experimentados lo aprendan a usar rapidamente.  Su misión es la de proveer una base [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>CodeIgniter es un <em>framework</em> muy interesante para el desarrollo de aplicaciones web.  Lo he estado utilizando por dos años y ha sido muy útil.  Su curva de aprendizaje no es muy pronunciada lo que ha facilitado que desarrolladores no muy experimentados lo aprendan a usar rapidamente.  Su misión es la de proveer una base para el desarrollo de aplicaciones web con PHP brindándonos una serie de herramientas y estructuras facilitadoras que, gracias a su arquitectura desacoplada, no son obligatorias ni restringen el uso de facilidades de terceros.  Es un <em>framework</em> general, es útil y flexible, y no es el mas complejo o restrictivo del mercado.</p>
<p><a href="http://en.wikipedia.org/wiki/CodeIgniter#Properties" target="_blank">Ventajas</a> tiene muchas, algunas de las cuales ya he mencionado: fácil aprendizaje, flexible, desacoplado, buen desempeño en términos de tiempo de ejecución y consumo de memoria, muy utilizado y bien documentado.  En pocas palabras, utilizar CodeIgniter le permitirá desarrollar PHP de la misma forma como lo realizaba anteriormente pero de una manera mas estructurada y con algunas herramientas que le permitirán agilizar su implementación.</p>
<p>Como desventajas se encuentra el hecho de que su desarrollo recaiga sobre un sólo hombre, <a href="http://derekallard.com/about/" target="_blank">Derek Allard</a>, haciendo que su proceso de actualización fuera lento en comparación con los deseos de la comunidad; sin embargo he estado leyendo un poco acerca de que ahora es un grupo de personas quienes lideran el desarrollo del <em>framawork</em> motivo por el cual me imagino que esto ha cambiado.  Una desventaja muy mencionada es su empeño por seguir soportando PHP4 además de PHP5 impidiéndole tomar ventaja de las mejoras que trajo el lenguaje en su última versión.  Otro punto en contra de CodeIgniter es que podría mejorarse su orientación a objetos en varios aspectos (probablemente producido por lo mencionado anteriormente), por ejemplo, los ayudantes (<em>helpers</em>) son en realidad una <em>librería</em> de funciones.</p>
<p>Por estos motivos un subconjunto de sus seguidores decidió hacer un <a href="http://en.wikipedia.org/wiki/Fork_(software_development)" target="_blank"><em>fork</em></a> del proyecto para implementar su propias mejoras.  Este fue el nacimiento de <a href="http://kohanaphp.com/" target="_blank">Kohana</a>.  Con este nuevo framework estoy desarrollando un proyecto desde hace unos seis meses y su implementación ha sido muy placentera, aunque no se si por las mejoras en el <em>framework</em> o por lo la calidad y lo interesante del proyecto.  Sobra decir que la <a href="http://docs.kohanaphp.com/installation/migration" target="_blank">migración de CodeIgniter a Kohana</a> es un proceso indoloro.  Pero no todo es color de rosa, actualmente la principal ventaja de Kohana es su propio punto débil: su comunidad activa y ávida de mejoras realiza modificaciones al <em>framework</em> frecuentemente haciendo que, según leo en los foros, la próxima versión que saldrá en el presente año no será <a href="http://en.wikipedia.org/wiki/Backward_compatibility" target="_blank">compatible con versiones anteriores</a>, haciendo que en este momento no sea idónea para desarrollar proyectos a largo plazo.  CodeIgniter por su parte a probado ser bastante estable y a documentar los <a href="http://codeigniter.com/user_guide/installation/upgrading.html" target="_blank">cambios necesarios para actualizar sus versiones</a>, que de paso no sobra decirlo, siempre es conveniente mantenerse al día con la última versión disponible.</p>
<h2>Obtención del <em>framework</em>.</h2>
<p>El objetivo de este paso es el de obtener los archivos de la distribución mas reciente de CodeIgniter que se va a instalar.</p>
<p><span style="font-family: courier new,courier;">$ cd /home/www</span></p>
<p><span style="font-family: courier new,courier;">$ wget http://codeigniter.com/download.php</span></p>
<h2>Instalación del <em>framework</em> en una ubicación privada.</h2>
<p>Como se mencionó, el <em>framework</em> se instalará en una ubicación privada y podrá ser compartido por múltiples aplicaciones.  Se crea un enlace dinámico (<span style="font-family: courier new,courier;">current</span>) para facilitar la actualización de versiones del <em>framework</em>.</p>
<p><span style="font-family: courier new,courier;">$ unzip CodeIgniter_1.7.1.zip</span></p>
<p><span style="font-family: courier new,courier;">$ rm CodeIgniter_1.7.1.zip</span></p>
<p><span style="font-family: courier new,courier;">$ mkdir codeigniter</span></p>
<p><span style="font-family: courier new,courier;">$ mv CodeIgniter_1.7.1 codeigniter/1.7.1</span></p>
<p><span style="font-family: courier new,courier;">$ cd codeigniter</span></p>
<p><span style="font-family: courier new,courier;">$ ln -s 1.7.1/ current</span></p>
<h2>Creación de una aplicación de prueba.</h2>
<p>Esta aplicación de prueba deberá mostrar al usuario el controlador (<span style="font-family: courier new,courier;">welcome</span>) y la vista (<span style="font-family: courier new,courier;">welcome_message</span>) que trae por defecto CodeIgniter.</p>
<p><span style="font-family: courier new,courier;">$ cd /home/www</span></p>
<p><span style="font-family: courier new,courier;">$ mkdir public/Demo1</span></p>
<p><span style="font-family: courier new,courier;">$ cp -rf codeigniter/current/system/application/* public/Demo1</span></p>
<p><span style="font-family: courier new,courier;">$ cp codeigniter/current/index.php public/Demo1</span></p>
<p><span style="font-family: courier new,courier;">$ rm public/Demo1/index.html</span></p>
<h2>Configuración del controlador frontal de la nueva aplicación.</h2>
<p>Es necesario indicarle al controlador frontal de la aplicación donde encontrar a la distribución del framework (<em>system</em>) y donde encontrar los archivos de la aplicación (<em>application</em>).</p>
<p><span style="font-family: courier new,courier;">$ vi public/Demo1/index.php</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">error_reporting(E_ALL);</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">$system_folder = &#8220;/home/www/codeigniter/current/system&#8221;;</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">$application_folder = &#8220;/home/www/public/Demo1&#8243;;</span></p>
<h2>Verificación del funcionamiento inicial del sitio.</h2>
<p>Si los pasos anteriores fueron exitosos, si se consulta el sitio web deberá obtenerse un página similar a la siguiente.  Téngase en cuenta que deberá reemplazarse el nombre del servidor (<span style="font-family: courier new,courier;">localhost</span>) por el que sea necesario si este no se encuentra en su mismo equipo.</p>
<p>Visitar con un navegador web la siguiente dirección.</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">http://localhost/Demo1/</span></p>
<h2>Enlaces.</h2>
<ul>
<li>CodeIgniter.<br />
<a href="http://codeigniter.com/" target="_blank">http://codeigniter.com/</a></li>
<li>User Guide.<br />
<a href="http://codeigniter.com/user_guide/" target="_blank">http://codeigniter.com/user_guide/</a></li>
<li>Documentación de CodeIgniter en español.<br />
<a href="http://www.jorgeivanmeza.com/blog/2008/12/14/documentacion-de-codeigniter-en-espanol/" target="_blank">http://www.jorgeivanmeza.com/blog/2008/12/14/documentacion-de-codeigniter-en-espanol/</a></li>
<li>Downloads.<br />
<a href="http://codeigniter.com/downloads/" target="_blank">http://codeigniter.com/downloads/</a></li>
<li>Contributions.<br />
<a href="http://codeigniter.com/wiki/Contributions" target="_blank">http://codeigniter.com/wiki/Contributions</a></li>
<li>Kohana.<br />
<a href="http://kohanaphp.com/" target="_blank">http://kohanaphp.com/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/03/instalacion-de-codeigniter-17x-en-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Documentación de CodeIgniter en español</title>
		<link>http://blog.jorgeivanmeza.com/2008/12/documentacion-de-codeigniter-en-espanol/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=documentacion-de-codeigniter-en-espanol</link>
		<comments>http://blog.jorgeivanmeza.com/2008/12/documentacion-de-codeigniter-en-espanol/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 22:27:34 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://www.jorgeivanmeza.com/blog/?p=1058</guid>
		<description><![CDATA[CodeIgniter es un framework MVC para el desarrollo de aplicaciones web.  Es una alternativa interesante ya que es útil, facilita el desarrollo pero a su vez es lo suficientemente desacoplado para no obligarle a utilizar nada que no se desee usar.  Entre sus ventajas se cuentan su velocidad, su buena documentación, tutoriales y el soporte [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://codeigniter.com/" target="_blank">CodeIgniter</a> es un framework <a href="http://en.wikipedia.org/wiki/Model-view-controller" target="_blank">MVC</a> para el desarrollo de aplicaciones web.  Es una alternativa interesante ya que es útil, facilita el desarrollo pero a su vez es lo suficientemente desacoplado para no obligarle a utilizar nada que no se desee usar.  Entre sus ventajas se cuentan su velocidad, su buena <a href="http://codeigniter.com/user_guide/" target="_blank">documentación</a>, <a href="http://codeigniter.com/wiki/Category:Help::Tutorials" target="_blank">tutoriales</a> y el <a href="http://codeigniter.com/forums/" target="_blank">soporte de una comunidad</a> de tamaño decente.</p>
<p>Si por alguna extraña razón, no es de su agrado la lectura de la documentación en inglés también puede elegir <a href="http://codeigniter.com/wiki/Language_Translation/" target="_blank">otros idiomas</a>.  Encontré que hay dos proyectos que se encuentran traduciendo la documentación al español actualmente.</p>
<ul>
<li>Por parte de <a href="http://www.conocimientovirtual.edu.co/" target="_blank">ConocimientoVirtual</a> se encuentran traduciendo la versión 1.6.3.<br />
<a href="http://www.conocimientovirtual.edu.co/descargas.html" target="_blank">http://www.conocimientovirtual.edu.co/descargas.html</a></li>
<li>Mientras que Miguel Herrero ha iniciado la traducción de la versión 1.7.0.<br />
<a href="http://www.4shared.com/file/68349959/a11c291f/spanish_170.html" target="_blank">http://www.4shared.com/file/68349959/a11c291f/spanish_170.html</a></li>
</ul>
<p>Para mas información consultar el sitio Wiki de CodeIgniter acerca del <a href="http://codeigniter.com/wiki/Language_Translation/" target="_blank">estado de los proyectos de traducción</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2008/12/documentacion-de-codeigniter-en-espanol/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducción a Kohana Framework</title>
		<link>http://blog.jorgeivanmeza.com/2008/07/introduccion-a-kohana-framework/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=introduccion-a-kohana-framework</link>
		<comments>http://blog.jorgeivanmeza.com/2008/07/introduccion-a-kohana-framework/#comments</comments>
		<pubDate>Sat, 26 Jul 2008 01:47:32 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[KohanaFramework]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://www.jorgeivanmeza.com/blog/?p=482</guid>
		<description><![CDATA[KohanaPHP  es  un  framework  liviano  y  flexible  para  el desarrollo  de  aplicaciones  web  pequeñas  y  medianas con PHP.   Se basa  en CodeIgniter  al cual complementa con  una  mejor  apropiación  de  la  OO  y  PHP5,  así  como un mayor soporte brindado por toda una comunidad. En  esta  sesión  se  expondrán  los  conceptos  del framework  necesarios  para  [...]]]></description>
			<content:encoded><![CDATA[<p>KohanaPHP  es  un  framework  liviano  y  flexible  para  el desarrollo  de  aplicaciones  web  pequeñas  y  medianas con PHP.   Se basa  en CodeIgniter  al cual complementa con  una  mejor  apropiación  de  la  OO  y  PHP5,  así  como un mayor soporte brindado por toda una comunidad.</p>
<p>En  esta  sesión  se  expondrán  los  conceptos  del framework  necesarios  para  empezar  a  diseñar  las aplicaciones  web,  sin  embargo  no  se  profundizarán  en detalles  específicos,  se  recomienda complementar  este documento  junto  con  el  wiki  de  la  sección  de documentación.</p>
<div style="width:425px;text-align:left" id="__ss_528699"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=introduccin-a-kohana-framework-1217036460499961-8"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=introduccin-a-kohana-framework-1217036460499961-8" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<div>&nbsp;</div>
<ul>
<li>Introducción.</li>
<li>Características.</li>
<li>Instalación.</li>
<li>Directorios.</li>
<li>Configuración.</li>
<li>URLs.</li>
<li>Controladores.</li>
<li>Librerías.</li>
<li>Ayudantes.</li>
<li>Vistas.</li>
<li>Modelos.</li>
<li>Eventos.</li>
<li>Hooks.</li>
<li>Manejo de errores.</li>
<li>Módulos.</li>
<li>Recursos del framework.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2008/07/introduccion-a-kohana-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
