Yii 2 set up controller to accept json requests - php

I'm quite new to Yii 2 but here goes:
What I'm trying to accomplish is to set up a controller that simply reads in any json data posted to it.
I'm slightly confused as to how this works in Yii.
What I've tried so far is set up a controller called ftest to see if I could get it returning some json which seems to work:
public function actionFTest(){
$request = Yii::$app->request;
Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
$headers = Yii::$app->response->headers;
$headers->add('Content-Type', 'text/json');
$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON;
$response->data = ['message' => 'Evan .. WHERE ARE YOU?'];
//$notificationData = json_decode(file_get_contents("php://input"), true);
//echo var_dump($notificationData);
}
Its a bit messy since I've been throwing in code back and forth. I know I should usually return something like $this->render(etc), but I'm not sure what I need to return as a view.
Thanks for any help you can provide

This might be helpful
use Yii;
use yii\web\Response;
public function actionFTest()
{
Yii::$app->response->format = Response::FORMAT_JSON;
}
Then after that just return a simple array like that:
return ['param' => $value];
Read this
http://www.yiiframework.com/doc-2.0/yii-web-response.html#$format-detail

I recommend you using behavior and contentNegotiator
public function behaviors()
{
return array_merge(
parent::behaviors(),
[
'contentNegotiator' => [
'class' => 'yii\filters\ContentNegotiator',
'formats' => [
'application/json' => \yii\web\Response::FORMAT_JSON,
]
]
],
);
}

Related

How to remove parameter from a URL in laravel 5.2

How can I remove the parameters from a URL after processing in my controller? Like this one:
mydomain/mypage?filter%5Bstatus_id%5D
to
mydomain/mypage
I want to remove the parameters after the ? then I want to use the new URL in my view file. Is this possible in laravel 5.2? I have been trying to use other approaches but unfortunately they are not working well as expected. I also want to include my data in my view file. The existing functionality is like this:
public function processData(IndexRequest $request){
//process data and other checkings
return view('admin.index')
->with([
'data' => $data,
'person' => $persons,
]);
}
I want it to be like:
public function processData(IndexRequest $request){
//process data and other checkings
// when checking the full url is
// mydomain/mypage?filter%5Bstatus_id%5D
// then I want to remove the parameters after the question mark which can be done by doing
// request()->url()
// And now I want to change the currently used url using the request()->url() data
return view('admin.index')
->with([
'data' => $data,
'person' => $persons,
]);
}
I'm stuck here for days already. Any inputs are appreciated.
You can use request()->url(), it will return the URL without the parameters
public function processData(IndexRequest $request){
$url_with_parameters = $request()->url();
$url= explode("?", $url_with_parameters );
//avoid redirect loop
if (isset($url[1])){
return URL::to($url[0]);
}
else{
return view('admin.index')
->with(['data' => $data,
'person' =>$persons,]);
}
}
add new url to your routes and assuming it will point to SomeController#SomeMethod, the SomeMethod should be something like :
public function SomeMethod(){
// get $data and $persons
return view('admin.index')
->with(['data' => $data,
'person' =>$persons,]);
}
I hope this helps

Insert array of arrays in Lumen with Eloquent ORM

