From 654a9cae43358c7eecf3b522e9876aa7815e2453 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Mon, 7 Dec 2015 15:57:51 +0100 Subject: Move urls from pradosoft.com to github's project page; drop unmaintained quickstart tutorial translations --- .../protected/pages/Day4/CreateListPost.page | 4 +- .../protected/pages/Day4/CreateNewPost.page | 2 +- .../protected/pages/Day4/fr/CreateEditPost.page | 136 --------------- .../protected/pages/Day4/fr/CreateListPost.page | 182 -------------------- .../protected/pages/Day4/fr/CreateNewPost.page | 144 ---------------- .../protected/pages/Day4/fr/CreateReadPost.page | 135 --------------- .../protected/pages/Day4/fr/Overview.page | 28 ---- .../protected/pages/Day4/fr/directories.gif | Bin 11129 -> 0 bytes .../protected/pages/Day4/fr/output.gif | Bin 3406 -> 0 bytes .../protected/pages/Day4/fr/output2.gif | Bin 6326 -> 0 bytes .../protected/pages/Day4/fr/output3.gif | Bin 11874 -> 0 bytes .../protected/pages/Day4/fr/output4.gif | Bin 11916 -> 0 bytes .../protected/pages/Day4/id/CreateEditPost.page | 133 --------------- .../protected/pages/Day4/id/CreateListPost.page | 185 --------------------- .../protected/pages/Day4/id/CreateNewPost.page | 142 ---------------- .../protected/pages/Day4/id/CreateReadPost.page | 135 --------------- .../protected/pages/Day4/id/Overview.page | 26 --- .../protected/pages/Day4/id/directories.gif | Bin 11129 -> 0 bytes .../protected/pages/Day4/id/output.gif | Bin 3406 -> 0 bytes .../protected/pages/Day4/id/output2.gif | Bin 6326 -> 0 bytes .../protected/pages/Day4/id/output3.gif | Bin 11874 -> 0 bytes .../protected/pages/Day4/id/output4.gif | Bin 11916 -> 0 bytes 22 files changed, 3 insertions(+), 1249 deletions(-) delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/CreateEditPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/CreateListPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/CreateNewPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/CreateReadPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/Overview.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/directories.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/output.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/output2.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/output3.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/fr/output4.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/Overview.page delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/directories.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/output.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/output2.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/output3.gif delete mode 100755 demos/blog-tutorial/protected/pages/Day4/id/output4.gif (limited to 'demos/blog-tutorial/protected/pages/Day4') diff --git a/demos/blog-tutorial/protected/pages/Day4/CreateListPost.page b/demos/blog-tutorial/protected/pages/Day4/CreateListPost.page index 1dada650..1c266c83 100755 --- a/demos/blog-tutorial/protected/pages/Day4/CreateListPost.page +++ b/demos/blog-tutorial/protected/pages/Day4/CreateListPost.page @@ -28,8 +28,8 @@ We now create the template and class files for the ListPost page: p Based on the functionality requirement of the ListPost page, we will use two controls in the page template:

diff --git a/demos/blog-tutorial/protected/pages/Day4/CreateNewPost.page b/demos/blog-tutorial/protected/pages/Day4/CreateNewPost.page index 7797efaa..fe36b3ff 100755 --- a/demos/blog-tutorial/protected/pages/Day4/CreateNewPost.page +++ b/demos/blog-tutorial/protected/pages/Day4/CreateNewPost.page @@ -51,7 +51,7 @@ We now create two files protected/pages/posts/NewPost.page and prot

Creating Page Template

-The NewPost page template contains a TTextBox to collect the post title and a THtmlArea to collect the post content. The latter is a WYSIWYG HTML editor. To ensure the user input is valid, we associate validators with these input controls. +The NewPost page template contains a TTextBox to collect the post title and a THtmlArea to collect the post content. The latter is a WYSIWYG HTML editor. To ensure the user input is valid, we associate validators with these input controls.

diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/CreateEditPost.page b/demos/blog-tutorial/protected/pages/Day4/fr/CreateEditPost.page deleted file mode 100755 index 09220322..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/fr/CreateEditPost.page +++ /dev/null @@ -1,136 +0,0 @@ - - -

Création de la page modification d'un message EditPost

- - -

-La page EditPost est fournie aux auteurs et administrateurs pour modifier les messages. Comme la page NewPost, elle affiche un formulaire permettant de modifier les données d'un message. -

- - -

-Nous créons deux fichiers protected/pages/posts/EditPost.page et protected/pages/posts/EditPost.php contenant respectivement le gabarit et la classe de notre page. -

- -

Création du gabarit

-

-Le gabarit de la page EditPost est très proche de celui de la page NewPost template. Seul le titre et le texte du bouton sont différents. -

- - -<%@ Title="Mon Blog - Modification Message" %> - -<com:TContent ID="Main"> - -

Modification message

- -Titre: -<com:TRequiredFieldValidator - ControlToValidate="TitleEdit" - ErrorMessage="Veuillez indiquer un titre." - Display="Dynamic" /> -
-<com:TTextBox ID="TitleEdit" Columns="50" /> - -
-Message: -<com:TRequiredFieldValidator - ControlToValidate="ContentEdit" - ErrorMessage="Veuillez indiquer le contenu du message." - Display="Dynamic" /> -
-<com:THtmlArea ID="ContentEdit" /> - -
-<com:TButton Text="Enregistrer" OnClick="saveButtonClicked" /> - -</com:TContent> -
- - -

Création du fichier de classe

- - -

-La classe de EditPage est un peu plus complexe que celle de la page NewPage parce qu'elle doit lire les informations auparavant. Elle doit aussi vérifier les autorisations. En particulier, elle doit s'assurer que le message ne puisse être modifié que par l'auteur ou par un administrateur. Ces vérifications d'autorisation ne sont pas fournies par PRADO. -

