Adding or updating a record in one function - cakephp

In this function I would like to see if a user with such email has already been registered, if so the fields have to be updated, if not a new user has to be created.
I have tried to implement it in the following way, but this just does not work.
public function facebook_add(){
if ($this->request->is('post')) {
$User_data = array('User'=>$this->request->data);
$this->User->email = $User_data['User']['email'];
if($this->User->exists()){
if($this->User->save($User_data)){
$message='1';
}else{
$errors = $this->User->invalidFields();
$user_error=array_shift(array_slice($errors, 0, 1));
$message= array_shift(array_slice($user_error, 0, 1));
}
}else{
if($this->User->save($User_data)){
$message='1';
}else{
$errors = $this->User->invalidFields();
$user_error=array_shift(array_slice($errors, 0, 1));
$message= array_shift(array_slice($user_error, 0, 1));
}
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
}
The problem is initiating a new user object if there was none user found. Any help to go around it is much appreciated.

As I said in the comments, when you need to create a new record, yout should call $this->User->create() before $this->User->save($User_data) so the data that you are saving is already initialized.

Related

Symfony - saving array to database

I wrote a function where I get array of marks that i need to post to my database..
My function stores it in a filed row like:
And I need to pull just one per column individually like:
Here is my api call..
public function generate(Map $seatMap)
{
$layout = $seatMap->getSeatLayout();
$seats = [];
$layoutArray = json_decode($layout, true);
$columns = range('A', 'Z');
foreach($layoutArray as $index => $result)
{
$columnLetter = $columns[$index];
$letters = str_split($result);
$letterIndex = 1;
foreach($letters as $letterIndex => $letter) {
switch($letter) {
case 'e':
$seats[] = $columnLetter . $letterIndex;
$letterIndex++;
}
}
}
foreach($seats as $seat => $result) {
$result = new Seat();
$result->setName(json_encode($seats));
$this->em->persist($result);
$this->em->flush();
}
}
Any suggestions?
I think that problem is in the part where I need to store it to database..
If I understand you correctly, your issue is here:
foreach($seats as $seat => $result) {
$result = new Seat();
$result->setName(json_encode($seats));
$this->em->persist($result);
$this->em->flush();
}
}
You're indeed creating new Seat instance for every seat, but in this line:
$result->setName(json_encode($seats));
you still assign all (encoded) seats to every instance of Seat. What you want is to assign only the seat from current loop iteration, which is represented by $result variable.
So try with:
$result->setName($result);
You do not need json_encode here too.
If your array is like you say it it then try this
foreach($seats as $seat) {
$result = new Seat();
$result->setName($seat);
$this->em->persist($result);
$this->em->flush();
}

CakePHP 3 : display data from other model and pass parameter in url from action

I'm working on a project using CakePHP 3.x.
I have UserAddress, ServiceRequests, Service models.
There is a button on service/view/$id which when clicked will ask user to select address from service-requests/serviceArea which has a list of addresses added by user. service-requests/serviceArea view will contain a select button which when clicked will call add action in ServiceRequests controller with passing two parameters serviceId and userAddressId
This is the serviceArea function created by me.
public function serviceArea($id = null)
{
public $uses = array('UserAddress');
$service = $id;
$query = $userAddresses->find('all')
->where(['UserAddresses.user_id =' => $this->Auth->user('id')]);
$this->set(compact('userAddresses'));
$this->set('_serialize', ['userAddresses']);
}
How to display the address and also pass the $service parameter to the serviceArea view.
I am new to CakePHP, so if you think question is incomplete any edit to it will be appreciated instead of down-voting.
Thank You.
Edit 2
Thank for your answer #jazzcat
After changing my code according to yours and visiting http://domain.com/service-requests/service-area/$id. It is showing error as
Record not found in table "service_requests"
and pointing to the ServiceRequestsController on line no 33
The ServiceRequestController as containing line no 33 is
<?php
namespace App\Controller;
use App\Controller\AppController;
/**
* ServiceRequests Controller
*
* #property \App\Model\Table\ServiceRequestsTable $ServiceRequests
*/
class ServiceRequestsController extends AppController
{
/**
* isAuthorized method
*
*/
public function isAuthorized($user)
{
$action = $this->request->params['action'];
// The add and index actions are always allowed.
if(in_array($action, ['index', 'add', 'serviceRequests'])) {
return true;
}
// All other actions require an id.
if (empty($this->request->params['pass'][0])) {
return false;
}
// Check that the service request belongs to the current user.
$id = $this->request->params['pass'][0];
$serviceRequest = $this->ServiceRequests->get($id); // line : 33
if($serviceRequest->user_id == $user['id']) {
return true;
}
return parent::isAuthorized($user);
}
/* Other actions */
}
?>
This worked for me.
Just added the serviceArea action name in the isAuthorized method
if(in_array($action, ['index', 'add', 'serviceArea'])) {
return true;
}
and it's working fine as expected.
There is alot wrong with your code. Please read the docs
Is the table named user_addresses or user_address ?
You seem to mix the both.
The following would be the correct way to do it assuming your table is named user_addresses
public function serviceArea($id = null)
{
$this->loadModel('UserAddresses');
$userAddresses = $this->UserAddresses->find('all')
->where(['UserAddresses.user_id =' => $this->Auth->user('id')]);
// If you want to filter on the serviceArea ID aswell
if($id)
$userAddresses->andWhere(['id' => $id]);
// Setting SerivceArea ID to compact makes it available in view.
$serviceAreaId = $id;
$this->set(compact('userAddresses', 'serviceAreaId'));
$this->set('_serialize', ['userAddresses']);
}
This snippet:
$id = $this->request->params['pass'][0];
$serviceRequest = $this->ServiceRequests->get($id); // line : 33
Just checks if the first parameter passed to the method exists in ServiceRequests.
(That parameter could be anything, you have to keep that in mind when creating all your methods in that controller, that is to say the least.. bad)
I'm assuming that the service_requests table is associated with the users table and an user_id column exists in the service_requests table.
If that is the case this should work:
public function isAuthorized($user)
{
$action = $this->request->params['action'];
// The add and index actions are always allowed.
if(in_array($action, ['index', 'add'])) {
return true;
}
// Is not authorized if an argument is not passed to the method.
// Don't know why you'd want this , but sure.
if (empty($this->request->params['pass'][0])) {
return false;
}
// Check that the service request belongs to the current user.
$user_id = $this->Auth->user('id');
$serviceRequest = $this->ServiceRequests->find()->where(['ServiceRequests.user_id' => $user_id])->first();
if(!empty($serviceRequest)) {
return true;
}
return parent::isAuthorized($user);
}

cakephp 3 controller action -> how to make it smart

I implementet a controller action in the maybe most unelegant way. How could this made better? Table classes are just like after bin/cake bake. I think the part where the Entity is created could be simplyfied very much.
What I'm doing:
Books --belongsTo--> Publishers <--habtm--> Publishernumbers
When adding a Book to the database, the publishernumber is extracted from the ISBN number. This number is then linked to the publisher in a habtm relation. I need this to suggest the user some publishers when typing an isbn in the form.
The code works for now, but in a year, only god will know what I did here. The first part is straightforward.
public function add()
{
$book = $this->Books->newEntity();
$associations = ['associated' =>
[
'Tags',
'Publishers',
'Publishers.Publishernumbers'
]
];
if ($this->request->is('post')) {
$data= $this->request->data;
$publisher = $this->Books->Publishers->get(
$this->request->data['publisher_id'],
['contain' => ['Publishernumbers']]
);
unset($data['publisher_id']);
$book->publisher = $publisher;
//extract group- and publishernumber from the ISBN
$this->loadComponent('Isbn.Isbn');
$split = $this->Isbn->splitIsbn($this->request->data['isbn']);
$publishernumber = $split[1].$split[2];
This is the part where the mess begins. I think this could be done way more elegant.
//check if the publisher contains already the $publishernumber
//and if not, add it to the entity
$new = true;
foreach ($book->publisher->publishernumbers as $n){
if ($n->number == $publishernumber){
$new = false;
}
}
if ($new){
$existingNumber = $this->Books->Publishers->Publishernumbers
->findByNumber($publishernumber)
->first();
if (!$existingNumber){
//publishernumber does not exist in the database
$pubnumber = $this->Books->Publishers->Publishernumbers
->newEntity();
$pubnumber = $this->Books->Publishers->Publishernumbers
->patchEntity($pubnumber, ['number' => $publishernumber]);
$book->publisher->publishernumbers[] = $pubnumber;
} else {
//publishernumber exists in the database
//but is not associated with the publisher
$book->publisher->publishernumbers[] = $existingNumber;
}
$book->publisher->dirty('publishernumbers', true);
}
$book = $this->Books->patchEntity($book, $data, $associations);
Saving
if ($this->Books->save($book, $associations)){
Cache::delete('exlibrisBooksIndex');
$this->Flash->success(__('The book has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('Error.'));
}
}
$publishers = $this->Books->Publishers->find('list')
->order('name')
->toArray();
$this->set(compact('book', 'publishers'));
$this->set('_serialize', ['book']);
}

Add wordpress custom post type data to an external db

This function adds custom post 'event' data into a Salesforce db. I've tested the function outside of Wordpress and it works flawlessly. When I test it inside Wordpress by adding a new event, no error is generated and a the data is not inserted into the SF db. I've also tested this by printing out the $_POST and saw that the data is being collected. How can I get this display some errors so that I can trouble shoot this?
function add_campaign_to_SF( $post_id) {
global $SF_USERNAME;
global $SF_PASSWORD;
if ('event' == $_POST['post-type']) {
try {
$mySforceConnection = new SforceEnterpriseClient();
$mySoapClient = $mySforceConnection->createConnection(CD_PLUGIN_PATH . 'Toolkit/soapclient/enterprise.wsdl.xml');
$mySFlogin = $mySforceConnection->login($SF_USERNAME, $SF_PASSWORD);
$sObject = new stdclass();
$sObject->Name = get_the_title( $post_id );
$sObject->StartDate = date("Y-m-d", strtotime($_POST["events_startdate"]));
$sObject->EndDate = date("Y-m-d", strtotime($_POST["events_enddate"]));
$sObject->IsActive = '1';
$createResponse = $mySforceConnection->create(array($sObject), 'Campaign');
$ids = array();
foreach ($createResponse as $createResult) {
error_log($createResult);
array_push($ids, $createResult->id);
}
} catch (Exception $e) {
error_log($mySforceConnection->getLastRequest());
error_log($e->faultstring);
die;
}
}
}
add_action( 'save_post', 'add_campaign_to_SF');
I would use get_post_type() to check for "event" posts. Use error_log() to write to the PHP error log for additional debugging - check the status of your Salesforce login, etc.
Keep in mind that save_post will run every time a post is saved - created or updated - so you might want to do some additional checking (like setting a meta value) before creating a new Campaign in Salesforce, otherwise you will end up with duplicates.
function add_campaign_to_SF( $post_id ) {
$debug = true;
if ($debug) error_log("Running save_post function add_campaign_to_SF( $post_id )");
if ( 'event' == get_post_type( $post_id ) ){
if ($debug) error_log("The post type is 'event'");
if ( false === get_post_meta( $post_id, 'sfdc_id', true ) ){
if ($debug) error_log("There is no meta value for 'sfdc_id'");
// add to Salesforce, get back the ID of the new Campaign object
if ($debug) error_log("The new object ID is $sfdc_id");
update_post_meta( $post_id, 'sfdc_id', $sfdc_id );
}
}
}
add_action( 'save_post', 'add_campaign_to_SF' );

Refresh the view after I submitted POST params on deleting a record

My question is how can I refresh my view "search.ctp" to take into account the record I just deleted. The problem is the following.
My controller code
public function search() {
if ($this->request->is('post')) {
$this->set("isPost", TRUE);
$query = $this->data;
$output = $this->Question->find("all", array("conditions"=>array("Question.lectureId"=>$query["Lecture"]["Lecture"],
"Question.type"=>$query["Lecture"]["status"])));
$this->set("questions", $output);
} else {
$this->LoadModel("Lecture");
$outputL = array();
$for = $this->Lecture->find("all", array("fields" => array("_id", "title")));
foreach ($for as $key => $value) {
$outputL[$value["Lecture"]["_id"]] = $value["Lecture"]["title"];
}
$this->set("lectures",$outputL);
//
$statuses = array(
"" => "Select a question type",
"anonymousQuestion" => "anonymousQuestion",
"handUp" => "handUp",
"userQuestion" => "userQuestion"
);
$this->set("statuses", $statuses);
}
}
So the following happens;
I open the view "search.ctp" ("my admin interface"), set the 2 search params,
and use the submit button to post that data. Then my IF statement recognizes that as POSt and gives me back my query results. The problem is when i delete a record...
It redirects me back to my search action to enter the query params again... How do i just refresh the page with the same query params and NOT leave my view.
o forgot my delete function code:
public function delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Question->id = $id;
if (!$this->Question->exists()) {
throw new NotFoundException(__('Invalid configuration'));
}
if ($this->Question->delete()) {
$this->Session->setFlash(__('Question deleted'));
return $this->redirect(array("action"=>"search"));
}
$this->Session->setFlash(__('Question was not deleted'));
$this->redirect(array('action' => 'search'));
}
As a workaround i made another function that does the same thing with GET request that my search function does with a POST request. Basically returns the data with the query params. And i used the Session helper to carry the query over to my other function. Dont know how smart that was, but it does the trick for me...
Still would be nice to know if someone has a solution where i dont have to make another function/view

Resources