spicywebau / craft-neo

A Matrix-like field type for Craft CMS that uses existing fields
Other
403 stars 64 forks source link

Relabel Support #154

Closed glitchedmob closed 5 years ago

glitchedmob commented 5 years ago

This plugin https://github.com/Anubarak/craft-relabel adds the ability to relabel fields. It doesn't quite work in Neo though. Someone already opened an issue with that plugin to try and get Neo support added and the maintainer said that it would have to be added on Neo's end. Any idea if this is something that could be supported?

kylecotter commented 5 years ago

Hi!

Piggy-backing on this, is this something on the roadmap for Neo?

Thanks!

rjhewitt3 commented 5 years ago

@tonysambell @ttempleton Are you guys planning on adding support for Relabel? It's much requested featured based on the +1's on this issue. We'd very much appreciate a response! If this won't be a consideration, I may need to seek alternative solutions.

rjhewitt3 commented 5 years ago

For your convenience, here's a link to the issue over on Relabel: https://github.com/Anubarak/craft-relabel/issues/2

Anubarak commented 5 years ago

Just a note from me (the creator of Relabel). If you want to provide support for Relabel there are "only" a view things to do. I included the funtionality to Neo but since all your files are minified I won't really create a pull request.

To include supprt for the Plugin you need to first register/publish your field layout id in the field layout designer either by including a name input or by adding the data('fieldLayoutId') property to the class fieldlayoutform. Craft itself always has a hidden input with the ID, so that was my reference. If it's a new Field Layout my plugin will handle everything as it passes new0 automatically.

As soon as you display your field layout designers or create a new one call the function Craft.relabel.refreshFieldLayout(); and you are done. New labels can be stored for your field layouts

To Register Labels for a Neo Field all you need to do is this

$class = 'anubarak\\relabel\\services\\RelabelService';
if (Craft::$app->getPlugins()->isPluginInstalled('relabel')) {
    Event::on(
        $class,
        'eventRegisterAdditionalLabels',
        function(Event $event) {
            $layoutId = $event->fieldLayoutId;
            $fields = Craft::$app->getFields()->getFieldsByLayoutId($layoutId);
            $plugin = Craft::$app->getPlugins()->getPlugin('relabel');
            /** @var RelabelService $service */
            $service = $plugin->get('relabel');

            foreach ($fields as $field){
                if($field instanceof Field){
                    $blocks = $field->getBlockTypes();
                    foreach ($blocks as $block){
                        $layoutForBlock = (int)$block->fieldLayoutId;
                        $index = $field->handle . '.' . $block->handle;
                        $relabels = $service->getAllLabelsForLayout($layoutForBlock, $index);
                        foreach ($relabels as $relabel){
                            $event->labels[] = $relabel;
                        }
                    }
                }
            }
        }
    );
}

This will grab the current field layout, search for Neo fields in it and pass all blocks with their relabels with the correct namespace to my JavaScript file.

The only thing left is to apply the new labels when a new block type is created via JavaScript. I'm not really sure if this is my part or yours but you can apply them via Craft.relabel.refresh(); If you don't want to support Relabel I'm fine with it since I don't use Neo and Relabel was originally just for me. Otherwise feel free to contact me.

aaronbushnell commented 5 years ago

We're wrapping up a sizable Craft 2 → Craft 3 update and it would be awesome to get Relabel support back into Neo! Any chance of @Anubarak's update being included in a future release?

ttempleton commented 5 years ago

Spicy Web has taken over the original Relabel from @benjamminf, the creator of Relabel, and we've renamed it Field Labels. We've ported it to Craft 3 and will release it on the Plugin Store. Neo (having previously supported the Craft 2 version of the original Relabel) has had its support for Field Labels restored in the dev branch, and it'll be released for general use in Neo 2.3. We will only be supporting Field Labels in Neo.

bstein-clever commented 5 years ago

Just noticing this - I somehow missed during our upgrade that our Neo fields no longer supported relabel. I just tried installing your Field Labels plugin, but it doesn't seem like any of the label overrides got migrated. Is there any way to do trigger this manually, and/or get a list of data that existed to re-enter? Thanks!

ttempleton commented 5 years ago

Hi @bstein-clever,

Field Labels runs a migration process on install that is intended for labels from its previous version, the original Relabel for Craft 2 -- but, due to the other Relabel for Craft 3 using the same database table and column names as the original, the migration process should work fine for converting from it, too. The catch, though, is that the Craft 3 Relabel still needs to be installed when you install Field Labels -- once it's uninstalled and it drops its table, Field Labels can't really do anything about that. If that's the case in your situation, then if you can reinstall the Craft 3 Relabel and restore its labels (e.g. from a DB backup or project.yaml backup), then install Field Labels and then uninstall the Craft 3 Relabel again, you should be good to go.

Otherwise, if you've installed Field Labels, the Craft 3 Relabel is still installed and the labels haven't migrated, then running the following migration script in your Craft project should do it:

$oldLabels = (new \craft\db\Query)
    ->select([
        'id',
        'fieldId',
        'fieldLayoutId',
        'name',
        'instructions',
        'uid',
    ])
    ->from('{{%relabel}}')
    ->all();

