title: Call PHP function inside TinyMCE modal window on the WordPress backend
body: <p>I am using a static .js file that is registered for a TinyMCE plugin. You click on the new button and it opens up the modal window, with a form in it, that I use to generate a Shortcode. The problem is that I need some of my form fields to be populated from PHP functions. I've been looking at articles on this for hours and haven't found a workable solution. Right now my php function is a Shortcode, so I need to adapt it to be a regular old function. But the big challenge is figuring out how to arrange this so that the .js file can take the function in the form. Here's the basic stuff. First, some chunks of the .js file:</p>
  <pre><code>(function(){
      // creates the plugin
      tinymce.create('tinymce.plugins.myshortcode', {
          // creates control instances based on the control's id.
          createControl : function(id, controlManager) {
              if (id == 'myshortcode') {
                  // creates the button
                  var button = controlManager.createButton('myshortcode', {
                      title : 'My Shortcode', // title of the button
                      image : '../wp-content/plugins/my-shortcode/js/images/myshortcode.png',  // path to the button's image
                      onclick : function() {
                          // triggers the thickbox
                          var width = jQuery(window).width(), H = jQuery(window).height(), W = ( 720 &lt; width ) ? 720 : width;
                          W = W - 80;
                          H = H - 80;
                          tb_show( 'My Shortcode', '#TB_inline?width=' + W + '&amp;height=' + H + '&amp;inlineId=myshortcode-form' );
                      }
                  });
                  return button;
              }
              return null;
          }
      });
      // registers the plugin.
      tinymce.PluginManager.add('myshortcode', tinymce.plugins.myshortcode);
      jQuery(function(){
          var form = jQuery(' \
  \
  The HTML Web Form all goes in here.\
  \
   ');
  var table = form.find('table');
          form.appendTo('body').hide();
          form.find('#myshortcode-submit').click(function(){
              var options = { 
                  'att1'  : '',
                  'att2'   : '',
                  'att3'   : '',
                  'att4'   : '',
                  };
              var shortcode = '[myshortcode';
              
                  for( var index in options) {
                  var value = table.find('#myshortcode-' + index).val();
                  
                  if ( value !== options[index] &amp;&amp; value != null )
                      shortcode += ' ' + index + '=&quot;' + value + '&quot;';
              }
              
              shortcode += '] content here. [/myshortcode]';
              
              tinyMCE.activeEditor.execCommand('mceInsertContent', 0, shortcode);
              
              tb_remove();
          });
      });
  })()
  </code></pre>
  <p>But in that spot where it says, &quot;The HTML Web Form goes in here,&quot; I need to have a couple of fields that are generated based on PHP functions. I've only written one of the two so far, and as I said, it's currently written as a Shortcode, so I need to change it (not sure the best way to do that given the other big questions here). But here it is:</p>
  <pre><code>add_shortcode('rolescapsdropdown', 'sc_rolescapsdropdown');
  function sc_rolescapsdropdown($attr) {
      global $wp_roles;
      $all_roles = $wp_roles-&gt;roles; 
      $editable_roles = apply_filters('editable_roles', $all_roles); 
      $user = new WP_User( 1 );
      $capslist = $user-&gt;allcaps;
      $dropdown = '&lt;select multiple&gt;';
      foreach($editable_roles as $role=&gt;$theroles){
          $dropdown .= '&lt;option value=&quot;'.$role.'&quot;&gt;'.$role.'&lt;/option&gt;';
      }
      foreach($capslist as $cap=&gt;$caps){
          if($cap !== 'administrator' &amp;&amp; $cap !== 'level_0' &amp;&amp; $cap !== 'level_1' &amp;&amp; $cap !== 'level_2' &amp;&amp; $cap !== 'level_3' &amp;&amp; $cap !== 'level_4' &amp;&amp; $cap !== 'level_5' &amp;&amp; $cap !== 'level_6' &amp;&amp; $cap !== 'level_7' &amp;&amp; $cap !== 'level_8' &amp;&amp; $cap !== 'level_9' &amp;&amp; $cap !== 'level_10'){ 
              $dropdown .= '&lt;option value=&quot;'.$cap.'&quot;&gt;'.$cap.'&lt;/option&gt;';
          }
      }
      $dropdown .= '&lt;/select&gt;';
      return $dropdown;
  }
  </code></pre>
  <p>I'm hoping to avoid having to learn Ajax here. But I tried making the .js file a .php file and just wrapping the JavaScript in <code>&lt;script&gt;</code> tags, but then all the TinyMCE buttons disappeared, so apparently it won't let me use a .php file to register the plugin.</p>
  <h3>Update 1</h3>
  <p>One idea I have is to try to move the web form to a php file, and just have the .js file that registers the TMCE plugin call it up, but I wouldn't know if that would work, nor how to get the .js file to recognize the existence of the form in an external php file.</p>
  <h3>Update 2</h3>
  <p>Based on ScottA's help, here's how I'm trying to work this:</p>
  <p>I've added this to my static .js file that has the form:</p>
  <pre><code>$.get( &quot;ajax/test.php&quot;, function( data ) {
    var options = data.options;
    for(row in options) {
       $(&quot;#option-list&quot;).append(&quot;&lt;option value=&quot; + options[row].value + &quot;&gt;&quot; + options[row].name + &quot;&lt;/option&gt;&quot;);
       // debug for unexpected results
       console.log(data.options);
    }
  }, &quot;json&quot; );
  </code></pre>
  <p>I've created this test.php file in a subdirectory called &quot;ajax&quot;:</p>
  <pre><code>function rolescapsdropdown() {
      global $wp_roles;
      $all_roles = $wp_roles-&gt;roles; 
      $editable_roles = apply_filters('editable_roles', $all_roles); 
      $user = new WP_User( 1 );
      $capslist = $user-&gt;allcaps;
      $all_options = $editable_roles . $capslist;
      $all_options[]['value'] = $value;
      $all_options[]['name'] = $name;
      echo json_encode( array('options' =&gt; $all_options) );
  }
  </code></pre>
  <p>And I added this HTML to the form in the static .js file:</p>
  <pre><code>&lt;select id=&quot;option-list&quot;&gt;&lt;/select&gt;
  </code></pre>
  <p>What I'm getting is a blank modal window. None of the HTML is showing up at all when I include the <code>$.get</code> function.</p>
  <h3>Update 3</h3>
  <p>Still getting a blank modal window. I converted it back to a shortcode to see what it outputs. This...</p>
  <pre><code>add_shortcode('rolesdropdown', 'sc_rolesdropdown');
  function sc_rolesdropdown() {
      global $wp_roles;
      $all_roles = $wp_roles-&gt;roles; 
      $editable_roles = apply_filters('editable_roles', $all_roles); 
      $user = new WP_User( 1 );
      $capslist = $user-&gt;allcaps;
      foreach ($editable_roles as $role=&gt;$theroles){
          $all_options = $role;
      }
      foreach ($capslist as $cap=&gt;$caps){
          $all_options .= $cap;
      }
      echo json_encode( array('options' =&gt; $all_options) );
  }
  </code></pre>
  <p>outputs this on the page:</p>
  <blockquote>
  <p>{&quot;options&quot;:&quot;trollswitch_themesedit_themesactivate_pluginsedit_pluginsedit_usersedit_filesmanage_optionsmoderate_commentsmanage_categoriesmanage_linksupload_filesimportunfiltered_htmledit_postsedit_others_postsedit_published_postspublish_postsedit_pagesreadlevel_10level_9level_8level_7level_6level_5level_4level_3level_2level_1level_0edit_others_pagesedit_published_pagespublish_pagesdelete_pagesdelete_others_pagesdelete_published_pagesdelete_postsdelete_others_postsdelete_published_postsdelete_private_postsedit_private_postsread_private_postsdelete_private_pagesedit_private_pagesread_private_pagesdelete_userscreate_usersunfiltered_uploadedit_dashboardupdate_pluginsdelete_pluginsinstall_pluginsupdate_themesinstall_themesupdate_corelist_usersremove_usersadd_userspromote_usersedit_theme_optionsdelete_themesexportbe_trollexec_phpedit_others_phpadministrator&quot;}</p>
  </blockquote>
  <p>But when in the modal window on the backend, the window is just blank when the <code>$.get</code> is calling the file with that function in it.</p>