gabordemooij / redbean

ORM layer that creates models, config and database on the fly
https://www.redbeanphp.com
2.31k stars 280 forks source link

$this->__info['changelist'] is null #869

Closed BelleNottelling closed 3 years ago

BelleNottelling commented 3 years ago

Hey guys, I've been working on BoxBilling and we have been trying to update our instance of RedBeanPHP updated from an old old version (around 4.0.4) Experienced a slight hiccup though where $this->__info['changelist'] is null (code here).

It's an issue that only cropped up in our phpunit tests, but real world showed no issues. We opted to comment out the line sine it's only related to partialBeans, however I figured I'd drop in to ask if there was a configuration update we may have missed or something else simple on our end?

Outside of that issue and disabling setEnforceNamingPolicyit was amazingly a drop-in update, but we were only ever using the SimpleModel so it was never an advanced integration Thanks :)

Lynesth commented 3 years ago

Hey there !

I don't know how you're trying to access the value, but if you're doing something like:

$bean = R::dispense('bean');
$bean->name = 'something';
var_dump($bean->__info); // null

it won't work as __info is protected (and since SimpleModel doesn't extend OODBBean, you cannot access it via the model either).

OODBBean objects have a getMeta function to access those values:

$bean = R::dispense('bean');
$bean->name = 'something';
var_dump($bean->getMeta('changelist')); // array(1) { [0]=> string(4) "name" }

Let me know if that works out for you :)


Edit: I wanted to check out the failing tests to see how it was done, but they have either been deleted or I'd need to log in to access them ? Not sure ¯\_(ツ)_/¯


Edit 2: Or you're creating OODBBean objects in your tests in an unorthodox way, bypassing both initializeForDispense() and importRow() (like simply doing new \RedBean\OODBBean()). I could probably help out more if you point me in the direction your tests are failing, but glancing over them, I'd think this could be the issue.

BelleNottelling commented 3 years ago

@Lynesth Thanks for the quick reply! Yeah, all the failing tests were done in a separate branch so that's lost now. I went ahead and reverted our hack on my fork so you can see how the test fails. This is the error, and the failing testcase.

TypeError: array_push(): Argument #1 ($array) must be of type array, null given

/home/runner/work/boxbilling/boxbilling/src/rb.php:2779
/home/runner/work/boxbilling/boxbilling/src/rb.php:11085
/home/runner/work/boxbilling/boxbilling/src/bb-modules/Activity/Service.php:51
/home/runner/work/boxbilling/boxbilling/tests/bb-modules/Activity/ServiceTest.php:78

The associated lines in your source code are in SimpleModel.php and OODBBean.php.

Specifically, array_push( $this->__info['changelist'], $property ); because it's receiving null instead of an array, we never actually use that variable and as far as I know it's only part of the partialBeans functionality you guys added (somewhat?) recently.

Or you're creating OODBBean objects in your tests in an unorthodox way

I'll have to look into this tomorrow, I've only been contributing to BoxBilling for a few weeks so all of the code is new to me, but as far as I know it should be using the same creation method as the rest of our system does which end up at this function

Anyways, it's 11pm so I'm off for the night, but tomorrow I will look at the few things you mentioned, thanks again!

(P.S. I'm not expecting you to go look at our code and find the problem, just getting a few specific things to look at is super helpful)

Lynesth commented 3 years ago

@BenNottelling No worries :)

I'm pretty sure the new \RedBean\OODBBean() is the culprit (they are only used in tests afaict). If that's indeed the case, you could simply make a class for your needs and use that in your tests instead, like:

class DummyBean {
    function __construct() {
        $bean = new \RedBean\OODBBean();
        $bean->initializeForDispense('dummybean');
        /*
         * You could simply do `$bean->setMeta('changelist', array());` instead of
         * `initializeForDispense()` but that would be less future proof I guess
         */
        return $bean;
    }
}

Or maybe you could try using the actual dispense method ? Only you can tell from your code :)

BelleNottelling commented 3 years ago

I'm pretty sure the new \RedBean\OODBBean() is the culprit (they are only used in tests afaict).

It looks like you're spot on. As a test, I added $model->setMeta('changelist', array()); to the first test that caused an error, and now that one passes without problem. I guess we will have to update / re-write the 500 or so failing test so we won't have to hack RedBeanPHP in the future.

Thanks for the help, should be able to get it from here!

Lynesth commented 3 years ago

You're welcome !

Feel free to hit us up if you need anything else :)