Catch db error with Doctrine\DBAL\Exception - database

I want to catch any error (ie: foreign key error) from an insert statement or any other. How can I achive that with use Doctrine\DBAL\Exception?
I have this when I do the insert:
$db->beginTransaction();
try {
$db->insert('bbc5.produccionpry',$datos);
$datos['propryid'] = $db->lastInsertId();
$db->commit();
// $db = null;
$resp[] = $datos;
} catch (Exception $e) {
$error = array_merge($error, array('error' => $e->errorInfo()));
$db->rollback();
throw $e;
}
But, that doesn't prevent the concrete5 to return a website telling about the error, so, I don't want that website to be shown, I want to catch the error in an array() in order to return it via echo json_encode($error)
I'm not using the controller for a page, I'm using it for managing RESTful calls from my JavaScript App with this code:
return fetch(`/scamp/index.php/batchprodpry/${maq}`, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(this.state.a)
})
I'm using ReactJS
Thank you

Don't throw the exception.
Instead of throwing the exception, just get the exceptions message $e->getMessage() from the DBALException $e object and encode it as a JSON string. Important: Put an exit; after the echo to assure that no further code is executed.
use Doctrine\DBAL\DBALException;
try {
$db->insert('bbc5.produccionpry',$datos);
$datos['propryid'] = $db->lastInsertId();
$db->commit();
$resp[] = $datos;
}
catch(DBALException $e){
$db->rollback();
echo \Core::make('helper/json')->encode($e->getMessage());
exit;
}
If this code is inside a page controller you could do this:
try {
$db->insert('bbc5.produccionpry',$datos);
$datos['propryid'] = $db->lastInsertId();
$db->commit();
$resp[] = $datos;
}
catch(DBALException $e){
$this->error->add($e->getMessage());
}
if($this->error->has()) {
// All variables that have been set in the view() method will be set again.
// That is why we call the view method again
$this->view();
return;
}
And concrete5 will take care of displaying an appropriate error message.
Or you could save the $e->getMesssage() in the session and call it inside the view:
$session = \Core::make('session');
// ...
catch(Exception $e){
$session->set('error', $e->getMessage());
}
And in the view:
// html
<?php
$session = \Core::make('session');
if($session->has('error')) {
$m = $session->get('error');
?>
<div id="session_error" class="alert alert-danger">
×
<div id="session_error_msg">
<?php print $m ?>
</div>
</div>
<?php
}
$session->remove('error');
?>
//html

Since you have throw $e in your catch block you throw this exception further which means that it is (probably) handled by global exception listener. Once you throw exception you exit your code immediately, so a solution for you is just remove throw $e line and you should be good

Related

Unexpected end of input error in react native

I get an error prompt SyntaxError: Unexpected end of input when I try to the message from API.
Here is my code:
.then((response) =>response.json())
.then((response)=>{
alert(response[0].Message);
})
.catch((error) => {
alert("Error"+error);
});
If I change to the code below, it runs well with no errors, but it will not prompt any successful message.
try{
((response) =>response.json()),
((response)=>{
alert(response[0].Message);
})
}
catch{
((error) => {
alert("Error"+error);
})
}
Here is the api script:
<?php
$CN = mysqli_connect('localhost', 'root', '');
$DB = mysqli_select_db($CN, 'iostest');
$EncodedData = file_get_contents('php://input');
$DecodedData = json_decode($EncodedData, true);
$userid = $DecodedData['userid'];
$jid=$DecodedData['jid'];
$job=$DecodedData['job'];
$mcode=$DecodedData['mcode'];
$insertuserid = "insert into scan(user,job,jobid,machinecode) values ('$userid','$job','$jid','$mcode')";
$register = mysqli_query($CN, $insertuserid);
if ($register)
$Message = "Member has been registered successfully";
else
$Message = "Server Error... please try latter";
$Response[] = array("Message" => $Message);
echo json_encode($Response);
?>

Session issues in cakephp 2.x with facebook sdk in production

