The exportables system by default produces objects of class stdClass, and there's provision to set this to a different class by setting 'object' in the hook_schema data.
However, this doesn't quite go far enough.
In Clients module, client connection objects have different classes depending on their type -- this is the same pattern as in Flag module, for instance.
Obviously I can work around this in my load callback like this:
$type = $result[$name]->type;
$class = 'clients_connection_' . $type;
// Hand the object over to the constructor which takes care of putting the
// data into the handler object and any processing that needs doing.
$connection = new $class((array) $result[$name]);
but it's a bit messy to have to remake the object, and also it means I have to implement my own static caching rather than rely on that in ctools_export_load_object().
What I suggest is either:
a) a 'object class callback' setting, where the callback is called with the $data before calling _ctools_export_unpack_object().
b) two settings, 'object class key' and 'object class prefix'. So in my case I would set this in my hook_schema():
'object class key' => 'type'
'object class prefix' => 'clients_connection_'
Let me know which you prefer, or another method, and I'll work on a patch :)
Comment | File | Size | Author |
---|---|---|---|
#7 | 1146604-3.ctools.exportables-class-callback-factory.patch | 2.04 KB | joachim |
#3 | 1146604-2.ctools.exportables-class-callback.patch | 3.09 KB | joachim |
#2 | 1146604.ctools.exportables-class-callback.patch | 2.57 KB | joachim |
Comments
Comment #1
merlinofchaos CreditAttribution: merlinofchaos commentedThe callback is probably more flexible. Since I had never imagined a usecase where there would be multiple classes used for objects of the same time, I suspect the array of possible use cases is larger than what we have here. The callback would enable support for any. I'm in favor of going that route, and I'm happy to support this kind of case.
Comment #2
joachim CreditAttribution: joachim commentedOn 6 as that's where I have a test setup right now... will reroll for 7 if you approve the approach.
I'm not entirely sure about having all this prelude to calling _ctools_export_unpack_object() present in two places -- my gut feeling would be to change _ctools_export_unpack_object() to look inside $schema which it already has as a first parameter. In fact nothing calls _ctools_export_unpack_object() with an object to unpack into -- at least within ctools and as an underscore-prefixed function, it's meant to be internal...
Comment #3
joachim CreditAttribution: joachim commentedHere's another approach which I think is cleaner, though it removes the ability to pass in an arbitrary string to _ctools_export_unpack_object().
Comment #4
merlinofchaos CreditAttribution: merlinofchaos commentedThe second approach seems pretty reasonable.
Comment #5
joachim CreditAttribution: joachim commentedHad an idea for a third approach in my sleep... ;)
Define 'object factory' in the schema, and if set, that function is called instead of _ctools_export_unpack_object().
This would mean implementing modules can call their constructor with whatever parameters they need. In my case:
Comment #6
merlinofchaos CreditAttribution: merlinofchaos commentedOkay, I like approach #3 as a very sane, flexible way to do it.
Comment #7
joachim CreditAttribution: joachim commentedHere's approach #3. It's actually the simplest patch out of all three too! :)
Comment #8
merlinofchaos CreditAttribution: merlinofchaos commentedCommitted to D6 and D7. Note that in D6 I updated the API version for the new functionality and in both cases I updated API.txt