Symfony, twig transmit data - php

In symfony I have twig and I want to transmit data for action but in url for action I dont want see 'role', only transmit for action, how do this?
routing:
artel_admin_index:
path: /{ida}/edit/{id}/submit
defaults: { _controller: ArtelProfileBundle:Dashboard:edit }
requirements: { _method: POST|GET }
twig:
<td>
{{ developer.firstname }} {{ developer.lastname }}
</td>
action:
public function editAction($ida, $id)
{
$request = $this->get('request');
$value = $request->getSession()->get('role');
dump($request, $value);exit;
And I see:
DashboardController.php on line 138:
Request {#7 ▼
+attributes: ParameterBag {#10 ▶}
+request: ParameterBag {#8 ▶}
+query: ParameterBag {#9 ▶}
+server: ServerBag {#13 ▶}
+files: FileBag {#12 ▶}
+cookies: ParameterBag {#11 ▶}
+headers: HeaderBag {#14 ▶}
#content: null
#languages: null
#charsets: null
#encodings: null
#acceptableContentTypes: null
#pathInfo: "/39/edit/116/submit"
#requestUri: "/app_dev.php/39/edit/116/submit"
#baseUrl: "/app_dev.php"
#basePath: null
#method: "GET"
#format: null
#session: Session {#151 ▶}
#locale: null
#defaultLocale: "en"
}
DashboardController.php on line 138:
"ROLE_COMPANY"
I try transmit $role indexAction -> editAction in indexAction I set:
public function indexAction($username)
{
$user_role = $user->getRoles();
$request->getSession()->set('role', $user_role[0]);
and in form I have action hoe in this action transmit this $role but this role not add in routing:
<td>
{{ developer.firstname }} {{ developer.lastname }}
</td>
in indexAction
$user_role = $user->getRoles();
$request->getSession()->set('role', $user_role[0]);
$role = $request->getSession()->get('role');
dump($user_role, $role);exit;
And I see
UserProfileController.php on line 69:
array:1 [▼
0 => "ROLE_COMPANY"
]
UserProfileController.php on line 69:
"ROLE_COMPANY"
Now in index action I render in template ? Because now in indexAction I render some data and in template I have

If you want to pass a variable from a view to the receiving controller you should use POST method.
You can achieve this, for example, submitting a form.
If you knew this data when executing the previous action, then you can store this information in session:
$request->getSession()->set('VARIABLE_NAME', $value);
And then get it back with:
$value = $request->getSession()->get('VARIABLE_NAME');

Related

Getter on a ManyToMany relation - Symfony\ApiPlatform

Describe here your problem or what you are trying to do.
Hello ,
I'm on a small Symfony/ApiPlatform project but I have to admit that I'm really stuck on a (small?) problem..
I have several entities including a #City entity, an #Company entity and an #Manager entity.
Each city can have multiple companies, and each company can have multiple cities;
Each company can have multiple managers, but each manager can only have one company.
So a manager must be linked to a company but also to a city. For instance :
MyCompany Limited is present in New York and Los Angeles, we have a manager for New York and another manager for Los Angeles.
So far, it's very simple. But where things get tricky is that I can't limit a manager to only company cities.
For example, the New York manager of MyCompagny Limited should not be able to change his city to Chicago, given that his company is not present in this city.
I try to do it from my events in PRE_VALIDATE, I manage to recover the manager's company but on the other hand the $company->getCity() method returns my #Company object rather than the city object?
class ManagerCitySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['setCityForManager', EventPriorities::PRE_VALIDATE]
];
}
public function setCityForManager(ViewEvent $event)
{
$result = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if ($result instanceof Manager && ($method === "POST" || $method === "PATCH"))
{
$company= $result->getCompany();
$city= $result->getCity();
$cityCompany = $company->getCity();
if($city instanceof City){
dd(
$company, // dd : return my company object
$city, // dd : returns the city the user wants
$cityCompany // dd : return also my company object ?
);
} else {
dd("This is not an instance of #City ; else");
}
};
}
}
What I want
It's quite simple, at this stage the user (Manager) can assign himself the city he wants, such as the city of Chicago or Boston (provided he knows his IRI), even if his company is not present in this city but only in New York and Los Angeles.
So I would like to limit the possibility only to the same cities as his company.
A manager of the same company can change city, as long as he respects one of the cities of his company.
So I'm trying to retrieve his company, the city he wants to assign himself but also the cities of his company to be able to make a condition:
if($desiredcity == $cityOfMyCompany) { then I assign the city; } else { I return an error: You don't have access to this city; }
what i get
I can't do the above condition because I can't retrieve the cities of the manager's company. However, I manage to get the manager's company, the city he wants to assign himself, but my $company->getCity() method returns my company object:
dd($cityCompany); =
ManagerCitySubscriber.php on line 35:
Doctrine\ORM\PersistentCollection {#1049
#collection: Doctrine\Common\Collections\ArrayCollection {#1051
-elements: []
}
#initialized: false
-snapshot: []
-owner: Proxies\__CG__\App\Entity\Company {#797
-id: 3
-createdAt: DateTimeImmutable #1662842908 {#1052
date: 2022-09-10 20:48:28.0 UTC (+00:00)
}
-company: "MyCompany Limited"
-companyState: "Limited"
-city: Doctrine\ORM\PersistentCollection {#1049}
-Manager: Doctrine\ORM\PersistentCollection {#1056
#collection: Doctrine\Common\Collections\ArrayCollection {#1057
-elements: []
}
#initialized: false
-snapshot: []
-owner: Proxies\__CG__\App\Entity\Company {#797 …2}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#642 …11}
-backRefFieldName: "company"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#692 …}
-isDirty: false
}
-Clients: Doctrine\ORM\PersistentCollection {#1058
#collection: Doctrine\Common\Collections\ArrayCollection {#1059
-elements: []
}
#initialized: false
-snapshot: []
-owner: Proxies\__CG__\App\Entity\Company{#797 …2}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#642 …11}
-backRefFieldName: "company"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#796 …}
-isDirty: false
}
+__isInitialized__: true
…2
}
-association: array:20 [ …20]
-em: Doctrine\ORM\EntityManager {#642 …11}
-backRefFieldName: "companies"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#770 …}
-isDirty: false
}
Re,
I "found" the solution to my problem, however I don't know if this is the right method to follow. If anyone has a better idea for cleaner code, it's with great pleasure :
public function setCityForManager(ViewEvent $event)
{
$result = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if ($result instanceof Manager && ($method === "POST" || $method === "PATCH"))
{
$company= $result->getCompany();
$city= $result->getCity();
if($city instanceof City && in_array($city, $company->getCity()->toArray())) {
$result->setCity($city);
} else {
die();
}
};
}

Error message: Creating default object from empty value

Facing this error message but not sure what is wrong with it? Tried the solutions at StackOverflow and other forums but didn't work either.
The error is at line $review->title=$request->title;
public function updateReview(Request $request)
{
// dd($request->all());
$review = Review::find($request->id);
$review->id=$request->id;
$review->title=$request->title;
$review->review=$request->review;
$review->rating=$request->rating;
$review->save();
return redirect('/');
}
A dd($request->all()); returns the following:
array:5 [▼
"id" => "3"
"title" => "User 3 has updated title"
"review" => "User 4 just updated review"
"rating" => "5"
"_token" => "pGFVAzHNg7HmXbkMXylxcM6biqaGnwFmsxjsrTgl"
]
And these are my routes:
Route::get('/edit_review/{id}', 'App\Http\Controllers\UserController#editReview');
Route::post('/update', 'App\Http\Controllers\UserController#updateReview')->middleware('user');
You're getting this error Warning: Creating default object from empty value because $review->title returns false.
find() takes an id and returns a single model. If no matching model exist, it returns null.
You can use findOrFail() instead of find(), if the record not matched then findOrFail() will throw a 404 error :
$review = Review::findOrFail($request->id);
I think you've missed to define a parameter on your function, that passes with your route, probaby its {id} :
public function updateReview(Request $request, $id)
{
$review = Review::findOrFail($id);
//...
}

Sending data with put / post to a webservice in Laravel

I'm trying to create a dynamic method to send / receive my data with my webservice using guzzle and laravel
I have the following structure in my controller
class TipoProjetoController extends Controller
{
private $Tabela = 'tipoprojeto';
public function AppWebService($Who, $Type, $Data)
{
$Client = new Client(['base_uri' => config('constants.caminhoWS').$Who]);
$response = $Client->request($Type, $Data);
return $response->getBody()->getContents();
}
public function index()
{
$Dados = $this->AppWebService($this->Tabela,'GET','');
$Titulo = 'Tipos de Projeto';
$jsonObj = json_decode($Dados);
$Obj = $jsonObj->data;
return view('Painel.TipoProjeto.index',compact('Obj','Titulo') );
}
public function create()
{
return view('Painel.TipoProjeto.create-edit');
}
public function store(Request $request)
{
//
}
public function show($id)
{
//
}
public function edit($id)
{
$Dados = $this->AppWebService($this->Tabela.'/'.$id,'GET','');
if( $Dados == null )
return redirect()->route('TipoProjeto.index');
else
{
$Objeto = json_decode($Dados);
return view('Painel.TipoProjeto.create-edit',compact('Objeto'));
}
}
public function update(Request $request, $id)
{
$Dados = $this->AppWebService($this->Tabela.'/'.$id, 'PUT', '');
dd($Dados);
}
public function destroy($id)
{
//
}
}
Until then everything worked perfectly in my Index and Edit method, because the method of sending is GET. now I am trying to send a request to the server with the PUT method and I am not getting.
The AppWebService method has as the first parameter the name of the route that I am accessing, the type and the information that I am going to pass.
I tried this way
public function update(Request $request, $id)
{
$Dados = $this->AppWebService($this->Tabela.'/'.$id, 'PUT', ['data'=>'$request']);
dd($Dados);
}
and the error was
(1/1) InvalidArgumentException URI must be a string or UriInterface
my request received from my client was
dd($request)
Request {#38 ▼
#json: null
#convertedFiles: null
#userResolver: Closure {#154 ▶}
#routeResolver: Closure {#156 ▶}
+attributes: ParameterBag {#40 ▶}
+request: ParameterBag {#39 ▶}
+query: ParameterBag {#46 ▶}
+server: ServerBag {#42 ▶}
+files: FileBag {#43 ▶}
+cookies: ParameterBag {#41 ▶}
+headers: HeaderBag {#44 ▶}
#content: null
#languages: null
#charsets: null
#encodings: null
#acceptableContentTypes: null
#pathInfo: "/Painel/TipoProjeto/1"
#requestUri: "/index.php/Painel/TipoProjeto/1"
#baseUrl: "/index.php"
#basePath: null
#method: "PUT"
#format: null
#session: Store {#185 ▶}
#locale: null
#defaultLocale: "en"
-isHostValid: true
-isForwardedValid: true
basePath: ""
format: "html"
}
as my application is in laravel and my webservice too, is it any problem that I send the request this way? or do I have to extract and send it?
and how do I send the put and post methods to my dynamic function?
[EDIT] File Web Service, Route and Controller
Route::group(['prefix' => 'api'],function(){
Route::group(['prefix' => 'user'], function(){
Route::group(['prefix' => 'tipoprojeto'], function(){
Route::get('/','Painel\TipoProjetoController#All');
Route::get('{id}','Painel\TipoProjetoController#Get');
Route::post('','Painel\TipoProjetoController#Save');
Route::put('{id}','Painel\TipoProjetoController#Update');
Route::delete('{id}','Painel\TipoProjetoController#Delete');
});
});
});
Webservice method that receives my request
class TipoProjetoController extends Controller
{
public function Update(Request $request, $id){
return 'Change data of id:'.$id;
}
}
Try with ['data'=>$request] instead of ['data'=>'$request']
you're also using $Client->request(); wrong. The second parameter should be the URI, not an array, hence your error.
Also the base URI is not meant to be used that way,
so instead try
$Client = new Client();
$url = config('constants.caminhoWS').$Who;
$response = $Client->request($Type,$url, $Data);
(if you are going to use a base URI, use the second parameter in $Client->request() to pass the rest of the URL, like
$Client = new Client(['base_uri' => config('constants.caminhoWS')]);
$response = $Client->request($Type, $Who, $Data);
Then Guzzle will construct the URL...
http://docs.guzzlephp.org/en/stable/quickstart.html#making-a-request

can't using foreach for collection Laravel 5.3

I'm creating an edit page of a group-making of an organization. each group consists of a mentor and some mentees.
The problem is i can't iterate using the result because it is a collection of a collection and a user, instead of giving a (directly) collection of user.
the error is this
ErrorException in dd3280396f5fc9a234b8faac1b17b55bd5c30ae2.php line 77:
Undefined property: Illuminate\Database\Eloquent\Collection::$id (View: E:\Documents\Karya\simentor\resources\views\group\edit.blade.php)
Here's the result of dd($mentees)
Collection {#260 ▼
#items: array:2 [▼
0 => Collection {#286 ▼
#items: array:1 [▼
0 => User {#284 ▶}
]
}
1 => User {#261 ▶}
]
}
To get all mentors and mentees who don't have any group yet and to get the mentor and mentees of the to-be-edited group, i did this in GroupController.php
public function edit($id)
{
$group = Group::find($id);
//get mentor and mentee who don't have group yet
$unassignedMentors = User::whereHas(
'roles', function ($q) {
$q->where('name', 'mentor');
})
->doesntHave('groups')
->get();
$unassignedMentees = User::whereHas(
'roles', function ($q) {
$q->where('name', 'mentee');
})
->doesntHave('groups')
->get();
//get mentor and mentee of the to-be-edited group
$assignedMentor = $group->mentor();
$assignedMentee = $group->mentee();
//combine those mentors and mentees into a collection
$mentors = $unassignedMentors->prepend($assignedMentor);
$mentees = $unassignedMentees->prepend($assignedMentee);
return view('group.edit', compact('group', 'mentees', 'mentors', 'assignedMentor', 'assignedMentee'));
}
The mentor() and mentee() method defined in Group.php like this
public function mentor()
{
return $this->users()->whereHas(
'roles', function($q){
$q->where('name', 'mentor');
})
->first();
}
public function mentee()
{
return $this->users()->whereHas(
'roles', function($q){
$q->where('name', 'mentee');
})
->get();
}
Here's the code to display the checkboxes and names in edit.blade.php
#foreach ($mentees as $mentee)
<tr>
<td><input type="checkbox" name="mentee_id[]" value="{{$mentee->id}}" {{ array_has($assignedMentee, $mentee) ? 'checked' : '' }}></td> --> line 77
<td>{{ucwords($mentee->profile->name)}}</td>
</tr>
#endforeach

Persisting/Flushing a form created an extra row in the database

I have a form with multiple rows created from one table (no relationships to other tables). When I save the form, every change I've made is saved, but I do have an additional empty row in the database.
See below for (hopefully) all neccessary informations.
PropertyAdditionCostFrequency.php
/**
* #ORM\Entity
* #ORM\Table(name="property_addition_cost_frequency")
*/
class PropertyAdditionCostFrequency
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $label = '';
private $costFrequencyCollection;
public function __construct()
{
$this->costFrequencyCollection = new ArrayCollection();
}
// + the getters and setters
}
PropertyAdditionCostFrequencyLabelType.php
class PropertyAdditionCostFrequencyLabelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('label' )
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => PropertyAdditionCostFrequency::class,
));
}
}
PropertyAdditionCostFrequencyForm.php
class PropertyAdditionCostFrequencyForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add( 'cost_frequency_collection', CollectionType::class, array(
'entry_type' => PropertyAdditionCostFrequencyLabelType::class,
'label' => ''
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => PropertyAdditionCostFrequency::class
]);
}
}
AdminCoreDataController.php
public function showCoreDataListAction( Request $request )
{
$PropertyAdditionCostFrequency = new PropertyAdditionCostFrequency();
$repository = $this->getDoctrine()->getRepository('AppBundle:PropertyAdditionCostFrequency');
$cost_frequency = $repository->findAll();
foreach ($cost_frequency as $k => $v) {
$PropertyAdditionCostFrequency->getCostFrequencyCollection()->add($v);
}
$form = $this->createForm( PropertyAdditionCostFrequencyForm::class, $PropertyAdditionCostFrequency);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$propertyAdditionCostFrequency_form = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($propertyAdditionCostFrequency_form);
$em->flush();
$this->addFlash('success', 'successfully changed the data');
return $this->redirectToRoute('admin_core_data');
}
return $this->render('logged_in/content/admin/core_data/core_data.html.twig', [
'propertyCostFrequencyForm' => $form->createView()
]);
}
core_data.html.twig
{{ form_start(propertyCostFrequencyForm) }}
<div class="row" id="cost_frequency_box">
{% for single_frequency in propertyCostFrequencyForm.cost_frequency_collection %}
<div class="row js-single-cost-frequency-box">
<div class="col-sm-1 js-delete-cost-frequency">
<a href="/admin/property/delete/5">
<i class="fa fa-trash"></i>
</a>
</div>
<div class="col-sm-4">
{{ form_widget(single_frequency.label) }}
</div>
</div>
{% endfor %}
</div>
<div class="row">
<div class="col-sm-3">
<button class="col-sm-12 btn btn-success" type="submit">Speichern</button>
</div>
</div>
{{ form_end(propertyCostFrequencyForm) }}
a dump() of $propertyAdditionCostFrequency_form right before '$em->persist($propertyAdditionCostFrequency_form)'
PropertyAdditionCostFrequency {#394 ▼
-id: null
-label: ""
-costFrequencyCollection: ArrayCollection {#395 ▼
-elements: array:4 [▼
0 => PropertyAdditionCostFrequency {#422 ▼
-id: 1
-label: "1"
-costFrequencyCollection: null
}
1 => PropertyAdditionCostFrequency {#424 ▼
-id: 2
-label: "2"
-costFrequencyCollection: null
}
2 => PropertyAdditionCostFrequency {#425 ▼
-id: 47
-label: "3"
-costFrequencyCollection: null
}
3 => PropertyAdditionCostFrequency {#426 ▼
-id: 38
-label: "4"
-costFrequencyCollection: null
}
]
}
}
The reason why this is happening is evident from the dump you have posted: the top level PropertyAdditionCostFrequency has the id set to null, so of course it is going to create a new row for that, so if you were simply wondering why it creates a new row thats your reason :).
On the other hand I can't help but think, you have misunderstood how symfony forms / doctrine works, UNLESS having multiple child PropertyAdditionCostFrequency added to one parent PropertyAdditionCostFrequency is the desired effect.
IF it is not the desired effect and you simply want to create a form which contains a form for every entry of PropertyAdditionCostFrequency in the database(which I would not recommend, because once the DB gets big, it won't be very efficient), you can just use createFormBuilder method inside the controller, add an arbitrary CollectionType field (i.e. $builder->add('frequencies', CollectionType::class), then just create an array and assign the result of findAll() to a key(key name should correspond to the field name, in this case, 'frequencies') and finally set that as the data for the form you have just created (use $builder->getForm() method to get the form, since thats what you want in the controller and you should use the set data method on that :)) (P.S. these are just rough guidelines, I'm not sure, that I haven't missed anything)

Categories