<?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>xlab &#187; sfGuardPlugin</title>
	<atom:link href="http://xlab.pl/tag/sfguardplugin/feed/" rel="self" type="application/rss+xml" />
	<link>http://xlab.pl</link>
	<description>XSolve laboratory - dzielimy się tym co wiemy...</description>
	<lastBuildDate>Mon, 30 Aug 2010 07:34:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Połączenie sfGuardUser oraz sfGuardUserProfile</title>
		<link>http://xlab.pl/2009/08/polaczenie-sfguarduser-oraz-sfguarduserprofile/</link>
		<comments>http://xlab.pl/2009/08/polaczenie-sfguarduser-oraz-sfguarduserprofile/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 09:03:01 +0000</pubDate>
		<dc:creator>kibao</dc:creator>
				<category><![CDATA[Programowanie PHP]]></category>
		<category><![CDATA[admin generator]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sfGuardPlugin]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.xlab.pl/?p=162</guid>
		<description><![CDATA[Przy ostatnich pracach związanych z przeniesienie naszej aplikacji z symfony 1.0 na symfony 1.2 natknęliśmy się na kilka problemów z pluginem sfGuardPlugin, a dokładniej z połączeniem administracji sfGuardUser oraz sfGuardUserProfile.
Chcieliśmy aby podczas listowania użytkowników, poprzez moduł sfGuardUser, można było wyświetlać nie tylko pola znajdujące się w tabeli sf_guard_user ale także wybrane pola z profilu usera, [...]]]></description>
			<content:encoded><![CDATA[<p>Przy ostatnich pracach związanych z przeniesienie naszej aplikacji z symfony 1.0 na symfony 1.2 natknęliśmy się na kilka problemów z pluginem <a href="http://www.symfony-project.org/plugins/sfGuardPlugin" target="_blank">sfGuardPlugin</a>, a dokładniej z połączeniem administracji sfGuardUser oraz sfGuardUserProfile.<br />
Chcieliśmy aby podczas listowania użytkowników, poprzez moduł sfGuardUser, można było wyświetlać nie tylko pola znajdujące się w tabeli sf_guard_user ale także wybrane pola z profilu usera, a także mieć możliwość filtrowania po nich.</p>
<p>Na początek stworzymy sobie możliwość wyświetlania pól z profilu użytkownika podczas listowania. Otwieramy <em>generator.yml</em> z modułu sfGuardUser, który w oryginale wygląda tak:</p>
<pre name="code">generator:
  class: sfPropelGenerator
  param:
    model_class:           sfGuardUser
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          sf_guard_user
    with_propel_route:     1

    config:
      fields:
        password_again: { label: "Password (again)" }

      list:
        title:   User list
        display: [=username, created_at, last_login]

      form:
        class: sfGuardUserAdminForm
        display:
          "NONE":                   [username, password, password_again]
          "Permissions and groups": [is_active, is_super_admin, sf_guard_user_group_list, sf_guard_user_permission_list]

      edit:
        title: Editing User "%%username%%"

      new:
        title: New User</pre>
<p>Interesuje nas dokładnie sekcja</p>
<pre name="code" class="YML">list:
  title:   User list
  display: [=username, created_at, last_login]</pre>
<p>Do wyświetlania informacji z pól z profilu użytkownika, będziemy korzystać z możliwości użycia własnych partiali.<br />
Nas interesuje np. imię, nazwisko, oraz adres e-mail użytkownika, dlatego wprowadzamy takie modyfikacje:</p>
<pre name="code" class="YML">list:
  title:   User list
  display: [=username, created_at, last_login, _first_name, _last_name, _email]</pre>
<p>Następnie tworzymy 3 pratiale w katalogu<em> sfGuardUser/templates/</em> :<br />
<em>_first_name.php</em></p>
<pre name="code"  class="php">&lt;?php echo $sf_guard_user-&gt;getProfile()-&gt;getFirstName(); ?&gt;</pre>
<p><em>_last_name.php</em></p>
<pre name="code"  class="php">&lt;?php echo $sf_guard_user-&gt;getProfile()-&gt;getLastName(); ?&gt;</pre>
<p><em>_email.php</em></p>
<pre name="code"  class="php">&lt;?php echo $sf_guard_user-&gt;getProfile()-&gt;getEmail(); ?&gt;</pre>
<p>Po tym</p>
<pre name="code"  class="bash">symfony cc</pre>
<p>I po odświeżeniu strony z listowaniem użytkowników będziemy mieli także informacje o imieniu, nazwisku oraz adresie email.<br />
Wszytko pięknie tylko po takich modyfikacjach nie można sortować po dodanych polach. A to dlatego, że generator podczas tworzenia kodu naszych template&#8217;ów sprawdza czy pole które ma być wyświetlone istnieje w modelu.<br />
Dlatego musimy obejść to sprawdzanie poprzez zmodyfikowanie informacji o polach w listowaniu (<em>generator.yml</em>):</p>
<pre name="code"  class="YML">list:
  title:   User list
  display: [=username, created_at, last_login, _first_name, _last_name, _email]
  fields:
    last_name:      { is_real: true }
    first_name:     { is_real: true }
    email:          { is_real: true }</pre>
<p>Teraz po wyczyszczeniu cache i odświeżeniu strony mamy już możliwość sortowania po polach z profilu.</p>
<p>Jeżeli przejdziecie teraz w środowisko dev zauważycie, że nagle zwiększyła się bardzo ilość zapytań do bazy.<br />
A to ze względu, że dla każdego użytkownika pobierany jest osobno jego profil.<br />
Należałoby to zoptymalizować, aby nie wywoływać niepotrzebnie tylu zapytań. Tutaj natknęliśmy się na kilka problemów, ponieważ klasa sfGuardUserPeer nie posiada metody doSelectJoinsfGuardUserProfile.<br />
Otwieramy plik <em>sfGuardUserPeer.php</em> i wprowadzamy pewne modfikacje:</p>
<pre name="code"  class="php">&lt;?php
class sfGuardUserPeer extends PluginsfGuardUserPeer
{
  public static function doSelectJoinsfGuardUserProfile(Criteria $c, $con = null, $join_behavior = Criteria::LEFT_JOIN)
  {

    foreach (sfMixer::getCallables('BasesfGuardUserPeer:doSelectJoin:doSelectJoin') as $callable)
    {
      call_user_func($callable, 'BasesfGuardUserPeer', $c, $con);
    }

    $c = clone $c;

    if ($c-&gt;getDbName() == Propel::getDefaultDB()) {
      $c-&gt;setDbName(self::DATABASE_NAME);
    }

    sfGuardUserPeer::addSelectColumns($c);
    $startcol = (sfGuardUserPeer::NUM_COLUMNS - sfGuardUserPeer::NUM_LAZY_LOAD_COLUMNS);
    sfGuardUserProfilePeer::addSelectColumns($c);

    $c-&gt;addJoin(array(sfGuardUserPeer::ID,), array(sfGuardUserProfilePeer::USER_ID,), $join_behavior);
    $stmt = BasePeer::doSelect($c, $con);
    $results = array();

    while ($row = $stmt-&gt;fetch(PDO::FETCH_NUM)) {
      $key1 = sfGuardUserPeer::getPrimaryKeyHashFromRow($row, 0);
      if (null !== ($obj1 = sfGuardUserPeer::getInstanceFromPool($key1))) {
      } else {

        $omClass = sfGuardUserPeer::getOMClass();

        $cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
        $obj1 = new $cls();
        $obj1-&gt;hydrate($row);
        sfGuardUserPeer::addInstanceToPool($obj1, $key1);
      }
      $key2 = sfGuardUserProfilePeer::getPrimaryKeyHashFromRow($row, $startcol);
      if ($key2 !== null) {
        $obj2 = sfGuardUserProfilePeer::getInstanceFromPool($key2);
        if (!$obj2) {

          $omClass = sfGuardUserProfilePeer::getOMClass();

          $cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
          $obj2 = new $cls();
          $obj2-&gt;hydrate($row, $startcol);
          sfGuardUserProfilePeer::addInstanceToPool($obj2, $key2);
        }
        $obj1-&gt;setProfile($obj2);

      }
      $results[] = $obj1;
    }
    $stmt-&gt;closeCursor();
    return $results;
  }
}</pre>
<p>A w pliku <em>sfGuardUser.php</em>, dodajemy funkcję setProfile :</p>
<pre name="code"  class="php">&lt;?php
class sfGuardUser extends PluginsfGuardUser
{
  public function setProfile( $profile )
  {
    $this-&gt;profile = $profile;
  }
}</pre>
<p>Na koniec musimy tylko zmienić peer_method wywoływaną przez generator do pobierania wyników.<br />
Otwieramy plik <em>sfGuardUser/lib/sfGuardUserGeneratorConfiguration.class.php</em> i dodajemy funkcję getPeerMethod:</p>
<pre name="code"  class="php">&lt;?php

/**
 * sfGuardUser module configuration.
 *
 * @package    sfGuardPlugin
 * @subpackage sfGuardUser
 */
class sfGuardUserGeneratorConfiguration extends BaseSfGuardUserGeneratorConfiguration
{
  public function getPeerMethod()
  {
    return 'doSelectJoinsfGuardUserProfile';
  }
}</pre>
<p>Teraz po wyczyszczeniu cache, odświeżeniu strony ilość zapytań do bazy powinna spaść.</p>
<p>Na dzisiaj to tyle. Zostało jeszcze opisanie jak filtrować po polach z profilu użytkownika ale to już innym razem.</p>
]]></content:encoded>
			<wfw:commentRss>http://xlab.pl/2009/08/polaczenie-sfguarduser-oraz-sfguarduserprofile/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
