0

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;
}

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

Comments

0

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!

Comments

0

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 } }

2 Comments

Yeah i am having trouble with how that translates into PHP. I have a nested array do I make the key of the nested array "$set"? like is it myArray[Key] = array('$set' => myNestedArray) or myArray[Key] = array('$set' => array($BSONfield => myNestedArray)?
Nope, you'd use just like my second example. array('$set' => array( 'nested.field' => value ) )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.