The POST request I'm sending looks like this:
{ "array1":
[
{"title":"my blogADD","description":"myblogdescriptionADD","status":1},
{"title":"my blogUPDATEDADD","description":"myblogdescriptionUPDATEDADD","status":1},
{"title":"my blog33ADD","description":"myblogdescription33ADD","status":1}
]
}
Its JSON format, headers have been set.
The controller code which gets the request looks like this:
public function create(Request $request){
$this->validate($request, [
'array1' => 'present|array',
'array1.*.title' => 'required',
'array1.*.description' => 'required'
]);
$data = $request->getContent();
$data = json_decode($data, true);
//dd($data);
Article::insert($data);
}
Now, I've looked into multiple questions and answers on SO on this problem, and the findings are somehow contradictory.
Model::insert() shall be able to insert multiple rows in ONE call.
However, as you can see, this hasn't worked for me so far.
Model::create() is only able to create one new row, but I found solutions which use loops to iterate over the arrays. I would very very much like to avoid such a solution, unless someone can FOR CERTAIN tell me that there is no other, simple solution. Because I very much believe that there must be one.
When I input the json_decoded ARRAY then I get the response that an Array to String conversion is hindering the process.
When I input the mere JSON-String, then I get the error:
"Argument 1 passed to Illuminate\Database\Query\Builder::insert() must be of the type array, string given, called in E:\LumenTut\firstTut\vendor\illuminate\database\Eloquent\Builder.php on line 1350"
Well, here are two links to SO posts which, in my opinion, basically dealt with the same problem. But somehow it seems they could solve it and I can't, so I wonder what I am missing:
How to insert a multidimensional array in a database using laravel
laravel 5.6 bulk inserting json data
For completeness, here is the full Code of ArticleController.php:
EDIT:
<?php
namespace App\Http\Controllers;
//use Validator;
use App\Article;
use Illuminate\Http\Request;
class ArticleController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
//
}
//
public function showAllArticles(){
return response()->json(Article::get(['title', 'description', 'status'])); // ::get([]) spezifiziert die zu referenzierenden Attribute
// ::all() referenziert alle Attribute einer Tabelle/Relation
}
public function showOneArticle($id){
return response()->json(Article::find($id));
}
public function create(Request $request){
$this->validate($request, [
'array1' => 'present|array',
'array1.*.title' => 'required',
'array1.*.description' => 'required'
]);
$data = $request->getContent();
//$data = json_decode($data, true);
//dd($data);
Article::insert($data);
}
public function update($id, Request $request){
$this->validate($request, [
'title' => 'required',
'description' => 'required'
]);
$article = Article::findOrFail($id);
$article->update($request->all());
return response()->json($article, 200);
}
public function delete($id, Request $request){
Article::findOrFail($id)->delete();
return response('Deleted Successfully', 200);
}
public function resetRecords(Request $request){
Article::where('id', '>', 2)->delete();
}
}
From the looks of it, it feels like you are trying to push array1 directly in your table, whereas you need to push the content of it so maybe try like this, in your controller code:
$requestData = $request->all();//this will give you an array with key array1
$data = $requestData['array1'];//this will give you data you want to insert
Article::insert($data);
Based on the error. You are not passing an array. You can change the $data with
$data = $request->all();
$request->all() returns the data from the post in array.
You can rewrite your create method with the following.
public function create(Request $request){
$request->validate([
'array1' => 'present|array',
'array1.*.title' => 'required',
'array1.*.description' => 'required'
]);
$data = $request->all();
Article::insert($data['array1']);
}

Problem with the function update() using Repository pattern to write REST API

