<com:TContent ID="Main">

<h1>Membuat Halaman <tt>EditUser</tt></h1>

<p>
Halaman <tt>EditUser</tt> sangat mirip dengan <a href="?page=Day3.CreateNewUser">NewUser</a>. Perbedaan utamanya adalah bahwa saat <tt>EditUser</tt> awalnya diminta, field input harus diinisialisasi dengan informasi pengguna yang sudah ada. Sedikit perbedaan lainnya adalah bahwa <tt>EditUser</tt> juga bisa diakses oleh pengguna normal.
</p>

<p>
Untuk menentukan akun pengguna mana yang diedit, kita menggunakan kebijakan berikut:
</p>
<ul>
<li>Jika pengguna saat ini adalah administrator, dia dapat mengedit setiap akun pengguna dengan menetapkan akun nama pengguna dalam variabel GET bernama 'username'. Sebagai contoh, <tt>http://hostname/blog/index.php?page=users.EditUser&username=demo</tt>.</li>
<li>Jika pengguna saat ini adalah administrator dan URL tidak berisi 'username', data administrator sendiri sedang dimutakhirkan.</li>
<li>Jika pengguna saat ini adalah pengguna normal, dia hanya bisa mengedit informasi akunnya sendiri, dan dia tidak bisa memodifikasi data aturannya.</li>
</ul>

<p>
Kita membuat dua file <tt>protected/pages/users/EditUser.page</tt> dan <tt>protected/pages/users/EditUser.php</tt> masing-masing untuk menyimpan template halaman dan kelas halaman.
</p>

<h2>Membuat Template Halaman</h2>
<p>
Seperti yang telah Anda tebak, template halaman <tt>EditUser</tt> sebagian besar sama seperti pada <tt>NewUser</tt>. Selain perbedaan dalam judul halaman dan judul tombol submit, ada tiga perbedaan utama.
</p>
<ul>
<li>Kotak teks "username" diganti oleh kontrol <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Label">TLabel</a> karena kita tidak membolehkan memodifikasi nama pengguna;</li>
<li>Validator untuk input "password" dihilangkan. Ini dikarenakan jika pengguna tidak melengkapi kata sandi selama mengedit, itu berarti pengguna tidak ingin mengubah kata sandi.</li>
<li>Input "role" dikelilingi oleh <tt>TControl</tt> yang penampakannya dihidup matikan berdasarkan aturan pengguna yang masuk saat ini. Jika pengguna bukan administrator, input "role" tidak akan ditampilkan karena pengguna normal tidak diperbolehkan untuk memodifikasi aturannya.</li>
</ul>
</p>

<com:TTextHighlighter CssClass="source" Language="prado">
&lt;%@ Title="My Blog - Edit User" %>

&lt;com:TContent ID="Main">

<h1>Edit User</h1>

<span>Username:</span>
&lt;com:TLabel ID="Username" />

<br/>
<span>Password:</span>
<br/>
&lt;com:TTextBox ID="Password" TextMode="Password" />

<br/>
<span>Re-type Password:</span>
&lt;com:TCompareValidator
    ControlToValidate="Password"
    ControlToCompare="Password2"
    ErrorMessage="Your password entries did not match."
    Display="Dynamic" />
<br/>
&lt;com:TTextBox ID="Password2" TextMode="Password" />

<br/>
<span>Email Address:</span>
&lt;com:TRequiredFieldValidator
    ControlToValidate="Email"
    ErrorMessage="Please provide your email address."
    Display="Dynamic" />
&lt;com:TEmailAddressValidator
    ControlToValidate="Email"
    ErrorMessage="You entered an invalid email address."
    Display="Dynamic" />
<br/>
&lt;com:TTextBox ID="Email" />

&lt;com:TControl Visible="&lt;%= $this->User->IsAdmin %>">
<br/>
<span>Role:</span>
<br/>
&lt;com:TDropDownList ID="Role">
    &lt;com:TListItem Text="Normal User" Value="0" />
    &lt;com:TListItem Text="Administrator" Value="1" />
&lt;/com:TDropDownList>
&lt;/com:TControl>

<br/>
<span>First Name:</span>
<br/>
&lt;com:TTextBox ID="FirstName" />

<br/>
<span>Last Name:</span>
<br/>
&lt;com:TTextBox ID="LastName" />

<br/>
&lt;com:TButton Text="Save" OnClick="saveButtonClicked" />

&lt;/com:TContent>
</com:TTextHighlighter>


<h2>Membuat Kelas Halaman</h2>

