Sending email to GMail with Zend_Mail - zend-mail

I'm developing a webapp which has to send mail, I'm using the basic mail router (which is sendmail if I'm not wrong) with the following interface class :
class My_Mail_Interface
{
protected $_defaultCharset = 'utf-8';
public function __construct() {
$this->init();
}
public function init() {
}
/**
* Send the email
* #param string $from the sender address
* #param string $to the receiver address
* #param string $subject the subject
* #param string $bodyHtml the HTML message
* #param string $bodyText the text message
* #param string $sender the sender label
* #param string $receiver the receiver label
* #return void
*/
public function send($from, $to, $subject, $bodyHtml = NULL, $bodyText = NULL, $sender = NULL, $receiver = NULL) {
if (!isset($sender)) {
$sender = $from;
}
if (!isset($receiver)) {
$receiver = $to;
}
$mail = $this->_getNewMail();
$mail->setFrom($from, $sender);
$mail->addTo($to, $receiver);
$mail->setSubject($subject);
$mail->setBodyHtml($bodyHtml);
$mail->setBodyText($bodyText);
$mail->send();
}
/**
* Get a new mail object
* #return Zend_Mail
*/
protected function _getNewMail() {
return new Zend_Mail($this->_defaultCharset);
}
}
It works fine when it's about sending email to a Yahoo address but it fails when sending email to a GMail one. I plan to move to mail services like SendGrid in the future, but for test purpose using this configuration shouldn't be a problem. Is there a point I'm missing or has GMail becomed SPAM paranoiac ?

Related

Laravel 5.8 : manage failed mail notifications from a queue

I'm a little confused about the management of mail notifications failed from a queue.
I've created a mail notification class that I use to send a same notification to multiple users.
The process works well, but i'm trying to set up a management for the notifications that would fail (like sending a mail to the admin users to alert them about the failed notifications).
Here is the mail notification class :
class MyCustomMailNotification extends Notification implements
ShouldQueue {
use Queueable;
/**
* The number of times the job may be attempted.
*
* #var int
*/
public $tries = 3;
/**
* The number of seconds the job can run before timing out.
*
* #var int
*/
//public $timeout = 90;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('My Subject')
->greeting('My greeting')
->line('My mail body')
->salutation('My salutations');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
public function failed(Exception $e)
{
dd('Entered failed from MyCustomMailNotification : ' . $e));
}
}
I've set a listener "LogNotification" To reach the handle of notification event, with a specific instruction to generate a fail :
EventServiceProvider:
/**
* The event listener mappings for the application.
*
* #var array
*/
protected $listen = [
'Illuminate\Notifications\Events\NotificationSent' => [
'App\Listeners\LogNotification',
],
];
Listener:
namespace App\Listeners;
use Illuminate\Notifications\Events\NotificationSent; use
Illuminate\Queue\InteractsWithQueue; use
Illuminate\Contracts\Queue\ShouldQueue;
class LogNotification {
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param NotificationSent $event
* #return void
*/
public function handle(NotificationSent $event)
{
$result = 1/0;
}
}
The mailing is made in a controller like this:
$when = Carbon::now()->addSeconds(5);
foreach ($users as $user) {
$user->notify((new MyCustomMailNotification())->delay($when));
}
As in the failed function, I don't get any information of the notification that has failed, my question is:
How can I related a failure with the notification that has failed?
The goal is to be able to get the information of the user who has therefore not received his notification email.
Thanks for any help, idea or solution!
Well, that was so simple that I didn't see it...
As the failed function is inside the notification class, I can related to the notification simply with:
$this->id
And then of course get all the informations about the notification from model/table like user id (notifiable_id) and data field with custom informations.

Symfony 4 API Rest PUT : Map data to database entity

