Access a property from another property in controller - php

I'm bulding a webapp in Symfony, and I need to access to some properties of an entity in a controller to add this values to $candidature entity. Thank you for the help.
Controller.php :
class CandidatureController extends AbstractController
{
#[Route('/candidature', name: 'app_candidature')]
public function index(EntityManagerInterface $entityManager): Response
{
$candidature = new Candidature();
//$candidatNom = $entityManager->getRepository(ProfileCandidat::class)->findBy($Nom);
$candidature->setNom($candidatNom);
$candidature->setPrenom('Charles');
$candidature->setCv('cv');
$candidature->setPostId('4');
$entityManager->persist($candidature);
$entityManager->flush();
return $this->render('candidature/index.html.twig', [
'controller_name' => 'CandidatureController',
]);
}
}

$candidatNom = $entityManager->getRepository(ProfileCandidat::class)->findBy(['nom' => $Nom);
should do the trick

Related

Undefined method getDoctrine

I am a beginner on Symfony 6 and I am blocked because I have an error message: "Undefined method getDoctrine" with Intelephense
Here is my code:
#[Route('/recettes', name: 'app_recettes')]
public function index(int $id): Response
{
$em = $this->getDoctrine()->getManager();
$recette = $em->getRepository(Recettes::class)->findBy(['id' => $id]);
return $this->render('recettes/index.html.twig', [
'RecettesController' => 'RecettesController',
]);
}
Your controller should extends AbstractController from use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
You should not use getDoctrine()->getManager() in symfony 6. If you look into the method from AbstractController you can see:
trigger_deprecation('symfony/framework-bundle', '5.4', 'Method "%s()" is deprecated, inject an instance of ManagerRegistry in your controller instead.', __METHOD__);
You should just autowire your entity manager in your method or constructor and use it directly.
private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
#[Route('/recettes', name: 'app_recettes')]
public function index(int $id): Response
{
$recette = $this->entityManager->getRepository(Recettes::class)->findBy(['id' => $id]);
return $this->render('recettes/index.html.twig', [
'RecettesController' => 'RecettesController',
]);
}
You could also autowire your RecettesRepository directly instead of the entity manager if you just want to fetch some data.
I'm guessing that you want to show a specific resource by using its id. You probably want to add something /{id} in your route:
#[Route('/recettes/{id}', name: 'app_recettes')]
Dylan response is really good !
If you want to fecth a specific recette (blog de cuisine?), you can autowire the 'recette' as an argument :
#[Route('/recettes/{id}', name: 'app_recettes')]
public function index(Recette $recette): Response
{
return $this->render('recettes/index.html.twig', [
'recette' => $recette,
]);
}
To do so, don't forget to install and import :
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;

Call component inside component October CMS gives an error

I am trying to extend an existing plugin component and I
need to add a function but use plugins methods.
Here what I have:
<?php namespace Bbrand\Shop\Components;
use Cms\Classes\ComponentBase;
use Jiri\JKShop\Components\Basket;
class Shopextend extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'shopextend Component',
'description' => 'No description provided yet...'
];
}
public function defineProperties()
{
return [];
}
public function onBasket(){
$data = [];
$data["basket"] = Basket::getSessionBasket();
$data["jkshopSetting"] = \Jiri\JKShop\Models\Settings::instance();
return [
$this->property("idElementWrapperBasketComponent") => $this->renderPartial('#basket-0', $data)
];
}
}
But I'm getting an error
"Non-static method Jiri\JKShop\Components\Basket::getSessionBasket()
should not be called statically" on line 30 of
/Applications/MAMP/htdocs/fidgycube.co/plugins/bbrand/shop/components/Shopextend.php
Any help!?
thanks
You need to add component first.
<?php namespace Bbrand\Shop\Components;
class Shopextend extends ComponentBase
{
public function init()
{
// Add component
$this->addComponent('\Jiri\JKShop\Components\Basket', 'basket', []);
}
}

Can't initialize my plugin function in ZF2 constructor