I have a problem that all the create-read-delete using Repository Pattern is good but the update function is error. I still have the data but the information is not updated.
This is my code in EventController
public function update(EventRequest $request, $id)
{
$events = $this->repository->update($request->all());
return $this->sendResponse($events->toArray(), 'Successfully updated the Event!!');
}
This is i use DI for inject from the Repository, this is EventRepository.php
public function update($id, array $array) {
$events = $this->model->findOrFail($id);
$events->update($array);
return $events;
}
when i use dd($array) and the result returns [] without anything. Can anyone help me. Did i write anything wrong in this. Or i write the wrong Request
public function rules()
{
// $id = $this->events ? ',' . $this->events->id : '';
return $rules = [
'event_title' => 'required|max:255',
'event_type_id' => 'required|integer|between:1,3',
'from_date' => 'required|date_format:Y-m-d H:i:s',
'to_date' => 'date_format:Y-m-d H:i:s|nullable',
'is_recurring' => 'boolean|required',
'remarks' => 'nullable',
];
}
This method takes two arguments:
public function update($id, array $array) {
However, that's not how you are calling it:
$this->repository->update($request->all());
I take it $request->all() gives you an array, so pass the ID first.
$this->repository->update($id, $request->all());

Global Value in laravel 5.6

Here is my code ...
public function index()
{
$clientIP = request()->ip();
$cats=DB::table('catagory')->get();
$news=DB::table('news')->orderby('nID','desc')->limit('5')->get();
$books=DB::table('book')->where('bPrice','=',0)->orderby('bID','desc')->limit('5')->get();
return view('index',compact('clientIP','cats','news','books'));
}
As you see there are some variables, I passed them to my view but I have to repeat them in every view I wanna show.Is there any way to globalize them and use anywhere.Please help with sample code.Thanks.
Laravel view composer may help you.
You should add this code to your app/Providers/AppServiceProvider.php.
view()->composer(['index', 'index1', 'index2'], function($view) {
$clientIP = request()->ip();
$cats=DB::table('catagory')->get();
$news=DB::table('news')->orderby('nID','desc')->limit('5')->get();
$books=DB::table('book')->where('bPrice','=',0)->orderby('bID','desc')->limit('5')->get();
$view->with([
'clientIP' => $clientIP,
'cats' => $cats,
'news' => $news,
'books' => $books,
]);
});

How to render ZF2 view within JSON response?

So far, I have figured out how to return a typical JSON response in Zend Framework 2. First, I added the ViewJsonStrategy to the strategies section of the view_manager configuration. Then, instead of returning a ViewModel instance from the controller action, I return a JsonModel instance with all my variables set.
Now that I've figured that piece out, I need to understand how to render a view and return it within that JSON response. In ZF1, I was able to use $this->view->render($scriptName), which returned the HTML as a string. In ZF2, the Zend\View\View::render(...) method returns void.
So... how can I render an HTML view script and return it in a JSON response in one request?
This is what I have right now:
if ($this->getRequest()->isXmlHttpRequest()) {
$jsonModel = new JsonModel(...);
/* #todo Render HTML script into `$html` variable, and add to `JsonModel` */
return $jsonModel;
} else {
return new ViewModel(...);
}
OK, i think i finally understood what you're doing. I've found a solution that i think matches your criteria. Though i am sure that there is room for improvement, as there's some nasty handwork to be done...
public function indexAction()
{
if (!$this->getRequest()->isXmlHttpRequest()) {
return array();
}
$htmlViewPart = new ViewModel();
$htmlViewPart->setTerminal(true)
->setTemplate('module/controller/action')
->setVariables(array(
'key' => 'value'
));
$htmlOutput = $this->getServiceLocator()
->get('viewrenderer')
->render($htmlViewPart);
$jsonModel = new JsonModel();
$jsonModel->setVariables(array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1,2,3,4,5,6)
));
return $jsonModel;
}
As you can see, the templateMap i create is ... nasty ... it's annoying and i'm sure it can be improved by quite a bit. It's a working solution but just not a clean one. Maybe somehow one would be able to grab the, probably already instantiated, default PhpRenderer from the ServiceLocator with it's template- and path-mapping and then it should be cleaner.
Thanks to the comment ot #DrBeza the work needed to be done could be reduced by a fair amount. Now, as I'd initially wanted, we will grab the viewrenderer with all the template mapping intact and simply render the ViewModel directly. The only important factor is that you need to specify the fully qualified template to render (e.g.: "$module/$controller/$action")
I hope this will get you started though ;)
PS: Response looks like this:
Object:
html: "<h1>Hello World</h1>"
jsonArray: Array[6]
jsonVar1: "jsonVal2"
You can use more easy way to render view for your JSON response.
public function indexAction() {
$partial = $this->getServiceLocator()->get('viewhelpermanager')->get('partial');
$data = array(
'html' => $partial('MyModule/MyPartView.phtml', array("key" => "value")),
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1, 2, 3, 4, 5, 6));
$isAjax = $this->getRequest()->isXmlHttpRequest());
return isAjax?new JsonModel($data):new ViewModel($data);
}
Please note before use JsonModel class you need to config View Manager in module.config.php file of your module.
'view_manager' => array(
.................
'strategies' => array(
'ViewJsonStrategy',
),
.................
),
it is work for me and hope it help you.
In ZF 3 you can achieve the same result with this code
MyControllerFactory.php
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$renderer = $container->get('ViewRenderer');
return new MyController(
$renderer
);
}
MyController.php
private $renderer;
public function __construct($renderer) {
$this->renderer = $renderer;
}
public function indexAction() {
$htmlViewPart = new ViewModel();
$htmlViewPart
->setTerminal(true)
->setTemplate('module/controller/action')
->setVariables(array('key' => 'value'));
$htmlOutput = $this->renderer->render($htmlViewPart);
$json = \Zend\Json\Json::encode(
array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1, 2, 3, 4, 5, 6)
)
);
$response = $this->getResponse();
$response->setContent($json);
$response->getHeaders()->addHeaders(array(
'Content-Type' => 'application/json',
));
return $this->response;
}
As usual framework developer mess thing about AJAX following the rule why simple if might be complex Here is simple solution
in controller script
public function checkloginAction()
{
// some hosts need to this some not
//header ("Content-type: application/json"); // this work
// prepare json aray ....
$arr = $array("some" => .....);
echo json_encode($arr); // this works
exit;
}
This works in ZF1 and ZF2 as well
No need of view scrpt at all
If you use advise of ZF2 creator
use Zend\View\Model\JsonModel;
....
$result = new JsonModel($arr);
return $result;
AJAX got null as response at least in zf 2.0.0

Categories