I'm a begginer in Symfony 4 and I'm developing an API Rest. I want to create a PUT resource that can handle many update cases.
In my case, I have a user with many properties but I will take an example with 3 properties to keep things simple :
User {
username,
email,
password
}
My PUT resource can be called in order to update Username, update Email or update Password. For example, to update Username, the user of my API will send a PUT request with only username :
{
username: "New username"
}
Same for email and password, he will only send the property he wants to change.
My problem is in my Controller, I have to do things like this :
/**
* #Rest\Put("/user/{id}")
* #param Request $request
* #return View
*/
public function putUserRequest(Request $request)
{
$userId = $request->get('id');
$user = $this->doctrine->getRepository(User::class)->findOneBy('id' => $userId);
$userFromRequest = $this->serializer->deserialize($request->getContent(), User::class, 'json');
if ($userFromRequest->getUsername() != NULL) {
$user->setUsername($userFromRequest->getUsername())
}
if ($userFromRequest->getEmail() != NULL) {
$user->setEmail($userFromRequest->getEmail())
}
if ($userFromRequest->getPassword() != NULL) {
$user->setPassword($userFromRequest->getPassword())
}
// ...
}
In my example I have only 3 properties, but imagine when I have 30 properties.
With Symfony 3 I used forms to validate / save my datas :
$form->submit($request->request->all(), $clearMissing);
Where $clearMissing is false to keep datas not provided by the user of my API. I can't find a way to do it with serializer but I guess I'm doing things wrong.
Thanks.
If I understand correctly, You can use the validator Component like this :
/**
* #Rest\Put("/user/{id}")
* #param Request $request
* #return View
*/
public function putUserRequest(User $user, Request $request, ValidatorInterface $validator)
{
$data = $request->getContent();
$this->serializer->deserialize($data, User::class, 'json', ['object_to_populate' => $user]);
//At this moment, the data you sent is merged with your user entity
/** #var ConstraintViolationList $errors */
$errors = $validator->validate($user, null ,['groups' => 'user_update']);
if (count($errors) > 0) {
//return json reponse with formated errors;
}
//if ok $entityManager->flush() and Response Json with serialization group;
...
}
In your user class :
class User implements UserInterface
{
/**
* #Assert\Email(groups={"user_create", "user_update"})
*/
private $email;
/**
* #Assert\NotBlank(groups={"user_create", "user_update"})
* #Assert\Length(min=7, groups={"user_create", "user_update"})
*/
private $password;
/**
* #Assert\Length(min=2, groups={"user_create", "user_update"} )
*/
private $username;
}
Related Validator component documentation : https://symfony.com/doc/current/validation/groups.html
You can also check this project : https://github.com/attineos/relation-deserializer

Spring JDBCTemplates: execute a query with Join

