Сборник советов для Yii1

public function rules() {  
    return array(  
        array('username, password', 'required', 'message' => 'Будьте любезны заполнить поле "{attribute}"'),  
    );  
}
public function actions() {  
    return array(  
        'captcha' => array(  
            'class' => 'CCaptchaAction',  
            'backColor' => 0xFFFFFF,  
            'testLimit'=> 1, //   
        ),  
    );  
}  

По-умолчанию, 'testLimit' установлен в значении 3. Поэтому код обновляется только после третьего неверного ввода.

$this->renderPartial('index', array(  
        'criteria' => $criteria, ), false, true);  

Именно, последний параметр, установленный в true, сообщает что нужно отдавать страницу со всеми скриптами.

1 Способ

$adminMenuItems = array(  
        array('label' => '<img src="'.Yii::app()->request->baseUrl.'/images/adminmenu/manage_ads.png" />',   
                'url'=>array('/apartments/backend/main/admin'),   
                'linkOptions'=>array('title' => Yii::t('module_apartments', 'Manage apartments'))  
            )  
);  
 
$this->widget('zii.widgets.CMenu', array(  
            'items'=>$adminMenuItems,                     
            'encodeLabel' => false,   
));  

2 Способ

$adminMenuItems = array(  
        array('label'=>'',   
                'url'=>array('/quicksearch/main/index'),   
                'template' => '<img src="'.Yii::app()->request->baseUrl.'/images/adminmenu/manage_ads.png" />'  
        )  
);  
 
