Problem/Motivation

In my current use case, i have a real need to have exportable bean instances. More specifically, I'm using UUID Features Integration as a deploment solution for several projects. Having Bean UUID already solved, it appeared to me that all we needed for exportable bean instances was an implementation for uuid_beans.features.inc.

Proposed resolution

I have written a patch (see first comment) that acts as a proof-of-concept for this solution. Although I'm using it daily now, i thought I would share it for those interested.

Remaining tasks

At this point, so long as your bean types are module-provided, this solution is workable, although there is a pesky PHP Notice upon export writing:

"Array to string conversion in features_export_prepare() (line 208 of features.export.inc)"

I haven't been able to sniff this out yet (the patch still works), but if the maintaners have any advice, i'd really like to clean that up. In the end the patch still needs work to be solid.

Also missing at this time is dependency detection to make sure the bean type is valid when reverting. If you add the dependency manually, things are fine. There is a @todo in uuid_bean.features.inc

User interface changes

You will see a "Bean UUID" fieldset on the Features create or recreate UIs, i.e.

  • admin/structure/features/create
  • admin/structure/features/[FEATURE_ID]/recreate

API changes

None other than adding bean_uuid support.

Original report by beanluc

A more general request for arbitrary entity types, and bean export support was requested in #1643704: Refactoring needed to support all entities that have UUIDs. I don't see a way to implement this for general entities, but the Bean part has been addressed here.

Comments

mpgeek’s picture

Here is the patch.

mpgeek’s picture

The previous patch had whitespace errors in it. Use this one instead.

mpgeek’s picture

Status: Active » Needs review

Bumping to needs review... hoping for some feedback.

joelcollinsdc’s picture

crickets. this is fantastic work. thank you so much. I'm not sure if this is the 'correct' solution to this problem but at least it works. Hope it gets the attention it deserves.

one issue i found is the bean export does not detect that the bean type hasn't been exported yet. not too hard to add it in manually, and may actually be desired behavior... but still.

joelcollinsdc’s picture

Some more things that I noticed:

If you export the bean type along with the bean itself, the fields don't come in properly.
The 'changed' field on the bean will cause the bean to always appear overrridden.

mpgeek’s picture

Status: Needs review » Needs work

@joelcollinsdc, i've noticed the same behavior and i've had to do a revert, then update to get the state to be "default". There's obviously a bug in there. Bumping back to needs work.

saltednut’s picture

@joelcollinsdc, i've noticed the same behavior and i've had to do a revert, then update to get the state to be "default". There's obviously a bug in there. Bumping back to needs work.

If you look at bean/includes/bean.core.inc - the save() method overrides the changed value.

So maybe its not a bug. But the API is working as expected?

i've had to do a revert, then update to get the state to be "default". There's obviously a bug in there. Bumping back to needs work.

I'm not exactly sure why reverting could even work. A Features update would surely "fix" it though, since you're actually writing in then the proper 'changed' value thats in the DB.

The bean is new to the system, so bringing along the changed value doesn't seem to have much of a use case.

Anyway, I've made some changes to this patch. Attempted to fix some minor coder problems (whitespace), and I've also negated the need to do a Delete/Resave when rebuilding an existing Bean - opting to instead just load and update the existing Bean using the value stored in the export. This seems simpler and doesn't involve having to juggle the existing bid. Finally, I'm unsetting the changed value so that the Bean does not show up overridden.

I've also attached a Feature for testing.

Edit: I uploaded the wrong patch here. See #9 below.

saltednut’s picture

Status: Needs work » Needs review
StatusFileSize
new1015 bytes

oops I uploaded the wrong patch. jeesh. please ignore that last one, its just the copy of mpgeek's patch I started with.
Edit: See #9 below.

saltednut’s picture

ok wow - doublechecked this one. (Maybe less coffee would help :) - #8 above was missing the additional file and #7 was mpgeek's patch.

saltednut’s picture

missing at this time is dependency detection to make sure the bean type is valid when reverting. If you add the dependency manually, things are fine. There is a @todo in uuid_bean.features.inc

Updated patch includes support for detecting Bean plugin module dependencies.

saltednut’s picture

Issue tags: +demo_framework

adding tag

mpgeek’s picture

@brantwynn, i've used your version in a few different development workflows and now a successful from-blank deployment without issue. Reversion and dependency checking looks to be in order. Thanks for showing the right way to do it.

saltednut’s picture

@mpgeek - good to hear! I too have been using this and the only issue I've run into is a hard dependency on bean_uuid. If you have uuid_features and bean enabled but not bean_uuid, it will throw an error when you try to make a new feature or recreate one. I'll see if I can't find time to do one more patch on this to make it more stable in the next day or two.

saltednut’s picture

New patch adds error prevention when bean_uuid is not enabled.

saltednut’s picture

Status: Needs review » Needs work

I have seen some duplicate vid SQL errors using this but I'm not exactly sure how to reproduce them. In any case, I'm going to mark this as needs work.

mpgeek’s picture