foreach ($oldLabels as $oldLabelRow) {
    $newLabel = new \spicyweb\fieldlabels\models\FieldLabel($oldLabelRow);
    \spicyweb\fieldlabels\Plugin::$plugin->methods->saveLabel($newLabel);
}
bstein-clever commented 5 years ago

That makes sense. Thanks for the extra context! I was actually just digging into this some more this evening, and noticed something sadder ... we were using the other relabel craft3 plugin (https://github.com/Anubarak/craft-relabel), and in looking over their page again, I find it says:

This plugin requires Craft CMS 3.0.0 or later. Important: if you are coming from Craft 2 - there is no migration currently so all your Relabels will be deleted. If you really need a migration feel free to contact me or backup the table and insert it on your own

which to me is quite frankly ridiculous, and there should be much bigger warnings when upgrading if this is the case. It also explains why all my labels disappeared - they were just dropped.

Fortunately, I do still have a database backup from before our upgrade, which I dug out in the hopes that I could use it to restore, and then use your migration. However, my latest woe is that there's a foreign key relation on both craft_fields and craft_fieldlayouts, and many of these do not match.

I confess I'm not entirely clear on why, unless there were massive db-wide changes to fields in the upgrade from craft2 to craft3, which seems surprising. Do you know if there's any way to reconcile this data set? I'm happy to restore the specific table from the snapshot, and then just load in Field Labels through the normal plugins to trigger the migration manually, but I would like to make sure all our overrides are there, first.

Any ideas would be greatly appreciated. Thanks again!

ttempleton commented 5 years ago

I've done some playing around with this with a test installation upgraded from Craft 2 and its DB backup; I don't think anything specifically related to the Craft 3 upgrade would cause this sort of issue, as the field/layout IDs didn't change and I was able to import the original Relabel table and data without issue. I'm not too sure how the IDs could have changed -- the only thing that comes to mind is that IDs could differ when syncing a Craft 3.1 project between environments with the project.yaml, but I don't think that's likely in this case since the fields/layouts were originally created back on Craft 2.

As long as the original fields and layouts still exist, though, their UIDs would be the same, so if you check the fields and layouts from your backup, compare with the fields/layouts in the Craft 3 installation's database and are able to find UID matches, you could then update the IDs in the data from the backup.

I hope this helps; good luck with the UID lookup and let me know how you go!

bstein-clever commented 5 years ago

That's an interesting idea, thanks. I just tried it out (pulling more of the data from the backup), but unfortunately it didn't help. Its seems like while many of the original UIDS (and actually IDs) are the same, all of the Neo ones have been recreated. In the Craft2 DB, all of the Neo_Block (type) field layouts have a dateCreated of 2018-10-24 - which is suprising, we've been using Neo a lot longer than that. I'm guessing it's related to an upgrade of some sort. In the Craft3 DB, all of the Neo elements are now of type benf\neo\elements\Block, and have a dateCreated of 2019-02-05, which isn't when we did the upgrade, nor the last time we upgraded Neo - we upgraded to the 3.1* bugfix on 3/25). I think we might have added a new field around then, but I'm no positive. None of the IDs or UIDs for Neo field layouts match at all, while it seems like all the other ones do. Any other things you can think of?

ttempleton commented 5 years ago

I'm a bit puzzled about all the Neo field layout IDs/UIDs changing... That said, as long as all of your field and Neo block type handles have not changed, we should still be able to resolve this.

I've come up with a process to save a Craft 2 installation's Neo-specific Relabel data to a JSON file, and to then try to import the data into a Craft 3 installation based on the field and block type handles. The potentially inconvenient part is that it does require the Craft 2 installation to be set up, so if that isn't possible for any reason, let me know and I'll try to come up with an alternative for the first half of the process. It also requires your Craft 3 installation to already have Field Labels installed, but if only the Neo field layout IDs have changed, then I think you should be able to insert the other label data into the fieldlabels table (or alternatively, the relabel table before installing Field Labels) without issues.

The files turned out a bit large to post in a comment, so here's the gist. Follow these steps:

The migration will match the field/block type handles saved in neorelabeldata.json with the field layout IDs in the Craft 3 installation, if the fields/block types with those handles exist, and should then restore your labels.

Good luck! And let me know if you run into any issues.

bstein-clever commented 5 years ago

Phew. That ended up being more work than I expected, because of some weird permissions/setup issues from spinning up an old instance of our setup. But I was able to extract the data (which was already a big help to see the assignments) and then run the data migration.

The second half actually threw me for a bit as well, because I was expecting it to show up in the craft_relabel table, when in fact there was now a new craft_fieldlablels table. (Please correct me if I'm wrong on that).

My flow in Craft 3 ended up being:

So ultimately a success! Thanks again for all of your time and help here. I was not expecting to get a custom import/export handler written for me. :)

ttempleton commented 5 years ago

No worries! Glad the original data was restored 😄 And yeah, the Craft 3 release as Field Labels is now using the fieldlabels table to avoid any potential conflicts with the other Relabel's data, so the import process just saves the Neo labels straight into the new table.