I am trying to use Facebook PHP sdk with cakephp 2.x for login purpose.
And it is working with debug mode 1 or 2 but it is not working with debug mode 0.
It seems session is not working properly in production.
I search about it on the web many times but not get the right solution for me.
I read these two threads in detail but did not cope with the problem.
https://github.com/facebook/php-graph-sdk/issues/473
How do I integrate Facebook SDK login with cakephp 2.x?
I use these two functions in AppController for login.
public function beforeFilter()
{
$this->disableCache();
$this->Facebook = new Facebook(array(
'app_id' => 'appId',
'app_secret' => 'appSecret',
'default_graph_version' => 'v2.7',
));
$this->Auth->allow(['.....']);
}
public function login()
{
if (!session_id()) {
session_start();
}
$this->loadModel("User");
$user_id = $this->Session->read('Auth.User.id');
$fb = $this->Facebook->getRedirectLoginHelper();
$permissions = ['email']; // Optional permissions
$callback_url = HTTP_ROOT . 'login';
$fb_login_url = $fb->getLoginUrl($callback_url, $permissions);
$this->set('fb_login_url', $fb_login_url);
if (!empty($user_id)) {
//redirect to profile page if already logged in
$this->redirect(... . );
}
//local login request
if ($this->request->is('post')) {
......
}
// when facebook login is used
elseif ($this->request->query('code')) {
try {
$accessToken = $fb->getAccessToken();
} catch (\Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
$this->Session->setFlash('Graph returned an error: ' . $e->getMessage(), 'error');
$this->redirect($this->referer());
} catch (\Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
$this->Session->setFlash('Facebook SDK returned an error: ' . $e->getMessage(), 'error');
$this->redirect($this->referer());
}
if (!isset($accessToken)) {
if ($fb->getError()) {
header('HTTP/1.0 401 Unauthorized');
$this->Session->setFlash("Error: " . $fb->getError() . "\n", 'error');
$this->Session->setFlash("Error Code: " . $fb->getErrorCode() . "\n", 'error');
$this->Session->setFlash("Error Reason: " . $fb->getErrorReason() . "\n", 'error');
$this->Session->setFlash("Error Description: " . $fb->getErrorDescription() . "\n", 'error');
$this->redirect($this->referer());
} else {
header('HTTP/1.0 400 Bad Request');
$this->Session->setFlash('Bad request', 'error');
$this->redirect($this->referer());
}
}
// Logged in
$oAuth2Client = $this->Facebook->getOAuth2Client();
$tokenMetadata = $oAuth2Client->debugToken($accessToken);
$tokenMetadata->validateAppId('1200125790051089'); // Replace {app-id} with your app id
$tokenMetadata->validateExpiration();
if (!$accessToken->isLongLived()) {
try {
$accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
} catch (\Facebook\Exceptions\FacebookSDKException $e) {
$this->Session->setFlash('Error getting long-lived access token: ' . $helper->getMessage() . "</p>\n\n", 'error');
$this->redirect($this->referer());
}
}
$_SESSION['fb_access_token'] = (string) $accessToken;
$fb_access_token = (string) $accessToken;
if (isset($accessToken)) {
try {
// Returns a `Facebook\FacebookResponse` object
$response = $this->Facebook->get('/me?fields=id,first_name,last_name,email', $accessToken);
} catch (\Facebook\Exceptions\FacebookResponseException $e) {
$this->Session->setFlash('Graph returned an error: ' . $e->getMessage(), 'error');
$this->redirect($this->referer());
} catch (\Facebook\Exceptions\FacebookSDKException $e) {
$this->Session->setFlash('Facebook SDK returned an error: ' . $e->getMessage(), 'error');
$this->redirect($this->referer());
}
$fb_user = $response->getGraphUser();
// We will varify if a local user exists first
$local_user = $this->User->find('first', array(
'conditions' => array('facebook_id' => $fb_user['id']),
));
// If exists, we will log them in
if ($local_user) {
$this->Auth->login($local_user['User']);
} else {
// we will create new user with facebook_id and log them in
$data['User'] = array(.........);
// You should change this part to include data validation
$new_user = $this->User->save($data);
$this->Auth->login($new_user['User']);
}
// redirect to profile page here
}
}
}
I've had some issues with the SDK and CakePHP 2.x as well. I wrote a small handler that lets the SDK make use of CakeSession.
You can find it here:
https://github.com/WrDX/FacebookCakeSessionPersistentDataHandler

