Laravel how to auto get array id - php

I know the title isn't that understanding but I will try to explain here my problem.
So I have a form that auto generates input fields by jquery and I'm trying to store that data in the db
the blade:
<div>
<input type="text" placeholder="ID" name="myproduct[]"/>
<input type="text" placeholder="Șansa" name="mychance[]"/>
Delete
</div>
My Controller:
class SomeController extends BaseController {
public function someMethod(Request $request) {
...
$items = '{"'.$request->myproduct[0].'":"'.$request->mychance[0].'", "'.$request->myproduct[1].'":"'.$request->mychance[1].'"}';
$case = Cases::create([
'items' => $items
]);
$case->save();
...
}
}
It is kinda working but I want to know how to get all data in $items without creating new variables like $variable[0], $variable[1],2 ,3 for every input I generate

If you can guarantee that you always have the same amount of products and choices you can use array_combine
$myproduct = [1,2,3];
$mychance = ['test1', 'test2', 'test3'];
$items = array_combine($myproduct, $mychance);
// result: [1 => "test1", 2 => "test2", 3 => "test3"]
// encode it to a string with json_encode
// result: "{"1":"test1","2":"test2","3":"test3"}"
$case = Cases::create(['items' => json_encode($items)]);
Additionaly you can cast your items column to an array
In your Cases model add
protected $casts = [
'items' => 'array',
];
Laravel will then automatically serialize it when storing and deserialize it when accessing giving you an array.
then you could just do
$myproduct = [1,2,3];
$mychance = ['test1', 'test2', 'test3'];
$case = Cases::create(['items' => array_combine($myproduct, $mychance)]);
Array & JSON Casting
The array cast type is particularly useful when working with columns
that are stored as serialized JSON. For example, if your database has
a JSON or TEXT field type that contains serialized JSON, adding the
array cast to that attribute will automatically deserialize the
attribute to a PHP array when you access it on your Eloquent model

You maybe want to do this:
class SomeController extends BaseController {
public function someMethod(Request $request) {
...
$items = [];
foreach($request->myproduct as $i => $myProductSingle) {
$items[$myProductSingle] = $request->mychance[$i];
}
$case = Cases::create([
'items' => json_encode($items)
]);
$case->save();
...
}
}

Hope it helps..
$items = [];
foreach($request->myproduct as $key => $myProduct) {
$items[$myProduct] = $request->mychance[$key];
}

Related

How to output data in multipleSelect to laravel-admin form?

Model - Promo:
...
protected $table = 'promo';
...
public function locations()
{
return $this->belongsToMany(Cities::class, 'cities_promo');
}
Controller in laravel-admin
...
protected function form()
{
$location = Cities::pluck('name', 'id');
$form = new Form(new Promo);
$form->text('title', __('Title'));
$form->textarea('desc', __('Description'));
$form->multipleSelect('locations')->options($location);
return $form;
}
...
The bottom line is that it does not display the values that were previously selected and saved. An empty field is displayed there, where you can select values from the City model.
An intermediate solution was to use the attribute.
It is necessary that the format for multipleSelect (and others) was in array format [1,2,3 ... ,7].
In normal communication, an array of the form is transmitted:
{
['id' => 1,
'name' => 'Moscow',
...
],
['id' => 2,
'name' => 'Ekb',
...
],
}
Therefore, for formalization, I used a third-party attribute "Cities" to the model "Promo".
...
//Add extra attribute
//These attributes will be written to the database, if you do not want
//this, then do not advertise!
//protected $attributes = ['cities'];
//Make it available in the json response
protected $appends = ['cities'];
public function getCitiesAttribute()
{
return $this->locations->pluck('id');
}
public function setCitiesAttribute($value)
{
$this->locations()->sync($value);
}
If there are other suggestions, I am ready to listen.
Thank.
change $location to
$location = Cities::All()->pluck('name', 'id');
you can return $location to know it has value or not
also you can set options manually
$form->multipleSelect('locations')->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);
to know it works

How to import JSON file into database