- - -class EditPost extends TPage -{ - /** - * initialise les contrôles de saisies avec les données du message. - * cette méthode est appelée lors de l'initialisation de la page - * @param mixed param : paramètres de l'évènement - */ - public function onInit($param) - { - parent::onInit($param); - // récupère les données de l'utilisateur. Equivalent à: - // $postRecord=$this->getPost(); - $postRecord=$this->Post; - // vérification des droits: seul l'auteur ou un administrateur peuvent modifier le message - if($postRecord->author_id!==$this->User->Name && !$this->User->IsAdmin) - throw new THttpException(500,'Vous n êtes pas autoriser à modifier ce message.'); - - if(!$this->IsPostBack) // est-ce le premier appel à la page - { - // rempli les contrôles avec les données du message - $this->TitleEdit->Text=$postRecord->title; - $this->ContentEdit->Text=$postRecord->content; - } - } - - /** - * Enregistre si toutes les validations sont Ok - * cette méthode répond à l'évènement OnClick du bouton "Enregistrer". - * @param mixed sender : celui qui a généré l'évènement - * @param mixed param : paramètres de l'évènement - */ - public function saveButtonClicked($sender,$param) - { - if($this->IsValid) // toutes les validations sont ok ? - { - // récupère les données de l'utilisateur. Equivalent à: - // $postRecord=$this->getPost(); - $postRecord=$this->Post; - - // affecte les données saisies aux champs de la BDD - $postRecord->title=$this->TitleEdit->SafeText; - $postRecord->content=$this->ContentEdit->SafeText; - - // enregistre les données par la méthode save de l'Active Record - $postRecord->save(); - - // redirige le navigateur vers la page ReadPost - $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id)); - $this->Response->redirect($url); - } - } - - /** - * retourne les données du message devant être modifiées. - * @return PostRecord les données devant être modifiés. - * @throws THttpException si le message est inexistant. - */ - protected function getPost() - { - // l'ID du message devant être modifié passé par un paramètre GET - $postID=(int)$this->Request['id']; - // utilise Active Record pour lire le message correspondant à cet ID - $postRecord=PostRecord::finder()->findByPk($postID); - if($postRecord===null) - throw new THttpException(500,'Message inexistant.'); - return $postRecord; - } -} - - -

Test

-

-Pour tester notre page EditPost, authentifiez-vous auparavant et allez à l'URL http://hostname/blog/index.php?page=EditPost&id=1. Cette URL peut aussi être atteinte par le bouton Modifier de notre page de détail. -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/CreateListPost.page b/demos/blog-tutorial/protected/pages/Day4/fr/CreateListPost.page deleted file mode 100755 index ab6ddfc4..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/fr/CreateListPost.page +++ /dev/null @@ -1,182 +0,0 @@ - - -

Création de la page d'affichage des messages ListPost

- -

-La page ListPost affiche les derniers messages sous forme de liste. S'il y a trop de messages, ils seront affichés dans différentes pages. -

- -

-Avant que nous ne passions à l'implémentation, nous voudrions que notre page d'accueil pointe vers la page à venir ListPost, ceci dans le but d'afficher la liste des derniers messages dès qu'un utilisateur se connecte au site. Pour cela, nous allons modifier le fichier de configuration de l'application protected/application.xml de cette manière. -

- - -...... - - - - - - - -

-Nous alons maintenant créer le gabarit et le fichier de classe pour notre page ListPost : protected/pages/posts/ListPost.page et protected/pages/posts/ListPost.php. -

- -

Création du gabarit

-

-Pour satisfaire les fonctionnalités de notre page ListPost, nous allons utiliser deux contrôles dans notre gabarit. -

-
    -
  • TRepeater: ce contrôle permet d'afficher principalement une liste d'éléments. La présentation de chacun ce ces éléments peut être défini soit par un gabarit interne, soit par un gabarit externe (choix que nous avons fait).
  • -
  • TPager: ce contrôle permet de faire la pagination d'une liste d'éléments. Il interagit avec l'utilisateur pour définir quelle page doit être affiché dans un contrôle de liste (ie: TListBox) ou dans un contrôle de données (ie: TRepeater).
  • -
-

-Ci-dessous le contenu du gabarit : -

- - -<%@ Title="Mon Blog" %> - -<com:TContent ID="Main"> - -<com:TRepeater ID="Repeater" - ItemRenderer="Application.pages.posts.PostRenderer" - AllowPaging="true" - AllowCustomPaging="true" - PageSize="5" - /> - -<com:TPager ControlToPaginate="Repeater" OnPageIndexChanged="pageChanged" /> - -</com:TContent> - - -

-Dans la partie répétée TRepeater, nous indiquons que l'affichage du contenu est délégué à l'élément PostRenderer que nous allons créer après. Pour permettre à PRADO de trouver cette classe, nous fournissons l'espace de noms complet Application.pages.posts.PostRenderer, qui correspond au fichier protected/pages/posts/PostRenderer.php. -

- -

-Nous définissons aussi quelques propriétés complémentaires du TRepeater pour activer la pagination. Et nous définissons la propriété ControlToPaginate du TPager afin qu'il sache quelle est la zone répetée à paginer. -

- - -

Création du fichier de classe

-

-En fonction du gabarit précédent, nous pouvons voir que notre fichier de classe doit implémenter un gestionnaire d'évènement pour pageChanged() (déclenché par OnPageIndexChanged du TPager). Nous devons aussi remplir les données qui apparaitront dans le TRepeater. Ci-dessous le source complet du fichier de classe : -

- - -class ListPost extends TPage -{ - /** - * Initialise le TRepeater. - * Cette méthode est appelé par le framework lors de l'initialisation de la page - * @param mixed param : paramètres de l'évènement - */ - public function onInit($param) - { - parent::onInit($param); - if(!$this->IsPostBack) // la page est chargée pour la première fois ? - { - // récupère le nombre total de messages - $this->Repeater->VirtualItemCount=PostRecord::finder()->count(); - // rempli le TRepeater avec les données - $this->populateData(); - } - } - - /** - * Gestionnaire d'évènement pour OnPageIndexChanged du TPager. - * Cette méthode est appelée lors du changement de page - */ - public function pageChanged($sender,$param) - { - // change l'index de la page courante par le nouvel index - $this->Repeater->CurrentPageIndex=$param->NewPageIndex; - // rempli de nouveau le TRepeater - $this->populateData(); - } - - /** - * détermine quelle page doit être affichée et remplie - * TRepeater avec les données lues - */ - protected function populateData() - { - $offset=$this->Repeater->CurrentPageIndex*$this->Repeater->PageSize; - $limit=$this->Repeater->PageSize; - if($offset+$limit>$this->Repeater->VirtualItemCount) - $limit=$this->Repeater->VirtualItemCount-$offset; - $this->Repeater->DataSource=$this->getPosts($offset,$limit); - $this->Repeater->dataBind(); - } - - /** - * lis les données à partir de la base de données en utilisant les fonctionnalités offset et limit. - */ - protected function getPosts($offset, $limit) - { - // construit les critères de la requête - $criteria=new TActiveRecordCriteria; - $criteria->OrdersBy['create_time']='desc'; - $criteria->Limit=$limit; - $criteria->Offset=$offset; - // lit les messages en fonction des critères précédents - return PostRecord::finder()->withAuthor()->findAll($criteria); - } -} - - -

Création du PostRenderer

- -

-Nous devons toujours créer la classe PostRenderer. Elle définit la manière dont sera affichée chaque ligne de notre TRepeater. Nous la créons en tant que gabarit de contrôle, ce qui nous permet d'utiliser notre système de gabarit. Le fichier de gabarit ainsi que notre fichier de classe seront sauvegardés respectivement sous PostRenderer.tpl et PostRenderer.php dans le dossier protected/pages/posts. -

-

Création du gabarit pour PostRenderer

-

-Le gabarit définit la présentation des différentes informations d'un message : titre, nom, heure, contenu. Nous lions le titre à la page ReadPost qui affiche le détail du message. -

-

-L'expression $this->Data fait référence aux données provenant du TRepeater. Dans notre cas, c'est un objet de type PostRecord. Remarquez comment nous accédons au nom de l'auteur du message par $this->Data->author->username. -

- - -
-

-<com:THyperLink Text="<%# $this->Data->title %>" - NavigateUrl="<%# $this->Service->constructUrl('posts.ReadPost',array('id'=>$this->Data->post_id)) %>" /> -

- -

-Auteur: -<com:TLiteral Text="<%# $this->Data->author->username %>" />
-Heure: -<com:TLiteral Text="<%# date('m/d/Y h:m:sa', $this->Data->create_time) %>" /> -

- -

-<com:TLiteral Text="<%# $this->Data->content %>" /> -

-
-
- -

Création du fichier de classe pour PostRenderer

- -

-Notre classe est très simple, elle hérite de TRepeaterItemRenderer et ne contient aucun autre code. -

- -class PostRenderer extends TRepeaterItemRenderer -{ -} - - -

Test

-

-Pour tester la page ListPost, naviguons à l'URL http://hostname/blog/index.php (rappellez-vous, nous avons défini ListPost comme étant notre page d'accueil). Nous devrions obtenir le résultat suivant. vu que nous n'avons qu'un seul message pour le moment, le contrôle de pagination n'apparait pas. Plus tard, quand nous aurons fini la page NewPost, nous pourrons ajouter des messages et revenir ici pour tester notre contrôle de pagination. -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/CreateNewPost.page b/demos/blog-tutorial/protected/pages/Day4/fr/CreateNewPost.page deleted file mode 100755 index 9ddd97b9..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/fr/CreateNewPost.page +++ /dev/null @@ -1,144 +0,0 @@ - - -

Création de la page nouveau message NewPost

- -

-La page NewPost permet aux utilisateurs authentifiés de créer des nouveaux messages. Elle doit afficher un formulaire permettant la saisie des informations du message. -

- - -

-Parce que la page NewPost ne peut être vue que par les utilisateurs authentifiés, nous ajoutons un fichier de configuration de page config.xml dans le dossier protected/pages/posts. Ce fichier indique que seuls les utilisateurs authentifiés peuvent voir les pages NewPost et EditPost qui sera implémentée dans la section suivante. Tous les autres utilisateurs n'ont accès qu'aux pages ListPost et ReadPost. -

- - - - - - - - - - - - - - - Il est souvent utile de démarrer les règles d'autorisation par un <deny users="*">, puis, de le compléter en donnant pas à pas les accès aux différentes pages à l'aides de règles allow supplémentaires - -

-Vu le nombre grandissant de pages, nous allons modifier le pied de page de notre gabarit principal pour qu'il inclus des liens vers : la page d'accueil, la page nouvel utilisateur NewUser (visible seulement par les administrateurs), et la page à venir : nouveau message NewPost (visible seulement par les utilisateurs authentifiés). -

- - - - - -

-Nous allons maintenant créer deux fichiers protected/pages/posts/NewPost.page et protected/pages/posts/NewPost.php contenant respectivement le gabarit et la classe de notre page. -

- - -

Création du gabarit

-

-Le gabarit de NewPost contient une référence à un TTextBox pour saisir le titre de notre message et à un THtmlArea pour saisir le contenu. Ce dernier est un éditeur WYSIWYG HTML. Pour contrôler les valeurs saisies, nous associons des validateurs aux contrôles précédents. -

- - - -<%@ Title="Mon Blog - Nouveau Message" %> - -<com:TContent ID="Main"> - -

Création nouveau message

- -Titre: -<com:TRequiredFieldValidator - ControlToValidate="TitleEdit" - ErrorMessage="Veuillez indiquer un titre." - Display="Dynamic" /> -
-<com:TTextBox ID="TitleEdit" Columns="50" /> - -
-Message: -<com:TRequiredFieldValidator - ControlToValidate="ContentEdit" - ErrorMessage="Veuillez indiquer le contenu du message." - Display="Dynamic" /> -
-<com:THtmlArea ID="ContentEdit" /> - -
-<com:TButton Text="Ajouter" OnClick="createButtonClicked" /> - -</com:TContent> -
- - -

Création du fichier de classe

-

-Dans le gabarit précédent, nous voyons que la fonction principale de notre page est l'appel de la méthode createButtonClicked() implémenté par un évènement OnClick attaché au bouton Ajouter. -

- - -class NewPost extends TPage -{ - /** - * création d'un nouveau message si toutes les données sont valides. - * cette méthode est appelée par l'évènement OnClick du bouton "Ajouter". - * @param mixed sender : celui qui a généré l'évènement - * @param mixed param : paramètres de l'évènement - */ - public function createButtonClicked($sender,$param) - { - if($this->IsValid) // tous les validateurs sont Ok ? - { - // créer un nouvel objet PostRecord avec les données du formulaire - $postRecord=new PostRecord; - // utiliser SafeText à la place de Text évite les attaques XSS - $postRecord->title=$this->TitleEdit->SafeText; - $postRecord->content=$this->ContentEdit->SafeText; - $postRecord->author_id=$this->User->Name; - $postRecord->create_time=time(); - $postRecord->status=0; - - // enregistre les données dans la BDD par la méthode save de l'Active Record - $postRecord->save(); - - // redirige le navigateur vers le message nouvellement créé - $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id)); - $this->Response->redirect($url); - } - } -} - - -

Test

-

-Pour tester notre page NewPost, identifiez-vous auparavant et cliquez sur le lien Nouveau message dans le pied de page. Le navigateur affiche le résultat suivant avec comme URL http://hostname/blog/index.php?page=NewPost. -

- - -Quand vous visitez la page NewPost pour la première fois, vous pourrez remarquer qu'elle mettra plusieurs secondes avant de s'afficher. Ceci est dû au fait que PRADO a besoin de décompresser et de publier le code javascript et les images pour l'éditeur WYSIWYG du contrôle THtmlArea. Ceci est fait une fois pour toutes. - - - -Pour tester la fonctionnalité de pagination que nous avons mise en place dans la page ListPost, nous pouvons créer cinq messages ou plus et regardez ce qu'il se passe sur la page d'accueil. Le contrôle TPager de la page ListPost affiche cinq éléments par page. - - - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/CreateReadPost.page b/demos/blog-tutorial/protected/pages/Day4/fr/CreateReadPost.page deleted file mode 100755 index 385737d3..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/fr/CreateReadPost.page +++ /dev/null @@ -1,135 +0,0 @@ - - -

Création de la page détail d'un message ReadPost

- -

-La page ReadPost affiche le détail d'un message. Pour les utilisateurs autorisés, un lien sera disponible permettant de modifier ou de supprimer le message. -

- -

-Nous créons deux fichiers protected/pages/posts/ReadPost.page et protected/pages/posts/ReadPost.php qui contiendront respectivement notre gabarit et notre classe. -

- -

Création du gabarit

-

-Le gabarit de ReadPost est très proche du gabarit de PostRenderer, chacun d'eux affiche le détail d'un message. La différence est que la page ReadPost doit afficher deux boutons, permettant aux utilisateurs autorisés de modifier ou supprimer le message. -

- - -<com:TContent ID="Main"> - -

-<com:TLiteral Text="<%= $this->Post->title %>" /> -

- -<com:TControl Visible="<%= $this->canEdit() %>"> - Modifier | - <com:TLinkButton Text="Supprimer" - OnClick="deletePost" - Attributes.onclick="javascript:if(!confirm('Etes vous sûr ?')) return false;" /> -</com:TControl> - -

-Auteur: -<com:TLiteral Text="<%= $this->Post->author->username %>" />
-Heure: -<com:TLiteral Text="<%= date('m/d/Y h:m:sa', $this->Post->create_time) %>" /> -

- -

-<com:TLiteral Text="<%= $this->Post->content %>" /> -

- -</com:TContent> -
- -

-Plusieurs expressions PHP sont utilisées dans le gabarit. L'expression $this->Post fait référence à la propriété définie dans la classe de ReadPost. Elle représente l'objet PostRecord correspondant au message actuel. -

- - -Même si nous utilisons régulièrement des expressions dans nos gabarits, nous n'en abusons pas. Une des règles principales pour savoir si l'on doit utiliser une expression est l'expression doit être une propriété ou une simple mise en forme d'une propriété. En suivant cette ligne de conduite, nous nous assurons d'une bonne séparation entre le contenu et la présentation, sans perdre en flexibilité. - - -

-Nous pouvons aussi remarquer dans le gabarit précédent, que, nos deux boutons sont entourés d'un TControl dont la propriété 'visible' est déterminée par l'expression $this->canEdit(). Pour le bouton Supprimer, nous utilisons une boite de dialogue javascript pour confirmer la suppression du message. -Nous pouvons aussi remarquer dans le gabarit précédent, que, nos deux boutons sont entourés d'un TControl dont la propriété 'visible' est déterminée par l'expression $this->canEdit(). Pour le bouton Supprimer, nous utilisons une boite de dialogue javascript pour confirmer la suppression du message. -

- - -Tous les contrôles PRADO, ont une propriété très utile Attributes qui accepte n'importe quelle paire de valeurs (nom-valeur). La plupart des contrôles PRADO répercutent directement ces informations dans la balise HTML. Par exemple, dans le bouton Supprimer nous définissons onclick qui est directement reporté dans la balise <a> sous forme d'un attribut onclick. - - -

Création du fichier de classe

- -

-Dans le gabarit précédent, nous voyons que notre classe doit implémenter le gestionnaire d'évènement deletePost() (attaché à l'évènement Onclick de notre bouton Supprimer). Nous devons aussi lire les données du message dont l'ID est passé par un paramètre GET.

- - -Nous implémentons la fonctionnalité suppression dans le classe ReadPost parce qu'il est classique de faire ainsi. Quand l'utilisateur clique sur le bouton Supprimer, une boite de dialogue demande confirmation de la suppression. Si l'utilisateur confirme, l'évènement OnClick du bouton Supprimer est déclenché. - - - -class ReadPost extends TPage -{ - private $_post; - /** - * lis les données du message. - * cette méthode est appelée lors de l'initialisation de la page - * @param mixed param : paramètres de l'évènement - */ - public function onInit($param) - { - parent::onInit($param); - // id du message passé par un paramètre GET - $postID=(int)$this->Request['id']; - // lis le message ainsi que les données correspondantes à l'auteur - $this->_post=PostRecord::finder()->withAuthor()->findByPk($postID); - if($this->_post===null) // si l'id du message est invalide - throw new THttpException(500, 'Impossible de trouver le message demandé.'); - // défini le titre de la page comme étant celui du message - $this->Title=$this->_post->title; - } - - /** - * @return PostRecord retourne l'objet PostRecord correspondant au message - */ - public function getPost() - { - return $this->_post; - } - - /** - * supprime le message actuellement visualisé - * cette méthode est appelée par l'évènement OnClick du bouton "Supprimer" - */ - public function deletePost($sender,$param) - { - // seul l'auteur ou un administrateur peuvent supprimer le message - if(!$this->canEdit()) - throw new THttpException('Nous n'êtes pas autorisé à effectuer cette action.'); - // le supprime de la base de données - $this->_post->delete(); - // redirige le navigateur vers la page d'accueil - $this->Response->redirect($this->Service->DefaultPageUrl); - } - - /** - * @return boolean infiquant si le message peut être modifier ou supprimer par l'utilisateur actuel - */ - public function canEdit() - { - // seul l'auteur ou un administrateur peuvent modifier/supprimer le message - return $this->User->Name===$this->Post->author_id || $this->User->IsAdmin; - } -} - - -

Test

-

-Pour tester notre page ReadPost, allons à l'URL http://hostname/blog/index.php et cliquons sur le titre du seul message affiché. Notre navigateur devrait afficher le résultat suivant avec l'URL http://hostname/blog/index.php?page=ReadPost&id=1. Notez que si vous n'êtes pas connecté, les deux boutons ne sont pas visibles. -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/Overview.page b/demos/blog-tutorial/protected/pages/Day4/fr/Overview.page deleted file mode 100755 index baaf13af..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/fr/Overview.page +++ /dev/null @@ -1,28 +0,0 @@ - - -

Vue d'ensemble de la gestion des messages

- -

-Dans cette section, nous allons créer les pages correspondantes à la gestion des messages. En particulier, nous mettrons en place les quatre opérations de base (Création-Lecture-Modification-Suppression) (CRUD:Create-Retrieve-Update-Delete). -

- - -

-Nous allons créer les nouvelles pages dans le dossier protected/pages/posts créé à cet effet. -

- - -
    -
  • ListPost affiche la liste des messages triés par ordre de date décroissante.
  • -
  • ReadPost affiche le détail d'un message.
  • -
  • NewPost permet aux utilisateurs enregistrés de créer un nouveau message.
  • -
  • EditPost permet à l'auteur et aux administrateurs de modifier un message.
  • -
- -

-Après avoir fini cette section, nous devrions obtenir l'arborescence suivante : -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/directories.gif b/demos/blog-tutorial/protected/pages/Day4/fr/directories.gif deleted file mode 100755 index 5ba55184..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/fr/directories.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/output.gif b/demos/blog-tutorial/protected/pages/Day4/fr/output.gif deleted file mode 100755 index 8c1caea8..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/fr/output.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/output2.gif b/demos/blog-tutorial/protected/pages/Day4/fr/output2.gif deleted file mode 100755 index 7078e6c6..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/fr/output2.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/output3.gif b/demos/blog-tutorial/protected/pages/Day4/fr/output3.gif deleted file mode 100755 index ff1834a4..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/fr/output3.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/fr/output4.gif b/demos/blog-tutorial/protected/pages/Day4/fr/output4.gif deleted file mode 100755 index b1208a0d..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/fr/output4.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page deleted file mode 100755 index b7ded3b3..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page +++ /dev/null @@ -1,133 +0,0 @@ - - -

Membuat Halaman EditPost

- -

-Halaman EditPost disediakan bagi para pembuat dan administrator untuk mengedit tulisan blog yang sudah ada. Seperti halaman NewPost , ia menampilkan sebuah formulir untuk mengumpulkan perubahan terhadap judul dan konten tulisan. -

- -

-Kita membuat dua file protected/pages/posts/EditPost.page dan protected/pages/posts/EditPost.php masing-masing untuk menyimpan template halaman dan kelas halaman. -

- -

Membuat Template Halaman

-

-Template halaman EditPost sangat mirip dengan template NewPost. Hanya judul halaman dan tombol yang berbeda. -

- - -<%@ Title="My Blog - Edit Post" %> - -<com:TContent ID="Main"> - -

Edit Post

- -Title: -<com:TRequiredFieldValidator - ControlToValidate="TitleEdit" - ErrorMessage="Please provide a title." - Display="Dynamic" /> -
-<com:TTextBox ID="TitleEdit" Columns="50" /> - -
-Content: -<com:TRequiredFieldValidator - ControlToValidate="ContentEdit" - ErrorMessage="Please provide content." - Display="Dynamic" /> -
-<com:THtmlArea ID="ContentEdit" /> - -
-<com:TButton Text="Save" OnClick="saveButtonClicked" /> - -</com:TContent> -
- - -

Membuat Kelas Halaman

- -

-Kelas halaman EditPage lebih kompleks dibanding NewPage karena ia perlu mengambil data tulisan yang ditetapkan terlebih dulu. Ia juga perlu melakukan pemeriksaan otorisasi tambahan. Ada kalanya ia perlu memastikan bahwa tulisan hanya bisa diedit oleh pembuat atau administrator. Pemeriksaan otorisasi sudah disediakan oleh PRADO. -

- - -class EditPost extends TPage -{ - /** - * Menginisialisasi input dengan data tulisan yang sudah ada. - * Metode ini dipanggil oleh kerangka kerja saat halaman diinisialisasi. - * @param parameter event campuran - */ - public function onInit($param) - { - parent::onInit($param); - // Menambil data pengguna yang sudah ada. Ini sama dengan: - // $postRecord=$this->getPost(); - $postRecord=$this->Post; - // Pemeriksaan otorisasi: hanya pembuat atau administrator dapat mengedit tulisan - if($postRecord->author_id!==$this->User->Name && !$this->User->IsAdmin) - throw new THttpException(500,'You are not allowed to edit this post.'); - - if(!$this->IsPostBack) // jika halaman pertama kali diminta - { - // Mempopulasikan kontrol input dengan data tulisan yang sudah ada - $this->TitleEdit->Text=$postRecord->title; - $this->ContentEdit->Text=$postRecord->content; - } - } - - /** - * Menyimpan tulisan jika semua input sudah benar. - * Metode ini merespon event OnClick pada tombol "Save". - * @param pengirim event campuran - * @param parameter event campuran - */ - public function saveButtonClicked($sender,$param) - { - if($this->IsValid) // jika semua validasi sukses - { - // Mengambil data pengguna yang sudah ada. Ini sama dengan: - // $postRecord=$this->getPost(); - $postRecord=$this->Post; - - // Mengambil data input - $postRecord->title=$this->TitleEdit->SafeText; - $postRecord->content=$this->ContentEdit->SafeText; - - // menyimpan ke database via mekanisme Rekaman Aktif - $postRecord->save(); - - // mengalihkan browser ke halaman ReadPost - $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id)); - $this->Response->redirect($url); - } - } - - /** - * Mengembalikan data tulisan yang akan diedit. - * @return PostRecord data tulisan yang akan diedit. - * @throws THttpException jika data tulisan tidak ada. - */ - protected function getPost() - { - // ID tulisan yang diedit dikirimkan via parameter GET 'id' - $postID=(int)$this->Request['id']; - // gunakan Rekaman Aktif untuk mencari ID tulisan tertentu - $postRecord=PostRecord::finder()->findByPk($postID); - if($postRecord===null) - throw new THttpException(500,'Post is not found.'); - return $postRecord; - } -} - - -

Pengujian

-

-Untuk menguji halaman EditPost, masuk lebih dulu dan kemudian kunjungi URL berikut: http://hostname/blog/index.php?page=EditPost&id=1. URL ini juga bisa dijangkau dengan mengklik link Edit pada halaman rician tulisan. -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page deleted file mode 100755 index d682535e..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page +++ /dev/null @@ -1,185 +0,0 @@ - - -

Membuat Halaman ListPost

- -

-Halaman ListPost menampilkan tulisan blog terakhir dalam sebuah daftar. Jika di sana terlalu banyak tulisan, maka akan ditampilkan dalam beberapa lembar halaman. -

- -

-Sebelum kita berlanjut dengan implementasi, kita ingin mengarahkan homepage kita ke halaman ListPage mendatang, karena kita ingin para pengguna melihat tulisan terakhir saat mereka menyentuh website. Untuk melakukannya, kita mengubah konfigurasi aplikasi protected/application.xml sebagai berikut, -

- - -...... - - - - - - - -

-Sekarang kita membuat file template dan kelas untuk halaman ListPost: protected/pages/posts/ListPost.page dan protected/pages/posts/ListPost.php. -

- -

Membuat Template Halaman

-

-Berdasarkan pada kebutuhan fungsionalitas halaman ListPost, kita akan menggunakan dua kontrol dalam template halaman: -

-
    -
  • TRepeater: kontrol ini dipakai terutama untuk menampilkan daftar atas item data. Penyajian dari setiap item data bisa ditetapkan melalui template inline atau kontrol template eksternal (pendekatan yang akan kita gunakan di sini).
  • -
  • TPager: kontrol ini dipakai untuk memecah daftar item data. Ia berinteraksi dengan pengguna-akhir untuk menentukan halaman data mana yang ditampilkan dalam kontrol daftar (misalnya TListBox) pada kontrol data (misalnya TRepeater).
  • -
- -

-Di bawah ini adalah konten dalam template halaman: -

- - -<%@ Title="My Blog" %> - -<com:TContent ID="Main"> - -<com:TRepeater ID="Repeater" - ItemRenderer="Application.pages.posts.PostRenderer" - AllowPaging="true" - AllowCustomPaging="true" - PageSize="5" - /> - -<com:TPager ControlToPaginate="Repeater" OnPageIndexChanged="pageChanged" /> - -</com:TContent> - - -

-Dalam pengulang, kita menetapkan bahwa konten yang diulang ditampilkan menggunakan penyaji item PostRenderer yang akan kita buat nantinya. Agar PRADO bisa menemukan kelas ini, kita memberikan namespace Application.pages.posts.PostRenderer, berarti file kelasnya adalah protected/pages/posts/PostRenderer.php. -

- -

-Kita juga menyetel beberapa properti lain pada pengulang untuk menghidupkan lembaran halaman. Dan kita menyetel properti ControlToPaginate pada lembaran agar ia mengetahui konten mana yang diulang harus dibuat lembaran. -

- - -

Membuat Kelas Halaman

- -

-Dari template halaman di atas, kita melihat bahwa kita perlu menulis kelas halaman yang mengimplementasikan pengendali event: pageChanged() (ditempelkan ke event lembaran OnPageIndexChanged). Kita juga perlu mempopulasikan data tulisan ke dalam pengulang berdasarkan pada setelan lembaran saat ini. Berikut ini adalah kode sumber lengkap kelas halaman: -

- - -class ListPost extends TPage -{ - /** - * Menginisialisasi pengulang. - * Metode ini dipanggil oleh kerangka kerja saat menginisialisasi halaman - * @param mixed event parameter - */ - public function onInit($param) - { - parent::onInit($param); - if(!$this->IsPostBack) // jika halaman diminta pertama kali - { - // ambil jumlah total tulisan yang tersedia - $this->Repeater->VirtualItemCount=PostRecord::finder()->count(); - // populasikan data tulisan ke dalam pengulang - $this->populateData(); - } - } - - /** - * Pengendali event untuk event OnPageIndexChanged pada lembaran. - * Metode ini dipanggil saat pengguna mengklik tombol halaman - * dan kemudian mengubah halaman tulisan yang ditampilkan. - */ - public function pageChanged($sender,$param) - { - // ubah indeks halaman sekarang ke yang baru - $this->Repeater->CurrentPageIndex=$param->NewPageIndex; - // re-populasi data ke dalam pengulang - $this->populateData(); - } - - /** - * Menentukan halaman tulisan mana yang ditampilkan dan - * mempopulasi pengulang dengan data yang sudah diambil. - */ - protected function populateData() - { - $offset=$this->Repeater->CurrentPageIndex*$this->Repeater->PageSize; - $limit=$this->Repeater->PageSize; - if($offset+$limit>$this->Repeater->VirtualItemCount) - $limit=$this->Repeater->VirtualItemCount-$offset; - $this->Repeater->DataSource=$this->getPosts($offset,$limit); - $this->Repeater->dataBind(); - } - - /** - * Mengambil tulisan dari database dengan ofset dan limit. - */ - protected function getPosts($offset, $limit) - { - // Bentuk kriteria query - $criteria=new TActiveRecordCriteria; - $criteria->OrdersBy['create_time']='desc'; - $criteria->Limit=$limit; - $criteria->Offset=$offset; - // query untuk tulisan dengan kriteria di atas dan informasi pembuat - return PostRecord::finder()->withAuthor()->findAll($criteria); - } -} - - -

Membuat PostRenderer

- -

-Kita masih perlu untuk membuat kelas penyaji item PostRenderer. Ia mendefinisikan bagaimana setiap tulisan harus ditampilkan dalam pengulang. Kita membuatnya sebagai kontrol template yang membolehkan kita untuk menetapkan penyajian tulisan menggunakan sintaks template fleksibel kita. Template dan file kelas masing-masing disimpan sebagai PostRenderer.tpl dan PostRenderer.php di bawah direktori protected/pages/posts. -

- -

Membuat Template Penyaji

-

-Template penyaji menetapkan penyajian berbagai field dalam sebuah tulisan, termasuk judul, nama pembuat, waktu penulisan dan kontennya. Kita me-link judul tulisan ke ReadPost yang menampilkan lebih rinci atas tulisan yang dipilih. -

-

-Ekspresi $this->Data merujuk ke item data yang dikirimkan ke pengulang. Dalam kasus kita, ia adalah obyek PostRecord. Perhatikan bagaimana kita mengambil nama pembuat pada tulisan dengan $this->Data->author->username. -

- - -
-

-<com:THyperLink Text="<%# $this->Data->title %>" - NavigateUrl="<%# $this->Service->constructUrl('posts.ReadPost',array('id'=>$this->Data->post_id)) %>" /> -

- -

-Author: -<com:TLiteral Text="<%# $this->Data->author->username %>" />
-Time: -<com:TLiteral Text="<%# date('m/d/Y h:m:sa', $this->Data->create_time) %>" /> -

- -

-<com:TLiteral Text="<%# $this->Data->content %>" /> -

-
-
- -

Membuat Kelas Penyaji

-

-Kelas penyaji sangat sederhana. Ia diperluas dari TRepeaterItemRenderer dan tidak berisi kode apapun. -

- -class PostRenderer extends TRepeaterItemRenderer -{ -} - - -

Pengujian

-

-Untuk menguji halaman ListPost, kunjungi URL http://hostname/blog/index.php (ingat kita telah menyetel ListPost sebagai homepage baru kita). Kita akan melihat hasil seperti berikut. Karena kita hanya mempunyai satu tulisan saat ini, lembaran tidak akan muncul. Nantinya ketika menyelesaikan NewPost, kita dapat menambah tulisan lebih banyak dan datang kembali untuk menguji lembaran halaman lagi. -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page deleted file mode 100755 index 31aba2bb..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page +++ /dev/null @@ -1,142 +0,0 @@ - - -

Membuat Halaman NewPost

- -

-Halaman NewPost disediakan untuk mengotentikasi pengguna untuk pembuatan tulisan blog baru. Ia perlu untuk menampilkan formulir yang mengumpulkan informasi mengenai tulisan baru, termasuk judul tulisan dan konten badan tulisan. -

- -

-Karena NewPost hanya bisa diakses oleh pengguna terotentikasi, kita menambahkan file konfigurasi config.xml di bawah direktori protected/pages/posts. Konfigurasi menetapkan bahwa para pengguna tidak bisa mengakses NewPost dan EditPost yang akan diperkenalkan dalam bagian berikutnya. Semua pengguna lainnya hanya memiliki akses ke ListPost dan ReadPost -

- - - - - - - - - - - - - -Selalu menjadi ide yang baik untuk memulai dengan deny="*" yang menampung semua aturan dari bawah dan secara bertahap memberikan akses ke halaman dengan aturan tambahan. - - -

-Karena jumlah halaman kita berkembang, kita ingin memodifikasi MainLayout agar dalam footer pada halaman blog kita ada link ke berbagai halaman, termasuk homepage, halaman NewUser (hanya terlihat oleh administrator), dan halaman NewPost mendatang (hanya terlihat oleh pengguna terotentikasi). -

- - - - - -

-Sekarang kita membuat dua file protected/pages/posts/NewPost.page dan protected/pages/posts/NewPost.php masing-masing untuk menyimpan template halaman dan kelas halaman. -

- -

Membuat Template Halaman

-

-Template halaman NewPost berisi TTextBox untuk mengumpulkan judul tulisan dan THtmlArea untuk mengumpulkan konten tulisan. Yang terakhir adalah editor HTML WYSIWYG. Guna memastikan bahwa input pengguna sudah benar, kita mengaitkan validator dengan kontrol input ini. -

- - -<%@ Title="My Blog - New Post" %> - -<com:TContent ID="Main"> - -

Membuat Tulisan Baru

- -Title: -<com:TRequiredFieldValidator - ControlToValidate="TitleEdit" - ErrorMessage="Please provide a title." - Display="Dynamic" /> -
-<com:TTextBox ID="TitleEdit" Columns="50" /> - -
-Content: -<com:TRequiredFieldValidator - ControlToValidate="ContentEdit" - ErrorMessage="Please provide content." - Display="Dynamic" /> -
-<com:THtmlArea ID="ContentEdit" /> - -
-<com:TButton Text="Create" OnClick="createButtonClicked" /> - -</com:TContent> -
- - -

Membuat Kelas Halaman

- -

-Dari template halaman di atas, kita melihat bahwa sebagian besar kita perlu menulis sebuah kelas halaman yang mengimplementasikan pengendali event: createButtonClicked() (ditempelkan ke tombo Create dalam event OnClick). -

- - -class NewPost extends TPage -{ - /** - * Membuat tulisan baru jika semua input benar. - * Metode ini merespon event OnClick pada tombol "create". - * @param mixed event sender - * @param mixed event parameter - */ - public function createButtonClicked($sender,$param) - { - if($this->IsValid) // bila semua validasi sukses - { - // populasikan obyek PostRecord dengan input pengguna - $postRecord=new PostRecord; - // menggunakan SafeText datipada Text guna menghindari serangan Penaskahan Situs Silang - $postRecord->title=$this->TitleEdit->SafeText; - $postRecord->content=$this->ContentEdit->SafeText; - $postRecord->author_id=$this->User->Name; - $postRecord->create_time=time(); - $postRecord->status=0; - - // simpan ke database lewat mekanisme Rekaman Aktif - $postRecord->save(); - - // alihkan browser ke halaman tulisan yang baru dibuat - $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id)); - $this->Response->redirect($url); - } - } -} - - -

Pengujian

-

-Untuk menguji halaman NewPost, masuk lebih dulu dan klik pada link tombol New Post dalam footer pada homepage. Browser kita akan menampilkan hasil berikut dengan URL http://hostname/blog/index.php?page=NewPost. -

- - -Ketika Anda mengunjungi halaman NewPost untuk pertama kali, Anda bisa melihat bahwa diperlukan beberapa detik sebelum halaman ditampilkan. Ini dikarenakan PRADO perlu mengurai dan mempublikasikan kode javascript dan gambar untuk kontrol THtmlArea yang dipakai dalam halaman. Ini dikerjakan sekali dan untuk semuanya. - - - -Untuk menguji fitur lembaran yang kita kembangkan untuk halaman ListPost, kita dapat membuat lima atau lebih tulisan dan melihat apa yang terjadi pada homepage. Lembar dalam ListPost menampilkan lima tulisan setiap halamannya. - - - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page deleted file mode 100755 index 9aeaed7b..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page +++ /dev/null @@ -1,135 +0,0 @@ - - -

Membuat Halaman ReadPost

- -

-Halaman ReadPost menampilkan rincian konten tulisan blog. Untuk para pengguna yang diotorisasi, akan ditampilkan tombol link yang membolehkan mereka untuk mengedit atau menghapus tulisan. -

- -

-Kita membuat dua file protected/pages/posts/ReadPost.page dan protected/pages/posts/ReadPost.php masing-masing untuk menyimpan template halaman dan kelas halaman. -

- -

Membuat Template Halaman

-

-Template halaman ReadPost sangat mirip dengan template PostRenderer, keduanya menyajikan konten tulisan. Perbedaannya adalah bahwa ReadPost perlu menampilkan dua tombol link ketika pengguna saat ini diotorisasi untuk mengedit atau menghapus tulisan. -

- - -<com:TContent ID="Main"> - -

-<com:TLiteral Text="<%= $this->Post->title %>" /> -

- -<com:TControl Visible="<%= $this->canEdit() %>"> - Edit | - <com:TLinkButton Text="Delete" - OnClick="deletePost" - Attributes.onclick="javascript:if(!confirm('Are you sure?')) return false;" /> -</com:TControl> - -

-Author: -<com:TLiteral Text="<%= $this->Post->author->username %>" />
-Time: -<com:TLiteral Text="<%= date('m/d/Y h:m:sa', $this->Post->create_time) %>" /> -

- -

-<com:TLiteral Text="<%= $this->Post->content %>" /> -

- -</com:TContent> -
- -

-Banyak ekspresi PHP dipakai dalam template di atas. Ekspresi $this->Post merujuk ke properti yang didefinisikan dalam kelas halaman ReadPost. Ia mewakili obyek PostRecord yang terkait dengan tulisan yang saat ini sedang dilihat. -

- - -Meskipun sebagian besar kita menggunakan ekspresi dalam template, we do not overuse them. A major guideline in determining whether we should use an expression in a template is that the expression should be a property or a simple presentational transformation of the property. By following this guideline, we ensure content and presentation are well separated without losing sufficient flexibility. - - -

-Kita juga mencatatan dalam template di atas bahwa dua link tombol dikurung di dalam TControl yang penampakannya ditentukan oleh ekspresi $this->canEdit(). Untuk link tombol Delete, kita menggunakan dialog konfirmasi javascript untuk memperoleh konfirmasi pengguna saat ia mengklik untuk menghapus tulisan. -

- - -Seluruh kontrol PRADO mempunyai properti yang sangat berguna bernama Attributes yang dapat menerima pasangan nama-nilai bebas. Kebanyakan kontrol PRADO akan menyajikan pasangan nama-nilai dalam Attributes secara literal terkait tag HTML. Sebagai contoh, daam link tombol Delete di atas, kita mendefinisikan sebuah onclick yang disajikan sebagai atribut onclick yang menghasilkan tag <a>. - - - -

Membuat Kelas Halaman

- -

-Dari template halaman di atas, kita melihat bahwa kita perlu menulis kelas halaman yang mengimplementasikan pengendali event: deletePost() (ditempelkan ke tombol Delete dalam event OnClick). Kita juga perlu untuk mengambil data tulisan yang ditetapkan oleh ID tulisan melalui parameter GET id.

- - -Kita mengimplementasikan fitur penghapusan tulisan dalam halaman ReadPost karena ini sangat alami untuk melakukannya di sini. Ketika pengguna mengklik pada tombol Delete, dialog konfirmasi javascript akan muncul. Jika pengguna mengkonfirmasinya, penghapusan akan dibawa dalam respon terhadap event OnClick dari tombol Delete. - - - -class ReadPost extends TPage -{ - private $_post; - /** - * Mengambil data tulisan. - * Metode ini dipanggil oleh kerangka kerja saat inisialisasi halaman - * @param mixed event parameter - */ - public function onInit($param) - { - parent::onInit($param); - // id tulisan dikirimkan via parameter GET 'id' - $postID=(int)$this->Request['id']; - // mengambil PostRecord dengan informasi pembuat terisi dalam - $this->_post=PostRecord::finder()->withAuthor()->findByPk($postID); - if($this->_post===null) // jika id tulisan tidak benar - throw new THttpException(500,'Unable to find the specified post.'); - // setel judul halaman sebagai judul tulisan - $this->Title=$this->_post->title; - } - - /** - * @return PostRecord yang saat ini sedang dilihat - */ - public function getPost() - { - return $this->_post; - } - - /** - * Menghapus tulisan yang saat ini sedang dilihat - * Metode ini dipanggil saat pengguna mengklik tombol "Delete" - */ - public function deletePost($sender,$param) - { - // hanya pembuat atau administrator bisa menghapus tulisan - if(!$this->canEdit()) - throw new THttpException('You are not allowed to perform this action.'); - // hapus dari DB - $this->_post->delete(); - // alihkan browser ke homepage - $this->Response->redirect($this->Service->DefaultPageUrl); - } - - /** - * @return boolean apakah pengguna saat ini bisa mengedit/menghapus tulisan yg sedang dilihat - */ - public function canEdit() - { - // hanya pembuat atau administrator bisa mengedi/menghapus tulisan - return $this->User->Name===$this->Post->author_id || $this->User->IsAdmin; - } -} - - -

Pengujian

-

-Untuk menguji halaman ReadPost, kunjungi URL http://hostname/blog/index.php dan klik pada judul tulisan. Browser kita akan menampilkan hasil berikut dengan URL http://hostname/blog/index.php?page=ReadPost&id=1. Catatan, jika kita tidak masuk, dua tombol link tidak akan terlihat. -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/Overview.page b/demos/blog-tutorial/protected/pages/Day4/id/Overview.page deleted file mode 100755 index 3427e11f..00000000 --- a/demos/blog-tutorial/protected/pages/Day4/id/Overview.page +++ /dev/null @@ -1,26 +0,0 @@ - - -

Tinjauan Manajemen Tulisan

- -

-Pada bagian ini, kita membuat halaman yang terkait dengan manajemen tulisan. Dalam keadaan tertentu, kita mengimplementasikan operasi CRUD (Create-Retrieve-Update-Delete) dengan memperhatikan tulisan blog. -

- -

-Berdasarkan pada kebutuhan, kita perlu membuat halaman berikut yang diatur di bawah direktori baru protected/pages/posts. -

- -
    -
  • ListPost menampilkan tulisan dengan waktu pembuatan dalam urutan mengecil.
  • -
  • ReadPost menampilkan rincian tulisan.
  • -
  • NewPost membolehkan pengguna teregistrasi untuk membuat tulisan baru.
  • -
  • EditPost membolehkan pembuat atau administrator untuk mengedit tulisan yang sudah ada.
  • -
- -

-Setelah menyelesaikan bagian ini, kita akan mengharapkan untuk melihat direktori dan file berikut: -

- - - -
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/directories.gif b/demos/blog-tutorial/protected/pages/Day4/id/directories.gif deleted file mode 100755 index 5ba55184..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/id/directories.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output.gif b/demos/blog-tutorial/protected/pages/Day4/id/output.gif deleted file mode 100755 index 8c1caea8..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/id/output.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output2.gif b/demos/blog-tutorial/protected/pages/Day4/id/output2.gif deleted file mode 100755 index 7078e6c6..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/id/output2.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output3.gif b/demos/blog-tutorial/protected/pages/Day4/id/output3.gif deleted file mode 100755 index ff1834a4..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/id/output3.gif and /dev/null differ diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output4.gif b/demos/blog-tutorial/protected/pages/Day4/id/output4.gif deleted file mode 100755 index b1208a0d..00000000 Binary files a/demos/blog-tutorial/protected/pages/Day4/id/output4.gif and /dev/null differ -- cgit v1.2.3