how to send emails with PHPmailer from WordPress Rest API end point

function my_send_email($name,$email, $current_user, $status, $subject, $Message) {
//most of the code here is from https://github.com/PHPMailer/PHPMailer/tree/master/examples
require_once ABSPATH . WPINC . '/class-phpmailer.php';
require_once ABSPATH . WPINC . '/class-smtp.php';
// build message body`enter code here`
$body = '
<html>
<body>
<h1>My Email</h1>
</body>
</html>
';
try {
//Create a new PHPMailer instance
$mail = new PHPMailer;
//Tell PHPMailer to use SMTP
$mail->isSMTP();
//Enable SMTP debugging
$mail->SMTPDebug = 2;
//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';
//Set the hostname of the mail server
$mail->Host = "mail.example.com";
//Set the SMTP port number - likely to be 25, 465 or 587
$mail->Port = 25;
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Username to use for SMTP authentication
$mail->Username = "contact#example.com";
//Password to use for SMTP authentication
$mail->Password = "1234";
//Set who the message is to be sent from
$mail->setFrom('contact#example.com', 'sender_name');
//Set an alternative reply-to address
$mail->addReplyTo('alternative_contact#example.com', 'alternative_contact_name');
//Set who the message is to be sent to
$mail->addAddress($email, $name);
//Set the subject line
$mail->Subject = 'PHPMailer SMTP test';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
//$mail->msgHTML(file_get_contents(dirname(__FILE__) .'/contents.html'));
$mail->MsgHTML($body);
//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';
$success=$mail->send();
//send the message, check for errors
if ($success) {
return array('mailError' => false, 'message' => 'email sent! ' . $mail->ErrorInfo , 'body'=>$body);
} else {
return array('mailError' => true, 'message' => 'email error! ' . $mail->ErrorInfo , 'body'=>$body);
}
} catch (phpmailerException $e) {
return array('mailError' => false, 'message' => 'email error! ' . $e->errorMessage() , 'body'=>$body); //Pretty error messages from PHPMailer
} catch (Exception $e) {
return array('mailError' => false, 'message' => 'email error! ' . $e->getMessage() , 'body'=>$body); //Boring error messages from anything else!
}
}
function my_register_endpoints(){
register_rest_route(
'my_namespace/v1',
'/abc/',
array(
'methods' => 'POST',
'callback' => 'my_end_point',
'args' => array(
.....
),
'permission_callback' => function (WP_REST_Request $request) {
if(!is_user_logged_in()){
.....
}
return true;
}
)
);
}
add_action('rest_api_init','my_register_endpoints');
//endpoint
function my_end_point(WP_REST_Request $request){
global $current_user;
$sender = wp_get_current_user();
$shortMsg=$request['shortMessage'];
$subject="Some text";
$email_resualt=my_send_email("reciver_name","reciver_email",$sender,$status,$subject,$shortMsg);
if($email_resualt['mailError']==false){
process.. $itemes, $item ..
$message='email sent!';
return array('message' => $message,'items' => $items, 'item'=>$item);
} else {
return new WP_Error('email error',__('some message','email-error'),$request['id']);
}
}
I am using angularJS $http.post to call the API end point, The emails are sent and I can see them on my inbox, but for some reason I am getting back undefined response:
Related errors on Chrome console:
1) SyntaxError: Unexpected token S in JSON at position 0
2) TypeError: Cannot read property 'message' of undefined
I use response.message in my client side code but as I stated above but as the response is empty I am getting errors.
I have other end points in my WordPress PHP code that looks the same but doesn't include send emails with PHPmailer and works fine. and even this end point without the send email functionality was also working fine.
I tried to debug it for two days but still I am not sure where the issue in my code?
I found what the issue was, In my send email function I had the lines:
//Enable SMTP debugging
$mail->SMTPDebug = 2;
$mail->Debugoutput = 'html';
And appears that because debugging was turned on the response from my end point was to match for angular to handle after I commented these two lines the response was well structured for for angular to be able to parse it.
The hint to solve it was in the following post Syntax error: Unexpected number at Object.parse, PHP to AngularJS

How to pass data into a Listener when using Guzzle?

