Yii2 error strtoupper() expects parameter 1 to be string, array given - yii2

I made a query like this:
return Orders::find()->where([
'customer_id' => $CustomerID,
['in', 'order_status', $statuses]
])->all();
It returns the following error:
"message": "strtoupper() expects parameter 1 to be string, array given",

This return a collection of Orders Rows
return Orders::find()
->where(['customer_id' => $CustomerID,['in','order_status',$statuses]])->all();
The strtouppoer work on a string so If you want a column value you should get a rows and a column eg: try using
$myOrders = Orders::find()
->where(['customer_id' => $CustomerID,['in','order_status',$statuses]])->all();
return $myOrder[0]->my_column_name;

I had code like this so i got error, in Yii2, mongodb
"strtoupper() expects parameter 1 to be string"
[
'$match' => [
[
'$or' => [
['patient.appointment_info.lab.lab_number' => $lab_number],
['test.name' => ['$regex' => ".*$searchText.*"]],
['patient.name' => ['$regex' => ".*$searchText.*"]],
['user.full_name' => ['$regex' => ".*$searchText.*"]],
]
]
]
],
it is fixed like
[
'$match' => [
'$or' => [
['patient.appointment_info.lab.lab_number' => $lab_number],
['test.name' => ['$regex' => ".*$searchText.*"]],
['patient.name' => ['$regex' => ".*$searchText.*"]],
['user.full_name' => ['$regex' => ".*$searchText.*"]],
]
]
],
I was using one extra curly brace.

Related

Yii2 - How can I remove unnecessary information from log file?

