0

I would be grateful for any help in resolving this issue.

I am trying without success to append to an array within a MongoDB collection using PHP.

The proccess is as follows:

A user selects a checkbox and clicks on the corresponding HTML 'Add' button. The value of the checkbox is a string i.e. 'Manchester City Football Club - Conference And Events' and the string is passed to a Symfony Controller using Ajax.

Once the string is retrieved within the Controller it is stored within a new PHP array as the array key and the word 'True' is assigned as the key value.

If the current system user has not previously attempted to save the array into a MongoDB collection then a MongoDB 'insert' successfully creates a new collection and stores the newly created array into the collection.

If a MongoDB collection was successfully created then an 'update' is used to add a new user checkbox selection to the 'marketingCategories' array.

Here is the Ajax script which first retrieves and sends the selected string to the Symfony Controller:

$('.addMPbtn').on('click', function(){
    var checkboxId = $(this).attr('checkboxId');
    if ($('#'+checkboxId).is(":checked"))
    {
      var checkboxVal = $('#'+checkboxId).val();
      // console.log(checkboxVal);

      // Fire off the request to the controller 
        request = $.ajax({
            url: "{{ path('sendManagedPreferences') }}",
            type: "POST",
            data: {"mpString" : checkboxVal},
        });

        // Callback handler that will be called on success
        request.done(function (response){
            console.log(response);
        });
    }
})

Here is the PHP (Symfony Controller) script which is used to interact with the MongoDB collection:

class sendManagedPreferencesController extends Controller
{

    public function indexAction(){

        /** @var $user \Attain\Dashboard\Document\User */
        $user = $this->get('security.context')->getToken()->getUser();
        $domainName = $user->getDomain();
        $userId = $user->getId();

        $mpDataArray = array();

        // Get the request method.
        $request = $this->get('request');

        if ($request->getMethod() == 'POST') {

            $mpString = $request->get('mpString');

            $mpDataArray[$mpString] = "true";

            // Connection details omitted
            $usersCollection = $mongoDB->selectCollection($domainName.'_managedPreferences');

            // Search criteria for use within a mongodb query
            $querySettings = array('userId' => array('$exists' => true));

            $cursorSettings = $usersCollection->findOne($querySettings);

            if(!isset($cursorSettings['userId'])) {

                // If their is no data stored within the domain_managedPreferences collection relating to the current user then
                // prepare a suitable array which can be used to insert into the collection.

                $newUserMC = array('userId' => $userId,'marketingCategories' => $mpDataArray);

                $usersCollection->insert($newUserMC);

            } else {

                $documentId = $cursorSettings['_id']->{'$id'};

                $existingUserMC = array('marketingCategories' => $mpDataArray);

                // If the current user has data stored within the domain_managedPreferences collection then we prepare an array
                // which can be used to append any selected marketing categories to the existing collection.

                if($documentId !='') {

                    $usersCollection->update(
                        array( '_id' =>  new \MongoId($documentId) ),
                        array( '$addToSet' => $existingUserMC )
                    );

                }

            }

        unset($mpDataArray);

        echo "Ajax procedure was successful.";

        }
    }
}

Here is the structure of a newly created MongoDB collection:

{
   "_id": ObjectId("5b0e98e899eccf502400003e"),
   "userId": "5ab8fb0f0efafb444e800e1e",
   "marketingCategories": {
     "Manchester City Football Club - Conference And Events": "true" 
  } 
}
M. Eriksson
  • 13,450
  • 4
  • 29
  • 40
  • That's not an array. PHP is very liberal with what "it" calls an array. For the rest of us it means things inside brackets `[]` in JSON notation. You want `$set` for this type of data, and using the same "key name" simply overwrites the existing one. – Neil Lunn May 31 '18 at 11:05
  • Try to isolate the problem. Confirm your ajax sends expected data. Confirm `findOne` returns the expected document. Confirm `$documentId` contains expected value. If all above is correct, the question can be reduced to few lines of PHP code with exact values. With current edition the problem is not reproducible and the question can be closed. – Alex Blex May 31 '18 at 11:08
  • Hello Neil, Thank you for your response. I have tried using the $set keyword as part of the update but that simply replaces the existing value stored within the MongoDB collection marketingCategories array. – Mark Hathaway May 31 '18 at 12:50
  • Hello Alex, Thank you too for your response. I can confirm that ajax is sending a string value to the Symfony controller, findOne returns the expected document and $documentId has the correct value. I am not sure if this is relevant but when I try to perform an update within MongoDB itself using $addToSet or $push I get a response saying 'The field 'marketingCategories' must be an array but is of type Object in document'. Any further help on this would be greatly appreciated. – Mark Hathaway May 31 '18 at 13:03

0 Answers0