Yii: Creating Demo Blog 2
Post Management
2) Customizing Relations() Method
4) Representing Status In Text
2) Customizing create and update Operations
1) Customizing View Operations
2) Customizing index Operation
1.1) Modify {webroot}/protected/model/Post.php
Edit rules()
public function rules() { return array( array('title, content, status', 'required'), array('title', 'length', 'max'=>128), array('status', 'in', 'range'=>array(1,2,3)), array('tags', 'match', 'pattern'=>'/^[\w\s,]+$/', 'message'=>'Tags can only contain word characters.'), array('tags', 'normalizeTags'),
array('title, status', 'safe', 'on'=>'search'), ); } |
1.2) Add New Method normalizeTags() to {webroot}/protected/model/Post.php
public function normalizeTags($attribute,$params) { $this->tags=Tag::array2string(array_unique(Tag::string2array($this->tags))); } |
1.3) Add New Methods to {webroot}/protected/model/Tags.php
public static function string2array($tags) { return preg_split('/\s*,\s*/',trim($tags),-1,PREG_SPLIT_NO_EMPTY); }
public static function array2string($tags) { return implode(', ',$tags); } |
2.1) Modify {webroot}/protected/model/Post.php
Edit relations()
public function relations() { return array( 'author' => array(self::BELONGS_TO, 'User', 'author_id'), 'comments' => array(self::HAS_MANY, 'Comment', 'post_id', 'condition'=>'comments.status='.Comment::STATUS_APPROVED, 'order'=>'comments.create_time DESC'), 'commentCount' => array(self::STAT, 'Comment', 'post_id', 'condition'=>'status='.Comment::STATUS_APPROVED), ); } |
2.2) Modify {webroot}/protected/model/Comment.php
Add.
const STATUS_PENDING=1; const STATUS_APPROVED=2; |
3.1) Modify {webroot}/protected/model/Post.php
Add.
public function getUrl() { return Yii::app()->createUrl('post/view', array( 'id'=>$this->id, 'title'=>$this->title, )); } |
4.1) Modify {webroot}/protected/model/Lookup.php
Add.
private static $_items=array();
public static function items($type) { if(!isset(self::$_items[$type])) self::loadItems($type); return self::$_items[$type]; }
public static function item($type,$code) { if(!isset(self::$_items[$type])) self::loadItems($type); return isset(self::$_items[$type][$code]) ? self::$_items[$type][$code] : false; }
private static function loadItems($type) { self::$_items[$type]=array(); $models=self::model()->findAll(array( 'condition'=>'type=:type', 'params'=>array(':type'=>$type), 'order'=>'position', )); foreach($models as $model) self::$_items[$type][$model->code]=$model->name; } |
4.2) Modify {webroot}/protected/model/Post.php
Add constants.
const STATUS_DRAFT=1; const STATUS_PUBLISHED=2; const STATUS_ARCHIVED=3; |
1.1) Modify {webroot}/protected/controllers/PostController.php
Edit accessRules().
public function accessRules() { return array( array('allow', // allow all users to perform 'list' and 'show' actions 'actions'=>array('index', 'view'), 'users'=>array('*'), ), array('allow', // allow authenticated users to perform any action 'users'=>array('@'), ), array('deny', // deny all users 'users'=>array('*'), ), ); } |
2.1) Modify {webroot}/protected/views/post/_form.php
Replace status Text Field with dropDownList.
<?php echo $form->dropDownList($model,'status',Lookup::items('PostStatus')); ?> |
2.2) Modify {webroot}/protected/models/Post.php
Add beforeSave()
Add afterSave()
Add $_oldTag
Add afterFind()
protected function beforeSave() { if(parent::beforeSave()) { if($this->isNewRecord) { $this->create_time=$this->update_time=time(); $this->author_id=Yii::app()->user->id; } else $this->update_time=time(); return true; } else return false; } |
protected function afterSave() { parent::afterSave(); Tag::model()->updateFrequency($this->_oldTags, $this->tags); }
private $_oldTags;
protected function afterFind() { parent::afterFind(); $this->_oldTags=$this->tags; } |
1.1) Modify {webroot}/protected/controllers/PostController.php
public function actionView() { $post=$this->loadModel(); $this->render('view',array( 'model'=>$post, )); }
private $_model;
public function loadModel() { if($this->_model===null) { if(isset($_GET['id'])) { if(Yii::app()->user->isGuest) $condition='status='.Post::STATUS_PUBLISHED .' OR status='.Post::STATUS_ARCHIVED; else $condition=''; $this->_model=Post::model()->findByPk($_GET['id'], $condition); } if($this->_model===null) throw new CHttpException(404,'The requested page does not exist.'); } return $this->_model; } |
2.1) Modify {webroot}/protected/controllers/PostController.php
Edit actionIndex().
public function actionIndex() { $criteria=new CDbCriteria(array( 'condition'=>'status='.Post::STATUS_PUBLISHED, 'order'=>'update_time DESC', 'with'=>'commentCount', )); if(isset($_GET['tag'])) $criteria->addSearchCondition('tags',$_GET['tag']);
$dataProvider=new CActiveDataProvider('Post', array( 'pagination'=>array( 'pageSize'=>5, ), 'criteria'=>$criteria, ));
$this->render('index',array( 'dataProvider'=>$dataProvider, )); } |
2.2) Modify {webroot}/protected/views/post/index.php
Replace all.
<?php if(!empty($_GET['tag'])): ?> <h1>Posts Tagged with <i><?php echo CHtml::encode($_GET['tag']); ?></i></h1> <?php endif; ?>
<?php $this->widget('zii.widgets.CListView', array( 'dataProvider'=>$dataProvider, 'itemView'=>'_view', 'template'=>"{items}\n{pager}", )); ?> |
1) Listing Posts in Tabular View
1.1) Modify {webroot}/protected/controllers/PostController.php
Edit actionAdmin()
public function actionAdmin() { $model=new Post('search'); if(isset($_GET['Post'])) $model->attributes=$_GET['Post']; $this->render('admin',array( 'model'=>$model, )); } |
1.2) Modify {webroot}/protected/views/post/admin.php
Replace All.
<?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', ), ), )); ?> |
2) Deleting Posts
2.1) Modify {webroot}/protected/controllers/PostController.php
Edit actionDelete.
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.'); } |
2.2) Modify {webroot}/protected/models/Post.php
Edit afterDelete()
protected function afterDelete() { parent::afterDelete(); Comment::model()->deleteAll('post_id='.$this->id); Tag::model()->updateFrequency($this->tags, ''); } |
2.3)