I'm trying to pass parameter in resource route. My routes.php has:
$routes->resources('Products', [
'map' => [
'sku/:sku' => [
'action' => 'viewBySku',
'method' => 'GET',
]
]
]);
});
And my control action is as follows:
public function viewBySku($sku) {
die($sku);
}
After I execute the route the controller is generating a warning:
Missing argument 1 for viewBySku()
What am I missing?
Edit:
I want to use alphanumeric value for the parameter. Most answers I've found are explaining how to pass integers only.
So here is what I've ended up doing:
routes.php
$routes->resources('Products', [
'map' => [
'sku/:sku' => [
'action' => 'viewBySku',
'method' => 'GET',
]
]
]);
controller
public function viewBySku() {
if (!$sku = $this->request->param('sku')) {
throw new BadRequestException("Sku is missing");
}
die($sku);
}
Apparently, my variable is being passed to router but not to the controller's action.
Other Solution
So after looking into resource routes I've found out that you can pass connect options to it:
$routes->resources('Products', [
'map' => [
'sku/:sku' => [
'action' => 'viewBySku',
'method' => 'GET',
]
],
'connectOptions' => [
'sku' => '[a-zA-Z0-9\-]{2,10}',
'pass' => ['sku', 'id']
]
]);
You can also modify the id's regex if you want to pass alphanumeric values to id parameter:
$routes->resources('Products', [
'connectOptions' => [
'id' => '[a-zA-Z0-9\-]{2,10}'
]
]);
Related
Below is the link to the Scout Elasticsearch Drive which I am using in my Laravel project.
https://github.com/babenkoivan/scout-elasticsearch-driver
I have database table users with the following columns:
id Integer
name String
created_at DateTime
Following the documentation on GitHub, my mapping in the User model looks like followings:
use Searchable; // using Searchable trait.
protected $mapping = [
'properties' => [
'name' => [
'type' => 'text',
'fields' => [
'raw' => [
'type' => 'keyword',
],
],
],
'created_at' => [
'type' => 'date',
'format' => 'dd-MM-yyyy HH:mm',
'fields' => [
'raw' => [
'type' => 'keyword',
],
],
],
// Custom field...
'created_date' => [
'type' => 'date',
'format' => 'dd-MM-yyyy',
'fields' => [
'raw' => [
'type' => 'keyword',
],
],
],
// Custom field...
'created_time' => [
'type' => 'date',
'format' => 'HH:mm',
'fields' => [
'raw' => [
'type' => 'keyword',
],
],
],
]
]
Below is the implementation of the toSearchableArray() function.
public function toSearchableArray()
{
$array = $this->toArray();
// Pre-format the custom fields before inserting them into Elasticsearch.
$array['created_date'] = $this->created_at->format('d-m-Y');
$array['created_time'] = $this->created_at->format('h:i');
return $array;
}
When using curl -X GET command I get the following results and of course with the custom fields.
"hits" : [
{
"_source" : {
"id" : 3,
"name": "John Doe",
"created_at": "31-12-2018 23:59",
"created_date": "31-12-2018", // My custom field.
"created_time": "23:59" // My custom field.
}
]
In my index() action in my controller, I query the data using the following code.
public function index()
{
return User::search("*")->get();
}
I get the records with only the original attributes, matching those columns in the database table as following.
[
{
"id" : 3,
"name": "John Doe",
"created_at": "31-12-2018 23:59",
}
]
Note that this is a JSON response provided by default by Laravel, responding to API calls. My custom attributes created_date and created_time do exist in Elasticsearch as well. How can I get them too as result? The reason I created these custom fields is to format the date and time on the server side beforehands so that my client-side does not need to worry about formating the date and time in the for-loop.
When I use User::search("*")->explain(); I do get my custom fields as well in the hits.hits._source{} object.
This should give you results directly from Elastic Search without matching up with your related models. I think thats the reason why your custom fields get lost.
public function index()
{
return User::search("*")->raw();
}
Documentation
Trying to run function _googleanalytics in controller ProcessingController, but getting an error:
unknown command
command:
./yii processing/_googleanalytics '2017-02-27' '2017-02-27'
controller path:
/console/controllers/
action
public function _googleanalytics($start, $finish) {...
controller
namespace console\controllers;
class ProcessingController extends Controller
{...
/console/config/main.php
return [
'id' => 'app-console',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'console\controllers',
'aliases' => [
'#bower' => '#vendor/bower-asset',
'#npm' => '#vendor/npm-asset',
],
'controllerMap' => [
'fixture' => [
'class' => 'yii\console\controllers\FixtureController',
'namespace' => 'common\fixtures',
],
],
'components' => [
'log' => [
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning','info'],
'exportInterval' => 1,
],
[
'class' => 'yii\log\FileTarget',
'levels' => ['info'],
'exportInterval' => 1,
'logVars' => [],
'categories' => ['calls'],
'logFile' => '#app/runtime/logs/calls.log',
'maxFileSize' => 1024 * 2,
'maxLogFiles' => 20,
],
],
],
],
'modules'=>[
'user-management' => [
'class' => 'webvimark\modules\UserManagement\UserManagementModule',
'controllerNamespace'=>'vendor\webvimark\modules\UserManagement\controllers', // To prevent yii help from crashing
],
'googleanalytics' => [
'class' => 'console\modules\googleanalytics\Module',
]
],
'params' => $params,
];
what I am doing wrong?
You need to make an action to access it via console/terminal the same way as we access the actions via our browser.
For example if i create a Test Controller like below inside console/controllers directory
<?php
namespace console\controllers;
class TestController extends \yii\console\Controller{
public function actionIndex($param1,$param2){
echo "\nIndex";
echo "\n$param1 $param2\n";
}
public function actionMango(){
echo "\nMango";
}
}
and then type ./yii and hit Enter it will show all default commands available along with the following at the end.
This is Yii version 2.0.14.1.
The following commands are available:
....
...
- test
test/index (default)
test/mango
which means it registers all the actions inside the controller as commands and if you write in the terminal the following command,
./yii test/index omer aslam
it will show you the output
Index
omer aslam
where omer and aslam are the 2 params passed to the function.
So you just need to prepend keyword action to your function name i would suggest using action names according to the convention, change the function from
public function _googleanalytics($start, $finish) {
to
public function actionGoogleanalytics($start, $finish) {
and then access it via
./yii process/googleanalytics 2017-02-27 2017-02-27
you can wrap with quotes but it isnt necessary to add one a space identitifies between separate params.
Hope it helps
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,
]
];
When I try to post using Postman,I get this error {"name":"Bad Request","message":"Invalid JSON data in request body: Syntax error.","code":0,"status":400,"type":"yii\\web\\BadRequestHttpException"}
My controller is
`class CountryController extends ActiveController
{
public $modelClass = 'app\models\Country';
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['index', 'view','create'],
'formats' => ['application/json' => Response::FORMAT_JSON,],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index'=>['get'],
'view'=>['get'],
'create'=>['post'],
'update'=>['put'],
'delete' => ['delete'],
'deleteall'=>['post'],
],
],
];
}
}`
added
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
in api/config.php file.
Where I am wrong??
Try this
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['index', 'view','create'],
'formats' => ['application/json' => Response::FORMAT_JSON]
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index'=>['get'],
'view'=>['get'],
'create'=>['post'],
'update'=>['post'],
'delete' => ['delete'],
'deleteall'=>['post'],
]
]
];
}
I am using wordpress 4.7 on php 7, also getting problems with the empty request body.
My Controller :
add_action('rest_api_init', function()
{
register_rest_route('v0', '/accounts/(?P<slug>[a-z0-9_\-]+)/accounts', array(
'methods' => 'GET',
'callback' => function($request)
{
try {
return 'hello';
}
catch (Exception $e) {
$error = json_decode($e->getMessage(), true);
return new WP_Error($error['status_code'], $error['message'], "");
}
}
));
});
Response Error :
{"code":"rest_invalid_json","message":"Invalid JSON body passed.","data":{"status":400,"json_error_code":4,"json_error_message":"Syntax error"}}
I did not found any solution rather than changing in WP core : wp-includes/rest-api/class-wp-rest-request.php and chaning line 672 for conditional check for empty body or not.
$params = json_decode( $this->get_body(), true );
Is there any way to apply a function to all requests and queries in Yii2?
I want to replace specific characters for all of them.
I am using Yii2 advanced app
Thanks.
This is the config file:
$config = [
'language' => 'en',
'components' => [
'request' => [
'cookieValidationKey' => 'something',
],
'authManager' => [
'class' => 'yii\rbac\DbManager',
'defaultRoles' => ['guest'],
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
],
],
];
return $config;
Without extending custom code on each request can be exexuted like so (add this to your application config):
return [
'on beforeRequest' => function () {
if (!Yii::$app->get('user', false)) {
return;
}
$user = User::getCurrent();
if ($user) {
Yii::$app->setTimeZone($user->time_zone);
}
},
'on afterRequest' => function () {
...
},
];
Depending on when you need to execute code (before or after the request) use 'on beforeRequest' or 'on afterRequest' accordingly.
yii2 have a request component. You can extend yii\web\request and define your custom implementation.
[
...
'components' =>
'request' => [
'class' => '\common\MyRequest',
'addGeoLocationForExample' => true,
]
...