Reputation: 673
I have a function that updates fine with a single dimensional array, but with a multidimensional array (or nested array) it will not update. the document data, the BSONfield (acts as the find key), and the collection are imputed. Any Idea what i am doing wrong?
Public Static function updateDocument($collection, $BSONfield, $document){
$dbcollection = $db->selectCollection($collection);
$sdata = $document[$BSONfield];
$secureInnerDocument = array();
$secureDocument = array();
if($BSONfield == "_id"){
$sdata = new MongoID($sdata);
unset($document["_id"]);
}
$filter = array($BSONfield=>$sdata);
foreach ($document as $k => $v) {
if (is_array($v)) {
foreach ($v as $sk => $sv) {
$secureInnerDocument[$sk] = Security::secureQuery($sv);
}
$secureDocument[$k] = $secureInnerDocument;
}else{
$secureDocument[$k] = Security::secureQuery($v);
}
}
$dbcollection->update($filter,array('$set'=>$secureDocument));
$objid = (string) $secureDocument['_id'];
return $objid;
}
Upvotes: 0
Views: 2438
Reputation: 1566
It translates fairly directly:
db.collection.update(
{fieldNameFilter:'filterValue'},
{$set: {'stringFieldName' : 'newValue'}}
);
Translates to:
$collection->update(
array('fieldNameFilter'=>'filterValue'),
array($set => array('stringFieldName'=>$value))
);
Then there are some flags for multi-row updates, etc. which I'm not showing here, but which are in the PHP and Mongo docs.
You might also want to look at: MongoDB - help with a PHP query
Upvotes: 1
Reputation: 12010
You don't seem to be using the $set
operator correctly. As per the MongoDB docs, you need to format your update document like so;
{ $set : { field : value } }
If you're running a $set
on nested keys, you need to use dot notation to get to them. For example;
{ $set : { field.nest : value } }
Upvotes: 0
Reputation: 673
So after fiddling around with is my solution ended up being kind of janky, I deleted the Document then re-create it. Here is the code in case anyone is looking:
/**
* updates document in the collection.
* This function secures the data
*
* @return object ID
* @param string $collection The name of the collection
* @param string $BSONfield The $BSON Field you want to index by
* @param string $document The document contents as an array
*/
Public Static function updateDocument($collection, $BSONfield, $document){
$db = Database::dbConnect();
$collection = Security::secureQuery($collection);
$BSONfield = Security::secureQuery($BSONfield);
$dbcollection = $db->selectCollection($collection);
if(array_key_exists('_id', $document)){
$document["_id"] = new MongoID($document["_id"]);
}
Database::deleteDocument($collection, $BSONfield, $document);
$objid = Database::createDocument($collection, $document);
return $objid;
}
/**
* Deletes a document in the collection.
* This function secures the data
*
* @return Boolean True - if successfully deleted, False if document not found
* @param string $collection The name of the collection
* @param string $BSONfield The $BSON Field you want to index by
* @param string $document The document contents as an array
*/
Public Static function deleteDocument($collection, $BSONfield, $document){
$db = Database::dbConnect();
$collection = Security::secureQuery($collection);
$BSONfield = Security::secureQuery($BSONfield);
$exists = False;
$dbcollection = $db->selectCollection($collection);
$documentList = $dbcollection->find();
$sdata = $document[$BSONfield];
if($BSONfield == "_id"){
$sdata = new MongoID($sdata);
}
foreach ($documentList as $doc) {
$documentID = $doc[$BSONfield];
if ($documentID == $sdata){
$exists = True;
}
}
if ($exists){
$deleted = True;
$filter = array($BSONfield=>$sdata);
$dbcollection->remove($filter,true);
}else{
$deleted = False;
}
return $deleted;
}
/**
* Inserts document into the collection.
* This function secures the data
*
* @return object ID.
* @param string $collection The name of the collection
* @param string $document The document contents as an array
*/
Public Static function createDocument($collection, $document){
$db = Database::dbConnect();
$collection = Security::secureQuery($collection);
$dbcollection = $db->selectCollection($collection);
$secureDocument = array();
$secureInnerDocument = array();
foreach ($document as $k => $v) {
if (is_array($v)) {
foreach ($v as $sk => $sv) {
$secureInnerDocument[$sk] = Security::secureQuery($sv);
}
$secureDocument[$k] = $secureInnerDocument;
}else{
if ($k == '_id'){
$secureDocument[$k] = $v;
}else{
$secureDocument[$k] = Security::secureQuery($v);
}
}
}
$dbcollection->insert($secureDocument);
$objid = (string) $secureDocument['_id'];
return $objid;
}
and how i am securing all the data from injections:
/**
* Secures string to be inputed into a database.
*
* @return Retuns secure string
* @param String $string String to be secured
*/
Public Static Function secureQuery($string){
$secureString = strtr($string, array(
"'" => "0x27",
"\"" => "0x22",
"\\" => "0x5C",
"<" => "0x3C",
">" => "0x3E",
"=" => "0x3D",
"+" => "0x2B",
"&" => "0x26",
"{" => "0x7B",
"}" => "0x7D",
));
return $secureString;
}
/**
* Un-Secures string to be inputed into a database.
*
* @return Retuns unsecure string
* @param String $string String to be un-secured
*/
Public Static Function unsecureQuery($string){
$secureString = strtr($string, array(
"0x27" => "'",
"0x22" => "\"",
"0x5C" => "\\",
"0x3C" => "<",
"0x3E" => ">",
"0x3D" => "=",
"0x2B" => "+",
"0x26" => "&",
"0x7B" => "{",
"0x7D" => "}",
));
return $secureString;
}
enjoy!
Upvotes: 0