I am quite new to ZF2 and I am preparing a demo application with simple login and CRUD system. Now for login I have prepared a plugin which consists of some functions that will authenticate users, return the logged in user data, return the logged in status etc. But the problem that I am facing is I can't initialize any variable into the constructor of my controller which will store any return value from the plugin. It's always showing service not found exception.
Please find my plugin code below:
AuthenticationPlugin.php
<?php
namespace Album\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
use Zend\Session\Container as SessionContainer;
use Zend\View\Model\ViewModel;
use Album\Entity\User;
class AuthenticationPlugin extends AbstractPlugin{
protected $entityManager;
protected $usersession;
public function __construct(){
$this->usersession = new SessionContainer('UserSession');
}
public function dologin($email,$password)
{
$getData = $this->em()->getRepository('Album\Entity\User')->findOneBy(array('email' => $email, 'password' => $password));
if(count($getData)){
$this->usersession->offsetSet('userid', $getData->getId());
return true;
}
else{
return false;
}
}
public function isloggedin(){
$userid = $this->usersession->offsetGet('userid');
if(!empty($userid)){
return true;
}
else{
return false;
}
}
public function logindata(){
$userid = $this->usersession->offsetGet('userid');
$getData = $this->em()->getRepository('Album\Entity\User')->findOneBy(array('id' => $userid));
return $getData;
}
public function logout(){
$this->usersession->offsetUnset('userid');
}
public function em(){
return $this->entityManager = $this->getController()->getServiceLocator()->get('Doctrine\ORM\EntityManager');
}
}
?>
In my module.config.php
'controller_plugins' => array(
'invokables' => array(
'AuthPlugin' => 'Album\Controller\Plugin\AuthenticationPlugin',
)
),
Now I am doing this in my controller:
protected $entityManager;
protected $isloggedin;
protected $authentication;
public function __construct(){
$this->authentication = $this->AuthPlugin();
$this->isloggedin = $this->authentication->isloggedin();
}
The error I am getting is like below:
An error occurred An error occurred during execution; please try again
later. Additional information:
Zend\ServiceManager\Exception\ServiceNotFoundException
File:
D:\xampp\htdocs\subhasis\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:555
Message:
Zend\Mvc\Controller\PluginManager::get was unable to fetch or create an instance for AuthPlugin
But if I write the above constructor code in any of my controller actions everything is fine. in ZF1 I could initialize any variable in the init() method and could use the variable in any of my actions. How can I do this in ZF2? Here, I want to detect if the user is logged in the constructor itself. Now I have to call the plugin in every action which I don't want.
What should I do here?
The error you are receiving is because you are trying to use the ServiceManager (via the Zend\Mvc\Controller\PluginManager) in the __construct method of the controller.
When a controller is registered as an invokable class, the Service Manager (ControllerManager) is responsible for the creating the controller instance. Once created, it will then call the controllers various default 'initializers' which also inlcudes the plugin manager. By having your code in __construct it is trying to use the plugin manager before it has been set.
You can resolve this by using a controller factory, rather than an invokable in module.config.php.
'controllers' => [
'factories' => [
'MyModule\Controller\Foo' => 'MyModule\Controller\FooControllerFactory',
],
],
Then the factory
namespace MyModule\Controller\FooControllerFactory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class FooControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $controllerManager)
{
$serviceManager = $controllerManager->getServiceLocator();
$controllerPluginManager = $serviceManager->get('ControllerPluginManager');
$authPlugin = $controllerPluginManager->get('AuthPlugin');
return new FooController($authPlugin);
}
}
Lastly, update the controller __construct to add the new argument and remove the call to $this->authPlugin()
class FooController extends AbstractActionController
{
public function __construct(AuthPlugin $authentication)
{
$this->authentication = $authentication;
$this->isloggedin = $authentication->isloggedin();
}
}

Yii2 envelope single data in JSON response

I went through offical guide and found a way to envelop JSON data like this.
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
}
This works perfect when I have a collection and then I have a response like this.
{
products:....
}
But what I want to do is that i have a envelope for single data. For example if I do products/10 GET request to get.
{
product:
}
Hope somebody figured it out.
Single Data Envelope is not supported by \yii\rest\Serializer. At least until Yii 2.0.6 only collections get enveloped in order to add _links and _meta data objects to the response.
To envelope single data resource objects you'll need to override ActiveController's default view action within your Controller :
public function actions()
{
$actions = parent::actions();
unset($actions['view']);
return $actions;
}
public function actionView($id)
{
$model = Product::findOne($id);
return ['product' => $model];
}
Old, but I just bumped into here with the same problem.
And found a better (I think) solution: create your own serializer class extending \yii\rest\Serializer:
class Serializer extends \yii\rest\Serializer
{
public $itemEnvelope;
public function serializeModel($model)
{
$data = parent::serializeModel($model);
if($this->itemEnvelope)return [$this->itemEnvelope=>$data];
return $data;
}
}
And then use it like this:
public $serializer = [
'class' => '[your-namespace]\Serializer',
'collectionEnvelope' => 'list',
'itemEnvelope' => 'item'
];

Symfony2 / FOSUserBundle: Change render variables in response without altering parent class

