XF 2.0 Ability to customize the data import during an addon installation

MaGeFH

Active member
Hello there,

I'm currently working on an addon that extends the advertising system shipping with XF2. In here, i've extended the advertising position entity to require a type (class string), type data (json) and some more fields. This also means that XF/AddOn/DataType/AdvertsingPosition will be extended to read and write the entity fields.

The problem i'm currentyl wrestling with is this: If i don't specify some defaults for the new fields in the database, the installation process will abort because it tries to import the data using the un-extended version of XF/AddOn/DataType/AdvertsingPosition during the installation process. This makes sense and should stay that way.

What we need would be the ability to defer the data import to a job that runs on the next app cycle (see XF/Job/Manager::enqueueLater). Ideally that would be a setting of the addon's setup class:

PHP:
class Setup extends AbstractSetup
{
    // Maybe put it into a trait
    use XF\AddOn\DeferDataImportTrait;

    // This method could be omitted, maybe?
    // The DataType classes could be generated automatically
    // by looking at the class extensions data...
    public function getDataImportToDefer()
    {
        // Return each base class that can't
        // or should'nt be imported straigt away
        return [
            'XF\AddOn\DataType\AdvertisingPosition',
        ];
    }
   
    /* ... */
}

My current approach would be to specify some defaults in the table and put deferred job to re-import the data onto the job queue. That should run on the next application call and import the data properly.

Has anyone faced similar "problems", or has a clean solution to this?
 
Last edited:
I think you want to look using at the postInstall and postUpgrade methods in your add-on setup class. When those run, you're generally guaranteed to have your add-on be active again.
 
I've started testing with extended data and ran into another problem:

The import of new data xml files fails on the old code because XF\AddOn\DataType\AdvertisingPosition::importAddOnData expects the contents of the advertising_position xml-tag to be a singular CDATA value.

However i changed the xml files format to save more than one CDATA value, e.g.:

XML:
<advertising_position position_id="search_results_above" active="1" fh_ad_type="Fh\Advertising\Position\Type\Single">
    <arguments><![CDATA[[{}]]]></arguments>
    <fh_ad_type_options><![CDATA[[{}]]]></fh_ad_type_options>
    <fh_ad_code_position_before><![CDATA[<li class="block-row">]]></fh_ad_code_position_before>
    <fh_ad_code_position_after><![CDATA[</li>]]></fh_ad_code_position_after>
    <fh_ad_code_advert_before><![CDATA[]]></fh_ad_code_advert_before>
    <fh_ad_code_advert_after><![CDATA[]]></fh_ad_code_advert_after>
</advertising_position>

This fails during install because extracting CDATA from advertising_position results in NULL and that results in this further down the line:

InvalidArgumentException: Attempted to convert NULL to JSON array [arguments] in src/XF/Mvc/Entity/Entity.php at line 685

I'm pretty much for adding the ability to defer the loading of specific addon data types during install/upgrade. It's not a use case that exotic, isn't it?

Cheers & Greetings! :)
 
I wouldn't ever recommend changing the format of the data in any of our XML files. It'd be roughly equivalent to changing default columns in our schema, which has caused problems in the past.

If you have to go down this particular route, you'd need to either insert your extra data in a way that doesn't interfere (such as additional attributes) or with a separate tag/file.

It's worth noting that while it's not 100% equivalent, you can do at least some of what you appear to be doing in this change directly in the template using a content check (the position before/after stuff).
 
Ok, I see your point there. :)

I think adding extra xml-tags as siblings to the advertising_position tags will work well enough. ;)

Thanks for your time. Most helpful! :)
 
Back
Top Bottom