I need to send multiple mails with symfony swiftmailer inside a loop. This is my code.
public function __construct($name = null, \Swift_Mailer $mailer, EngineInterface $templating) {
parent::__construct($name)
$this->mailer = $mailer;
$this->templating = $templating;
}
protected function execute(InputInterface $input, OutputInterface $output) {
foreach ($ads as $ad) {
if($counter == 10) break;
$this->sendMail($ad->getUser()->getMail(), $ad, 'matching');
$counter++;
}
}
protected function sendMail($mail, $ad, $template = '') {
if($template == 'matching'){
$template = 'emails/matching-cars.html.twig';
}elseif($template == 'owner'){
$template = 'emails/matching-car-owners.html.twig';
}
$message = (new \Swift_Message('Hello Email'))
->setFrom('admin#admin.com')
->setTo($mail)
->setBody(
$this->templating->render(
$template, [
'ad' => $ad
]
), 'text/html'
);
$this->mailer->send($message);
}
Since I'm doing it inside loop it's really hard to pass mails array to swift mailer. I'm running this inside Console Command and I'm getting this error in console.
17:14:09 ERROR [app] Exception occurred while flushing email
queue: Expected response code 354 but got code "550", with message
"550 5.7.0 Requested action not taken: too many emails per second
symfony swiftmailer send multiple mails inside loop
let assume you have function called sendEmail that you use to sent email to all users that have account in you system.
Here are explanation that can help you to solve email error with code implementation:
For me it work....
public function sendEmail(\Swift_Mailer $mailer): Response
{
$entityManager=$this->getDoctrine()->getManager();
$connection= $entityManager->getConnection();
$decl12="SELECT id
FROM
user";
$statement97=$connection->prepare($decl12);
$statement97->execute();
$tap=$statement97->fetchAll();
try{
foreach($tap as $i=>$data)
{
//check what type of data taken from variable data by
//var_dump($data);
$test =$this->getDoctrine()->getRepository(User::class)->findOneBy(['id'=>$data]);
$email=$test->getEmail();
$message = (new \Swift_Message('Email Subject'))
->setFrom('admin#gmail.com')
->setTo($email)
->setBody(
"click here to get bonus",
'text/html'
);
$mailer->send($message);
}
}
catch (\Swift_TransportException $e)
{
return new Response($e->getMessage());
}
}
Related
I am testing Ratchet with Symfony. Tests are fine but I cannot understand where a property $conn->resourceID is coming from... Here is the code from the official tutorial
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
// The sender is not the receiver, send to each client connected
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
// The connection is closed, remove it, as we can no longer send it messages
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
I cannot find it ($conn->resourceID), IDE cannot find it, but it works, it is populated somehow....
Does anyone has a clue to help me to understand?
Thanks
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 be able to set a Cookie onKernelRequest Method, but the cookie is not beeing set,
Everything else is working fine, what am missing here?
What i want to achieve is that if the user is not logged in and doesnt have the cookie he should see the http basic auth headers.
If the user is logged in or does have the cookie he has access to the preview domains without having to enter their user credentials in http basic auth.
const AUTH_USER = 'myuser';
const AUTH_PW = 'mypass';
public function sendAuthorizationHeader()
{
header('WWW-Authenticate: Basic realm="Preview Domain"');
header('HTTP/1.0 401 Unauthorized');
die();
}
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
$request = $event->getRequest();
$host = $request->getHost();
$loginSuccessful = false;
// check if we are on a preview domain
if (preg_match('/^preview-\d+/', $host)) {
$user = $request->getUser();
$cookie = $request->cookies->get('preview_user');
$phpAuthUser = $request->server->get('PHP_AUTH_USER');
$phpAuthPw = $request->server->get('PHP_AUTH_PW');
if (isset($phpAuthUser) && isset($phpAuthPw)) {
if ($phpAuthUser == self::AUTH_USER && $phpAuthPw == self::AUTH_PW) {
$loginSuccessful = true;
}
} else if ($user === null && $cookie === null) {
$this->sendAuthorizationHeader();
}
if (!$loginSuccessful) {
$this->sendAuthorizationHeader();
} else {
$cookie = new Cookie('preview_user', true, 86400, '/', null, false, false);
$response = new Response();
$response->headers->setCookie($cookie);
$response->sendHeaders();
}
}
}
Setting a cookie on a response object doesn't do anything but adding a cookie to that request. You need to return the same response object, so Symfony renders it back to the client. Rendering it yourself is not a good idea, as there might be contents send later and it's not really testable.
It's easier done in a kernel.response event listener, since you already have a response there. Remember to use the response that your application creates. Do not create it yourself.
If you set the cookie based on logic that should also be available during the request, you can split it into two event listener methods. One will set a request attribute on kernel.request, and the other one will set the cookie on the response on kernel.response:
public function onKernelRequest(GetResponseEvent $event)
{
// your logic goes here. calculate the $result
// ...
$event->getRequest()->attributes->set('my_result', $result);
}
public function onKernelResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();
$request = $event->getRequest();
$myResult = $request->attributes->get('my_result');
$cookie = new Cookie(/* ... */);
$response->headers->setCookie($cookie);
}
In the functional test below, the assertion that the text 'Glenshire' exists fails even though the output of echo $client->getResponse()->getContent(); includes
<li>Glenshire...
The first two assertions are true. There is no redirect.
The test
class SearchTest extends WebTestCase
{
public function setUp()
{
$classes = array(
'Vol\VolBundle\DataFixtures\ORM\LoadFocusSkillData',
'Vol\VolBundle\DataFixtures\ORM\LoadOpportunity',
);
$this->loadFixtures($classes);
}
public function testSearch()
{
$client = static::createClient();
$crawler = $client->request('GET', '/search');
$this->assertTrue($crawler->filter('html:contains("Focus")')->count() > 0);
$this->assertTrue($crawler->filter('html:contains("Skill")')->count() > 0);
$form = $crawler->selectButton('match_search[Submit]')->form();
$form['match_search[focuses][0]'] = 1;
$client->submit($form);
echo $client->getResponse()->getContent();
$this->assertTrue($crawler->filter('li:contains("Glenshire")')->count() > 0, 'Glenshire not found');
}
The fixture (using LiipFunctionalTestBundle)
public function load(ObjectManager $manager)
{
$manager->clear();
$org = new Organization();
$org->setOrganization('Glenshire Marmot Fund');
$foc1 = $manager->getRepository("VolVolBundle:Focus")->find(1);
$foc3 = $manager->getRepository("VolVolBundle:Focus")->find(3);
$foc4 = $manager->getRepository("VolVolBundle:Focus")->find(4);
$org->addFocus($foc1);
$org->addFocus($foc3);
$org->addFocus($foc4);
$opp = new Opportunity();
$opp->setName('Feeder');
$opp->setDescription("Beyond recourse");
$opp->setExpireDate(date_add(new \DateTime(), new \DateInterval('P1Y')));
$opp->setOrganization($org);
$manager->persist($opp);
$manager->flush();
}
Curiously, replacing the line
$this->assertTrue($crawler->filter('li:contains("Glenshire")')->count() > 0, 'Glenshire not found');
with
$this->assertRegExp(
'/Glenshire/', $client->getResponse()->getContent(), 'Glenshire not found'
);
provides a successful test!
I am trying to validate the form that I have made myself in .twig file.I am not creating form using createFormBuilder. This is my Controller Code that is call for both case 1) for view 2) after submitting the form.
public function cart_newAction(Request $request)
{
$entity = new Product();
$errors = '';
if ($request->getMethod() == 'POST')
{
$validator = $this->get('validator');
$errors = $validator->validate($entity);
if (count($errors) > 0) {
echo 'Error';
}
else {
echo 'Success';
}
}
return $this->render('CartCartBundle:Cart:Add.html.twig', array('errors' => $errors ));
}
this is view file and I am showing errors like this
Add.html.twig
{% for error in errors %}
{{error}}
{% endfor %}
I have set the error in validation.yml file for name that cannot be blank.
So now when I run the view page it every times show the error after I submit the form.
If no error it should not display me the error just show the blank error.
Note:Is there any better way that I can do this so please share it.Remember that I am doing it without createFormBuilder
UPDATE
It always show me Error.Even if my form is valid and don't missing any field.
If you want to make the form yourself then you can't validate it using the Syfmony form validator. You need to use a simple PHP validation Server-side. Something like this
if ($request->getMethod() == 'POST')
{
$username = $_POST['username'];
if ($username == '')
{
// set error message here
}
}
Ok let me be clear. I gonna give you tow solutions, the first is the best and the most proper way:
1) Generate your EntityForm Type: bin/console make:form or d:g:form command.
2) Then just add some few lines to submit and get the errors.
public function cart_newAction(Request $request)
{
$entity = new Product();
$form = $this->createForm(EntityType::class, $entity);
$form->submitForm($request->request->all(), false);
if ($request->getMethod()->isPost())
{
if ($form->isValid()) {
echo 'Error';
}
else {
echo 'Success';
}
}
return $this->render('CartCartBundle:Cart:Add.html.twig', [
'errors' => $form->getErrors(),
]);
}
The second solution is bind your data into your entity object because we need to set the data into our object.
1) First step create a private fonction in your current class to bind all the submited data:
private function bindEntityValues(Product $entity, array $data) {
foreach ($data as $key => $value){
$funcName = 'set'+ucwords($key);
if(method_exists($entity, $funcName)) $entity->$funcName($value);
}
}
Then your cart_newAction should be like this:
public function cart_newAction(Request $request)
{
$entity = new Product();
$this->bindEntityValues(entity, $request->request->all());
$errors= $this->get('validator')->validate($entity)
if (count($errors) > 0) {
echo 'Error';
}
else {
echo 'Success';
}
}
return $this->render('CartCartBundle:Cart:Add.html.twig', ['errors' => $errors]);
}
Wish this helped you to have a clear vision.
You must check if $errors is empty or not :
if (count($errors) > 0) {
return $this->render('CartCartBundle:Cart:Add.html.twig', array('errors' => $errors ));
} else {
return $this->render('CartCartBundle:Cart:Add.html.twig');
}
See the doc here.