I'd like to use a view as an email body.
I tried this one:
$renderer = new PhpRenderer();
$bodyHtml = $renderer->render(
'/user/email/reset-password-email',
[
'passwordResetUrl' => $passwordResetUrl,
]);
$html = new MimePart($bodyHtml);
I get the following error:
Unable to render template "/user/email/reset-password-email"; resolver could not resolve to a file
My view-template is located in:
Any help appreciated.
To render view as string, you need a renderer "ViewRenderer".
If you can get ServiceManager,
then,
$renderer = $serviceManager->get('ViewRenderer');
Now,
$bodyHtml = $renderer->render(
'/user/email/reset-password-email',
[
'passwordResetUrl' => $passwordResetUrl,
]);
$html = new MimePart($bodyHtml);
You need to retrieve the renderer from the service locator in the factory, and not instantiating it directly in the class where you are using it.
Email sender class factory
class EmailSenderFactory {
public function __invoke($services) {
$viewRenderer = $services->get('ViewRenderer');
return new EmailSender($viewRenderer);
}
}
Email sender class
class EmailSender {
private $viewRenderer;
public function __construct($viewRenderer) {
$this->viewRenderer = $viewRenderer;
}
public function createEmail() {
$template = '/user/email/reset-password-email';
$variables = ['passwordResetUrl' => $passwordResetUrl];
$bodyHtml = $renderer->render($template, $variables);
$html = new MimePart($bodyHtml);
}
}
I had the same problem (sending an email for password reset) and I solved this way. Hope this will help you :)
Related
i want to create an array as a session table to put it empty in the beggining for my cart shop to display nothing as an empty cart and when i press AddtoCart i want get that array and do an array_push with the new items but i didn't know how to do it
This is the first controller when i create the array empty
public function FrontAction()
{
$pro=new Produit();
$pro->setNom('');
$pro->setQuantite(0);
$pro->setPrix(0);
$em = $this->getDoctrine()->getManager();
$sess=new Session();
$sess->setName('PANIER');
$sess=array('');
array_push($sess,$pro->getNom(),$pro->getQuantite(),$pro->getPrix());
$paniers = $em->getRepository(Panier::class)->findByUserId(1);
$produits = $this->getDoctrine()->getRepository(Produit::class)->findAll();
$boutiques = $this->getDoctrine()->getRepository(Boutique::class)->GetBestShopsDQL();
if ($paniers != null)
{
$prixTotal = 0;
foreach ($paniers as $panier) {
$prixTotal += $panier->getPrixTotal();
}
$resultCount = count($paniers);
return $this->render('BoutiqueBundle:FrontViews:ListBoutique.html.twig', array('produits' => $produits, 'boutiques' => $boutiques,'paniers' => $paniers, 'prixTotal' => $prixTotal,'resultCount' => $resultCount));
}
return $this->render('BoutiqueBundle:FrontViews:ListBoutique.html.twig', array('produits' => $produits, 'boutiques' => $boutiques,'sess'=>$sess));
}
and this is the second controller where i want to fill that empty array with new items
public function ajouterauPanierAction($id)
{
$ses=new Session();
$ses->getName('PANIER');
$test=array('');
$test=$ses;
// $user_id = $this->getUser()->getId(); //à modifier!!!!!
$em = $this->getDoctrine()->getManager();
$produit = $em->getRepository(Produit::class)->find($id);
$test = $em->getRepository(Panier::class)->findExistant($id, 1);
// $session->replace(array_push($produit,));
if(($produit != null)&&(empty($test)))
{
array_push($test,$produit->getNom(),$produit->getQuantite(),$produit->getPrix());
/* $panier = new Panier();
$panier->setProduitId($produit->getId());
$panier->setUserId(1); //à changer avec le fos
$panier->setDate(new \DateTime("now"));
$panier->setPrixTotal($produit->getPrix());
$em->persist($panier);
*/ $em->flush();
$msg = "success";
// return $this->redirectToRoute('Dashboard');
}
else
{
//return $this->render('BoutiqueBundle:FrontViews:404.html.twig');
$msg = "failure";
}
return new JsonResponse(array('msg' => $msg));
}
i didn't know how to do it correctly or if my idea is wrong so hope u guys got what i need to do
Here is how I am doing it in Symfony 4, (I think this part is unchanged). First I have declared my session keys as class constants on the entities to avoid collisions.
class Appointment
{
const SESSION_KEY = 'confirmed_app_entity_appointment';
...
}
Then in the controller use the SessionInterface and it will get autowired into your controller method with a typehinted parameter (SessionInterface $session). Symfony will handle starting the session, just set, get, and/or remove the key as needed.
use Symfony\Component\HttpFoundation\Session\SessionInterface;
...
public function confirmAppointment($first_name, $last_name, $time, SessionInterface $session)
{
...
$session->set(Appointment::SESSION_KEY, $appointment);
$session->set(StaffMember::SESSION_KEY_SELECTED_STAFF, $member);
...
if ($this->isConflict($appointment)) {
$session->remove(Appointment::SESSION_KEY);
$session->remove(StaffMember::SESSION_KEY_AUTH);
$this->addFlash('error', 'Failed to create Appointment, conflict found');
return $this->redirectToRoute('customer');
}
...
}
public function saveAppointment(SessionInterface $session)
{
if (!empty($session->get(Appointment::SESSION_KEY))) {
$appointment = $session->get(Appointment::SESSION_KEY);
}
...
}
I want to change my date before to save in sonata admin bundle :
in fact try to change request in preCreate Method but I got nothing ...
here is my code (on my custom controller called eventAdminController.php):
protected function preCreate(Request $request, $object)
{
$jalali = $this->get('jalali');
$all = $request->request->all();
if(isset($request->request->get('s587f71334d196')['start_date'])){
$start_date = explode('/',$request->request->get('s587f71334d196')['start_date']);
$start_date_day = $start_date[0];
$start_date_mon = $start_date[1];
$start_date_yer = $start_date[2];
$start_date = $jalali->to_miladi($start_date_yer,$start_date_mon,$start_date_day);
$all['s587f71334d196']['start_date'] = $start_date[0].'-'.$start_date[1].'-'.$start_date[2];
}
if(isset($request->request->get('s587f71334d196')['end_date'])){
$end_date = explode('/',$request->request->get('s587f71334d196')['end_date']);
$end_date_day = $end_date[0];
$end_date_mon = $end_date[1];
$end_date_yer = $end_date[2];
$end_date = $jalali->to_miladi($end_date_yer,$end_date_mon,$end_date_day);
$all['s587f71334d196']['end_date'] = $end_date[0].'-'.$end_date[1].'-'.$end_date[2];
}
$request->request->replace($all);
}
You can do this in your Admin Class you need to add prePersist and preUpdate method for that. For example
public function prePersist($object)
{
$this->changeDate($object);
}
public function preUpdate($object)
{
$this->changeDate($object);
}
public function changeDate($object)
{
//Set your entity date.
}
In my SilverStripe project I have a controller which I call by a cronjob. But in this controller I want to use the translations from the yaml language files. So I want to set the locale to use the right translations. I tried to do something like this, but this doesn't work:
class CronController extends Controller {
public function opendataform() {
i18n::set_locale('it_IT');
$Params = $this->getURLParams();
self::$ad = $Params['ID'];
$selectMemberSelectionField = new DropdownField('SelectionName', _t('General.CHOOSE_SELECTION', "Choose selection"), MemberSelection::get()->map('ID', 'Name'));
$fields = new FieldList($selectMemberSelectionField);
$actions = new FieldList(
FormAction::create("doOpen")->setTitle(_t('General.Open', "Open"))
);
$form = new Form($this, 'OpenForm', $fields, $actions);
return $form;
}
}
Also tried with: Translatable::set_current_locale('it_IT');
Any suggestions? Thanks in advance!
I set up my mock object using Moq like this:
var accountRepositoryMock = new Mock<IGenericRepository<Account>>();
accountRepositoryMock.Setup(r => r.SingleOrDefault(a => a.AccountId == It.IsAny<long>())).Returns(new Account { AccountId = 99999999, Valid = true });
var unitOfWorkMock = new Mock<IUnitOfWork>();
unitOfWorkMock.SetupGet(unitofwork => unitofwork.AccountRepository).Returns(accountRepositoryMock.Object);
Then I pass it to my service like this:
IQuickPayService quickPayService = new QuickPayService(unitOfWorkMock.Object);
Account account = quickPayService.ValidateAccount(accountId);
When I do this in my client code, I am getting account as null
public class QuickPayService : IQuickPayService
{
public QuickPayService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public AccountStatus ValidateAccount(long accountId)
{
var account;
using (_unitOfWork)
{
account = _unitOfWork.AccountRepository.SingleOrDefault(acc => acc.AccountId == 99999999);
}
return account;
}
}
Any ideas on what I am doing wrong?
Assuming that your interface is declared similarly to the following:
public interface IGenericRepository<T>
{
T SingleOrDefault(Func<T, bool> predicate);
}
Specifying a delegate in Setup won't work. See Issue 300: Mocking Method with Delegate as Parameter. I get a NotSupportedException when I tried it.
Instead, try this:
accountRepositoryMock.Setup(r => r.SingleOrDefault(It.IsAny<Func<Account, bool>>()))
.Returns(new Account { AccountId = 99999999, Valid = true });
There's a more detailed example at Moq framework Func<T,T>
How to moq the OfType to return
class A
{
public void iterate()
{
foreach (var aTool in Handler.Tools.OfType<IDrawTool>())
{
//some code
}
}
}
//tools implementes both interface ITool and IDrawTool
//wanted to get the tool which implements the IDrawTool from the
//Handler.Tools<ITool> list
Mock<List<ITool>> aToolMockList = new Mock<ITool>();
Mock<IDrawTool> adrawToolMock = new Mock<IDrawTool>();
aToolMockList.Setup(list => list.OfType<IDrawTool>()).Returns((IEnumerable<IDrawTool>) adrawToolMock .Object);
But the OfType throws the exception setup on a non-member method
Should I override this? What should I do?
List<ITool> aToolMockList = new List<ITool>();
Mock<IDrawTool> adrawToolMock = new Mock<IDrawTool>();
Mock<ITool> aToolMock = new Mock<ITool>;
//additional setups
aToolMockList.Add(adrawToolMock.object);
aToolMockList.Add(aToolMock.object);
//
A a = new A(aToolMockList);
A.iterate();
//
adrawToolMock.Toolwork.Verify(Times.Once);
aToolMock.Toolwork.Verify(Times.Never);
Something like that :)