I was just about ready to do some more testing with this. Does the error occur on revert? I believe I had the same problem in the original version, and that was the reasoning behind delete-rewrite for revert (it seemed to work but felt hacky).

saltednut’s picture

Yeah - the error happens on a revert. The reason why is because it tries to insert a duplicate VID into the revisions table.

So we should either manually clean the Bean revisions table.

-or-

Unset the revision value during export. However, this will likely lead to the unintended consequence of new revisions being created every time we do a reversion.

saltednut’s picture

Status: Needs review » Needs work
StatusFileSize
new6.2 KB

Ok well...

Unset the revision value during export. However, this will likely lead to the unintended consequence of new revisions being created every time we do a reversion.

I actually am ok with this since it means people can roll more bean reversions.

Reverting the Feature works AND I get a revision on my bean. I think this is kind of an unintended bug for some -but when you think of it in a sense that Beans are mostly config entities, people "rolling back" are rolling forward on the current environment's track of revisions. So I would say works as designed here. The tests I have done manually show beans reverting cleanly and importing fine too.

saltednut’s picture

Status: Needs work » Needs review
mpgeek’s picture

Status: Needs work » Needs review
StatusFileSize
new6.34 KB

I did some basic testing on #18 and all the usual suspects seem to be working (export/create/revert) under normal conditions. I was thinking some more testing with more edge cases in the wild would be useful. I would agree that reverting *SHOULD* create a revision, since that's exactly what we are doing on revert.

I did find some more coding standards issues, so I've cleaned those up here in this version. Nothing has functionally changed. I have some more testing to do, so leaving as needs review.

mpgeek’s picture

I just completed more comprehensive testing in a variety of use cases, and all seems pretty good, save for one hangup. Here's what i found, using Features 2.x and stable releases of uuid, bean_uuid, and uuid_features dev:

1. UUID Bean dependency.
This is working as it should, as you cannot export a bean instance without uuid_bean enabled, i.e. the bean_uuid fieldset does not show up in the Features UI. Further, you cannot disable a feature containing a bean instance due to the dependency.

2. Workflow A: create bean instance > export > delete bean > revert.
This works without issue, and the bean is restored with the same revision ID as the orginal (deleted) bean instance.

3. Workflow B: create bean instance > export > change bean data > revert.
This creates an intended revision (and id). If i continue this case by executing workflow A, the revision history is lost, but the revision ID is maintaned. In the end, monkeying with the bean instances and export/revert variants are working as designed.

4. Workflow C: create bean instance > create new revision > update feature export > roll back to previous revision > revert feature.
This one breaks when you try to go back to a previous revision. You end up getting the confirm_form for setting the active revision twice, and ultimately a PHP fatal error:
Call to undefined method Bean::setDefault in bean.pages.inc on line 535
This appears to be the same issue as #1941168: "set active" gives fatal error "Call to undefined method Bean::setDefault()", but going to the latest dev of bean didn't fix the problem. The patched code is there, but the symptom remains.

You could argue that this is an issue with BEAN and not UUID Features, but one might consider it a blocker. There doesn't appear to be a problem with what we are trying to accomplish here, as futzing with revisions has nothing directly to do with this patch.

The other caveat here is that one of the bean instances used for these tests was a Relevant Content Bean (http://drupal.org/project/bean_relevant). One of the data items is (optionally) choosing a vocabulary for the related content, but the vocabulary is not autodetected when exporting the instance via features. Here again, I would argue that this is an issue with Relavant Content Bean; the vocabulary and term ids end up in the export (as designed), but the user would obviously need to be aware that the vocab/terms must be in place in order for reversion to completely work.

5. Workflow D: deployment
Utilizing uuid_features as a deployment strategy works just fine. I get my beans installed assuming all of the dependent items are deployed first.

I feel like this is really close, but I'm not certain how much of the fragility seen with contrib bean types is of concern for this patch. At this point I'm using it in real workflows, but i have to be aware of the limitations. Works for me.

saltednut’s picture

Workflow C: This sounds more like a problem with Bean itself and I'd consider it outside the normal 80% use case covered by workflows A and B.

We can't do much for bean plugins and how they store values. http://drupal.org/project/bean_tax is the main plugin I have been testing and it also dealt in storing vocabulary vids - these were getting exported, which "works as designed" in my opinion. I have the luxury of having written bean_tax so I actually updated the module and it now stores vocabulary machine_name instead of vid to make the exportables work better.

saltednut’s picture

Status: Needs review » Reviewed & tested by the community

I have been using the patch in #20 for 2 months without consequence.

saltednut’s picture

Status: Reviewed & tested by the community » Fixed
dgtlmoon’s picture

wow, good work all!

Automatically closed -- issue fixed for 2 weeks with no activity.

dvmanjunath’s picture

Issue summary: View changes

I added this patch still it exports only bean block and its fields but it wont export created blocks under bean block type.

saltednut’s picture

@manjunathdv16 this patch was committed 3 years ago. Are you using the latest dev version?

dvmanjunath’s picture

@brantwynn No i'm using alpha version not the dev version. Anyway after adding latest patch its working fine.