I am trying to log messages in Yii2 which are then emailed to my specified email address.
config file web.php contains:
'mail' => [
'class' => 'yii\log\EmailTarget',
'categories' => ['mail'],
'logVars' => [],
'mailer' => 'mailer',
'message' => [
'from' => ['user#example.com'],
'to' => ['user1#example.com'],
'subject' => 'Log message',
],
],
I am logging message like this:
Yii::info('Log message example','mail');
After successful execution, I am receiving mail like this:
2018-07-31 09:01:12 [127.0.0.1][user#example.com][-][info][mail] Log message example
So what I am trying to do is that I want to remove unwanted information like IP address, User Name etc. from this messages and at the end what I want is
2018-07-31 09:01:12 Log message example
You can remove first three parts from log by setting prefix property:
'mail' => [
'class' => 'yii\log\EmailTarget',
'categories' => ['mail'],
'logVars' => [],
'prefix' => function () {
return '';
},
'mailer' => 'mailer',
'message' => [
'from' => ['user#example.com'],
'to' => ['user1#example.com'],
'subject' => 'Log message',
],
],
Last two parts (level and category) are hardcoded, you need to extend EmailTarget and override formatMessage() to remove them.
You can set this either in your configuration file web.php or in your code.
Yii::$app->log->targets['test']->prefix = function (){
return null;
};
or
'mail' => [
'class' => 'yii\log\EmailTarget',
'categories' => ['mail'],
'logVars' => [],
'mailer' => 'mailer',
'prefix' => function () {
return null;
},
'message' => [
'from' => ['user#example.com'],
'to' => ['user1#example.com'],
'subject' => 'Log message',
],
],

Use of condition in query builder in case of multiple association in cakephp 3.0?

I am facing trouble in multilevel association using query builder when i used conditions inside multiple contain in cakephp 3.0. Lets suppose i have to get a data of single store so i am trying to add the storeId in condition but its not working else rest of data is fetching correct from all store below are the query builder that i am using:-
// generate query
$bestSellingReportData = $this->ArticleMaster->find('all')->contain([
'Category' => [
'fields' => ['Cat_Id', 'Cat_Code']
],
'size_category' => [
'fields' => ['sizeCat_Id', 'sizeCat_Code']
],
'ItemMaster' => [
'Invoicedetaile' => [
'Invoice' => [
'Store' => [
'fields' => ['Store_Id', 'Store_Code']
],
'conditions' => ['Invoice.StoreId ='.$this->request->data['storeId']],
],
],
],
]);
$bestSellingReportData->select(['totalSoldItems' => $bestSellingReportData->func()->sum('Invoicedetaile.Qty')])
->matching('ItemMaster.Invoicedetaile', function ($q) {
return $q->where([
'AND' => [
'Invoicedetaile.ItemId = ItemMaster.Item_ID',
]
]);
})
->group(['ArticleMaster.Article_Code'])
->order(['totalSoldItems' => 'DESC'])
->autoFields(true);
I try to add the condition in both way using add condition and in where clause. But data is not filtering based on conditions i.e storeId
Work for me after doing R&D of many hours. Below is the query builder that work for me.
$bestSellingReportData = $this->ArticleMaster->find('all')->contain([
'Category' => [
'fields' => ['Cat_Id', 'Cat_Code']
],
'size_category' => [
'fields' => ['sizeCat_Id', 'sizeCat_Code']
],
'ItemMaster' => [
'Invoicedetaile' => [
'Invoice',
],
],
]);
$storeId = $this->request->data['storeId'];
$bestSellingReportData->select(['totalSoldItems' => $bestSellingReportData->func()->sum('Invoicedetaile.Qty')])
->matching('ItemMaster.Invoicedetaile.Invoice', function ($q) use ($storeId) {
return $q->where([
'AND' => [
'Invoicedetaile.ItemId = ItemMaster.Item_ID',
'Invoice.StoreId ='.$storeId,
]
]);
})
->group(['ArticleMaster.Article_Code'])
->order(['totalSoldItems' => 'DESC'])
->autoFields(true);

How to set a Yii2 module to return JSON response using config/main.php

I am currently using the following lines of code on every controller in the API module in order to return JSON response/data.
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON;
return $behaviors;
}
It works well. But how can i achieve the same using main configuration file?
I tried the following on my frontend/config/main.php
'api' => [
'class' => 'app\modules\api\Module',
'components' => [
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'common\models\User',
'enableSession' => false,
'loginUrl' => null,
],
'response' => [
'class' => \yii\filters\ContentNegotiator::className(),
'formats' => [
'application/json' => \yii\web\Response::FORMAT_JSON,
],
]
],// Module component
],
above configuration still returns XML response only. What is the correct configuration to set all the controllers in the API module to return JSON data.Thanks
Configure your response component as follows:
'response' => [
'format' => yii\web\Response::FORMAT_JSON,
// ...
]
formats is an array containing the available formats. format is the actual output format.
Add this is your config/main-local.php
use yii\web\Response;
$config['bootstrap'][]=
[
'class' => '\yii\filters\ContentNegotiator',
'formats' => [
'text/html' => Response::FORMAT_JSON,
]
];

ZF3 zend-mvc generic route for many controllers in one module not working

