i have some problem with Log with Yii2.
I set Log Targets in this way:
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'flushInterval' => 1,//test
'targets' => [
[
'class' => 'common\components\SaDbTarget',
'levels' => ['error', 'warning','trace','info'],
'exportInterval' => 1,//test
//'categories' => ['application'],
/*'except' => [
'yii\db\*',
],*/
],
],
],
I create my SaDbTarget extending DbTarget Class, and this is working fine because i found in my table some log.
After that, in a controller i tried to set a log like this way
public function actionIndex(){
$searchModel = new CategorySearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
Yii::trace('trace log', __METHOD__);
Yii::warning('warning log');
// here is the rest of the code
}
I can see this 2 logs into the debug toolbar, but not in my db table.
According to the Docs
To make each log message appear immediately in the log targets, you
should set both flushInterval and exportInterval to be 1
I tried to set this values but still doesn't work.
I don't know what am I doing wrong.
UPDATE
This is my SaDbTarget
namespace common\components;
use Yii;
use yii\log\DbTarget;
use yii\log\Logger;
class SaDbTarget extends DbTarget{
//set custom table db for saving log
public $logTable = 'authlog';
//overwrite export();
public function export(){
$tableName = $this->db->quoteTableName($this->logTable);
$sql = "INSERT INTO $tableName ([[authlog_login]], [[authlog_ip]], [[authlog_area]], [[authlog_act]], [[authlog_time]], [[authlog_data]])
VALUES (:login, :ip, :area, :act, :time, :data )";
$command = $this->db->createCommand($sql);
//Get username
$user=Yii::$app->user->getId();
//Get user ip address
$ip = Yii::$app->request->getUserIP();
//Get area/controller
$controller=Yii::$app->controller->uniqueId;
//Get action
$event= Yii::$app->controller->module->requestedAction->id;
//Set timezone
$time = Yii::$app->formatter->asDate('now', 'php:Y-m-d H:i:s');
//Set Data
$data = $this->messages[0];
$command->bindValues([
':login' => $user,
':ip' => $ip,
':area' => $controller,
':act' => $event,
':time' => $time,
':data' => $data,
])->execute();
}
Could you check wether the 'log' component is set on bootstrap?
I think this could be the issue that the dispatcher is not setup and does not pickup the target.
So the bootstrap should look like
[
'bootstrap' => ['log'],
'components' => [
'log' => [
...
],
....
]
Another way would be to check in the debugger if the dispatcher on the logger is configured correctly.
Related
I'm trying to implement a multiple models form using the form-wizard widget, with Profile as main model and few others as linked ones. When I select the entity type field for the main model, I would like to change the linked model for the next step, basing on the value of entity type field.
I have tried with this code:
Create Form Code
$modelUrlReletedModelsCreate = Profile::urlRelatedModelCreate();
$urlLinkedProfile = Url::to(['create']);
echo FormWizard::widget([
'formOptions'=>[
'id'=>'profile_form',
'enableClientValidation'=>true,
'enableAjaxValidation'=>true,
'validationUrl' => Url::to(['profile-models-validation'])
],
'theme' => FormWizard::THEME_MATERIAL_V,
'steps' => [
//step 1
[
'model' => $model,
'title' => \Yii::t('app', 'Profile'),
'fieldConfig' => [
'only' => ['entity_type_id', 'profile_type_id'],
'entity_type_id' => [
'widget' => Select2::class,
'options' => [
'data' => EntityType::arrayNamesList(),
'options' => ['placeholder' => \Yii::t('app','Select an element')],
'pluginEvents' => ['select2:select'=>'function(e){;'
. 'var type = $("#pr-ty-sel").val();'
. 'var profile= "'.($model->profile_id ? : "no").'";'
. '$.ajax({ method: "GET",'
. 'url:"'.$urlLinkedProfile.'",'
. 'data:{ entity_text : e.params.data.text,'
. 'entity_id : e.params.data.id,'
. 'profile_type_id : type,'
. 'profile_id : profile},'
. 'success: function(data){'
. '$("#profile_form").html(data);'
. '}'
. '});}'],
],
],
'profile_type_id' =>[
'widget' => Select2::class,
'options' => [
'data' => \app\models\ProfileType::arrayNamesList(),
'options' => ['placeholder' => \Yii::t('app','Select an element'),'id'=>'pr-ty-sel'],
],
]
],
'description' => \Yii::t('app', 'Add Profile Type Data'),
'formInfoText' => \Yii::t('app', 'Fill all fields'),
],
//step 2 I want ot change here $linkedModel
[
'model' => [$model,$linkedModel],
'title' => \Yii::t('app', 'Personal Data'),
'description' => \Yii::t('app', 'Insert Personal Data'),
],
]
]);
Controller Action Create Code
public function actionCreate($profileId = NULL)
{
if($profileId AND $profileId !== 'no'){
$model = $this->findModel($profileId);
}else{
$model = new Profile();
}
$profileLinkedModel = new ProfilePrivate();
$renderMethod = 'render';
if (Yii::$app->request->isAjax) {
$entityText = \Yii::$app->request->get('entity_text');
$entity_id = \Yii::$app->request->get('entity_id');
$profileTypeId = \Yii::$app->request->get('profile_type_id');
$profileId = \Yii::$app->request->get('profile_id');
//Utility function to clean the entity text (remove number and special characters)
$entityTextCleaned = \app\components\Utility::cleanString($entityText);
if ($entityTextCleaned == 'private') {
$profileLinkedModel = new ProfilePrivate();
} elseif ($entityText == 'company') {
$profileLinkedModel = new ProfileCompany();
} else {
//#TODO
return FALSE;
}
$model->entity_type_id = $entity_id;
$model->profile_type_id = $profileTypeId;
$profileLinkedModel->profile_id = $model->profile_id;
Yii::$app->response->format = Response::FORMAT_JSON;
$renderMethod = 'renderAjax';
}
//extra table field used to enable custom rule in model
$model->createFullProfile = TRUE;
if ($model->load(Yii::$app->request->post())) {
return $this->redirect(['view', 'id' => $model->profile_id]);
}
return $this->$renderMethod('create', [
'model' => $model,
'profileLinkedModel' => $profileLinkedModel,
]);
}
When I select a field for entity type field, the server runs the ajax request on select event, but when it ends the other form field is not more selectable. So, in other words, after the ajax request I'm unable to select the profile type field. If I try to select the profile type field before the entity type field I can go to next step, but load always the default model.
when I want to update form in yii2
It tells me this error
creation time is invalid -- update time is invalid
What do you think is it?
public function beforeSave($insert)
{
$date = new \DateTime();
$date->setTimestamp(time());
$date->setTimezone(new \DateTimezone('Istanbul'));
$this->update_time = $date->format('Y-m-d H:i:s');
if($this->isNewRecord)
$this->creation_time = $date->format('Y-m-d H:i:s');
return parent::beforeSave($insert);
}
My problem has been resolved
change date to safe in rules
[['creation_time', 'update_time'], 'safe'],
Your code is correct "Nader" but some time assigning the value not work so just remove the value or use this
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'create_time',
'updatedAtAttribute' => 'update_time',
//'value' => new Expression('NOW()'),
],
];
}
Just comment the value,
it will work.
For more detail https://www.yiiframework.com/doc/api/2.0/yii-behaviors-timestampbehavior
Just could just use the available TimestampBehavior behavior
use yii\behaviors\TimestampBehavior;
use yii\db\Expression;
use yii\db\ActiveRecord;
class Mymodel extends ActiveRecord{
public function behaviors() {
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'creation_time',
'updatedAtAttribute' => 'update_time',
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'creation_time',
ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
],
'value' => new Expression('NOW()')
]
];
}
}
Remove any validation rules from your model you may have for this two attributes
creation_time and update_time
I am using the mpdf extension to generate pdf files. I have set global settings for the mpdf in the config file, hence I am able to call the function every time I want to generate a pdf from my controller action. However, I am finding it hard to change the orientation for the pdf with data that requires landscape orientation since the default orientation set in the global settings is portrait. Here are the codes:
main.pdf code for the global setting
'pdf' => [
'class' => Pdf::classname(),
'mode' => Pdf::MODE_UTF8, // leaner size using standard fonts
'format' => Pdf::FORMAT_A4,
'orientation' => Pdf::ORIENT_PORTRAIT,
'destination' => Pdf::DEST_BROWSER,
'cssFile' => '#vendor/kartik-v/yii2-mpdf/assets/kv-mpdf-bootstrap.min.css',
// any css to be embedded if required
'cssInline' => '.kv-heading-1{font-size:18px}',
'options' => [
'shrink_tables_to_fit' => 0
],
// refer settings section for all configuration options
],
Controller Action calling the global settings:
public function actionReservationsList()
{
$searchModel = new ReservationsSearch();
$dataProvider = $searchModel->search(Yii::$app->session->get('repquery'));
$dataProvider->pagination = false;
$pdf = Yii::$app->pdf;
$pdf->content = $this->renderPartial('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
$pdf->methods = [
'SetHeader' => [Yii::$app->user->identity->company->name.'||Date: ' . date("r")],
'SetFooter' => ['User: '.Yii::$app->user->identity->username.'||Page {PAGENO}'],
];
return $pdf->render();
}
So I need help in overriding the 'orientation' => Pdf::ORIENT_PORTRAIT, setting that is in the global settings main.php file from the controller action.
This work for me:
<?php
namespace backend\controllers;
use Yii;
use yii\web\Controller;
use kartik\mpdf\Pdf;
class InformesController extends Controller
{
...
public function actionImprimirInforme($id,$key)
{
$html = $this->renderPartial('informe-pdf', [
'title' => 'Informe'
]);
$pdf = new Pdf([
'format' => Pdf::FORMAT_A4,
'orientation' => Pdf::ORIENT_LANDSCAPE,
'destination' => Pdf::DEST_BROWSER,
'options' => [
'showImageErrors' => true,
]
]);
$pdf->configure([
'title' => 'Informe ',
]);
$pdf->content = $html;
$pdf->orientation = Pdf::ORIENT_LANDSCAPE;
$pdf->execute('SetFooter', ['{PAGENO} de {nbpg}']);
$pdf->filename = "Informe.pdf";
return $pdf->render();
}
}
My first answer was wrong, i have been setting the property 'orientation' into pdf component, so the dynamically assign does not work properly.
Here you have the documentation example
You need to add the contents via addPage. So if you build a array of pages, with the contents etc - you should be able to specify the orientation per page.
<?php
$mpdf = new mPDF('', 'Legal');
$mpdf->WriteHTML('
Hello World
');
$mpdf->AddPage('L'); // Adds a new page in Landscape orientation
$mpdf->WriteHTML('
Hello World
');
$mpdf->Output();
?>
Try add this line this :
$pdf = Yii::$app->pdf;
$pdf->orientation = Pdf::ORIENT_LANDSCAPE;
I'm trying to include a csv exporter in my application, And i used https://github.com/FriendsOfCake/cakephp-csvview.
It works fine on my local machine but for some reason it doesn't work on my server. It throws me View class "CsvView.csv" is missing. error. Is there a way to fix this issue?
Here's my controller for reference
public function export() {
$this->response->download('export.csv');
// $opts1['order'] = array('Blogs.created' => 'desc');
// $blogsinfos = $this->Blogs->find('all',$opts1);
$opts1['order'] = array('Incomes.title' => 'desc');
$data = $this->Incomes->find('all',$opts1)->toArray();
$_serialize = 'data';
// Give the needed the colums to extract
$_extract = ['id', 'title' ,'description' , 'created' , 'amount'];
//headings for the CSV
$_header = ['ID', 'Title' ,'Description' , 'Created' , 'Amount'];
$this->set(compact('data', '_serialize', '_header', '_extract'));
$this->viewBuilder()->className('CsvView.csv');
return;
}
Code to create the downloadable link.
<?= $this->Html->link('Monthly Report', [
'controller' => 'incomes',
'action' => 'export',
'_ext' => 'csv'
],
['class' => 'btn btn-success'])
?>
I'm using CakePHP 3.4.7.
i'm building multi lingual site with English and Arabic
url for English
url for Arabic
I want to switch language from any page exactly to the same page of the other language
so i made code like below.
$route = Yii::$app->controller->route;
$params = $_GET;
array_unshift($params, '/'.$route);
<?php if(Yii::$app->language == 'ar'){ ?>
<?= Html::a('English', [Yii::$app->urlManager->createUrl($params), 'language'=>'en']); ?>
<?php }else{?>
<?= Html::a('Arabic', [Yii::$app->urlManager->createUrl($params), 'language'=>'ar']); } ?>
and my url generating like below
/multi/backend/web/en/multi/backend/web/ar/site/index?val=hii&net=good
English
don't know what is wrong?
I'm using this for language management.
please check my main.php under backend/config
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);
return [
'id' => 'app-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'language' => 'en',
'sourceLanguage' => 'en_UK',
'bootstrap' => ['log'],
'modules' => [],
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'i18n' => [
'translations' => [
'app' => [
'class' => 'yii\i18n\DbMessageSource',
'sourceLanguage' => 'en_UK',
],
],
],
'urlManager' => [
'class' => 'codemix\localeurls\UrlManager',
'languages' => ['en', 'ar'],
'enableDefaultLanguageUrlCode' => false,
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
],
'params' => $params,
];
If you are doing it as in your example, you have to think about it on every link you create. This can be automated easily.
URL-Rule
You can solve this with an url-rule in your config file like so:
'<language:[\w]{2,2}>/<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
This will assert the proper routing to your controller and provide you the desired language in the language-variable.
Custom UrlManager
You can extend the UrlManager-class and make sure the current language is always appended to the params:
class MyUrlManager extends \yii\web\UrlManager
{
// ...
/**
* #inheritdoc
*/
public function createUrl($params)
{
if (!isset($params['language'])) {
$params['language'] = Yii::$app->language;
}
return parent::createUrl($params);
}
// ...
}
This will automate the process of adding the language to the links you create.
Custom Application
Now you should also override the Application-class and always set the language to the one provided or choose a default (in this case en):
class MyApplication extends \yii\web\Application
{
// ...
/**
* #inheritdoc
*/
public function init()
{
parent::init();
$lang = Yii::$app->request->get('language', 'en');
Yii::$app->language = $lang;
}
// ...
}
Now your language will always be set to the default value or the one provided viathe query param as specified above.
Final thoughts
This should give you the basic idea on how to solve your problem. Adjust as necessary...especially the last part with the Application-class and how you retrieve the value of the language-var. I hope it helped!
Possible problems with your code and the extension provided
If you read the docs of the extension the urls are generated differently. It tells you to create the urls as follows:
Url::to(['demo/action', 'language'=>'ar'])
You are createing a simple link-tag and overwrite the $params. Try this instead:
echo Html::a('Arabic', Url::to(['site/index', 'language'=>'ar']));
For redirection to the current page just replace the first part with the current route.
after lots of trying ..i found a solution.. now its worked for me.
$route = Yii::$app->controller->route;
if(Yii::$app->language == 'ar'){
$_GET['language'] = 'en';
}else{
$_GET['language'] = 'ar';
}
$params = $_GET;
array_unshift($params, '/'.$route);
<?php if(Yii::$app->language == 'ar'){ ?>
<?= Html::a('English', Yii::$app->urlManager->createUrl($params)); ?>
<?php }else{?>
<?= Html::a('Arabic', Yii::$app->urlManager->createUrl($params)); } ?>
its working for the url like
http://localhost/multi/backend/web/site/index?page=2&per-page=6
and
http://localhost/multi/backend/web/site/index