Good morning people.

It seems that due to the way the media browser popup is implemented as an iframe it's not possible to pass current node ID through the contexutal filters.

For example:

I'm trying to create a view in the media browser for "media attached to this node". I add a new display called "Files on node", add a relationship of "File usage: Content", and then a contexual filter of "Content: Nid", providing a default value of "Content ID from URL".

If I preview this in the views editor by putting "2" in the preview field, I see exactly what I would expect to see - all the media files that are attached to node 2. The query is:

SELECT file_managed.timestamp AS file_managed_timestamp, file_managed.fid AS fid, SUM(file_usage.count) AS file_usage_count
FROM 
{file_managed} file_managed
LEFT JOIN {file_usage} file_usage ON file_managed.fid = file_usage.fid
INNER JOIN {node} node_file_usage ON file_usage.id = node_file_usage.nid AND file_usage.type = 'node'
WHERE (( (node_file_usage.nid = '2' ) )AND(( (file_managed.status IN  ('1')) )))
GROUP BY file_managed_timestamp, fid
ORDER BY file_managed_timestamp DESC
LIMIT 25 OFFSET 0

Which is great.

Unfortunately, when you actually try this on a real node it doesn't work, because the query there is:

SELECT file_managed.timestamp AS file_managed_timestamp, file_managed.fid AS fid, SUM(file_usage.count) AS file_usage_count
FROM 
{file_managed} file_managed
LEFT JOIN {file_usage} file_usage ON file_managed.fid = file_usage.fid
INNER JOIN {node} node_file_usage ON file_usage.id = node_file_usage.nid AND file_usage.type = 'node'
WHERE (( (node_file_usage.nid = 'browser' ) )AND(( (file_managed.status IN  ('1')) )))
GROUP BY file_managed_timestamp, fid
ORDER BY file_managed_timestamp DESC
LIMIT 25 OFFSET 0

as dragged from the mysql.log file.

I'm assuming that this is because the "Content ID from URL" is calling "arg(1)" to get the node ID, but since we're now in an iframe, sticking a bit of PHP into the view to dump the current url gives me:

media/browser?render=media-popup&types%5B%5D=audio&types%5B%5D=image&types%5B%5D=video&types%5B%5D=document&activePlugins=&enabledPlugins=&file_directory=&id=media_wysiwyg&plugins=undefined

as the current URL - the URL of the iframe presumably.

I'm marking this as a bug, because it's very much not working as expected, but I'd be perfectly happy to work around it with a custom PHP filter to get the node ID instead of using "Content ID from URL" - if I could find any way to get at the current node ID from there that is.

Comments

James Tipler’s picture

Issue summary: View changes
pbattino’s picture

I had exactly the same problem.... I wanted to achieve the same result.
The workaround is painful.
I managed to change the URL of the IFRAME into

/media/browser?nid=5574&render=....

and use it as an input for the view, but it's really a hacky solution. It would be nice for Media module pop-up to automatically get those info from the calling page. In general, anyway, I would say that the IFRAME solution is not a good idea, I would prefer a full AJAX pop-up completely managed by the calling page. If there's an error, for example, I end up with a pop-up that I can't close containing another drupal page.... Not ideal.

After page load, I run this:

       if ($("body.page-node").size() < 1) return;
       var url = Drupal.settings.media.browserUrl;
       var i = url.indexOf("?"); 

       var nid = document.body.className.match(/(page-node-)(\d+)/)[2];
       if (!$.isNumeric(nid)) return;
       // use query string "?" and not "/" or you break Media Pop-up at last screen
       Drupal.settings.media.browserUrl = url.slice(0,i+1) + "nid="+ nid + "&" + url.slice(i+1);
James Tipler’s picture

Thankyou!