I am using Guzzle 3.8.1 with CakePHP 2.5.6 and I am making a call to the Box API. I would like to be able to refresh my access token when it expires. The issue I am encountering is that I may be using any one of N possible access tokens and I want to be able to use the $account_id that is in scope for the function I am defining this in. I don't see how I can pass it into the Listener defined function, since I am not calling that myself. I do see that the expired access_token exists in the $event variable, but I would have to locate it and then parse it from the header that I am passing to Box. I think I could add a custom header containing the account_id, but that seems like a bad way to approach the problem. Can I somehow specify a variable in the request that wouldn't be added as part of the call to Box? Any suggestions are much appreciated, thanks!
`
public function get_folder_list ($account_id = null, $parent_folder_id = null) {
// Get account
$this->Account = ClassRegistry::init('Account');
$account = $this->Account->findById($account_id);
$this->Account->log($account);
// If account doesn't exist, throw error
if(empty($account)) {
throw new NotFoundException(__('Account id not found: ' . $account_id));
}
// Call Box for folder list
$box_url = "https://api.box.com/2.0/folders/";
if (empty($parent_folder_id)) {
$box_url .= "0";
} else {
$box_url .= $parent_folder_id;
}
$this->Account->log($box_url);
$bearer = 'Bearer ' . $account['Account']['access_token'];
$client = new Guzzle\Http\Client();
$client->getEventDispatcher()->addListener('request.error', function(Event $event) {
if ($event['response']->getStatusCode() == 401) {
$Account = new Account;
$Account->log($event);
$Box = new BoxLib;
$account = $Box->refresh_token($account_id);
$bearer = 'Bearer ' . $account['Account']['access_token'];
$request = $client->get($box_url, array('Authorization' => $bearer));
$event['response'] = $newResponse;
$event->stopPropagation();
}
});
$request = $client->get($box_url, array('Authorization' => $bearer));
try {
$response = $request->send();
} catch (Guzzle\Http\Exception\BadResponseException $e) {
// HTTP codes 4xx and 5xx throw BadResponseException
$this->Account->log('Service exception!');
$this->Account->log('Uh oh! ' . $e->getMessage());
$this->Account->log('HTTP request URL: ' . $e->getRequest()->getUrl() . "\n");
$this->Account->log('HTTP request: ' . $e->getRequest() . "\n");
$this->Account->log('HTTP response status: ' . $e->getResponse()->getStatusCode() . "\n");
$this->Account->log('HTTP response: ' . $e->getResponse() . "\n");
}
$this->Account->log($response->json());
$json = $response->json();
$folder_list = array();
foreach ($json['item_collection']['entries'] as $folder) {
$folder_list[$folder['id']] = $folder['name'];
}
//$this->Account->log($folder_list);
return $folder_list;
}
`

Access database from ACL plugin

I want to load resources from database inside the ACL plugin
I make like this
class My_ACL extends Zend_Acl {
protected $_role_id;
protected $_userResource;
public function __construct() {
try {
$db = Zend_Db_Table::getDefaultAdapter();
$stmt = $db->query("CALL getUserPrivileges(?)", 998877445);
//Returns an array containing all of the result set rows
$rows = $stmt->fetchAll();
$stmt->closeCursor();
print_r($rows);
return $rows;
} catch (Exception $e) {
echo 'error ' . $e;
}
}
but this doesn't work since white page is rendered and nothing is print out!
I found the problem. The problem was calling default data adapter before initializing the default adapter, the trick was I have to get the data adapter inside the bootstrap and pass it to the plugin, so I make like this
in bootstrap file
protected function _initPlugins() {
$this->bootstrap('db');
$db = $this->getResource('db');
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_Acl($db));
}
and in the Application_Plugin_Acl, I make like this
class Application_Plugin_Acl extends Zend_Controller_Plugin_Abstract {
public function __construct($db) {
$this->_acl = new My_ACL($db);
}
}
and here's my_ACL
class My_ACL extends Zend_Acl {
public function __construct($db) {
try {
$stmt = $db->query("CALL getUserPrivileges(?)", 998877445);
//Returns an array containing all of the result set rows
$rows = $stmt->fetchAll();
$stmt->closeCursor();
print_r($rows);
return $rows;
} catch (Exception $e) {
echo 'error ' . $e;
}
}

Resources