Ver índice de contenidos del libro

13.2. Atributos del usuario

En los escenarios que describimos en el turorial del segundo día no incluimos ningún requisito para almacenar información en la sesión de usuario. Por tanto, a continuación vamos a definir un nuevo requerimiento: "para facilitar la navegación por las ofertas de trabajo, en el menú se muestran los enlaces a las tres últimas ofertas de trabajo vistas por el usuario".

Cuando el usuario visita la página de una oferta de trabajo, debemos incluir en el historial del usuario el objeto que representa a esa oferta y debemos guardar el historial en la sesión del usuario:

// apps/frontend/modules/job/actions/actions.class.php
class jobActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $this->job = $this->getRoute()->getObject();
 
    // fetch jobs already stored in the job history
    $jobs = $this->getUser()->getAttribute('job_history', array());
 
    // add the current job at the beginning of the array
    array_unshift($jobs, $this->job->getId());
 
    // store the new job history back into the session
    $this->getUser()->setAttribute('job_history', $jobs);
  }
 
  // ...
}

Nota En el código anterior podríamos haber guardado directamente los objetos JobeetJob en la sesión. No te aconsejamos que lo hagas porque las variables de sesión se serializan entre una petición y otra. Si guardáramos los objetos, al cargar la sesión se deserializarían los objetos JobeetJob y se podrían producir problemas si los objetos se han modificado o borrado desde que se guardaron en la sesión.

13.2.1. Los métodos getAttribute() y setAttribute()

El método sfUser::getAttribute() devuelve los valores de la sesión asociados al identificador que se indica. De la misma forma, el método setAttribute() guarda cualquier variable de PHP en la sesión del usuario y la asocia con el identificador proporcionado.

El método getAttribute() también permite indicar un segundo argumento opcional que es el valor que devuelve el método cuando el identificador proporcionado no está definido en la sesión del usuario.

Nota El valor por defecto que se puede indicar en el método getAttribute() es simplemente un atajo de:

if (!$value = $this->getAttribute('job_history'))
{
  $value = array();
}

13.2.2. La clase myUser

Para mantener la separación del código en capas, vamos a mover el código a la clase myUser. La clase myUser redefine la clase sfUser que incluye por defecto de Symfony y permite añadir características propias de la aplicación:

// apps/frontend/modules/job/actions/actions.class.php
class jobActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $this->job = $this->getRoute()->getObject();
 
    $this->getUser()->addJobToHistory($this->job);
  }
 
  // ...
}
// apps/frontend/lib/myUser.class.php
class myUser extends sfBasicSecurityUser
{
  public function addJobToHistory(JobeetJob $job)
  {
    $ids = $this->getAttribute('job_history', array());
 
    if (!in_array($job->getId(), $ids))
    {
      array_unshift($ids, $job->getId());
 
      $this->setAttribute('job_history', array_slice($ids, 0, 3));
    }
  }
}

El código anterior también se ha modificado para tener en cuenta todos los requerimientos definidos:

  • !in_array($job->getId(), $ids): una misma oferta de trabajo no se puede guardar dos veces en el historial.
  • array_slice($ids, 0, 3): sólo se muestran las tres últimas ofertas de trabajo vistas por el usuario.

En el layout, añade el siguiente código antes de la instrucción que muestra el contenido de la variable $sf_content:

// apps/frontend/templates/layout.php
<div id="job_history">
  Recent viewed jobs:
  <ul>
    <?php foreach ($sf_user->getJobHistory() as $job): ?>
      <li>
        <?php echo link_to($job->getPosition().' - '.$job->getCompany(), 'job_show_user', $job) ?>
      </li>
    <?php endforeach; ?>
  </ul>
</div>
 
<div class="content">
  <?php echo $sf_content ?>
</div>

El layout anterior utiliza un nuevo método llamado getJobHistory() para obtener el historial de ofertas de trabajo visitadas:

// apps/frontend/lib/myUser.class.php
class myUser extends sfBasicSecurityUser
{
  public function getJobHistory()
  {
    $ids = $this->getAttribute('job_history', array());
 
    return JobeetJobPeer::retrieveByPKs($ids);
  }
 
  // ...
}

El método getJobHistory() utiliza el método retrieveByPKs() de Propel para obtener varios objetos de tipo JobeetJob mediante una única llamada.

Historial de ofertas de trabajo visitadas

Figura 13.2 Historial de ofertas de trabajo visitadas

13.2.3. La clase sfParameterHolder

Para completar la nueva funcionalidad del historial de ofertas de trabajo, añade el siguiente método para borrar el historial:

// apps/frontend/lib/myUser.class.php
class myUser extends sfBasicSecurityUser
{
  public function resetJobHistory()
  {
    $this->getAttributeHolder()->remove('job_history');
  }
 
  // ...
}

Los atributos del usuario se gestionan a través de un objeto de la clase sfParameterHolder. Los métodos getAttribute() y setAttribute() de sfUser son en realidad atajos de los métodos getParameterHolder()->get() y getParameterHolder()->set(). Como el método remove() no dispone de un atajo en la clase sfUser, tenemos que utilizar directamente el objeto que representa al contenedor de parámetros.

Nota La clase sfRequest también guarda sus parámetros en un objeto de la clase sfParameterHolder.