<p>
Berdasarkan pada deskripsi di atas dan template, kita perlu menulis kelas halaman yang mengawali input dengan informasi pengguna yang sudah ada. Sebagai tambahan, kelas halaman juga perlu untuk mengimplementasikan metode <tt>saveButtonClicked()</tt> yang disertakan pada event tombol "save" <tt>OnClick</tt>.
</p>

<com:TTextHighlighter CssClass="source" Language="php">
class EditUser extends TPage
{
    /**
     * Menginisialisasi input dengan data pengguna yang sudah ada.
     * Metode ini dipanggil oleh kerangka kerja saat halaman diinisialisasi.
     * @param mixed event parameter
     */
    public function onInit($param)
    {
        parent::onInit($param);
        if(!$this->IsPostBack)  // jika halaman awalnya diminta
        {
            // Ambil data pengguna yang sudah ada. Ini sama dengan:
            // $userRecord=$this->getUserRecord();
            $userRecord=$this->UserRecord;

            // Populasikan kontrol input dengan data pengguna yang sudah ada
            $this->Username->Text=$userRecord->username;
            $this->Email->Text=$userRecord->email;
            $this->Role->SelectedValue=$userRecord->role;
            $this->FirstName->Text=$userRecord->first_name;
            $this->LastName->Text=$userRecord->last_name;
        }
    }

    /**
     * Menyimpan akun pengguna jika semua input sudah benar.
     * Metode ini merespon event OnClick pada tombol "save".
     * @param mixed event sender
     * @param mixed event parameter
     */
    public function saveButtonClicked($sender,$param)
    {
        if($this->IsValid)  // saat semua validasi sukses
        {
            // Ambil data pengguna yang sudah ada. Ini sama dengan:
            $userRecord=$this->UserRecord;

            // Ambil data input
            $userRecord->username=$this->Username->Text;
            // mutakhirkan kata sandi saat input tidak kosong
            if(!empty($this->Password->Text))
                $userRecord->password=$this->Password->Text;
            $userRecord->email=$this->Email->Text;
            // mutakhirkan aturan jika pengguna saat ini adalah administrator
            if($this->User->IsAdmin)
                $userRecord->role=(int)$this->Role->SelectedValue;
            $userRecord->first_name=$this->FirstName->Text;
            $userRecord->last_name=$this->LastName->Text;

            // simpan ke database melalui mekanisme Rekaman Aktif
            $userRecord->save();

            // alihkan browser ke homepage
			$this->Response->redirect($this->Service->DefaultPageUrl);
        }
    }

    /**
     * Mengembalikan data pengguna yang diedit.
     * @return UserRecord data pengguna yang diedit.
     * @throws THttpException jika data pengguna tidak ditemukan.
     */
    protected function getUserRecord()
    {
        // pengguna yang diedit adalah pengguna yang saat ini sudah masuk
        $username=$this->User->Name;
        // jika var GET 'username' tidak kosong dan pengguna saat ini adalah
        // administrator, lebih baik kita menggunakan nilai var GET.
        if($this->User->IsAdmin && $this->Request['username']!==null)
            $username=$this->Request['username'];

        // gunakan Rekaman Aktif untuk melihat nama pengguna yang ditetapkan
        $userRecord=UserRecord::finder()->findByPk($username);
        if(!($userRecord instanceof UserRecord))
            throw new THttpException(500,'Username is invalid.');
        return $userRecord;
    }
}
</com:TTextHighlighter>

<com:TipBox>
Metode <tt>onInit()</tt> dipanggil oleh PRADO selama salah satu <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Pages">masa hidup halaman</a>. Metode masa hidup umum lainnya ditimpa termasuk <tt>onPreInit()</tt>, <tt>onLoad()</tt> dan <tt>onPreRender()</tt>.
</com:TipBox>

<h2>Menambah Pemeriksaan Perijinan</h2>
<p>
Agar halaman <tt>EditUser</tt> juga bisa diakses oleh para pengguna (<tt>users="@"</tt>), kita juga perlu menyesuaikan file konfigurasi halaman <tt>protected/pages/users/config.xml</tt>.
</p>

<com:TTextHighlighter CssClass="source" Language="xml">
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <authorization>
    <allow roles="admin"/>
    <allow users="@" pages="EditUser"/>
    <deny users="*"/>
  </authorization>
</configuration>
</com:TTextHighlighter>


<h2>Pengujian</h2>
<p>
Untuk menguji halaman <tt>EditUser</tt>, kunjungi URL <tt>http://hostname/blog/index.php?page=users.EditUser&username=demo</tt>. Anda mungkin perlu masuk lebih dulu jika Anda belum melakukannya. Coba masuk dengan akun berbeda (e.g. admin/demo, demo/demo) dan lihat bagaimana halaman ditampilkan secara berbeda.
</p>

</com:TContent>