I'm developing an app for DB querying, using Spring Boot and JDBCTemplates.
The problem is this: if I have to ask the db on a single table, I have no problems. But, if I have a join, how can I perform this task?
More specifically, the SQL commands to create tables are these:
CREATE TABLE firewall_items
(
id INT NOT NULL AUTO_INCREMENT,
firewall_id INT NOT NULL,
date DATE,
src VARCHAR(15),
src_port INT,
dst VARCHAR(15),
dst_port INT,
protocol VARCHAR(4),
PRIMARY KEY(id)
);
CREATE TABLE firewalls (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
ip VARCHAR(15) NOT NULL,
info TEXT,
PRIMARY KEY(id)
);
The correspondings java class are these:
import java.util.Date;
public class FirewallItems
{
private Date date;
private String id;
private String protocol;
private String src;
private String dst;
private String src_port;
private String dst_port;
private String firewall_id;
public FirewallItems() {}
public FirewallItems(Date data, String identificativo, String protocollo, String sorgente, String destinazione,
String porta_sorgente, String porta_destinazione, String firewall_id)
{
super();
this.date = data;
this.id = identificativo;
this.protocol = protocollo;
this.src = sorgente;
this.dst = destinazione;
this.src_port = porta_sorgente;
this.dst_port = porta_destinazione;
this.firewall_id = firewall_id;
}
/**
* Return the date of the report
* #return date
*/
public Date getDate()
{
return date;
}
/**
* Set the date of the report
* #param date the report's date
*/
public void setDate(Date date)
{
this.date = date;
}
/**
* Return the id of the report
* #return id
*/
public String getId()
{
return id;
}
/**
* Set the id of the report
* #param id the report's id
*/
public void setId(String id)
{
this.id = id;
}
/**
* Return the protocol cecked by report
* #return protocol
*/
public String getProtocol()
{
return protocol;
}
/**
* Set the protocol cecked by report
* #param protocol
*/
public void setProtocol(String protocol)
{
this.protocol = protocol;
}
/**
* Return the source of firewall's drop
* #return Src
*/
public String getSrc()
{
return src;
}
/**
* Set the source of firewall's drop
* #param src the firewall's source drop
*/
public void setSrc(String src)
{
this.src = src;
}
/**
* Return the firewall's destionation drop
* #return dst
*/
public String getDst()
{
return dst;
}
/**
* Set the firewall's destination drop
* #param dst the firewall's destination drop
*/
public void setDst(String dst)
{
this.dst = dst;
}
/**
* Return the source's port
* #return src_port
*/
public String getSrc_port()
{
return src_port;
}
/**
* Set the source's port
* #param src_port the source's port
*/
public void setSrc_port(String src_port)
{
this.src_port = src_port;
}
/**
* Return the destination's port
* #return dst_port
*/
public String getDst_port()
{
return dst_port;
}
/**
* Set the destination's port
* #param dst_port the destination's port
*/
public void setDst_port(String dst_port)
{
this.dst_port = dst_port;
}
/**
* Return the id of firewall associated to report
* #return firewall_id
*/
public String getFirewall_id()
{
return firewall_id;
}
/**
* Set the id of firewall associated to report
* #param firewall_id the id of firewall associated to report
*/
public void setFirewall_id(String firewall_id)
{
this.firewall_id = firewall_id;
}
}
public class Firewall
{
private String id;
private String ip;
private String info;
private String name;
/**
* Empty constructor, which instantiates a Firewall specimen without setting default values
*/
public Firewall() {}
/**
* Constructor instantiating a Firewall specimen specifying its initial values
*
* #param id the firewall's id code
* #param ip the firewall's ip code
* #param info the info about firewall
* #param name firewall's name
*/
public Firewall(String id, String ip, String info, String nome)
{
super();
this.id = id;
this.ip = ip;
this.info = info;
this.name = nome;
}
/**
* Return the firewall's id
* #return id
*/
public String getId()
{
return id;
}
/**
* Set firewall's id
* #param id the firewall's id
*/
public void setId(String id)
{
this.id = id;
}
/**
* Return the firewall's ip
* #return ip
*/
public String getIp()
{
return ip;
}
/**
* Set firewall's ip
* #param ip the firewall's ip
*/
public void setIp(String ip)
{
this.ip = ip;
}
/**
* Return firewall's info
* #return info
*/
public String getInfo()
{
return info;
}
/**
* Set firewall's info
* #param info firewall's info fields
*/
public void setInfo(String info)
{
this.info = info;
}
/**
* Return firewall's name
* #return name
*/
public String getName()
{
return name;
}
/**
* Set firewall's name
* #param name firewall's name
*/
public void setName(String name)
{
this.name = name;
}
}
The constraint is that firewall_Items.firewall_id = firewall.id (so, these are the variables that i must use to perform join).
Now, if i want perform this query:
SELECT info, src
FROM firewalls, firewall_items
WHERE firewall_items.firewall_id = firewalls.id;
How my java code must be, using jdbctemplate?
Should i add to firewall class a collection to collect object of FirewallsItems, like an ArrayList?
Note1: i must use jdbctemplate project specifications. I can't use Hibernate or other instruments.
Note2: I know what rowmapper and resultset are, i regolary use them with query on a single table. What i nedd is to understand how to use them for a query with join, like that of the example.
Thanks a lot in advance for response!
you should use the JOIN keyword to join your tables before you query them.
Like so:
String query= "SELECT firewall_items.src, firewalls.info
FROM firewall_items
JOIN firewalls
ON firewall_items.firewalls_id = firewalls.id"
List<Item> items = jdbcTemplate.query(
query,
new MapSqlParameterSource(),
new FirewallInfoRowMapper()
);
Where Item is your retrieved object. You decide what that is.
Look at this article for more info
EDIT:
In response to your further inquiry. Above is the amended usage of jdbcTemplate, below you can find the classes you need. This requires you to have Spring.
I've assumed that if you're using jdbcTemplate you already have Spring.
Below is a cheat sheet, but please look at this site and learn more about querying databases with java Spring and jdbcTemplates.
The correct implementation for a row mapper is like so :
public class FirewallInfoRowMapper implements RowMapper<FirewallInfo>{
#Override
public FirewallInfo mapRow(ResultSet rs, int rowNum) throws SQLException{
return new FirewallInfo(rs.getString("src"), rs.getString("info"))
}
}
public class FirewallInfo{
private String src;
private String info;
public FirewallInfo(String src, String info){
this.src = src;
this.info = info;
}
{}<<< Getters and Setters Here
}
I know its late. There aren't a lot of good tutorial out there so incase someone else needs to know how to execute join query with spring and jdbc template. This is the way I did mine.
First ensure to import the following jars in your dao class like so
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
Then in your FirewallDao class, do something like
public List<Firewall> getData(){
return template.query("SELECT firewalls.info, firewall_items.src FROM firewalls INNER JOIN firewall_items ON firewall_items.firewall_id = firewalls.id",new RowMapper<Firewall>(){
public Firewall mapRow(ResultSet rs, int row) throws SQLException {
Firewall f =new Firewall();
f.setInfo(rs.getString(1));
f.setSrc(rs.getString(2));
return f;
}
});
}
In you controller, something like
#Autowired
FirewallDao dao;
#RequestMapping("/viewinfo")
public ModelAndView viewinfo(){
List<Firewall> list=dao.getData();
return new ModelAndView("viewinfo","list",list);
}
in ur view, do something like
<table border="2" width="70%" cellpadding="2">
<tr><th>Info</th><th>Src</th></th><th>Edit</th></tr>
<c:forEach var="f" items="${list}">
<tr>
<td>${f.info}</td>
<td>${f.src}</td>
</tr>
</c:forEach>
</table>

