Add DataObject to SiteConfig: No has_one found on class, but $has_one exists

Silverstripe Version: 4.2.x

I try to add a DataObject to SiteConfig and get the error “No has_one found on class”, but I added both relations

I googled a lot and thought I found a solution by adding this relationship to the app.yaml file, which doesn’t give me the above error, but a " [Warning] array_flip(): Can only flip STRING and INTEGER values!"

Here is my code:

class SocialMediaLink extends DataObject {
...
private static $has_one = [
        'SiteConfigExtension' => SiteConfigExtension::class,
        'Icon' => Image::class
    ]; 
...
}
class SiteConfigExtension extends DataExtension {
...
private static $has_many = [
        'SocialMediaLinks' => SocialMediaLink::class
    ];
...
}
 app.yaml:
SilverStripe\SiteConfig\SiteConfig:
  extensions:
    - mynamespace\SiteConfigExtension
mynamespace\SocialMediaLink:
  has_one: 
    - mynamespace\SiteConfigExtension: SiteConfigExtension

I am sure I can’t be the only one who wants to add Social Media links to the Site config.

Is there anything different by adding a DataObject to the SiteConfig than to a page?
What am I missing?

Thank you very much for your help!

The relationship should be with the SiteConfig class rather than an extension.
Change the has_one on SocialMediaLink to

private static $has_one = [
    'SiteConfig' => SiteConfig::class,
    'Icon' => Image::class
];

Hi kaftka,
Thank you for your quick reply, but unfortunately I still get the " [Warning] array_flip(): Can only flip STRING and INTEGER values!" error.
Any other idea?
Thanks

Did you update the yml as well? e.g. from SiteConfigExtension to SiteConfig?

On a related note… Could you do without the has_one relationship to the SiteConfig? You just need a place to manage SocialMediaLinks.

Hi andrewhoule,
Thanks for your reply.

Yes, I did try the yaml as well, but no success (I constantly did a dev/build and ?flush=all). I tried all of these different combinations possible in this regard…

What do you mean by “Could you do without the has_one relationship to the SiteConfig? You just need a place to manage SocialMediaLinks.”?
Is there another way to connect the SocialMediaLink to SiteConfig other than a has_one/has_many relationship?

This should be all you need:

SocialLink.php

<?php

use SilverStripe\Assets\Image;
use SilverStripe\ORM\DataObject;
use SilverStripe\SiteConfig\SiteConfig;

class SocialLink extends DataObject
{
    private static $table_name = 'Social';
    private static $singular_name = 'Social Media Link';
    private static $plural_name = 'Social Media Links';

    private static $db = [
        'Title' => 'Varchar'
    ];
    private static $has_one = [
        'Icon' => Image::class,
        'Config' => SiteConfig::class
    ];
    private static $owns = [
        'Icon'
    ];
}

SiteConfigExtension.php

<?php

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use SilverStripe\ORM\DataExtension;

class SiteConfigExtension extends DataExtension
{
    private static $has_many = [
        'SocialLinks' => SocialLink::class
    ];

    public function updateCMSFields(FieldList $fields)
    {
        $config = GridFieldConfig_RelationEditor::create();
        $fields->addFieldToTab('Root.Social',
            GridField::create('SocialLinks', 'Social Media Links', $this->owner->SocialLinks(), $config));

        parent::updateCMSFields($fields);
    }
}

configextension.yml

---
Name: MyConfig
---

Silverstripe\SiteConfig\SiteConfig:
  extensions:
    - SiteConfigExtension

THANK YOU, DorsetDigital!!! You’ve saved my day :wink:

I got really desperate as I couldn’t figure out where the big difference was between SS3.6 and SS4.2 to get this to work.

So, the key here was to use the
GridFieldConfig_RelationEditor instead of the GridFieldConfig_RecordEditor

Thanks a lot,
KimK

1 Like