Do you think you could expand on that a bit for me tho? I'm afraid javascript isn't my strong point. I'd assume that you'd create a custom module with a fixMediaPopup.js included, then wrap this in a $(document).ready() inside that file... doesn't appear to work as it doesn't seem to have access to the Drupal.settings.media.browserUrl object... is there somewhere specific that this code needs to go, or am I missing some pre-prep required to load that object into an external script?

pbattino’s picture

@James Tipler
yes this code goes into a js file that you need to run every time a page is loaded.
In my case I have it in a file with other scripts. You can have it alone if you want, but the TIME of execution (or better the ORDER of execution) is important because you need to make sure that the code generating Drupal.settings.media.browserUrl has run before this script.
If it does not work for you it may be for this reason. What I usually do I put all my code related to changing UI things into a single module and I give the module a very high weight at install time, so I'm sure it runs AFTER any other module:

/**
 * Implements hook_enable()
 * to set module weight: higher weight gets executed after other modules, so it can post-process their output
 */
function mymodule_ui_enable() {
	db_update('system') -> fields(array('weight' => 1000)) -> condition('type', 'module') -> condition('name', 'mymodule_ui') -> execute();
}

(I don't remember where I found this example but it works with D7)
In this case my JS is in a js file that is part of this "mymodule_ui" module.

/**
 * Implements hook_init().
 *
 * load essential JS script
 *
 */
function mymodule_ui_init() {
	drupal_add_js(drupal_get_path('module', 'mymodule_ui') . '/js/scripts.js');
}

/js/scripts.js contains:

(function($) {
    // here you may have other unrelated stuff
   //

    //Media pop up handling
    $(function(){
      // pass NID of current page to Media Browser Pop-up
      try {
       if ($("body.page-node").size() < 1) return;
       var url = Drupal.settings.media.browserUrl;
       var i = url.indexOf("?"); 

       var nid = document.body.className.match(/(page-node-)(\d+)/)[2];
       if (!$.isNumeric(nid)) return;
       // use query string "?" and not "/" or you break Media Pop-up at last screen
       Drupal.settings.media.browserUrl = url.slice(0,i+1) + "nid="+ nid + "&" + url.slice(i+1);
       
       
       
      } catch(err) {

      }
    });

})(jQuery);
James Tipler’s picture

That's perfect, got it working at last.

Thank you so much for your help.

smd_ksu’s picture

What did you use for the view contextual filter to get this to work? I was able to get the js script to rewrite the iframe URL.

smd_ksu’s picture

Ok, for anyone who runs across this. Here is what I used in the view contextual filter, along with the module code from #4.

$nids = $_SERVER ['REQUEST_URI'];
$parts = parse_url($nids);
parse_str($parts['query'], $query);
return $query['nid'];
pbattino’s picture

@smd_ksu I did something similar:

if (!empty($_GET["nid"])) {
return $_GET["nid"];
} else {
return 0;
}

it is somehow needed, to avoid getting errors when the NID is not specified (for example: a new node).

Jan van Diepen’s picture

Created a simple module that adds a new Argument Default Views Plugin that uses HTTP_REFERER to retrieve the Node ID.

https://www.drupal.org/project/views_plugin_argument_default_referer

tyler.frankenstein’s picture

#7 set me on the right path to acquiring node ids, organic group ids, etc. Except I used $_SERVER['HTTP_REFERER'] instead of $_SERVER ['REQUEST_URI'], thank you @smd_ksu and @Jan van Diepen for sending me in the right direction.

chris matthews’s picture

Status: Active » Closed (outdated)

Recent versions of media have resolved most of peoples concerns and is compatible with entity translation, multilingual and various advanced configurations. Due to the high volume of inactive and most often irrelevant issues we are Closing this as (outdated). If for whatever reason this issue is important to you AND you still have issues after checking the media recipe documentation, then let us know and we will review your concerns.

Otherwise, see the recipe documentation for how to configure media and for troubleshooting tips OR refer to the media_dev distribution if you want to see a working media setup.

As mentioned, feel free to make some noise in this issue if you still feel it is important to you or someone else.

Thanks,

Media team