Administrowanie wiadomościami

Administrowanie wiadomościami przede wszystkim odnosi się do wyświetlenia w liście wiadomości w widoku administratora co pozwala nam widzieć wiadomości o wszystkich statusach, aktualizować je oraz usuwać. Są one wykonywane odpowiednio przez operację admin oraz operację usuwania delete. Kod wygenerowany przez narzędzie yiic nie wymaga zbytniej modyfikacji. Poniżej wyjaśniamy przede wszystkim jak te dwie operacje zostały zaimplementowane.

1. Wyświetlenie listy wiadomości w widoku tabelarycznym

Operacja admin wyświetla wszystkie wiadomości o wszystkich statusach w widoku tabelarycznym. Widok wspiera sortowanie oraz stronicowanie. Poniżej znajduje się metoda actionAdmin() kontrolera PostController:

public function actionAdmin()
{
    $model=new Post('search');
    if(isset($_GET['Post']))
        $model->attributes=$_GET['Post'];
    $this->render('admin',array(
        'model'=>$model,
    ));
}

Powyższy kod został wygenerowany przez narzędzie yiic i nie został zmodyfikowany. Najpierw tworzy on model wiadomości Post dla scenariusza wyszukiwania search. Będziemy używać tego modelu do gromadzenia warunków wyszukiwania, które specyfikuje użytkownik. Jeżeli istnieją dane dostarczone przez użytkownika, przypisujemy je do modelu. Na koniec generujemy widok admin wraz z modelem.

Poniżej znajduje się kod widoku admin:

<?php
$this->breadcrumbs=array(
    'Manage Posts',
);
?>
<h1>Manage Posts</h1>
 
<?php $this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        array(
            'name'=>'title',
            'type'=>'raw',
            'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'
        ),
        array(
            'name'=>'status',
            'value'=>'Lookup::item("PostStatus",$data->status)',
            'filter'=>Lookup::items('PostStatus'),
        ),
        array(
            'name'=>'create_time',
            'type'=>'datetime',
            'filter'=>false,
        ),
        array(
            'class'=>'CButtonColumn',
        ),
    ),
)); ?>

Do wyświetlania wiadomości używamy klasy CGridView. Umożliwia ona nam sortowanie kolumn oraz wiadomości jeśli jest ich zbyt wiele by wyświetlić je na pojedynczej stronie. Nasza zmiana dotyczy sposobu wyświetlania każdej kolumny. Na przykład dla kolumny tytułu title, określamy iż powinna ona być wyświetlona jako hiperlink, który wskazuje na widok szczegółów wiadomości. Wyrażenie $data->url zwraca wartość właściwości url, którą zefiniowaliśmy w klasie wiadomości Post.

Wskazówka: Podczas wyświetlania tekstu wołamy metodę CHtml::encode() do zakodowania znajdujących się w nim wpisów HTML. Chroni to przed atakami XSS.

2. Usuwanie wiadomości

W każdym wierszu siatki danych administratora admin znajduje się przycisk usuwania. Kliknięcie w ten przycisk powinno usunąć odpowiednią wiadomość. W aplikacji wywołuje to wywołanie akcji delete zaimplementowanej w następujący sposób:

public function actionDelete()
{
    if(Yii::app()->request->isPostRequest)
    {
        // we only allow deletion via POST request
        $this->loadModel()->delete();
 
        if(!isset($_GET['ajax']))
            $this->redirect(array('index'));
    }
    else
        throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
}

Powyższy kod został wygenerowany przez narzędzie yiic i nie został zmieniony. Będziemy chcieli wyjaśnić nieco więcej na temat sprawdzania $_POST['ajax']. Widżet CGridView posiada bardzo fajną funkcję, która domyślnie wykonuje operacje sortowania, stronicowania, usuwania przy użyciu trybu AJAX. Oznacza to, że cała strona nie jest przeładowywana jeśli jakakolwiek z ww. operacji jest wykonywana. Jednakże, istnieje również możliwość uruchamiania widżetu bez trybu AJAX (poprzez ustawienie właściwości ajaxUpdate na false albo poprzez wyłączenie obsługi JavaScript po stronie klienta). Dla akcji delete zachodzi konieczność rozróżnienia tych dwóch scenariuszy: jeśli żądanie usuwania pochodzi z AJAX-a nie powinniśmy przekierowywać przeglądarki użytkownika, w przeciwnym przypadku powinniśmy.

Usuwanie wiadomości powinno również spowodować usuwanie jej wszystkich komentarzy. Dodatkowo powinniśmy również zaktualizować tabelę tbl_tag uwzględniając tagi z usuniętej wiadomości. Oba powyższe zadania powinny zostać osiągnięte poprzez napisanie metody afterDelete w klasie modelu wiadomości Post w następujący sposób:

protected function afterDelete()
{
    parent::afterDelete();
    Comment::model()->deleteAll('post_id='.$this->id);
    Tag::model()->updateFrequency($this->tags, '');
}

Powyższy kod jest bardzo prosty. Najpierw usuwane są wszystkie komentarze, których post_id jest takie same jak ID usuniętej wiadomości. Następnie aktualizowana jest tabela tbl_tag dla wartości tagów tags z usuniętej wiadomości.

Wskazówka: Musimy jawnie usunąć wszystkie komentarze dla usuniętej wiadomości, ponieważ SQLite nie wspiera ograniczeń klucza obcego. W silnikach bazy danych, które wpierają ograniczanie (takich jak MySQL, PostgreSQL), ograniczenie klucza obcego może zostać tak zdefiniowane, że silnik bazy danych automatycznie usunie powiązane komentarze w momencie usuwania wiadomości. W takim przypadku nie będziemy potrzebowali w naszym kodzie jawnego usuwania.

$Id: post.admin.txt 3557 2012-02-09 15:26:05Z alexander.makarow $

Be the first person to leave a comment

Please to leave your comment.