Have CakePHP saveAll function to ignore errors and continue - php

Trying to make it simple, I have an excel spreadsheet of people and their emails. What I want is to use saveAll to insert them all at once in the database.
Problem is that I need to re-upload the spreadsheet everytime it has some new people in it. In that case, I need saveAll to save all the new people and ignore the validation errors that will happen due to the old people already existing in the database (people emails have unique rule). Any ideas?
EDIT: What I have now is that, when the saveAll method tries to save a record that already exists (i.e. whose email is already in the database) it doesn't save anything. What I need is to save the new ones that come from the spreadsheet, and ignore the ones that already exist (i.e. not save the ones that already exist).

Set the second parameter to false so that validation is not checked.
Given your requirements, I would do this:
Loop through the data and check if that particular record exist, if it doesn't then push it to a temp array.
Now you can use that temp array as a parameter for your saveAll call.
The pseudo code would be something like this:
foreach ($originalDataToBeSaved as $something) {
if ($this->find('count', array('conditions' => $yourConditions)) == 0) {
$tempArray[] = $something;
}
}
$this->saveAll($tempArray);
Edit: I updated the code to reflect what Nunser said, new data doesn't have ID thus we need to do our search using another search criteria.

try this
foreach ($originalDataToBeSaved as $key => $something) {
if ($this->hasAny($your_condition_to_chekc_existing_user) {
unset($originalDataToBeSaved[$key]);
}
}
$this->saveAll(($originalDataToBeSaved);
if you dont want to validate then use -
$this->saveAll(($originalDataToBeSaved, array('validate' => false));

Related

WordPress Wedding RSVP using Gravity Forms

I am building my wedding website and want to integrate an RSVP form using Gravity Forms. The issue I am running into is how to set certain guest that have +1's. I would like to show an additional guest entry (First Name, Last Name, Meal Option) when the initial First Name and Last Name has been populated. How would I go about doing this? Any help would be great! Thanks in advance!
Here is how I'd solve this problem:
First, you need to put everything in the DB, the easiest way would be to either do it manually or somehow loop through an array/CSV calling add_option($key, $value) Again, I would recommend a mobile/phone number as they'll be unique so you don't pull the wrong "John Smith". I'll assume you'll keep it basic with $key as the unique identifier and $value as boolean as to whether to show additional info. Interestingly, by default, if not found get_option($key) will return false and therefore not show your additional data, which I would assume you'd want anyway. If you'd rather it return true just pass true as the second argument.
Now for your answer:
Your URL is something like https://somesite.com/rsvp?id=1234.
function allowed_plus_one() {
$id = $_GET["id"];
$allowed = get_option($id);
return $allowed;
}
Then assumedly it'll be something like
if (allowed_plus_one()) {
// show form with plus one
} else {
// show form without
}
EDIT:
Keeping separate incase this has already been viewed.
You should also be checking for the existence of $_GET["id"] and behaving accordingly. eg:
if (isset($_GET["id"] && !empty($_GET["id"]) {
//do logic above
} else {
//here by mistake so don't show any form?
}

CodeIgniter flash data working locally but not on server

Hello CodeIgniter users.
I have a problem with flash data and I would like some help. My CI version is 2.1.4.
I am using CI flash data to store data temporarily for a form that consists of multiple pages. Data entered on each page is stored so it can be accessed on the next pages and finally all data is entered int the database.
Now to keep data stored through multiple pages, instead of only one, I extended the Session class with the following function:
function keep_all_flashdata($prefix = '')
{
$userdata = $this->all_userdata();
foreach ($userdata as $key => $value)
{
if (strpos($key, ':old:' . $prefix))
{
$new_flashdata_key = str_replace(':old:', ':new:', $key);
$this->set_userdata($new_flashdata_key, $value);
}
}
}
This function preserves all flash data (or optionally only flash data that starts with a certain string) for another redirect. It is similar to the keep_flashdata function except for the fact that it works for multiple items without requiring their exact name.
After calling this function, both :old: and :new: keys are stored in the session data. Then after a redirect, old keys are removed and new keys are set to old. Then, if there's another page, I call keep_all_flashdata() again and so on until the last page.
This works fine when I'm working on my local WAMP server, but on my actual server, all flashdata just gets removed after a redirect, even if it has :new: in the key. I confirmed my keep_all_flashdata() function works by checking the contents of session->all_userdata() and everything looks as expected.
I am using some AJAX calls, but they should not erase flash data (a known issue) as I've prevented this with $this->CI->input->is_ajax_request() before flashdata is cleared (in the sess_update() and _flashdata_sweep() functions).
Is this a bug in CodeIgniter or am I doing something wrong? Any help is appreciated.
I think your if statement is causing the problem. I'm assuming that ":old:" or ":new:" is used as prefix for every key you store in a session?
strpos() returns the position of where the needle exists so that would be 0 when checking a key with the prefix ':old:'. That's intended as old flashdata needs to be removed. I tested the following piece of code:
$flashDataKey = ':new:myKey';
die(var_dump(strpos($flashDataKey, ':old:')));
Which returns false as expected since the needle was not found. Resulting in not storing the flashdata as ':old:' and keeping it for the next request.
I'm not sure why this is working on your localhost. You should change your if statement to:
if( strstr($key, ':new:') !== false)
Now only keys containing the string ':new:' will pass and everything else will return false. Hope this helped!

Assign variable to an array from Active Directory

I am having trouble figuring out how to correct an issue I am having with the following code. I am trying to list the names and emails of all the people in my Active Directory. This code works. However, I also get the following warning when it is executed.
Warning: Cannot use a scalar value as an array.
From what I have read online I need to set " $name['mail']['0'] = "Not Found";" to an array. My question is how would I go about doing this. I have tried every way I could think of with no success. If anyone could provide me with some feedback it would be greatly appreciated.
foreach ($results as $name) {
if (!isset($name['mail']['0'])){
$name['mail']['0'] = "Not Found";
}
$allnames[$name['cn']['0']]['mail'] = $name['mail']['0'];
It looks like you are trying to assign the "Not Found" value BACK into the results of the ldap query you are running.
When I wrote code to get user information from ldap, I always inserted values into a different array (getting the fields I wanted) and then displayed THAT array out in the HTML:
foreach ($results as $name)
{
if (isset($name['mail']['0']))
// Check if it IS set, rather than not set and then append the data.
{
$allnames[$name['cn']['0']]['mail'] = $name['mail']['0'];
}
}
Then after you have all the fields you want you display the $allnames array.
Having said that, when I construct the array of user information, I make the array much much simpler - knowing what I want to display out, more along the lines of this:
foreach ($results as $name)
{
if (isset($name['mail']['0']))
// Check if it IS set, rather than not set and then append the data.
{
$allnames['mail'] = $name['mail']['0'];
}
}
You (or at least I) don't need to follow the ldap structure when making the array of information I have gathered, but rather I want to get specific fields from the directory and then display them by what they are - for example when I output the value in mail I might want to hyperlink it as an email address, so I keep it in an array element that I know by key and refer to later.

Delete multiple files in MongoDB GridFS in PHP

I am using MongoDB and GridFS in PHP, and trying to figure out how to delete multiple files by the _id.
Here is the code I have:
$ids = array("50401f40ff558cec38000061", "62401f40ff558cec38000072", "73401f40ff558cec38000083");
$mongo_ids = array();
foreach($ids as $id) {
$mongo_ids[] = new MongoId($id);
}
$mongo_grid_fs->remove(array("_id" => $mongo_ids));
Any idea what I am doing wrong?
This impossible to do with a single request due to the way that GridFS actually works.
You have two collections:
Files
Chunks
Inorder to delete a GridFs file you must query BOTH of these table. As such the remove() function actually calls the chunk collection and then removes the file from the files collection.
Since MongoDB cannot, fundamentally, query two collections in one request (joined deleted basically) you must send a delete request per file to delete otherwise you will have left over chunks taking up space in your chunks collection.
As such, taking this into consideration #ToddMoses answer is the correct one.
You can of course use: http://www.php.net/manual/en/mongogridfs.remove.php but I believe it does exactly the same thing, just abstracted so your query should have been:
$mongo_grid_fs->remove(array("_id" => array('$in' => $mongo_ids)));
First, use MongoDB::lastError() to find out what is going wrong. MongoGridFS::remove won’t present you with a message if it fails. DO something like this:
$errorArray = $db->lastError();
var_dump($errorArray);
It appears the problem is that you are not setting the criteria properly. The easiest thing to do is just use Delete instead of Remove since Delete takes an ID as its only parameter:
public bool MongoGridFS::delete ( mixed $id )
This deletes a file from the database whereas remove deletes files from the collection. Since you are looping anyway, you can do something like this:
foreach($ids as $id) {
$mongo_grid_fs->delete($id);
}

PHP IF statement not taking variable into account!

I have a tabled view in a while loop, where a user can view information on books.
For example, book ISBN, book name, read status...
Basically, when the user sets their 'readstatus' to 'complete' I want that specific table row to become grey! The logic is very straight forward, however I can't get my IF statement to recognise this:
if ($readstatus == 'complete') {
echo '<tr class="completed">';
}
else if ($readstatus != 'complete') {
echo '<tr class="reading">';
}
I'm obviously doing something wrong here, table content to change if the value of 'readstatus' = 'complete', if not, then output is the default
Why are you using $_GET? Does this information come from an HTML form or a URL etc... ?
I suspect you meant to change $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];.
$_GET is an aray of GET parameters which come from the query string.
$row is a row in your database, so if the information is in the database - which I suspect it is - you want to use $row instead of $_GET.
Try changing $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];
The $_GET function relies on the value being contained in the query string of the URL, and it has nothing to do with the database. I have a hunch you're trying to get the value from the database here and you're using the wrong function to do it.
$_GET['readstatus'] says the value is coming from the browser.
$row['readstatus'] says the value is coming from the database.
You need to decide which should take precedence-- probably the $_GET['readstatus']` because it's what the user wants to change. If that's the case, you need to update your database with the new readstatus before you requery the db for the dataset.

Categories