One of my classes currently extends the BaseController on the FOSUserBundle, and returns the parent action. However, due to project spec, I shouldn't have the need to edit the parent class. Is there a way of sending additional variables, for twig to render, through the child response?
Child Class:
class ChangePasswordController extends BaseController
{
public function changePasswordAction(Request $request)
{
$response = parent::changePasswordAction($request);
return $response; // and 'myVariable' => $myVariable
}
}
Parent Class:
class ChangePasswordController extends ContainerAware
{
/**
* Change user password
*/
public function changePasswordAction(Request $request)
{
//lots of code.....
return $this->container->get('templating')
->renderResponse(
'FOSUserBundle:ChangePassword:changePassword.html.'
.$this->container->getParameter('fos_user.template.engine'),
array(
'form' => $form->createView()
//and 'myVariable' => $myVariable
)
);
}
}
So to summarise, is there a way of passing something to the parent class, without changing the parent class... whilst rendering the twig view with an additional variable.
-- Update --
Essentially I want to render a form using the FOSUserBundle changePassword action, therefore this works fine:
return $this->container
->get('templating')
->renderResponse(
'FOSUserBundle:ChangePassword:changePassword.html.'.$this->container->getParameter('fos_user.template.engine'),
array('form' => $form->createView())
);
However, I want to pass more variables to the view, just like the 'form' is passed as shown above, without altering the FosUserBundle ChangePassword Controller. Therefore I have a class which inherits the that controller, adds some additional functionality and returns the parent change password action:
class ChangePassController extends ChangePasswordController
{
public function changePasswordAction(Request $request)
{
// more code......
$response = parent::changePasswordAction($request);
return $response;
}
}
But, like with most applications, I want to add more than just the form variable to a view template. So is there a way of passing an additional variable to the view, without altering the parent controller / action? Like (but not like) pushing 'myVariable' => $myVariable to the parent changePasswordAction return statement?
There is a section in FOSUserBundle documentation that describes exactly how to do that, and from Symfony2's Cookbook, How to use Bundle Inheritance to Override parts of a Bundle.
In summary, create a Bundle class to override FOSUserBundle in src:
// src/Acme/UserBundle/AcmeUserBundle.php
<?php
namespace Acme\UserBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeUserBundle extends Bundle
{
public function getParent()
{
return 'FOSUserBundle';
}
}
Then, override the ChangePasswordController class:
use FOS\UserBundle\Controller\ChangePasswordController as BaseController;
class ChangePasswordController extends BaseController
{
public function changePasswordAction(Request $request)
{
$response = parent::changePasswordAction($request);
return $response; // and 'myVariable' => $myVariable
}
}
--UPDATE--
Ok I think I misread you question. Anyway what renderResponse() of the templating service does is essentially:
$response->setContent($this->render($view, $parameters));
You can see the Class of the templating service by running app/console container:debug which is actually the TwigEngine class.
So you can just re-invoke renderResponse() and supply you own extra parameters. eg:
return $this->container->get('templating')->renderResponse(
'FOSUserBundle:ChangePassword:changePassword.html.'.$this->container->getParameter('fos_user.template.engine'),
array(
'form' => $form->createView(),
'myVariable' => $myVariable', // There you go
),
$response // The previous response that has been rendered by the parent class, by this is not necessary
);
Think bottom up.
You can access your data without passing it through action, using Twig Extension http://symfony.com/doc/current/cookbook/templating/twig_extension.html
twig.extension.user_profile:
class: 'MyBundle\UserProfileExtension'
arguments:
- '#doctrine.orm.entity_manager'
tags:
- { name: twig.extension }
Extension class
class UserProfileExtension extends \Twig_Extension
{
/**
* #var EntityManager
*/
private $entityManager;
/**
* #param UserProfileDataService $userProfileDataService
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* #return array
*/
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('get_my_custom_var', array($this, 'getMyCustomVar')),
);
}
/**
* #return array
*/
public function getMyCustomVar()
{
$var = $this->entityManager->getRepository('MyCustomRepository')->findOneBy(['id' => 1]);
return $var;
}
/**
* Returns the name of the extension.
*
* #return string The extension name
*/
public function getName()
{
return 'user_profile_extension';
}
Template usage
{dump(get_my_custom_var())}
if I am understanding your question correctly you should be able to set additional variables on the response like this:
use FOS\UserBundle\Controller\ChangePasswordController as BaseController;
class ChangePasswordController extends BaseController
{
public function changePasswordAction(Request $request)
{
$response = parent::changePasswordAction($request);
$response['myVariable'] = $myVariable;
return $response;
}
}
Hope this helps!

Categories