Mając gotowy model wiadomości Post
, potrzebujemy dopracować akcje oraz widoki dla
kontrolera wiadomości PostController
. W części tej najpierw dostosujemy kontrolę dostępności
operacji CRUD; następnie zmodyfikujemy kod implementujący operacje tworzenia create
oraz
aktualizowania update
; na koniec zaimplementujemy funkcję podglądu dla obu operacji.
Pierwszą rzeczą jaką chcemy zrobić jest dostosowanie
kontroli dostępu
ze względu na to, że kod wygenerowany przez yiic
nie pasuje do naszych wymagań.
Modyfikujemy metodę accessRules()
w pliku /wwwroot/blog/protected/controllers/PostController.php
w następujący sposób:
public function accessRules()
{
return array(
array('allow', // zezwól wszystkim użytkownikom wykonać akcje 'list' oraz 'show'
'actions'=>array('list', 'show'),
'users'=>array('*'),
),
array('allow', // zezwól uwierzytelnionym użytkownikom wykonywać każdą akcję
'users'=>array('@'),
),
array('deny', // odmów wszystkim użytkownikom
'users'=>array('*'),
),
);
}
Powyższe reguły oznaczają, że wszyscy użytkownicy mogą uzyskać dostęp do akcji
listowania list
oraz wyświetlania show
, zaś uwierzytelnieni użytkownicy mogą
uzyskać dostęp do każdej akcji, włączając w to akcję administratora admin
.
Użytkownik powinien spotkać się z odmową dla każdego innego scenariusza.
Zauważ, że reguły te przetwarzane są w kolejności w jakiej zostały tutaj pokazane.
Pierwsza reguła pasująca do aktualnego kontekstu decyduje o uzyskaniu dostępu.
Na przykład, jeśli aktualny użytkownik to właściciel systemu, który próbuje
odwiedzić stronę służącą do tworzenia wiadomości, druga reguła będzie pasowała
i zagwarantuje ona dostęp dla tego użytkownika.
create
oraz aktualizacji update
¶Operacje tworzenia create
i aktualizacji update
są bardzo podobne.
Obie potrzebują wyświetlić formularz HTML w celu zebrania danych wejściowych od użytkownika,
sprawdzenia ich poprawności i zapisania ich w bazie danych. Główną różnicą jest to,
że operacja aktualizacji update
wypełni wstępnie formularz danymi z istniejącej
wiadomości znalezionymi w bazie danych. Z tego też powodu, narzędzie yiic
generuje częściowy widok/wwwroot/blog/protected/views/post/_form.php
, który jest
osadzany w obu widokach create
oraz update
w celu wygenerowania potrzebnego formularza HTML.
Na początek zmienimy plik _form.php
, tak że formularz HTML będzie zbierał jedynie
dane wejściowe, które chcemy: tytuł, title
, zawartość content
oraz status status
.
Używamy pól ze zwykłym tekstem aby zebrać dane wejściowe dla pierwszych dwóch atrybutów
oraz listy rozwijanej do zebrania danych wejściowych dla statusu status
. Opcje listy rozwijanej
stanowią teksty wyświetlające dopuszczalne statusy wiadomości:
echo CHtml::activeDropDownList($post,'status',Post::model()->statusOptions);
Wskazówka: W powyższym kodzie, możemy również użyć
Post::model()->getStatusOptions()
zamiastPost::model()->statusOptions
aby zwrócić dopuszczalne opcje statusu. Powodem dla którego
używamy ostatniego wyrażenia jest to, żePost
jest komponentem, który pozwala nam uzyskać dostęp do właściwości zdefiniowanych pod postacią metod getterów. defined in terms of getter methods.
Następnie zmodyfikujemy klasę wiadomości Post
, tak, że będzie ona automatycznie ustawiać
pewne atrybuty (np. czas utworzenia createTime
, ID autora authorId
) zanim wiadomość
zapisywana jest do bazy danych. Nadpisujemy metodę beforeValidate()
następująco:
protected function beforeValidate($on)
{
$parser=new CMarkdownParser;
$this->contentDisplay=$parser->safeTransform($this->content);
if($this->isNewRecord)
{
$this->createTime=$this->updateTime=time();
$this->authorId=Yii::app()->user->id;
}
else
$this->updateTime=time();
return true;
}
W metodzie tej używamy CMarkdownParser aby skonwertować zawartość w
formacie Markdown do postaci HTML
i zapisania rezultatu do contentDisplay
. Pozwala to uniknąć powtarzającej się
konwersji pomiędzy formatami podczas wyświetlania wiadomości. Jeśli mamy do czynienia
z nową wiadomości, ustawiamy jej atrybuty czas utworzenia createTime
oraz
ID autora authorId
; w przeciwnym przypadku ustawiamy datę aktualizacji updateTime
aby wskazywała aktualny czas. Zauważ, że metoda ta będzie wywołana automatycznie
gdy wywołamy metodę sprawdzenia poprawności validate()
lub zapisu save()
modelu.
Ponieważ chcemy zapisać otagowania wiadomości do tabeli Tag
potrzebujemy również następującej
metody w klasie Post
, która będzie wywołana automatycznie po zapisaniu wiadomości
do bazy danych:
protected function afterSave()
{
if(!$this->isNewRecord)
$this->dbConnection->createCommand(
'DELETE FROM PostTag WHERE postId='.$this->id)->execute();
foreach($this->getTagArray() as $name)
{
if(($tag=Tag::model()->findByAttributes(array('name'=>$name)))===null)
{
$tag=new Tag(array('name'=>$name));
$tag->save();
}
$this->dbConnection->createCommand(
"INSERT INTO PostTag (postId, tagId) VALUES ({$this->id},{$tag->id})")->execute();
}
}
public function getTagArray()
{
// rozbij ciąg tagów na zestaw tagów
return array_unique(
preg_split('/\s*,\s*/',trim($this->tags),-1,PREG_SPLIT_NO_EMPTY)
);
}
Powyżej, najpierw czyścimy tabelę PostTag
z wierszy powiązanych z aktualną wiadomością.
Następnie wstawiamy nowe tagi do tabeli Tag
i dodajemy referencję do tabeli PostTag
.
Zawarta tu logika jest trochę złożona. Zamiast używania
rekordu aktywnego
napisaliśmy czyste zapytanie SQL i wywołaliśmy je przy użyciu połączenia do bazy danych.
Wskazówka: Jest dobrym zwyczajem trzymać logikę biznesową, taką jak powyższy kod
beforeValidate()
orazafterSave()
w modelu zamiast w kontrolerze.
Poza powyższymi dostosowaniami, chcemy również dodać funkcję podglądu, która pozwoli nam podejrzeć wiadomość zanim zapiszemy ją do bazy danych.
Najpierw zmienimy plik widoku _form.php
w celu dodatnia przycisku podglądu preview
oraz wyświetlenia podglądu. Podgląd jest wyświetlany jedynie wtedy, gdy przycisk
podglądu został naciśnięty i nie wystąpił żaden błąd podczas sprawdzania poprawności.
echo CHtml::submitButton('Preview',array('name'=>'previewPost')); ...... if(isset($_POST['previewPost']) && !$post->hasErrors()): ...wyświetl podgląd wiadomości $post tutaj... endif;
Następnie zmieniamy metody actionCreate()
oraz actionUpdate()
kontrolera PostController
aby odpowiadały na żądanie podglądu. Poniżej prezentujemy zaktualizowany kod
actionCreate()
, który jest bardzo podobny do tego w actionUpdate()
:
public function actionCreate()
{
$post=new Post;
if(isset($_POST['Post']))
{
$post->attributes=$_POST['Post'];
if(isset($_POST['previewPost']))
$post->validate();
else if(isset($_POST['submitPost']) && $post->save())
$this->redirect(array('show','id'=>$post->id));
}
$this->render('create',array('post'=>$post));
}
W powyższym kodzie, jeśli przycisk podglądu został kliknięty, wywołujemy metodę
$post->validate()
aby sprawdzić poprawność danych wejściowych; w przeciwnym przypadku
jeśli przycisk submit (prześlij) został kliknięty, spróbujemy zapisach wiadomość
poprzez wywołanie metody $post->save()
, która w ukryciu dokona sprawdzenia poprawności.
Jeśli zapis powiódł się (nie wystąpiły żadne błędy sprawdzani poprawności i dane zostały
zapisane do bazy danych bez błędów), przekierowujemy przeglądarkę użytkownika
aby pokazała nowo utworzoną wiadomość.
Signup or Login in order to comment.