MongoCollection won't save

Hello,

Migrating to PHP 7.1 and latest version of Phalcon.

Using bootstrap code from an older PHP 5 project, changed to using the MongoCollection from the incubator.

I retrieve a model, but when saving I get: "A dependency injector container is required to obtain the services related to the ODM"

Line 73 in Phalcon\MVC\MongoCollection.php seems to have lost the DI.

$dependencyInjector = $this->_dependencyInjector;

How do I fix this?



2.8k
edited 13d ago

I've not used PHP7.1 and Phalcon3 for an ODM yet, but what is your model extending? Ie: class Robots extends \Phalcon\Mvc\Collection{}? The parent should have the save() method - and access to the DI automagically, you shouldn't need to inject/instanstiate it manually.



2.6k

My model is using the new Mongo class from the Incubator. It extends \Phalcon\Mvc\MongoCollection.

From index.php showing Loader with Incubator:

$loader = new \Phalcon\Loader();
$loader->registerNamespaces([
    'Phalcon' => SHARED_PATH . 'utils/incubator/Library/Phalcon/'
])->registerDirs([
    APP_PATH . 'app/controllers/',
    APP_PATH . 'app/plugins/',
    SHARED_PATH . 'library/',
    SHARED_PATH . 'models/'
])->register();

From services.php:

// shared mongo service 
$di->set('mongo', function() {

    if(IS_PRODUCTION) {
        $mongo = new \Phalcon\Db\Adapter\MongoDB\Client('mongodb://xxx');
    }
    else {
        $mongo = new \Phalcon\Db\Adapter\MongoDB\Client('mongodb://127.0.0.1');
    }
    return $mongo->selectDatabase('dbName');

}, true);

It is quite strange. I can query for a model, and it gets fetched properly, all methods and properties behave as expected. There is obviously a DI being used to access the Mongo service. I've only changed this code to add the Incubator namespace/classes. It worked perfectly before.

It only crashes when I try to save. There are no scope issues. Same behavior via the CLI.



2.8k
edited 13d ago

Weird. I'm looking at the incubator tests (related car collection) and they seem to translate to your set-up from my interpretation.

Are you able to run the test on your machine to see if that works - using phpunit - then we can conclude if it's your implementation/set-up or not.



2.6k
edited 13d ago

Everything installed. Wtih what command and from what directory do I run phpunit?



2.8k

I think phpunit --bootstrap _bootstrap.php unit/Mvc/MongoCollectionTest.php should work fine

Everything installed. Wtih what command and from what directory do I run phpunit?



2.6k

Hmmm... Class 'Codeception\TestCase\Test' not found

I find Test.php in /vendor/codeception/codeception/src/Codeception/Test not /TestCase

Version problem?

I think phpunit --bootstrap _bootstrap.php unit/Mvc/MongoCollectionTest.php should work fine

Everything installed. Wtih what command and from what directory do I run phpunit?



2.6k
edited 12d ago

Still trying to get the test to run. I read in the Codeception changelog that Codeception\TestCase\Test was removed in 2.2.0. Too many breaking dependencies trying to downgrade to 2.1.11. Not sure how any of these tests would work, as they all extend Codeception\TestCase\Test.

I tried changing CollectionsTest in MongoCollectionTest.php to extend Codeception\Test\Unit and running phpunit with:

phpunit --bootstrap _bootstrap.php CollectionsTest unit/Mvc/MongoCollectionTest.php --debug --verbose

I get this:

PHPUnit 6.1.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.1.3-3+deb.sury.org~xenial+1

Time: 347 ms, Memory: 6.00MB

No tests executed!

Any help appreciated. I have no idea about phpunit or (the well-named) codedeception. Thanks!



2.8k

Apologies for the late reply.

Ah, I'm uncertain, as I've not had much experience with phpunit. I'll set up a VM with Phalcon3, PHP7, and MongoDb3 tonight and give it a test and get back to you.

Still trying to get the test to run. I read in the Codeception changelog that Codeception\TestCase\Test was removed in 2.2.0. Too many breaking dependencies trying to downgrade to 2.1.11. Not sure how any of these tests would work, as they all extend Codeception\TestCase\Test.

I tried changing CollectionsTest in MongoCollectionTest.php to extend Codeception\Test\Unit and running phpunit with:

phpunit --bootstrap _bootstrap.php CollectionsTest unit/Mvc/MongoCollectionTest.php --debug --verbose

