Requirements
- Yii 1.1.10 or above (Requires jQuery 1.7.1)
Installation
- Download yii-ycm or clone the files to
protected/modules/ycm
- Edit Yii main configuration file
protected/config/main.php
. Enable module, set username, password and models you want to manage.
'modules'=>array(
...
'ycm'=>array(
'username'=>'YOUR USERNAME',
'password'=>'YOUR PASSWORD',
'registerModels'=>array(
//'application.models.Blog', // one model
'application.models.*', // all models in folder
),
'uploadCreate'=>true, // create upload folder automatically
'redactorUpload'=>true, // enable Redactor image upload
),
...
),
Screenshots
Examples
Basic
Create table:
CREATE TABLE `sample`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`field0` TINYINT(4) DEFAULT '0',
`field1` TINYINT(4) DEFAULT '0',
`field2` TINYINT(4) DEFAULT '0',
`field3` TINYINT(4) DEFAULT '0',
`field4` VARCHAR(128) NOT NULL,
`field5` VARCHAR(128) NOT NULL,
`field6` TEXT NOT NULL,
`field7` TEXT NOT NULL,
`field8` VARCHAR(64) DEFAULT NULL,
`field9` VARCHAR(64) DEFAULT NULL,
`field10` DATE DEFAULT NULL,
`field11` TIME DEFAULT NULL,
`field12` DATETIME DEFAULT NULL,
`field13` VARCHAR(64) DEFAULT NULL,
`field14` TINYINT(4) DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Create Sample model:
<?php
/**
* This is the model class for table "sample".
*
* The followings are the available columns in table 'sample':
* @property integer $id
* @property integer $field0
* @property integer $field1
* @property integer $field2
* @property integer $field3
* @property string $field4
* @property string $field5
* @property string $field6
* @property string $field7
* @property string $field8
* @property string $field9
* @property string $field10
* @property string $field11
* @property string $field12
* @property string $field13
* @property integer $field14
*/
class Sample extends CActiveRecord
{
/**
* Admin variables (ycm module)
*/
public $adminNames=array('Samples','sample','samples'); // admin interface, singular, plural
public $downloadExcel=true; // Download Excel
public $downloadMsCsv=true; // Download MS CSV
public $downloadCsv=true; // Download CSV
/**
* Behaviors.
* @return array
*/
function behaviors() {
return array(
'file' => array(
'class'=>'application.modules.ycm.behaviors.FileBehavior',
),
);
}
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Sample the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'sample';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('field4, field5, field6, field7', 'required'),
array('field0, field1, field2, field3, field14', 'numerical', 'integerOnly'=>true),
array('field4, field5', 'length', 'max'=>128),
array('field8, field9, field13', 'length', 'max'=>64),
array('field8, field9', 'unsafe'),
array('field8', 'file', 'on'=>'insert', 'allowEmpty'=>true, 'types'=>'jpg,jpeg,gif,png', 'maxSize'=>1024*1024*6),
array('field8', 'file', 'on'=>'update', 'allowEmpty'=>true, 'types'=>'jpg,jpeg,gif,png', 'maxSize'=>1024*1024*6),
array('field9', 'file', 'on'=>'insert', 'allowEmpty'=>true, 'types'=>'jpg,jpeg,gif,png,gz,tar,zip,pdf,doc,docx,xls,xlsx,ppt,pptx,pps,ppsx', 'maxSize'=>1024*1024*6),
array('field9', 'file', 'on'=>'update', 'allowEmpty'=>true, 'types'=>'jpg,jpeg,gif,png,gz,tar,zip,pdf,doc,docx,xls,xlsx,ppt,pptx,pps,ppsx', 'maxSize'=>1024*1024*6),
array('field10, field11, field12', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, field0, field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'field0' => 'Field 0',
'field1' => 'Field 1',
'field2' => 'Field 2',
'field3' => 'Field 3',
'field4' => 'Field 4',
'field5' => 'Field 5',
'field6' => 'Field 6',
'field7' => 'Field 7',
'field8' => 'Field 8',
'field9' => 'Field 9',
'field10' => 'Field 10',
'field11' => 'Field 11',
'field12' => 'Field 12',
'field13' => 'Field 13',
'field14' => 'Field 14',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('field0',$this->field0);
$criteria->compare('field1',$this->field1);
$criteria->compare('field2',$this->field2);
$criteria->compare('field3',$this->field3);
$criteria->compare('field4',$this->field4,true);
$criteria->compare('field5',$this->field5,true);
$criteria->compare('field6',$this->field6,true);
$criteria->compare('field7',$this->field7,true);
$criteria->compare('field8',$this->field8,true);
$criteria->compare('field9',$this->field9,true);
$criteria->compare('field10',$this->field10,true);
$criteria->compare('field11',$this->field11,true);
$criteria->compare('field12',$this->field12,true);
$criteria->compare('field13',$this->field13,true);
$criteria->compare('field14',$this->field14);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Config for attribute widgets (ycm module)
*
* @return array
*/
public function attributeWidgets()
{
return array(
array('field0','chosen'),
array('field1','chosenMultiple'),
array('field2','dropDown'),
array('field3','radioButton'),
array('field4','textField'),
array('field5','password'),
array('field6','textArea'),
array('field7','wysiwyg'),
array('field8','image'),
array('field9','file'),
array('field10','date'),
array('field11','time'),
array('field12','datetime'),
array('field13','disabled'),
array('field14','boolean'),
);
}
/**
* Select choices for field0 (ycm module)
*
* @return array
*/
public function field0Choices()
{
return array(
'1'=>'First',
'2'=>'Second',
'3'=>'Third',
);
}
/**
* Select choices for field1 (ycm module)
*
* @return array
*/
public function field1Choices()
{
return array(
'1'=>'First',
'2'=>'Second',
'3'=>'Third',
);
}
/**
* Select choices for field2 (ycm module)
*
* @return array
*/
public function field2Choices()
{
return array(
'1'=>'First',
'2'=>'Second',
'3'=>'Third',
);
}
/**
* Select choices for field3 (ycm module)
*
* @return array
*/
public function field3Choices()
{
return array(
'1'=>'First',
'2'=>'Second',
'3'=>'Third',
);
}
/**
* Config for TbGridView class (ycm module)
*
* @return array
*/
public function adminSearch()
{
return array(
'columns'=>array(
'field4',
'id',
array(
'name'=>'field0',
'value'=>'$data->field0',
'filter'=>Sample::model()->field0Choices(),
),
array(
'name'=>'field3',
'value'=>'$data->field3',
'filter'=>Sample::model()->field3Choices(),
),
array(
'name'=>'field14',
'value'=>'$data->field14==1 ? CHtml::encode("Yes") : CHtml::encode("No")',
'filter'=>array(1=>'Yes',0=>'No'),
),
array(
'name' => 'field12',
'value' => 'date("d.m.Y H:i:s",strtotime($data->field12))',
),
),
);
}
}
Go to: http://your.domain.com/ycm
One to many relationship (HAS_MANY)
Create tables:
CREATE TABLE `department`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(128) NOT NULL,
`description` TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `blog`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`department_id` INTEGER DEFAULT NULL,
`title` VARCHAR(128) NOT NULL,
`content` TEXT NOT NULL,
CONSTRAINT `FK_department` FOREIGN KEY (`department_id`) REFERENCES `department` (`id`) ON DELETE SET NULL ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Create Department model:
<?php
/**
* This is the model class for table "department".
*
* The followings are the available columns in table 'department':
* @property integer $id
* @property string $name
* @property string $description
*
* The followings are the available model relations:
* @property Blog[] $blogs
*/
class Department extends CActiveRecord
{
/**
* Admin variables (ycm module)
*/
public $adminNames=array('Blog departments','blog department','blog departments'); // admin interface, singular, plural
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Department the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'department';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('name', 'required'),
array('name', 'length', 'max'=>128),
array('description', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, name, description', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'blogs' => array(self::HAS_MANY, 'Blog', 'department_id'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'name' => 'Name',
'description' => 'Description',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('name',$this->name,true);
$criteria->compare('description',$this->description,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Config for attribute widgets (ycm module)
*
* @return array
*/
public function attributeWidgets()
{
return array(
array('description','wysiwyg'),
);
}
/**
* Config for TbGridView class (ycm module)
*
* @return array
*/
public function adminSearch()
{
return array(
'columns'=>array(
'id',
'name',
),
);
}
}
Create Blog model:
<?php
/**
* This is the model class for table "blog".
*
* The followings are the available columns in table 'blog':
* @property integer $id
* @property integer $department_id
* @property string $title
* @property string $content
*
* The followings are the available model relations:
* @property Department $department
*/
class Blog extends CActiveRecord
{
/**
* Admin variables (ycm module)
*/
public $adminNames=array('Blog posts','blog post','blog posts'); // admin interface, singular, plural
public $downloadExcel=true; // Download Excel
public $downloadMsCsv=true; // Download MS CSV
public $downloadCsv=true; // Download CSV
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Blog the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'blog';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('title, content', 'required'),
array('department_id', 'numerical', 'integerOnly'=>true),
array('title', 'length', 'max'=>128),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, department_id, title, content', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'department' => array(self::BELONGS_TO, 'Department', 'department_id'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'department_id' => 'Department',
'title' => 'Title',
'content' => 'Content',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('department_id',$this->department_id);
$criteria->compare('title',$this->title,true);
$criteria->compare('content',$this->content,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>20,
),
));
}
/**
* Config for attribute widgets (ycm module)
*
* @return array
*/
public function attributeWidgets()
{
return array(
array('department_id','chosen'),
array('content','wysiwyg'),
);
}
/**
* Select choices for department_id (ycm module)
*
* @return array
*/
public function department_idChoices()
{
return CHtml::listData(Department::model()->findAll(), 'id', 'name');
}
/**
* Config for TbGridView class (ycm module)
*
* @return array
*/
public function adminSearch()
{
return array(
'columns'=>array(
'id',
'title',
array(
'name'=>'department_id',
'value'=>'($data->department) ? $data->department->name : "No department"',
'filter'=>$this->department_idChoices(),
),
),
);
}
}
Go to: http://your.domain.com/ycm
Many to many relationship (MANY_MANY)
Create tables:
CREATE TABLE `post`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`title` VARCHAR(128) NOT NULL,
`content` TEXT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `category`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(128) NOT NULL,
`description` TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `post_category`
(
`post_id` INTEGER NOT NULL,
`category_id` INTEGER NOT NULL,
PRIMARY KEY (`post_id`,`category_id`),
CONSTRAINT `FK_post_category` FOREIGN KEY (`post_id`) REFERENCES `post` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_category_post` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Create Post model:
<?php
/**
* This is the model class for table "post".
*
* The followings are the available columns in table 'post':
* @property integer $id
* @property string $title
* @property string $content
*
* The followings are the available model relations:
* @property Category[] $categories
* @property PostCategory[] $category
*/
class Post extends CActiveRecord
{
/**
* Admin variables (ycm module)
*/
public $adminNames=array('Posts','post','posts'); // admin interface, singular, plural
/**
* Categories id array
*
* @var array
*/
public $assignedCategories;
/**
* Populate categories id array after find.
*/
public function afterFind() {
if (!$this->isNewRecord) {
$this->assignedCategories=CHtml::listData($this->category,'category_id','category_id');
}
}
/**
* Update categories after save.
*/
public function afterSave() {
if (!$this->isNewRecord) {
// delete all categories from Post
$criteria=new CDbCriteria;
$criteria->condition='post_id=:post_id';
$criteria->params=array(':post_id'=>$this->id);
PostCategory::model()->deleteAll($criteria);
}
// add selected categories to Post
if(!empty($this->assignedCategories)) {
foreach($this->assignedCategories as $category_id) {
$postCategory=new PostCategory;
$postCategory->post_id=$this->id;
$postCategory->category_id=$category_id;
$postCategory->save(false);
}
}
}
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Post the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'post';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('title, content', 'required'),
array('title', 'length', 'max'=>128),
array('assignedCategories', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, title, content, assignedCategories', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'categories'=>array(self::MANY_MANY,'Category','post_category(post_id,category_id)'),
'category'=>array(self::HAS_MANY,'PostCategory','post_id'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'assignedCategories' => 'Categories',
'title' => 'Title',
'content' => 'Content',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('title',$this->title,true);
$criteria->compare('content',$this->content,true);
$criteria->compare('category_id',$this->assignedCategories);
$criteria->with=array('category');
$criteria->together=true;
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>20,
),
));
}
/**
* @return string Category names separated with a comma.
*/
public function getRelatedCategoryNames()
{
$out=CHtml::listData($this->categories,'id','name');
return implode(', ', $out);
}
/**
* Config for attribute widgets (ycm module)
*
* @return array
*/
public function attributeWidgets()
{
return array(
array('assignedCategories','chosenMultiple'),
array('content','wysiwyg'),
);
}
/**
* Select choices for assignedCategories (ycm module)
*
* @return array
*/
public function assignedCategoriesChoices()
{
return CHtml::listData(Category::model()->findAll(array('order'=>'name ASC')), 'id', 'name');
}
/**
* Config for TbGridView class (ycm module)
*
* @return array
*/
public function adminSearch()
{
return array(
'columns'=>array(
'id',
'title',
array(
'name'=>'assignedCategories',
'value'=>'$data->relatedCategoryNames',
'filter'=>$this->assignedCategoriesChoices(),
'type'=>'html',
),
),
);
}
}
Create Category model:
<?php
/**
* This is the model class for table "category".
*
* The followings are the available columns in table 'category':
* @property integer $id
* @property string $name
* @property string $description
*
* The followings are the available model relations:
* @property Post[] $posts
* @property Post[] $postCount
*/
class Category extends CActiveRecord
{
/**
* Admin variables (ycm module)
*/
public $adminNames=array('Post categories','post category','post categories'); // admin interface, singular, plural
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Category the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'category';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('name', 'required'),
array('name', 'length', 'max'=>128),
array('description', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, name, description', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'posts' => array(self::MANY_MANY, 'Post', 'post_category(category_id, post_id)'),
'postCount' => array(self::STAT, 'Post', 'post_category(category_id, post_id)'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'name' => 'Name',
'description' => 'Description',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('name',$this->name,true);
$criteria->compare('description',$this->description,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>20,
),
));
}
/**
* Config for attribute widgets (ycm module)
*
* @return array
*/
public function attributeWidgets()
{
return array(
array('description','wysiwyg'),
);
}
/**
* Config for TbGridView class (ycm module)
*
* @return array
*/
public function adminSearch()
{
return array(
'columns'=>array(
'id',
'name',
),
);
}
}
Create PostCategory model:
<?php
/**
* This is the model class for table "post_category".
*
* The followings are the available columns in table 'post_category':
* @property integer $post_id
* @property integer $category_id
*/
class PostCategory extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return PostCategory the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'post_category';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('post_id, category_id', 'required'),
array('post_id, category_id', 'numerical', 'integerOnly'=>true),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('post_id, category_id', 'safe', 'on'=>'search'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'post_id' => 'Post',
'category_id' => 'Category',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('post_id',$this->post_id);
$criteria->compare('category_id',$this->category_id);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>20,
),
));
}
}
Go to: http://your.domain.com/ycm
License
yii-ycm is free and unencumbered public domain software.