[РЕШЕНО] Логирование действий с БД (которые отправляются в контроллер AJAX'ом) и вообще проблема...

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Закрыто
stop4uk
Сообщения: 159
Зарегистрирован: 2012.12.18, 07:08

[РЕШЕНО] Логирование действий с БД (которые отправляются в контроллер AJAX'ом) и вообще проблема...

Сообщение stop4uk »

Есть виджет booster.widgets.TbEditableField. При изменении поля, он отправляет ajax'ом данные определенному действию контроллера, который все сие добро обрабатывает и выплевывает результат.

Проблема. На странице есть куча полей редактируемых через TbEditableField и отдельная форма, которая отвечает за загрузку фотографии профиля. Фотография грузится, в БД записывается ее название и все хорошо до тех пор, пока не произойдет обновление любого поля через TbEditableField. Данные о фотографии просто слетают..

1. Как залогировать все запросы в БД, даже которые происходят через AJAX.
2. Как вообще решить данную проблему?


Часть вьюхи с TbEditableField

Код: Выделить всё

<div class="text-left block_name">
                    <?php echo Yii::t('system', 'email').':' ?>
                </div>
                <div class="text-left block_desc">
                    <?php $this->widget('booster.widgets.TbEditableField', array('type' => 'text', 'emptytext'=>Yii::t('system','specify'), 'model' => $model, 'attribute' => 'email', 'url' => array('/user/default/updateField'))); ?>
                </div>
                <div class="text-left block_name">
                    <?php echo Yii::t('system', 'password').':' ?>
                </div>
                <div class="text-left block_desc">
                    <?php $this->widget('booster.widgets.TbEditableField', array('type' => 'text', 'model' => $model, 'attribute' => 'password', 'url' => array('/user/default/updateField'), 'emptytext'=>Yii::t('system','change_password'))); ?>
                </div>
Вьюха с фотографией

Код: Выделить всё

<div style="display: inline-block;">
                        <?php echo CHtml::beginForm(array('/user/default/uploadPhoto'),'post', array('enctype'=>'multipart/form-data'));
                              echo CHtml::activeFileField($model,'photo'); ?>
                        
                </div>
                <div style="display: inline-block;">
                    <?php $this->widget('booster.widgets.TbButton',array('label' =>Yii::t('system', 'upload'), 'buttonType'=>'submit'));
                            echo CHtml::endForm(); ?>
                </div>

Действие контроллера для TbEditableField

Код: Выделить всё

public function actionUpdateField(){
       $model = User::model()->attr()->findbyPk(Yii::app()->user->id);
        
        if($_POST['name']!=='password')
            $model->$_POST['name'] = $_POST['value'];
        else
            $model->password = UserModule::encrypting($_POST['value']);
        
        $model->save();
    }
Действие контроллера для фото

Код: Выделить всё

$model = User::model()->attr()->findbyPk(Yii::app()->user->id);
        $model->photo = $_POST['User']['photo'];
        $model->save();
        
        $this->redirect(array('/user/default/index'));
Выдержки из модели и само сохранение фотки

Код: Выделить всё

public $photo;

public function rules(){
        return array(
            array('photo', 'file', 'types'=>'jpg, jpeg, gif, png','allowEmpty'=>true,'on'=>'insert, update'),
        );
}    

protected function beforeSave(){
        if(!parent::beforeSave())
            return false;
        
        if(($this->scenario=='insert' || $this->scenario=='update') && ($file = CUploadedFile::getInstance($this,'photo'))){
            $this->deletePhoto();
 
            $extension = strtolower($file->extensionName);
            $filename = RandomNameHelper::getRandomFileName(Yii::getPathOfAlias('webroot.uploads/user_photos'), $extension);
            $basename = $filename.'.'.$extension;
            
            $this->photo = $basename;
            $file->saveAs(Yii::getPathOfAlias('webroot.uploads/user_photos').DIRECTORY_SEPARATOR.$this->photo);
        }
        return true;
    }
    
    protected function beforeDelete(){
        if(!parent::beforeDelete())
            return false;
        $this->deletePhoto();
        return true;
    }
 
    public function deletePhoto(){
        $photoPath = Yii::getPathOfAlias('webroot').'/uploads/user_photos/'.User::model()->attr()->findbyPk(Yii::app()->user->id)->photo;
        if(is_file($photoPath))
            unlink($photoPath);
    }
Последний раз редактировалось stop4uk 2016.01.25, 22:55, всего редактировалось 1 раз.
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение SiZE »

Логирование запросов можно в конфиге добавить

Код: Выделить всё

'log' => array(
    array(
        'class' => 'CFileLogRoute',
        'logFile' => 'application_trace_db.log',
        'levels' => 'trace',
        'rotateByCopy' => true,
        'categories' => 'system.db.*',
        'enabled' => YII_DEBUG
    )
)
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение SiZE »

Ошибка тут:

Код: Выделить всё

$model->photo = $_POST['User']['photo'];
Цитата из руководства:
// add a hidden field so that if a model only has a file field, we can
// still use isset($_POST[$modelClass]) to detect if the input is submitted
Перевожу: если в форме единственное поле - это поле для файла, то добавляем скрытое поле чтобы был доступен массив $_POST с ключом равным имени модели. Значение у скрытого поля пустое, туда не передается имя файла из БД.
stop4uk
Сообщения: 159
Зарегистрирован: 2012.12.18, 07:08

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение stop4uk »

Судя по firebug'u пост запрос уходит в виде user[photo].
Скрытое поле добавил - эффект тот же. Фотграфия загружается, обновляется и делается с ней все то, что планируется.... Но стоит только обновить любое поле на странице через editable, которое к тому же отрабатывается через другой контроллер, данные о фотографии из БД стираются и ячейка становится пустой..


P.S. Если, не сложно. покажи на примере, что ли...
stop4uk
Сообщения: 159
Зарегистрирован: 2012.12.18, 07:08

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение stop4uk »

SiZE писал(а):Логирование запросов можно в конфиге добавить

Код: Выделить всё

'log' => array(
    array(
        'class' => 'CFileLogRoute',
        'logFile' => 'application_trace_db.log',
        'levels' => 'trace',
        'rotateByCopy' => true,
        'categories' => 'system.db.*',
        'enabled' => YII_DEBUG
    )
) 
Логирование включено, но в режиме online не обновляется. А хотелось бы, если это возможно наблюдать за всеми запросами в online режиме... Произошел запрос в БД - он высветился на экран.

У меня логирование запросов на экран показывается
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение SiZE »

шта? какой режим онлайн? я с программистом сейчас разговариваю?


По поводу скрытого поля. Я забыл приложить ссылку на документацию. Его не надо добавлять, это комментарий в коде.

https://github.com/yiisoft/yii/blob/1.1 ... .php#L1849

Я тебе указал строку которая перезаписывает твое поле с фоткой. Её надо убрать, если ты не понял.
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение yan »

при прочтении сложилось впечатление, что по аяксу делаются запросы в БД :), даже заинтригован
stop4uk
Сообщения: 159
Зарегистрирован: 2012.12.18, 07:08

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение stop4uk »

Да уже разобрался. Спасибо

P.S. Касаемо режима онлайн и аякс работы с БД. Режим онлайн это я так обозвал какой-нить debag'ер, который аяксом обновляет все что происходит с базой. Улетел isAjaxRequest, действие отработало с моделью и выплюнуло результат, но лог БД, который в этот момент отображается на странице (тот же CWebLog или YiiDebug) не обновился. Вот и говорю - мало ли есть какой дебагер, который аяксом обновляет и показываемую дебаг панель, кроме того реагируя на все запросы к БД из приложения в целом (тыкнул вьюху одного контролера, запрос отработал другой и отдал модели план действий) - результат на панельку). Улетел запрос, контроллер поработал с моделью, панель тут же обновилась показав что было сформировано в итоге
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение SiZE »

Готового не знаю. Можно просто читать application_trace_db.log ) пишецо за пол часа.
stop4uk
Сообщения: 159
Зарегистрирован: 2012.12.18, 07:08

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение stop4uk »