Laravel with Linkedin API error - ServiceFactory::createService() must be an instance of OAuth\Common\Storage\TokenStorageInterface

I'm using Laravel to develop my website, and I integrated the linkedin login to it, it works fine for like a few months. then suddenly, last week i received an error. I didn't change any code that has something to do with Linkedin API. I'm suspecting whether it has something to do with Linkedin itself.
here's what the error looks like:
If you are using this library to integrate Linkedin to your laravel project, there might be an issue right now with the update. you can simply fix the error in OAuth.php by replacing it with this code:
<?php namespace Artdarek\OAuth;
/**
* #author Dariusz Prząda <artdarek#gmail.com>
* #copyright Copyright (c) 2013
* #license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use \Config;
use \URL;
use \OAuth\ServiceFactory;
use \OAuth\Common\Consumer\Credentials;
class OAuth {
/**
* #var ServiceFactory
*/
private $_serviceFactory;
/**
* Storege name from config
*
* #var string
*/
private $_storage_name = 'Session';
/**
* Client ID from config
*
* #var string
*/
private $_client_id;
/**
* Client secret from config
*
* #var string
*/
private $_client_secret;
/**
* Scope from config
*
* #var array
*/
private $_scope = [];
/**
* Constructor
*
* #param ServiceFactory $serviceFactory - (Dependency injection) If not provided, a ServiceFactory instance will be constructed.
*/
public function __construct(ServiceFactory $serviceFactory = null)
{
if (null === $serviceFactory)
{
// Create the service factory
$serviceFactory = new ServiceFactory();
}
$this->_serviceFactory = $serviceFactory;
}
/**
* Detect config and set data from it
*
* #param string $service
*/
public function setConfig($service)
{
// if config/oauth-4-laravel.php exists use this one
if (Config::get('oauth-5-laravel.consumers') != null)
{
$this->_storage_name = Config::get('oauth-5-laravel.storage', 'Session');
$this->_client_id = Config::get("oauth-5-laravel.consumers.$service.client_id");
$this->_client_secret = Config::get("oauth-5-laravel.consumers.$service.client_secret");
$this->_scope = Config::get("oauth-5-laravel.consumers.$service.scope", []);
// esle try to find config in packages configs
}
else
{
$this->_storage_name = Config::get('oauth-5-laravel::storage', 'Session');
$this->_client_id = Config::get("oauth-5-laravel::consumers.$service.client_id");
$this->_client_secret = Config::get("oauth-5-laravel::consumers.$service.client_secret");
$this->_scope = Config::get("oauth-5-laravel::consumers.$service.scope", []);
}
}
/**
* Create storage instance
*
* #param string $storageName
*
* #return OAuth\Common\\Storage
*/
public function createStorageInstance($storageName)
{
$storageClass = "\\OAuth\\Common\\Storage\\$storageName";
$storage = new $storageClass();
return $storage;
}
/**
* Set the http client object
*
* #param string $httpClientName
*
* #return void
*/
public function setHttpClient($httpClientName)
{
$httpClientClass = "\\OAuth\\Common\\Http\\Client\\$httpClientName";
$this->_serviceFactory->setHttpClient(new $httpClientClass());
}
/**
* #param string $service
* #param string $url
* #param array $scope
*
* #return \OAuth\Common\Service\AbstractService
*/
public function consumer($service, $url = null, $scope = null)
{
// get config
$this->setConfig($service);
// get storage object
$storage = $this->createStorageInstance($this->_storage_name);
// create credentials object
$credentials = new Credentials(
$this->_client_id,
$this->_client_secret,
$url ? : URL::current()
);
// check if scopes were provided
if (is_null($scope))
{
// get scope from config (default to empty array)
$scope = $this->_scope;
}
// return the service consumer object
return $this->_serviceFactory->createService($service, $credentials, $storage, $scope);
}
}

