Symfony : get data from persistent collection in ManyToMany relation - php

I'm trying to get datas from a persistent collection in a ManyToMany relation.
$form = $this->formRepository->find($id);
dd($form->getAssocies());
give me something like :
Doctrine\ORM\PersistentCollection {#2558
-snapshot: []
-owner: App\Entity\Form {#2617
-id: 174
-name: "Aname"
-category: Proxies\__CG__\App\Entity\Category {#2554
+__isInitialized__: false
-id: 30
-name: null
-children: null
-parent: null
...
when I try this :
$form->getAssocies()->toArray();
it return me an empty array, same result with a ->getValues()
I also tried this :
foreach ($form->getAssocies() as $key => $associe) {
$data['associes'][$key] = $associe;
}
I don't really know why I can't access to theses data
there is my entity :
form.php
/**
* #var Form[]
*
* #ORM\ManyToMany(targetEntity="App\Entity\Form")
*/
private $associes;
public function __construct(){
$this->created = new \DateTime("now");
$this->associes = new ArrayCollection();
}
/**
* #return Form[]
*/
public function getAssocies()
{
return $this->associes;
}
Someone have an idea to how can I get theses datas in an array ?

Related

Laravel model attributes null when i saved it but but I have validated them in the constructor

working with Laravel PHP, I have this model with a constructor where i set the attributes:
class NutritionalPlanRow extends Model
{
use HasFactory;
private $nutritional_plan_id;
private $aliment_id;
private $nomeAlimento;
public function __construct($plan = null,
$aliment = null,
array $attributes = array()) {
parent::__construct($attributes);
if($plan){
$this->nutritional_plan()->associate($plan);
$this->nutritional_plan_id = $plan->id;
}
if($aliment){
$this->aliment()->associate($aliment);
$this->aliment_id = $aliment->id;
$this->nomeAlimento = $aliment->nome;
}
}
/**
* Get the plan that owns the row.
*/
public function nutritional_plan()
{
return $this->belongsTo('App\Models\NutritionalPlan');
}
/**
* Get the aliment record associated with the NutritionalPlanRow.
*/
public function aliment()
{
return $this->belongsTo('App\Models\Aliment');
}
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [];
/**
* Get the value of nomeAlimento
*/
public function getNomeAlimentoAttribute()
{
return $this->nomeAlimento;
}
/**
* Get the value of plan_id
*/
public function getNutritional_Plan_IdAttribute()
{
return $this->nutritional_plan_id;
}
/**
* Get the value of aliment_id
*/
public function getAliment_IdAttribute()
{
return $this->aliment_id;
}
}
Then I have a controller where I initialize the object:
public function addAlimentToPlan(Request $request){
$planId = $request->planId;
$alimentId = $request->alimentId;
$validatedData = Validator::make($request->all(), [
'planId' => ['required'],
'alimentId' => ['required'],
]);
if ($validatedData->fails()) {
return back()->withErrors($validatedData, 'aliment');
}
$plan = NutritionalPlan::find($planId);
$aliment = Aliment::find($alimentId);
$nutritionalPlanRow = new NutritionalPlanRow($plan, $aliment);
Log::info('Nome Alimento '.$nutritionalPlanRow->getNomeAlimentoAttribute());
$nutritionalPlanRow->save(); //
Toastr::success( 'Alimento aggiunto', '',
["positionClass" => "toast-bottom-right",
"closeButton" => "true"]);
return back();
}
The save operation return this error:
SQLSTATE[23502]: Not null violation: 7 ERRORE: null value in column "nomeAlimento" of relation "nutritional_plan_rows"
but logging the $nutritionalPlanRow->getNomeAlimentoAttribute() the attribure is enhanced.
Someone can help me?
Thank you.
In your constructor you have the following line:
$this->nomeAlimento = $aliment->nome;
You believe that this will fill the attribute in the eloquent model, but that is not happening. Normally such an assignment will pass the magic __set method on the model, but not during model/object construction.
You actually assign it to a property on the object, which is later accessible by your log function, but eloquent doesn't know about it. Therefore it is not sent to the database, resulting in a null error (no default value).
You may use the following to set the values in the constructor:
$this->setAttribute('nomeAlimento', $aliment->nome);
This calls the setAttribute function on the eloquent model, the attribute this becomes part of the model.
(Make sure to change also the other line in your constructor where you assign a value to the object)

Laravel hasOne relationship not loading

I'm trying to load a hasOne relationship in laravel with custom fields. This was built on top of an already defined database so i cant modify the database.
I have two tables both on sqlserver 2014 and on different schemas, all PK and FK are integers.
Tables:
Table CursoProgramado (schema dbo):
CursoProgramado(PK) fieldA fieldB
Table silabos (schema sga):
id(PK) fieldC fieldD CursoProgramado(FK)
Models:
CursoProgramado
class CursoProgramado extends Model {
protected $connection = 'sqlsrv';
protected $table = 'CursoProgramado';
protected $primaryKey = 'CursoProgramado';
public function silabo()
{
return $this->hasOne(Silabo::class, 'CursoProgramado', 'CursoProgramado');
}
}
Silabo
class Silabo extends Model {
protected $connection = 'sqlsrv';
protected $table = 'sga.silabos';
}
Controller, trying to get the relationship to work
$carga = CursoProgramado::findOrFail($carga);
//this return the model correctly
$carga->silabo;
//this should return the related model but returns NULL
// if i get the query log
DB::connection('sqlsrv')->enableQueryLog();
$carga->silabo;
dd(DB::connection('sqlsrv')->getQueryLog());
// i get this
array:1 [▼
0 => array:3 [▼
"query" => "select top 1 * from [sga].[silabos] where [sga].[silabos].[CursoProgramado] = ? and [sga].[silabos].[CursoProgramado] is not null"
"bindings" => array:1 [▼
0 => 147689
]
"time" => 18.59
]
]
//Runnig query
select top 1 * from [sga].[silabos] where [sga].[silabos].[CursoProgramado] = 147689 and [sga].[silabos].[CursoProgramado] is not null;
// it return data
id CursoProgramado consejeria
1933 147689 La consejería y orientación...
Not really sure what is causing this
You need to define the belongs to relationship in the Silabo class
class Silabo extends Model {
protected $connection = 'sqlsrv';
protected $table = 'sga.silabos';
public function cursoProgramado()
{
return $this->belongsTo(CursoProgramado::class, 'CursoProgramado', 'CursoProgramado')
}
}
cheers

My instance doesn't fetch me the table that I want

So I am trying to attach an object full of information from the MYSQL DB, but the outcome isn't what I am expecting.
Controller -
public function index()
{
$location = Location::orderBy('created_at', 'desc');
return view('location')->with('locations', $location);
}
Model -
class Location extends Model
{
// Primary Key
public $primaryKey = 'id';
// Timestamps
public $timestamps = true;
}
Result -
Builder {#486 ▼
#query: Builder {#485 ▶}
#model: Location {#484 ▶}
#eagerLoad: []
#localMacros: []
#onDelete: null
#passthru: array:12 [▶]
#scopes: []
#removedScopes: []
}
Change this
$location = Location::orderBy('created_at', 'desc');
To
$location = Location::orderBy('created_at', 'desc')->get();
When using $location = Location::orderBy('created_at', 'desc'); it is a instance of Illuminate\Database\Query\Builder.
For get all records you must use
$locations = Location::orderBy('created_at', 'desc')->get();
It is return instance of \Illuminate\Database\Eloquent\Collection
For get Limited records you must use
$limit = 20; // or custom
$limitedLocations = Location::orderBy('created_at', 'desc')->limit($limit)->get();
For get single data use
$location = Location::orderBy('created_at', 'desc')->first();
It is return null or instance of model Location

Convert json String into Object of custom class instead of stdClass.

my order.php file has
/**
* Encode the cart items from json to object
* #param $value
* #return mixed
*/
public function getCartItemsAttribute($value){
return json_decode($value);
}
And in my controller i fetch cartItems as follows
public function orderDetails(Order $order){
$address = implode(',',array_slice((array)$order->address,2,4));
foreach ($order->cartItems as $item){
dd($item);
}
return view('/admin/pages/productOrders/orderDetails',compact('order','address'));
}
And in above code dd($item) will outputs as follows
{#422 ▼
+"id": 4
+"user_id": 2
+"product_id": 1
+"quantity": 1
+"deleted_at": null
+"created_at": "2018-02-16 08:12:08"
+"updated_at": "2018-02-16 08:12:08"
}
but I want as below.
Cart {#422 ▼
+"id": 4
+"user_id": 2
+"product_id": 1
+"quantity": 1
+"deleted_at": null
+"created_at": "2018-02-16 08:12:08"
+"updated_at": "2018-02-16 08:12:08"
}
How can i achieve this in laravel.
Add true as a second parameter to your decode function like:
/**
* Decode the cart items from json to an associative array.
*
* #param $value
* #return mixed
*/
public function getCartItemsAttribute($value){
return json_decode($value, true);
}
I would create a CartItem model:
// CartItem.php
class CartItem extends Model {
public function order() {
return $this->belongsTo(Order::class);
}
}
Instantiate each one like:
// Controller.php
$cartItems = [];
foreach ($order->cartItems as $item){
// using json_encode and json_decode will give you an associative array of attributes for the model.
$attributes = json_decode(json_encode($item), true);
$cartItems[] = new CartItem($attributes);
// alternatively, use Eloquent's create method
CartItem::create(array_merge($attributes, [
'order_id' => $order->id
]);
}

Laravel + fractal "deeply" nested includes

I am using fractal (fractal.thephpleague.com) to develop an API with Laravel (laravel.com). It is an amazing library, by the way.
In certain web service, I need to return information of several nested models, which have 3 levels deep. That is, I have a Survey model which has many Survey Items, and each one of them has, in turn, many Survey Item Results (each one of a user). Well, I need the data from all of them, classified, that is:
"surveys": [
{
"id": 1,
...,
"items": [
{
"id": 14,
...,
"results": [
{
"id": 45,
...
},
{
...
}
]
},
{
...
}
]
},
{
...
}
}
With transformers and includes, I get the surveys and survey items info without problems, but I also need the survey item results...
That is, I need something like 2-level "nested" includes, to get the information of the third level.
My best approach, so far (only returning two levels: surveys and survey items). In my controller:
return fractal() -> transform(
Survey::where(...),
new SurveyTransformer()
) -> include(['SurveyItems']) -> respond();
Any help is much appreciated.
Thanks in advance.
Here's what I normally do
Survey Transformer
<?php
namespace App\Transformers;
use League\Fractal;
use App\Survey;
class SurveyTransformer extends Fractal\TransformerAbstract
{
/**
* List of resources possible to include
*
* #var array
*/
protected $availableIncludes = [
'items'
];
public function transform(Survey $survey)
{
return [
'id' => (int) $user->id,
];
}
/**
* Include Items
*
* #param App\Survey $survey
* #return League\Fractal\CollectionResource
*/
public function includeItems(Survey $survey)
{
$items = $survey->items;
if (!is_null($items)) {
return $this->collection($items, new ItemTransformer);
}
return;
}
}
Item Transformer
<?php
namespace App\Transformers;
use League\Fractal;
use App\Item;
class ItemTransformer extends Fractal\TransformerAbstract
{
/**
* List of resources possible to include
*
* #var array
*/
protected $availableIncludes = [
'results'
];
public function transform(Item $item)
{
return [
'id' => (int) $user->id,
];
}
/**
* Include results
*
* #param App\Item $item
* #return League\Fractal\CollectionResource
*/
public function includeResults(Item $item)
{
$results = $item->results;
if (!is_null($results)) {
return $this->collection($results, new ResultTransformer);
}
return;
}
}
On my base controller
/**
* get fractal tranformed data
* #param $resource
*/
protected function fractalResponse($resource, array $includes = [])
{
$manager = new Manager();
$manager->setSerializer(new DataArraySerializer()); //or what ever you like
if (sizeof($includes) == 0) {
$data = $manager->createData($resource)
->toArray();
} else {
$manager->parseIncludes($includes);
$data = $manager->createData($resource)
->toArray();
}
return $data;
}
then
$resource = new \League\Fractal\Resource\Collection($survies, new SurveyTransformer);
$response_data = $this->fractalResponse($resource, ['items.results'])

Categories