Adding Express Attributes

Hi, I’m trying to do add attributes programmatically to an Express database, I found in the documentation
use Express;

$object = Express::buildObject(‘marina2’, ‘marinas2’, ‘Marina2’);
$object->addAttribute(‘text’, ‘Name’, ‘marina_name’);
$object->addAttribute(‘address’, ‘Address’, ‘marina_address’);
$object = $object->save();

That works great to add a new database and add attributes to it, but I want to add attributes to an existing database

I tried grabbing the database object with

$object = Express::getObjectByHandle(‘marina’);

But that shows an error, Call to undefined method Concrete\Core\Entity\Express\Entity::addAttribute() Does anyone have an example on how to do this? Thanks

I think you cannot do it using current Concrete api. At least I haven’t found any class that can do it.
If someone knows better, I will be happy to be proved wrong:D

Express::buildObject() will create instance of Concrete\Core\Express\ObjectBuilder
where addAttribute() method is available.
Though save() method will return Concrete\Core\Entity\Express\Entity instance.

Express::getObjectByHandle(‘marina’) will return Concrete\Core\Entity\Express\Entity
so addAttribute() method is not available.

Going back to Concrete\Core\Express\ObjectBuilder class, it seems it can only build express objects from zero. There isn’t any setObject()/setEntity() method or something like that.

I was able to add attribute to existing Express object, but only by operating on entity manager directly (blatantly say by “stealing” code from core files). Though I don’t have that much experience with Express so I don’t know if it was ingenious or sketchy.

In case the slack channel gets overlooked (i guess a lot of the activity has moved to the forums):

you need to get a ObjectBuilder from that Express Object (like Express::buildObject provides) :

if (is_object(Express::getObjectByHandle('member'))) {
  $member = Express::getObjectByHandle('member');
  $cat = $member->getAttributeKeyCategory();
  $exists = $cat->getAttributeKeyByHandle('member_pos');
  if (!is_object($exists)) {
    $builder = $this->app->make(ObjectBuilder::class);
    $builder->setEntity($member);
    $builder->addAttribute('number', 'Position', 'member_pos');
    $builder->save();
  }
}

in the above example i added the position to existing express Members. hopefully that points you to the right direction

How did you make setEntity() method work? I can not see any method like that in ObjectBuilder class. Any magic function doesn’t seem to work too.

Just came back from the docs. Seems like it is not there and the paste i sent in the previous reply relies on this extension:

namespace Concrete\Package\YourPackage;
use Concrete\Core\Express\ObjectBuilder as CoreObjectBuilder;
class ObjectBuilder extends CoreObjectBuilder
{
    public function setEntity($entity)
    {
        $this->entity = $entity;
    }
}

Thanks, it makes sense now.
Cheers

Hi all. I came across this post as it is exactly what I needed. But unfortunately, I am getting an error I can’t solve.

Object { type: “Doctrine\ORM\Exception\EntityMissingAssignedId”, message: “Entity of type Concrete\Core\Entity\Attribute\Key\Settings\TextSettings is missing an assigned ID for field ‘key’. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.”, code: 0, … }

Any ideas?

Not sure why but this error has stopped. I think it was reinstalling the package.

1 Like