$this->widget('zii.widgets.CMenu', array(  
    'items'=>$adminMenuItems,  
)); 
$globalConfig = CJavaScript::encode(Yii::app()->params->toArray());   
Yii::app()->clientScript->registerScript('globalConfig', "var globalConfig = ".$globalConfig.";", CClientScript::POS_HEAD);  
Yii::app()->clientScript->registerScript('testConfig', ' 
    if(globalConfig){ 
            alert(globalConfig["languages"]); 
    } 
', CClientScript::POS_END); 
public function behaviors(){  
    return array(  
        'AutoTimestampBehavior' => array(  
            'class' => 'zii.behaviors.CTimestampBehavior',  
            'createAttribute' => 'date_updated',  
            'updateAttribute' => 'date_updated',  
        ),  
    );  
}  
$this->widget('zii.widgets.grid.CGridView', array(  
    'dataProvider'=>$model->search(),  
    'filter'=>$model,  
    'columns'=>array(  
        array (  
            'name' => 'img',  
            'type' => 'image',  
            'value'=> 'url/to/image' /* например: 'Yii::app()->request->baseUrl."/".$data->sliderThumbPath."/".$data->img' - обязательно в ковычках */  
            'filter' => false,  
        ),  
        ...  
));
$model->scenario = 'upload'; // Обязадельно должен объявляться до присвоения атрибутов  
$model->attributes = $_POST['form_name'];      
if($model->validate()) {  
    //...  
}  

в правилах валидации указываем сценарий 'on' ⇒ 'upload':

public function rules() {  
    return array(  
        array(  
            'upload', 'file',  
            'types' => "{$this->supportExt}",  
            'maxSize' => $this->fileMaxSize,  
            'tooLarge' => Yii::t('module_slider', 'The file was larger than {size}MB. Please upload a smaller file.', array('{size}' => $this->fileMaxSize)),  
            'on' => 'upload',  
        ),  
    );  
} 
if(isset($_POST["{$this->modelName}"])){  
    $model->attributes = $_POST;                  
    $model->scenario = 'upload';  
 
    if($model->validate()) {  
        $model->upload = CUploadedFile::getInstance($model,'upload');                                 
        $model->img = md5(uniqid()).'.'.$model->upload->extensionName;                
 
        if($model->save()){  
            $model->upload->saveAs($model->uploadPath.'/'.$model->img);  
 
            Yii::import('application.extensions.image.Image');  
            $image = new Image($model->uploadPath.'/'.$model->img);  
            $image->resize($model->maxWidth, $model->maxHeight);  
            $image->save();  
 
            Yii::app()->user->setFlash(  
                    'mesSlider', tt('Image succesfullty added to slider.')  
            );  
            $model->unsetAttributes();                
        }  
    }  
}  
Yii::app()->user->setFlash(  
        'message', 'Image succesfullty added to slider.'  
);    
// CSS
Yii::app()->clientScript->registerCssFile(Yii::app()->assetManager->publish(Yii::app()->basePath . '/css/').'css1.css', 'screen');  
 
// JS
// JQuery
Yii::app()->clientScript->registerCoreScript('jquery');  
// Custom script
Yii::app()->clientScript->registerScriptFile(Yii::app()->assetManager->publish(Yii::app()->basePath . '/js/'). '/jcarousel/lib/jquery.jcarousel.min.js', CClientScript::POS_END);  

Втавка в темплайт

Yii::app()->clientScript->registerScript('loading', ' 
    $("#loading").bind("ajaxSend", function(){ 
        $(this).show(); 
    }).bind("ajaxComplete", function(){ 
        $(this).hide(); 
    }); 
', CClientScript::POS_READY);  
  • POS_READY значит, что скрипт выполнится в $(document).ready(function() { })
  • POS_LOAD - скрипт выполнится в window.onload
  • POS_END - вставка перед закрывающим тэгом body
  • POS_BEGIN - вставка перед открывающим тэгом body
  • POS_HEAD - вставка перед тэгом title

Статьи:

class MainController extends CController {  
    public $defaultAction='test';  
      //....        
    public function actionTest() {  
    }    
}  
  $this->redirect(Yii::app()->homeUrl);  
// Controller
$controllerId = Yii::app()->controller->id;  
 
// Получение ID контролера
$actionId = $this->getAction()->getId();  
$actionId = Yii::app()->controller->action->id;
 
// Обращение к модулю из чужого модуля или контролера
$module = Yii::app()->getModule('userGroups');
$module->mailMessages();
 
 
// Вызов чужого контроллера
$p = Yii::app()->createController('userGroups/user/login');
$act = $p[0]->createAction('login');
$act->run();
 
// Вызов чужого контроллера
// Если необходимо наличие _action в контролере
$controller = Yii::app()->createController('social/profile/friendsFeed')[0];
$action = $controller->createAction('friendsFeed');
$controller->runActionWithFilters($action, $controller->filters());
 
// Вызов чужого контроллера
// Если необходимо наличие _owner
Yii::app()->runController('social/profile/friendsFeed');
$url = Yii::app()->createAbsoluteUrl('user/activation',array('activationKey'=>$activationKey));
public function rules() {  
    return array(  
        ...  
        array('verifyCode', 'required', 'on' => 'registration'),  
        array('verifyCode', 'captchaValidate', 'on' => 'registration'),  
    )  
}     
 
public function captchaValidate() {  
  $code = Yii::app()->controller->createAction('captcha')->getVerifyCode();  
    if ($code != $this->verifyCode)  
        $this->addError('verifyCode', 'Неверный код с капчи'); 
} 

Объявляем расширение контролера в ext.test.testActionDelele

<?php  
class testActionDelele extends CAction {  
    public $modelName;  
    public $redirectAfter = array('index');  
 
    public function run($id = null) {  
        if (id) {  
            CActiveRecord::model($this->modelName)->deleteByPk($id);  
        }  
 
        if(Yii::app()->getRequest()->getIsAjaxRequest()) {  
            Yii::app()->end(200, true);  
        }  
        else {  
            $this->getController()->redirect($this->redirectAfter);  
        }  
    }  
} 

Создаем общий метод

<?php  
class testController extends CController {  
    public function actions() {  
        return array(  
            'deleteUser' => array(  
                'class' => 'ext.test.testActionDelele',  
                'modelName' => 'User',  
                'redirectAfter' => array('indexUsers'),  
            ),  
            'deletePost' => array(  
                'class' => 'ext.test.testActionDelele',  
                'modelName' => 'Post',  
                'redirectAfter' => array('indexPosts'),  
            ),  
        );  
    }   
} 
if($isFancyBox){  
    Yii::app()->clientscript->scriptMap['jquery.js'] = false;  
    Yii::app()->clientscript->scriptMap['jquery.min.js'] = false;  
    Yii::app()->clientscript->scriptMap['jquery-ui.min.js'] = false;  
 
    $this->renderPartial('form', array(  
        'model' => $model,  
    ), false, true);  
 
} else{  
    $this->render('form', array(  
        'model' => $model,  
    ));  
}

ext.compress.compressPage

<?php  
class compressPage extends CFilter {  
    protected function preFilter($filterChain) {  
        ob_start();  
        return parent::preFilter($filterChain);  
    }  
 
    protected function postFilter($filterChain) {  
        $html = ob_get_clean();  
        echo preg_replace("~>(\s+|\t+|\n+)<~", "><", $html);  
        parent::postFilter($filterChain);  
    }  
}  

В контолере

public function filters() {  
    return array(  
        array(  
            'ext.compress.compressPage + view, index'  
        ),  
    );  
}
echo CHtml::dropDownList('Cars', 'car_id', array(  
    'Toyota'=>array(  
        1=>'Avensis',  
        2=>'Camry',  
    ),  
    'Volvo'=>array(  
        3=>'S60',  
        4=>'XC70',  
    ),  
)); 
$records = array(  
    array('id' => 1, 'name' => 'Yii', 'group' => 'Фреймворк'),  
    array('id' => 2, 'name' => 'Drupal', 'group' => 'Фреймворк'),  
    array('id' => 3, 'name' => 'Joomla', 'group' => 'Фреймворк'),  
    array('id' => 4, 'name' => 'Сodeigniter', 'group' => 'Фреймворк'),  
    array('id' => 5, 'name' => 'Mercurial', 'group' => 'Система контроля версий'),  
    array('id' => 6, 'name' => 'Git', 'group' => 'Система контроля версий'),  
    array('id' => 7, 'name' => 'SVN', 'group' => 'Система контроля версий'),  
);  
 
$dropDownList = CHtml::listData($records, 'id', 'name', 'group');   
echo CHtml::dropDownList('dropDownList', '', $dropDownList);  
echo CHtml::activeLabel($model, 'name', array('required' => true));
  • 'filter' ⇒ array(0 ⇒ 'Все', 1 ⇒ 'Продажа', 2 ⇒ 'Аренда'),
$this->widget('zii.widgets.grid.CGridView', array(    
    'id'=>'apartments-grid',    
    'dataProvider'=>$model->search(),    
    'filter'=>$model,    
    'columns'=>array(    
        ...    
        array(    
            'name' => 'type',    
            'type' => 'raw',    
            'value' => 'Apartment::getNameByType($data->type)',    
            'filter' => array(0 => 'Все', 1 => 'Продажа', 2 => 'Аренда'),  
        ),          
        ...    
    )    
));

Добавить в модели метода search

if ($this->type)  
    $criteria->compare('type', $this->type);  
public function actionCreate() {  
    $category = new Category;  
    $subCategory = new SubCategory;  
 
    if(isset($_POST['Category'], $_POST['SubCategory'])) {  
        // собираем входные данные  
        $model->attributes = $_POST['Category'];  
        $sub->attributes = $_POST['SubCategory'];  
 
        // валидация  
        $valid = $model->validate();  
        $valid = $sub->validate() && $valid;  
 
        if($valid) {  
            // сохраняем данные без валидации (параметр false), так как уже валидация была выше.  
            if($model->save(false)) {  
                $sub->category_id = $model->id;  
                $sub->save(false);  
                $this->redirect(array('view','id'=>$model->id));  
            }             
        }  
    }  
 
    $this->render('create', array(  
        'model'=>$model,  
        'sub'=>$sub,  
    ));  
}    
?>

Представление create модели Category имеет вид:

<?php  
$this->breadcrumbs=array(  
    'Управление категориями' => array('admin'),  
    'Добавить категорию',  
);  
 
$this->renderPartial('_form',array(  
    'model'=>$model,  
    'sub' => $sub,  
));  
?>

И представление _form:

<div class="form">  
    <?php $form=$this->beginWidget('CActiveForm', array(  
        'id'=>'category-form',  
        'enableAjaxValidation'=>false,  
    )); ?>  
 
    <p class="note">Поля, отмеченные <span class="required">*</span> являются обязательными.</p>  
 
    <?php echo $form->errorSummary(array($model, $sub)); ?>  
 
    <div class="row">  
        <?php echo $form->labelEx($model, 'model_field1'); ?>  
        <?php echo $form->textField($model, 'model_field1'); ?>  
        <?php echo $form->error($model, 'model_field1'); ?>  
    </div>  
 
    <div class="row">  
        <?php echo $form->labelEx($sub, 'sub_field1'); ?>  
        <?php echo $form->textField($sub, 'sub_field1'); ?>  
        <?php echo $form->error($sub, 'sub_field1'); ?>  
    </div>  
 
    <div class="row buttons">  
        <?php echo CHtml::submitButton($model->isNewRecord ? 'Добавить' : 'Сохранить'); ?>  
    </div>  
 
<?php $this->endWidget(); ?>  
</div> 

config/main.php

'cache'=>array(  
    'class'=>'system.caching.CFileCache',  
), 

Выставляем время кеша в 1000 секунд для DAO:

$sql = 'SELECT field1, field2 FROM {{apartment_reference}}';  
$dependency = new CDbCacheDependency('SELECT MAX(date_updated) FROM apartment_reference');  
$apReference = Yii::app()->db->cache(1000, $dependency)->createCommand($sql)->queryAll();

То же самое для AR:

$dependency = new CDbCacheDependency('SELECT MAX(date_updated) FROM apartment_reference');      
$apReference = apReference::model()->cache(1000, $dependency)->findAll();  

Для очистки всего кэша вызываем метод flush():

Yii::app()->cache->flush();  

config/main.php

'db'=>array(  
    'charset' => 'utf8',  
    'enableParamLogging' => 0,  
    'enableProfiling' => true,  
    'schemaCachingDuration' => 0,   
),   
'log'=>array(  
    'class'=>'CLogRouter',  
    'routes'=>array(  
        array(  
            'class'=>'CWebLogRoute',  
            'levels'=>'trace',  
            'showInFireBug'=>true,  
        ),  
    ),  
), 

Запрос, созданный при помощи построителя запросов, можно посмотреть при помощи CDbCommand::getText().

var_dump(Yii::app()->db->createCommand($sql)->text); 

Удаление записи

Yii::app()->db->createCommand()->delete('{{apartment_reference}}', 'apartment_id=:id', array(':id'=>$this->id));

Вставка записи

Yii::app()->db->createCommand()->insert('{{apartment_reference}}', array(  
    'field1'=>'valueField1',  
    'field2'=>'valueField2',  
));

Изменение значения с строке

Yii::app()->db->createCommand()->update('{{apartment_reference}}', array(  
    'field1'=>'valueField1',  
), 'id=:id', array(':id'=>1));  

Выборка данных

$apReference = Yii::app()->db->createCommand()  
  ->select('field1, field2')  
  ->from('{{apartment_reference}}')  
  ->where('id=:id', array(':id'=>1))  
  ->queryRow();  

Контролер:

public function actionViewGrid() {  
    $items = array(  
            array('id' => 1, 'title'=>'Title1', 'description' => 'Description1'),  
            array('id' => 2, 'title'=>'Title2', 'description' => 'Description2'),  
            array('id' => 3, 'title'=>'Title3', 'description' => 'Description3'),  
            array('id' => 4, 'title'=>'Title4', 'description' => 'Description4')  
    );  
 
    $itemsProvider = new CArrayDataProvider($items, array(  
        'pagination' => array(  
            'pageSize' => 2,  
        ),  
    ));  
 
    $this->render('viewgrid', array('itemsProvider' => $itemsProvider));  
}

Представление:

$this->widget('zii.widgets.grid.CGridView', array(  
    'id' => 'itemGrid',  
    'dataProvider' => $itemsProvider,  
    'enablePagination' => true,  
    'columns' => array(  
        array(  
            'name' => 'ID',  
            'value' => '$data["id"]',  
            'sortable' => true,  
            'filter' => false,  
        ),  
        array(  
            'name' => 'Название',  
            'value' => '$data["title"]'  
        ),  
        array(  
            'name' => 'Описание',  
            'value' => '$data["description"]'  
        ),  
    )  
));
echo Yii::app()->request->userHostAddress;
Yii::app()->clientScript->registerMetaTag('описание сайта', 'description');  
Yii::app()->clientScript->registerMetaTag('ключевые слова сайта', 'keywords');  

onBeforeValidate

public function onBeforeValidate($event) {  
    $scenarioArray = array(  
                    1 => 'scanario1',  
                    2 => 'scanario2',  
                    3 => 'scanario3',  
                    4 => 'scanario4',  
                    5 => 'scanario5',  
    );  
    $this->scenario = $scenarioArray[$this->fieldFromDB1];  
 
    if (!$this->field2 || !$this->field3)  
        $this->addError('phone', 'Заполните поля field2 и field3');  
    else   
        $this->fieldFromDB2 = $this->field2.$this->field3;  
}
 
public function onAfterValidate($event) {  
    // здесь некий код  
}
 
public function beforeValidate(){
}
 
public function AfterValidate(){
}

Добавим дивчик на страницу:

<div id="loading" style="display:none;">Загрузка ...</div>  

CSS:

#loading{   
    position: fixed;   
    top: 40px;   
    leftleft: 0;   
    z-index: 5000;   
    background-color: #3C69AC;   
    font-size: 100%;  
    color: #FFFFFF;   
    padding: 5px;  
}

Отображение и скрытие дивчика:

Yii::app()->clientScript->registerScript('loading', ' 
    $("#loading").bind("ajaxSend", function(){ 
        $(this).show(); 
    }).bind("ajaxComplete", function(){ 
        $(this).hide(); 
    }); 
', CClientScript::POS_READY);  

Установка путей загрузки картинки

Yii::getPathOfAlias('webroot.uploads');  
 if( Yii::app()->request->isAjaxRequest) {
 
    // do some thing….
 
}
Yii::app()->session->add(‘product’, $productId);
Yii::app()->session->get(‘product’);
Yii::app()->session->remove(‘product’);
unset(Yii::app()->session[$variable][$key]);
$cookie=Yii::app()->request->cookies[$name];
$value=$cookie->value;
 
$cookie=new CHttpCookie($name,$value);
Yii::app()->request->cookies[$name]=$cookie;