Views object from a different multisite.
I have an installation with multiple Drupal sites in one install (Drupal multisite). One of the multisites needs information from another multisite's nodes which use CCK. I've done such things before with direct, custom queries, but it's always bothered me that the CCK fields could shift around on me and my queries break. This time I'm trying to use Views2.
Let's say the site that has the information I want is #1 and the site querying the data is #2. I made the view that gets the data I want in site #1. It works perfectly. Then since I don't really want a formatted display of the data, I whipped up a tiny module to use views_get_view_result() in site #1 to make sure it returned an array that would be something I could use; it was.
Note here that the view is configured to be unrestricted access. It queries nid, author, a rolereference field, and a date field. The fields are managed in #1 by content_permissions module and the node by workflow_access. With all that node configuration and filters for the rolereference and workflow of the node, it still showed the view correctly on #1 through views_get_view_result().
I took exactly the same code I used for views_get_view_result() and put it on site #2, but I wrapped it in a db_prefix changer. The idea I thought would be that Drupal would just temporarily switch database tables and then switch right back transparently. Then I activated all the same workflow, CCK, and views modules on #2 to make sure there wouldn't be any missing modules that #1 needed to put up the same view result.
<span style="color: #000000"><span style="color: #0000BB"><?php<br>$old_db_prefix </span><span style="color: #007700">= </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'db_prefix'</span><span style="color: #007700">];<br></span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'db_prefix'</span><span style="color: #007700">] = </span><span style="color: #DD0000">'number_one_'</span><span style="color: #007700">;<br></span><span style="color: #0000BB">$view </span><span style="color: #007700">= </span><span style="color: #0000BB">views_get_view_result</span><span style="color: #007700">(</span><span style="color: #DD0000">'my_view_name'</span><span style="color: #007700">);<br></span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'db_prefix'</span><span style="color: #007700">] = </span><span style="color: #0000BB">$old_db_prefix</span><span style="color: #007700">;<br></span><span style="color: #0000BB">?></span></span>
This almost works to query the data I want from #1, except it doesn't return the CCK fields, only the nid and author. I did a little bit of debugging and found that in views_get_view_result(), the $view object handler for the CCK fields is listed as views_handler_field_broken.
Before I did some debugging to find the reference to views_handler_field_broken, I thought perhaps with the permissions modules on #1, it was a field access issue. I'm logged in as UID 1 on #2, I copied a $user object from a UID 1 session on #1, I inserted a session in the sessions table on #1, and I tried faking a masquerade, so I'm pretty sure it's not a permissions issue since I should be pretending to be UID 1 on #1 when that view executes.
I've tried re-installing views, CCK, the widgets, and workflow on #2 to make sure all the various parts were available to views when it came time to execute the view on #1 during the db_prefix switch. What I'm wondering now is whether CCK does some sort of hook_init() static variable field caching on #2 so that when it gets time to find those CCK fields I want on #1, they're not in the cache. Someone else suggested that perhaps I needed to re-execute some part of bootstrapping after I switch db_prefix, and then again after I switch back. I'm really not sure where to go next for getting those CCK fields to display and the doxygen stuff I found on views_handler_field_broken isn't very detailed on the reasons why it would be used as the handler. Perhaps there's an even better way than swapping out db_prefix and I can't see it cause I'm stuck in db_prefixing land.
A solution:
I figured out a hack that involves refreshing some CCK cache and preventing views from caching by hacking views.
After switching to the #2 db_prefix, I call content_clear_type_cache(TRUE);
then comment out the static $cache
variable in _views_fetch_data()
. I see that _views_fetch_data()
calls hook_views_data_alter
, but that is executed before I switch to the #2 db_prefix and does not run again as long as the static $cache
variable is set.
I still have a little bit of hope there's a way to do this without hacking up views. I saw this in view::execute()
that makes me think perhaps there's something I could do when configuring a view in #1 perhaps that would reference data in #2:
<span style="color: #000000"><span style="color: #0000BB"><?php<br> </span><span style="color: #FF8000">// Allow for a view to query an external database.<br> </span><span style="color: #007700">if (isset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">base_database</span><span style="color: #007700">)) {<br> </span><span style="color: #0000BB">db_set_active</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">base_database</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">$external </span><span style="color: #007700">= </span><span style="color: #0000BB">TRUE</span><span style="color: #007700">;<br> }<br></span><span style="color: #0000BB">?></span></span>
Post categories