SMS Integration with Magento API

I am using Magento 1.8.1 and I want to integrate SMS with our store.
I have an API URL of SMS but don't know how and where to put that URL in Magento.
They provide me this code:
<?php
class sendsms
{
private $api_url;
private $time;
private $unicode;
private $working_key;
private $start;
private $sender_id;
public $api;
public $wk;
public $sid;
public $to;
/**function to set the working key
*
* #param string_type $wk:helps to change the working_key
*/
function setWorkingKey($wk)
{
$this->working_key=$wk;
}
/**function to set sender id
*
* #param string_type $sid:helps to change sender_id
*/
function setSenderId($sid)
{
$this->sender_id=$sid;
}
/**function to set API url
*
* #param string_type $apiurl:it is used to set api url
*/
function setapiurl($apiurl)
{ $this->api=$apiurl;
$a=strtolower(substr($apiurl,0,7));
if ($a=="http://") //checking if already contains http://
{
$api_url=substr($apiurl,7,strlen($apiurl));
$this->api_url=$api_url;
$this->start="http://";
}
elseif ($a=="https:/") //checking if already contains htps://
{
$api_url=substr($apiurl,8,strlen($apiurl));
$this->api_url=$api_url;
$this->start="https://";
}
else {
$this->api_url=$apiurl;
$this->start="http://";
}
}
/** function to intialize constructor
*
* #param string_type $wk: it is working_key
* #param string_type $sd: it is sender_id
* #param string_type $apiurl: it is api_url
* used for intializing the parameter
*/
function __construct($apiurl,$wk,$sd)
{
$this->setWorkingKey($wk);
$this->setSenderId($sd);
$this->setapiurl($apiurl);
}
/**
* function to send sms
*
*/
function send_sms($to,$message,$dlr_url,$type="xml")
{
$this->process_sms($to,$message,$dlr_url,$type="xml",$time="null",$unicode="null");
}
/**
* function to schedule sms
*
*/
function schedule_sms($to,$message,$dlr_url,$type="xml",$time)
{
$this->process_sms($to,$message,$dlr_url,$type="xml",$time,$unicode='');
}
/**
* function to send unicode message
*/
function unicode_sms($to,$message,$dlr_url,$type="xml",$unicode)
{
$this->process_sms($to,$message,$dlr_url,$type="xml",$time='',$unicode);
}
/**
* function to send out sms
* #param string_type $to : is mobile number where message needs to be send
* #param string_type $message :it is message content
* #param string_type $dlr_url: it is used for delivering report to client
* #param string_type $type: type in which report is delivered
* #return output $this->api=$apiurl;
*/
function process_sms($to,$message,$dlr_url="",$type="xml",$time='',$unicode='')
{
$message=urlencode($message);
$this->to=$to;
$to=substr($to,-10) ;
$arrayto=array("9", "8" ,"7");
$to_check=substr($to,0,1);
if(in_array($to_check, $arrayto))
$this->to=$to;
else echo "invalid number";
if($time=='null')
$time='';
else
$time="&time=$time";
if($unicode=='null')
$unicode='';
else
$unicode="&unicode=$unicode";
$url="$this->start$this->api_url/web2sms.php?workingkey=$this->working_key&sender=$this->sender_id&to=$to&message=$message&type=$type&dlr_url=$dlr_url$time$unicode";
$this->execute($url);
}
/**
* function to check message delivery status
* string_type $mid : it is message id
*/
function messagedelivery_status($mid)
{
$url="$this->start$this->api_url/status.php?workingkey=$this->working_key&messageid=$mid";
$this->execute($url);
}
/**
* function to check group message delivery
* string_type $gid: it is group id
*/
function groupdelivery_status($gid)
{
$url="$this->start$this->api_url/groupstatus.php?workingkey=$this->working_key&messagegid=$gid";
$this->execute($url);
}
/**
* function to request to clent url
*/
function execute($url)
{
$ch=curl_init();
// curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output=curl_exec($ch);
curl_close($ch);
echo $output;
return $output;
}
}
I am new to Magento, so please help me with the API integration.
For SMS Integration you need to decide what event you want to handle.
Magento Events List are available here.
After it you need to create observer for choosen event.
An Observer is an event handler. It listens to any event it is attached to and accordingly reacts to the event.
Your SMS API should be usen in observer. ( It is method in PHP class. )
For creating observer in Magento you need to read this documentation.