Yii2 Method is not allowed in testing with Codeception - yii2

I try to test my code with Codeception and my tests (both functional and acceptance) fails when I test logout option. They fails with "Method is not allowed (405)" because they are sent by GET method.
I have this code out of the box within the Nav widget:
$menuItems[] = ['label' => 'Logout (' . Yii::$app->user->identity['username'] . ')',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']
This code works fine when I click the link by hand. In this case they are sent by POST method.
But it doesn't work while testing.
Why does it happens?

for logout you can add the form as follows, which will send the request using POST
$menuItems[] = '<li>'
. Html::beginForm(['/site/logout'], 'post')
. Html::submitButton(
'Logout ('.Yii::$app->user->identity['username'].')', ['class' => 'btn btn-link btnlogout']
)
. Html::endForm()
. '</li>';

Related

Yii2 Fileinput allow multiple screenshot insert

I have a Fileinput field and I want to insert there screenshots one by one, using print screen, but Fileinput remove previous file. What can I do ?
use kartik\widgets\FileInput
echo '<label class="control-label">Add Attachments</label>';
echo FileInput::widget([
'model' => $model,
'attribute' => 'attachment_1[]',
'options' => ['multiple' => true]
]);

WP_remote_post how to add filters to JSON API call

I am trying to integrate an API into my Wordpress plugin. The following PHP code successfully connects to the API and retrieves a list of Estates (the API is from a real-estate software):
$url = 'https://api.whise.eu/v1/estates/list';
$body = array(
'Filter' => array( 'languageId' => 'nl-BE'),
);
$args = array(
'headers' => array( 'Authorization' => 'Bearer ' . $token),
'body' => json_decode($body)
);
$response = wp_remote_post($url,$args);
As per the documentation (http://api.whise.eu/WebsiteDesigner.html#operation/Estates_GetEstates) it is possible to filter the results, but I haven't been able to get this to work. I don't have much experience with APIs and JSON, so I might be missing something here.
The code above still retrieves the data in English, even though I added the language filter as explained in the docs. When I replace 'body' => json_decode($body) with 'body' => $body, I get the following response:
{"Message":"The request entity's media type 'application/x-www-form-urlencoded' is not supported for this resource."}
Thanks!
Just so that this question doesn't go unanswered:
You need to add the Content-Type header and set it to application/json. This is so the endpoint can interpret your data as a JSON string.
You also need to change 'body' => json_decode($body) to 'body' => json_encode($body) as you want to convert your $body array into a JSON string (see json_decode() vs json_encode()).
This is how your code should look now:
$url = 'https://api.whise.eu/v1/estates/list';
$body = array(
'Filter' => array( 'languageId' => 'nl-BE'),
);
$args = array(
'headers' => array(
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json'
),
'body' => json_encode($body)
);
$response = wp_remote_post($url,$args);

How to use action /user/profile/show in label?

I just want to add Profile in navbar for logged user.
And I found /user/profile/show in dektrium yii2-user docs.
But it said:
Displays user's profile (requires id query param)
How to implement /user/profile/show in label that requires id query param?
Thanks in advance
if (Yii::$app->user->isGuest) {
$menuItems[] = ['label' => 'Signup', 'url' => ['/user/registration/register']];
$menuItems[] = ['label' => 'Login', 'url' => ['/user/security/login']];
} else {
$menuItems[] = ['label' => 'Profile', 'url' => ['/user/profile/show']];
$menuItems[] = '<li>'
. Html::beginForm(['/user/security/logout'], 'post')
. Html::submitButton(
'Logout (' . Yii::$app->user->identity->username . ')',
['class' => 'btn btn-link']
)
. Html::endForm()
. '</li>';
}
When I use code above and click the Profile navbar, it said Bad Request (#400), Missing required parameters: id. Yea I know becuse of the id query param isn't defined.
You can add id to params like so:
$menuItems[] = ['label' => 'Profile', 'url' => ['/user/profile/show', 'id' => $id]];
url parameter is processed with Url::to() method in case of array, so you can pass additional parameters as key-value pairs.

Yii2.0 pagination issue second page not working

How do I do a pagination? I have a search form and a search button which passes in a date range. The first page is working successfully, however when I click on the second page, it shows everything. How do I pass the date range into my pagination?
EDIT:
Below is my ReportSearch.php (model)
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 5,
//'params' => array('search' => 'true', 'from_dt'=>$stockmovement_summary_from_sales_date, 'to_dt'=> $stockmovement_summary_to_sales_date),
],
]);
$dataProvider->setSort([
'defaultOrder' => [
'd_item.desc_e_tx' => SORT_ASC,
],
'attributes' => [
'd_item.desc_e_tx'
]
]);
return $dataProvider;
}
Below is my controller:
$searchModel = new ReportSearch();
$dataProvider = $searchModel->searchStockMovementSummary($stockmovement_summary_from_sales_date, $stockmovement_summary_to_sales_date);
return $this->render('stockmovementreportsummary', [
'search' => 'true',
'dataProvider' => $dataProvider,
'from_dt' => $stockmovement_summary_from_sales_date,
'to_dt' => $stockmovement_summary_to_sales_date,
'model' => $searchModel,
]);
Below is my index.php
$reports = $dataProvider->getModels();
$i=1;
echo "<table class='table table-striped table-bordered'>";
echo "<tr><th>#</th><th>Item</th><th>Total Summary Usage Qty</th><th>Current Stock On Hand</th><th>Measurement</th></tr>";
foreach ($reports as $report) {
$item_key = $report['report_item_key'];
$item_model = Item::find()->where(['item_key' =>$item_key])->one();
$item_e_desc_tx = $item_model->desc_e_tx;
$item_c_desc_tx = $item_model->desc_c_tx;
$item_qty_no = $item_model->qty_no;
$item_measurement_tx = $item_model->measurement;
echo "<tr>";
echo "<td>" . $i++ . "</td>";
echo "<td>" . Html::a($item_key, array('stockmovementreportdetailbyitem', 'item_key' => $item_key, 'search' => 'true', 'from_dt' => $from_dt, 'to_dt'=>$to_dt)) . "<br>" . $item_e_desc_tx . "<br>" . $item_c_desc_tx ."</td>";
echo "<td>" . $report['total_summary_usage_qty'] . "</td>";
echo "<td>" . $item_qty_no . "</td>";
echo "<td>" . $item_measurement_tx . "</td>";
echo "</tr>";
}
echo "</table>";
echo \yii\widgets\LinkPager::widget([
'pagination'=>$dataProvider->pagination,
]);
GridView should be used but I do not think it will help. Do you by any chance use POST instead of GET to filter the results? If you take a look here https://github.com/yiisoft/yii2/blob/master/framework/data/Pagination.php#L257 at the createUrl function you will see that it uses getQueryParams http://www.yiiframework.com/doc-2.0/yii-web-request.html#getQueryParams() to create the query string. If you use POST then this function will not pick up the params properly hence the next page pagination will fail.
Ok, because you actually do use POST then you have to create your own pagination function that takes post into consideration. Or just use GET. You are not performing any operations to the DB you can safely use GET. It is better for everybody.
You have to edit the code in your action.
Read this documentation.
And edit $dataProvider->pagination

ZF2 ZendSkeleton why using '__NAMESPACE__' key in default route?

in ZF2 skeleton, router configuration uses a key :
'__NAMESPACE__'
precisely :
'__NAMESPACE__' => 'Application\Controller',
cf:
https://github.com/zendframework/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php#l32
We tried in our modules router config to use without quote:
__NAMESPACE__ => 'Application\Controller',
but it seems to break configuration.
why do we use quote instead of
__NAMESPACE__
to get its value ?
because by default, config files hasn't namespace declared. Config parser can read string
'__NAMESPACE__'
and determine correctly the namespace.
If you want to use it without quotes, you can declare in your config file :
namespace Application;
and use __NAMESPACE__ without quote.
That's why you can see sometimes in tutorials for Doctrine config's sample like :
'doctrine' => array(
'driver' => array(
'application_entity' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'paths' => __DIR__ . '/../src/' . __NAMESPACE__ . '/Entity',
),
'orm_default' => array(
'drivers' => array(
__NAMESPACE__ . '\Entity' => 'application_entity',
)
)
)
),