Upgrading package and change Express objects attributes

Permalink
I am currently developing a package and using Express objects. So in the install() method of the package controller I create the objects with attributes as described onhttps://documentation.concrete5.org/developers/express/programmatica...

But how do I change (add/remove) attributes of Express objects if I upgrade the package? If I use the same method (Express::buildObject) it will complain that the object already exists.

Any tips or links to examples how to do this?

piipolnl
 
JohntheFish replied on at Permalink Reply
JohntheFish
In any installer, adopt the principle of checking if something exists before creating it. That way the installer can serve the same purpose on install or on update and will still work correctly if patching up after a partially failed install.
piipolnl replied on at Permalink Reply
piipolnl
For anyone having the same question in the future.
I have extended the core ObjectBuilder (Concrete\Core\Express) in my package just to extend it with a setEntity() method. This way I can use the builders methods to create forms, attributes and associations for existing entities.

To create an attribute only in the case it does not exist yet I created this function in the controller of the package:
private function createAttribute($entity_handle, $type_handle, $name, $handle, Settings $settings = null)
    {
        $entity = Express::getObjectByHandle($entity_handle);
        $category = $entity->getAttributeKeyCategory();
        $existing = $category->getAttributeKeyByHandle($handle);
        if (!is_object($existing)) {
            $builder = $this->app->make(ObjectBuilder::class);
            $builder->setEntity($entity);
            $builder->addAttribute($type_handle, $name, $handle, $settings);
            $builder->save();
        }
    }


To delete an attribute I created this method:
private function deleteAttribute($entity_handle, $handle)
    {   
        $entity = Express::getObjectByHandle($entity_handle);
        $category = $entity->getAttributeKeyCategory();
        $existing = $category->getAttributeKeyByHandle($handle);
        if (is_object($existing)) {
            \ORM::entityManager()->remove($existing);
            \ORM::entityManager()->flush();
        }   
    }


The ObjectBuilder in my package src folder looks like this:
<?php
namespace Concrete\Package\MyPackage\Src;
use Concrete\Core\Express\ObjectBuilder as CoreObjectBuilder;
class ObjectBuilder extends CoreObjectBuilder
{
    public function setEntity($entity)
    {
        $this->entity = $entity;
    }
}