I get this:

```php PHPUnit 6.1.0 by Sebastian Bergmann and contributors.

Runtime: PHP 7.1.3-3+deb.sury.org~xenial+1

Time: 347 ms, Memory: 6.00MB

No tests executed! ```

Any help appreciated. I have no idea about phpunit or (the well-named) codedeception. Thanks!



2.6k

No worries.

One thing I noticed in the MongoCollectionTest.php was the absence of a test that fetched a collection THEN saved. This is exactly when my code fails.

Thanks

Apologies for the late reply.

Ah, I'm uncertain, as I've not had much experience with phpunit. I'll set up a VM with Phalcon3, PHP7, and MongoDb3 tonight and give it a test and get back to you.

Still trying to get the test to run. I read in the Codeception changelog that Codeception\TestCase\Test was removed in 2.2.0. Too many breaking dependencies trying to downgrade to 2.1.11. Not sure how any of these tests would work, as they all extend Codeception\TestCase\Test.

I tried changing CollectionsTest in MongoCollectionTest.php to extend Codeception\Test\Unit and running phpunit with:

phpunit --bootstrap _bootstrap.php CollectionsTest unit/Mvc/MongoCollectionTest.php --debug --verbose

I get this:

```php PHPUnit 6.1.0 by Sebastian Bergmann and contributors.

Runtime: PHP 7.1.3-3+deb.sury.org~xenial+1

Time: 347 ms, Memory: 6.00MB

No tests executed! ```

Any help appreciated. I have no idea about phpunit or (the well-named) codedeception. Thanks!



2.6k

Any news?

Apologies for the late reply.

Ah, I'm uncertain, as I've not had much experience with phpunit. I'll set up a VM with Phalcon3, PHP7, and MongoDb3 tonight and give it a test and get back to you.



2.8k

Sorry, I got really busy over the last couple days with work. I have tonight off, so I should be able to experiment then

Any news?

Apologies for the late reply.

Ah, I'm uncertain, as I've not had much experience with phpunit. I'll set up a VM with Phalcon3, PHP7, and MongoDb3 tonight and give it a test and get back to you.



2.6k
edited 5d ago

Did some testing

Made a simple Model:

class Tester extends \Phalcon\Mvc\MongoCollection {

    public static function findA() {

        return self::findFirst();
    }
}

And two CLI tests:

public function test1Action(array $params = null) {

  $t = new self();
  $t->test = 'here is a string';
  $t->save();
}

public function test2Action(array $params = null) {

  $t = self::findA();
  echo 'test: ', $t->test, PHP_EOL, PHP_EOL;

  $t->test = 'another string';
  $t->save();
}

After running test1, I get this in Mongo:

{
    "_id" : ObjectId("58f5ee18962d741fd126d472"),
    "_dependencyInjector" : {

    },
    "_modelsManager" : {

    },
    "_source" : "tester",
    "_operationMade" : 1,
    "_dirtyState" : 1,
    "_connection" : {

    },
    "_errorMessages" : [ ],
    "_skipped" : false,
    "test" : "here is a string"
}

All good, but where did these underscore-prefixed properties come from??? Never seen before.

When I run test2, I get this:

test: here is a string

PHP Fatal error:  Uncaught Phalcon\Mvc\Collection\Exception: A dependency injector container is required to obtain the services related to the ODM in /var/www/proj/shared/utils/incubator/Library/Phalcon/Mvc/MongoCollection.php:76
Stack trace:
#0 /var/www/proj/cli/app/tasks/TestTask.php(3168): Phalcon\Mvc\MongoCollection->save()
#1 [internal function]: TestTask->test2Action(Array)
#2 [internal function]: Phalcon\Cli\Dispatcher->callActionMethod(Object(TestTask), 'test2Action', Array)
#3 [internal function]: Phalcon\Dispatcher->_dispatch()
#4 [internal function]: Phalcon\Dispatcher->dispatch()
#5 /var/www/proj/cli/app/cli.php(42): Phalcon\Cli\Console->handle(Array)
#6 {main} thrown in /var/www/proj/shared/utils/incubator/Library/Phalcon/Mvc/MongoCollection.php on line


2.6k

I found a patch that I outlined in https://github.com/phalcon/incubator/issues/760

Would still love some insight as to why MongoCollection ignores the original getReservedAttributes() in collection.zep at https://github.com/phalcon/cphalcon/blob/master/phalcon/mvc/collection.zep