I have json file in folder database\data\countries.json and I have CountriesTableSeeder.php
I want to seed all data in countries.json into my table Country. But it occurs error Trying to get property of non-object
I have followed the step that I found, but I still got an error.
This is my model:
protected $fillable = ['country_name', 'iso_code'];
This is my seeder code:
public function run()
{
$countryJson = File::get("database/data/countries.json");
$data = json_decode($countryJson, true);
foreach ($data as $obj) {
Country::create(array(
'country_name' => $obj->name, 'iso_code' => $obj->sortname
));
}
}
You need to pass same variable in foreach, also make sure you have name element by checking dd($data); and you need to get array element by $obj['name'] not by $obj->name as it's not object.
$data = json_decode($countryJson, true);
foreach ($data['countries'] as $obj) {
Country::create(array(
'country_name' => $obj['name'], 'iso_code' => $obj['sortname']
));
}

Laravel and a While Loop

I'm new to Laravel and at the moment I have a piece of code in a Controller which without the while loop it works, it retrieves my query from the database.
public function dash($id, Request $request) {
$user = JWTAuth::parseToken()->authenticate();
$postdata = $request->except('token');
$q = DB::select('SELECT * FROM maps WHERE user_id = :id', ['id' => $id]);
if($q->num_rows > 0){
$check = true;
$maps = array();
while($row = mysqli_fetch_array($q)) {
$product = array(
'auth' => 1,
'id' => $row['id'],
'url' => $row['url'],
'locationData' => json_decode($row['locationData']),
'userData' => json_decode($row['userData']),
'visible' => $row['visible'],
'thedate' => $row['thedate']
);
array_push($maps, $product);
}
} else {
$check = false;
}
return response()->json($maps);
}
I am trying to loop through the returned data from $q and use json_decode on 2 key/val pairs but I can't even get this done right.
Don't use mysqli to iterate over the results (Laravel doesn't use mysqli). Results coming back from Laravel's query builder are Traversable, so you can simply use a foreach loop:
$q = DB::select('...');
foreach($q as $row) {
// ...
}
Each $row is going to be an object and not an array:
$product = array(
'auth' => 1,
'id' => $row->id,
'url' => $row->url,
'locationData' => json_decode($row->locationData),
'userData' => json_decode($row->userData),
'visible' => $row->visible,
'thedate' => $row->thedate
);
You're not using $postdata in that function so remove it.
Do not use mysqli in Laravel. Use models and/or the DB query functionality built in.
You're passing the wrong thing to mysqli_fetch_array. It's always returning a non-false value and that's why the loop never ends.
Why are you looping over the row data? Just return the query results-- they're already an array. If you want things like 'locationData' and 'userData' to be decoded JSON then use a model with methods to do this stuff for you. Remember, with MVC you should always put anything data related into models.
So a better way to do this is with Laravel models and relationships:
// put this with the rest of your models
// User.php
class User extends Model
{
function maps ()
{
return $this->hasMany ('App\Map');
}
}
// Maps.php
class Map extends Model
{
// you're not using this right now, but in case your view needs to get
// this stuff you can use these functions
function getLocationData ()
{
return json_decode ($this->locationData);
}
function getUserData ()
{
return json_decode ($this->userData);
}
}
// now in your controller:
public function dash ($id, Request $request) {
// $user should now be an instance of the User model
$user = JWTAuth::parseToken()->authenticate();
// don't use raw SQL if at all possible
//$q = DB::select('SELECT * FROM maps WHERE user_id = :id', ['id' => $id]);
// notice that User has a relationship to Maps defined!
// and it's a has-many relationship so maps() returns an array
// of Map models
$maps = $user->maps ();
return response()->json($maps);
}
You can loop over $q using a foreach:
foreach ($q as $row) {
// Do work here
}
See the Laravel docs for more information.

Symfony2 form to JSON structure