I'm in ZF3, using the zend-mvc-skeleton and trying to configure a generic route that will match as many URLs as possible as I want to be able to create new controllers (including action methods of course), and have them immediately available.
The common approach described in the documentation is to write a route that matches the controller and action (same with ZF2).
Here is my module.config.php
namespace Application;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'router' => [
'routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'default' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/:controller[/:action]]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
'constraints' => [
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
],
],
],
],
'controllers' => [/* ... */],
'view_manager' => [/* ... */],
],
It works like a charm for http://localhost/ and http://localhost/application calling the indexAction() function of the IndexController class inside the /module/Application/src/IndexController.php file.
However, it's not working when I try to get the fooAction() function in the same Controller (i.e. IndexController). It's not resolving correctly http://localhost/application/foo. and I get the following error:
A 404 error occurred
Page not found.
The requested controller could not be mapped to an existing controller class.
Controller:
foo (resolves to invalid controller class or alias: foo)
No Exception available
Same error if I try http://localhost/bar/foo to get the fooAction() in the barController.
Do you have any idea of what's wrong with this? Any help will be appreciated. Many thanks.
The route http://localhost/application/foo won't resolve to fooAction() in the index controller, since /foo in the URL will match the controller not the action. With that route setup you would need to visit http://localhost/application/index/foo.
To get it working you'll also need to make sure you have aliased your controller in the config, e.g. assuming you have:
'controllers' => [
'invokables' => [
'Application\Controller\Index' => \Application\Controller\IndexController::class
]
],
Then alias the controller so it matches the route parameter:
'controllers' => [
'invokables' => [
'Application\Controller\Index' => \Application\Controller\IndexController::class
],
'aliases' => [
'index' => 'Application\Controller\Index'
]
],
You'll need to add aliases that match the route parameter for each controller that isn't registered using the string you want for the route, e.g. a controller Namespace\Controller\BarController should be aliased to bar, etc.
I came here with similar problem. I have created two controllers in
"Application" module, and two in new module "Account" with the same name.
Application/Controller/IndexController
Application/Controller/OverviewController
Account/Controller/IndexController
Account/Controller/OverviewController
here are my modules.config.php
module/Account/config/module.config.php
return [
'router' => [
'routes' => [
'Account-account' => [
'type' => Segment::class,
'options' => [
'route' => '/account[/][:controller[/][:action][/]]',
'defaults' => [
'__NAMESPACE__' => 'Account\Controller',
'controller' => Account\Controller\IndexController::class,
'action' => 'index',
'locale' => 'en_us'
],
],
'may_terminate' => true,
'child_routes' => [
'wildcard' => [
'type' => 'Wildcard'
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => AccountControllerFactory::class,
Controller\OverviewController::class => AccountControllerFactory::class,
],
'aliases' => [
'index' => IndexController::class,
'overview' => OverviewController::class
]
],
and my
module/Application/config/module.config.php
return [
'router' => [
'routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'Application-application' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/][:controller[/][:action][/]]',
'defaults' => [
'__NAMESPACE__' => 'Application\Controller',
'controller' => Application\Controller\IndexController::class,
'action' => 'index',
'locale' => 'en_US'
],
],
'may_terminate' => true,
'child_routes' => [
'wildcard' => [
'type' => 'Wildcard'
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => IndexControllerFactory::class,
Controller\OverviewController::class => IndexControllerFactory::class,
],
'aliases' => [
'index' => IndexController::class,
'overview' => OverviewController::class,
]
],
With this configuration if aliases sections are commented there is a error message which says that there is invalid controller or alias (index/overview).
If there are aliases
route: "application/overview/index" goes into Account module.

Yii2 kartik typeahead - get number of suggestions

I'm using kartik's typeahead widget for Yii2 in a view:
echo \kartik\typeahead\Typeahead::widget([
'name' => 'serial_product',
'options' => [
'placeholder' => 'Filter as you type ...',
'autofocus' => "autofocus"
],
'scrollable' => TRUE,
'pluginOptions' => [
'highlight' => TRUE,
'minLength' => 3
],
'dataset' => [
[
'remote' => Url::to(['transfers/ajaxgetinventoryitemsnew']) . '?search=%QUERY',
'limit' => 10
]
],
'pluginEvents' => [
"typeahead:selected" => "function(obj, item) { add_item(item.id); return false;}",
],
]);
How can i get the number of loaded suggestions after the remote dataset is retrieved to execute a javascript function like:
displaynumber(NUMBEROFSUGGESTIONS);
After checking through the source of kartiks widget i came up with the following solution:
echo \kartik\typeahead\Typeahead::widget([
'name' => 'serial_product',
'options' => [
'placeholder' => 'Filter as you type ...',
'autofocus' => "autofocus",
'id' => 'serial_product'
],
'scrollable' => TRUE,
'pluginOptions' => [
'highlight' => TRUE,
'minLength' => 3
],
'dataset' => [
[
'remote' => [
'url' => Url::to(['transfers/ajaxgetinventoryitemsnew']) . '?search=%QUERY',
'ajax' => ['complete' => new JsExpression("function(response)
{
jQuery('#serial_product').removeClass('loading');
checkresult(response.responseText);
}")]
],
'limit' => 10
]
],
'pluginEvents' => [
"typeahead:selected" => "function(obj, item) { checkresult2(item); return false;}",
],
]);
where response.responseText is containing the response from server (json).
function checkresult(response) {
var arr = $.parseJSON(response);
console.log(arr.length);
}
With this function i can get then count of suggestions delivered from server.