Эффект от убранного присвоения аттрибута photo никак себя не проявил. Происходит все как и раньше. Постараюсь более конкретно описать:

1. Есть страница профиля с кучей полей. Каждое поле пользователь может изменить нажав на соответсвующее значение и в popover (используется bootstrap) окне введя новое. Реализована данная фишка через виджет TbEditableField (Yii booster). Каждое изменение отправляет ajax post (по умолчанию) запрос к определенному действию контроллера, который этот post запрос отрабатывает. В моем случае все поля, которые изменяются через данный виджет, отправляются к actionUpdateField. Каждый post запрос отправляет следующие параметры: name (название аттрибута), pk (id пользователя), scenario (insert или update) и value(введенное пользователем значение).
Выглядит это примерно так:

Код: Выделить всё

<a href="#" rel="User_email_2" data-pk="2">user@user.ru</a>   

$('a[rel="User_email_2"]').editable({'name':'email','title':' E-Mail','url':'/index.php?r=user/default/updateField','type':'text','emptytext':'Указать','params':{'scenario':'update'}});
 
2. На данной странице есть форма с фотографией, которая отправляет данные к ДРУГОМУ ДЕЙСТВИЮ контроллера. В частности к actionUploadPhoto. Post запрос отправляется с параметром User[photo] - более ничего нет

ПРОБЛЕМА: TbEditableField отрабатывает хорошо, данные заносятся и изменяются. Форма с фотографией тоже обновляется хорошо, фотография заносится и меняется. Но!!!!! Если при наличии фотографии у пользователя (ячейка photo в базе заполнена), изменить через TbEditableField любое поле профиля... Ячейка с фотографией в базе становится пустой
stop4uk
Сообщения: 159
Зарегистрирован: 2012.12.18, 07:08

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение stop4uk »

Всем спасибо. Проблему решил)
stop4uk
Сообщения: 159
Зарегистрирован: 2012.12.18, 07:08

Re: Логирование ajax действий при работе с БД и вообще проблема

Сообщение stop4uk »

Взглянул на документацию и понял где тупил. Модель может работать с конкретным атрибутом, следовательно, зачем сохранять всю модель заново (а насколько я понял тип атрибута file указанный для photo не катит к чтению, ибо всегда поднимается с пустым значением), если я могу сохранить сведения о конкретном атрибуте (я ведь только его и меняю)....

Решилось изменением actionUpdateField:

Код: Выделить всё

$model->save(true, array($_POST['name']));
Закрыто