How can the Symfony2 form be transformed to JSON data structure? Looking for proper bundle gave me no results;
Example:
$builder
->add('name', 'text')
->add('password', 'password')
;
Would result in something like that:
{
fields: {
name: {
type: 'text'
},
password: {
type: 'password'
}
}
}
Iterating over each element in form after $form = $this->createForm(new FormType(), new Entity()) was not helpful, could not find some properties that could be defined in form builder.
I assume that you want to get this information in a controller once you have posted the form, in which case you can easily get the underlying entity from the form object, like so:
$entity = $form->getData();
At this point you can either manually pull out the fields you want into an array and json_encode() that, or... implement the JsonSerializable interface in your entity and then directly json_encode() the object itself.
For example:
<?php
namespace FooApp/BarBundle/Entity;
use JsonSerializable;
class Baz implements JsonSerializable
{
private $name;
private $password;
// ...
function jsonSerialize()
{
return [
'fields' => [
'name' => ['type' => $this->name],
'password' => ['type' => $this->password],
],
];
}
}
Then, in your controller:
$entity = $form->getData();
$json = json_encode($entity);
Calling json_encode() will automatically invoke Baz::jsonSerialize() and return the array structure you defined, which in turn is JSON-encoded.
Update 2016-06-23
I happened across this question again by chance - and... I realise that I didn't answer your actual question.
You didn't want to convert the form's underlying entity to JSON - instead you want to represent form structure as data. My apologies for misunderstanding - hopefully I can rectify that with an update.
This is a proof-of-concept that should work for a non-nested form (although it should be straightforward to create a recursive version or something for that case). But, assuming a scenario where you have instantiated a form, comprising of fields name and password, like so:
$form = $this->createForm(FooType::class, $foo);
It should then possible to iterate over the instance and derive a representation of the structure; e.g:
$fields = ['fields' => []];
foreach ($form->all() as $field) {
$name = $field->getName();
$type = $field->getConfig()->getType()->getBlockPrefix();
$fields['fields'][$name] = ['type' => $type];
}
echo json_encode($fields, JSON_PRETTY_PRINT);
Yields:
{
"fields": {
"name": {
"type": "text"
},
"password": {
"type": "password"
}
}
}
Hope this helps :)
If you need to get the JSON representation of the form object, you can get the entity object and encode it:
$jsonStr =json_encode($builder->getData());
Take a look on http://jmsyst.com/libs/serializer#installation
and fosrestbundle
$view = $this->view( $form->createView() );
return $this->handleView( $view );
Does what you are looking for.

Laravel-5 merge multi-level form array validation

I have a form which I have created in Laravel-5. This form contains input arrays. I have also created a Request file using php artisan make:request ClassRequest. Within my request file, I have added the Laravel validator() function which I use to add additional fields to the form array when the form gets posted.
However, I can't seem to get the form array updated/merged in the way that I would like.
View file:
<input type="text" name="class[0]['location_id']" value="1">
<input type="text" name="class[1]['location_id']" value="2">
Request file (ClassRequest.php):
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\Factory as ValidatorFactory;
use DB;
class ClassRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function validator(ValidatorFactory $factory)
{
$input = $this->get('class');
foreach($input as $key => $val)
{
$dateInString = strtotime(str_replace('/', '-', $input[$key]['date']));
$this->merge(['class' => [$key => [
'location_id' => $input[$key]['location_id'],
'location' => 'test123'
]
]]);
}
return $factory->make($this->input(), $this->rules(), $this->messages());
}
}
As you can see from the request file above, I am trying to add a new key/value pair to the form array (location => 'test123'). However, only 1 field ever gets posted through to the controller.
Does anyone know the proper way to do this?
Merge function merges given array into collection and any string key in the array matching a string key in the collection will overwrite the value in the collection.So this is why you saw only 1 field posted through to controller.
foreach($input as $key => $val)
{
$this->merge(['class' => [$key => [
'location_id' => $input[$key]['location_id'],
'location' => 'test123'
]
]]);
}
'class' key is overwritten in each iteration and only last one persist.So the only item is last one.
$input = $this->get('class');
foreach($input as $key => $val)
{
$another[$key]['location_id']=$input[$key]["'location_id'"];
$another[$key]['location']='123';
}
$myreal['class']=$another;
$this->merge($myreal);
return $factory->make($this->input(), $this->rules(), $this->messages());
If you are getting error related with location id then try this
public function validator(ValidatorFactory $factory)
{
$input = $this->get('class');
foreach($input as $key => $val)
{
foreach($input[$key] as $v){
$another[$key]['location_id']=$v;
$another[$key]['location']='124';
}
}
$myreal['class']=$another;
$this->merge($myreal);
return $factory->make($this->input(), $this->rules(), $this->messages());
}

Categories