• Resolved DanRoller

    (@danroller)


    I am converting a web application to wordpress.
    I need a way to write a page from the plugin with the http header from the plugin values.

    Use cases:
    (1) Extract a subset of plugin data in csv format into a spreadsheet.
    (2) Export a private file (.doc, .xls, .txt, …) as uploaded back into the native application.

    The uploading and extraction code is working but when I try exporting a file,
    the wordpress headers and menus have already been written. The ob_end_clean, header, header,
    ob_clean, flush,readfile, and die approach deals with the tail end but not the start.

    Being new to wordpress,
    (1) is there a way to have full control of the http response? Disabling headers?
    (2) should I not try to support a common business application on wordpress?

    I have seen responses that
    (1) have the site mug their template for either a page# or url parameter,
    but I think it prohibitly ugly to require sites to manually.
    (2) suppose it could also require a theme and try to bind the plugin to it.
    I don’t know how to do that or if it is possible.
    (2) could such an plugin use a “static” page? I haven’t figure that out.
    (3) indicate that another platform such as Drupal is more appropriate for such activity.

    Love to hear your thoughts.

Viewing 12 replies - 1 through 12 (of 12 total)
  • Moderator bcworkz

    (@bcworkz)

    You can control the full http response by requesting your own php page instead of a WP page or post, but that may not be necessary. To send your required headers, it’s a matter of sending them from an action hook that fires early enough that no html content has yet been sent. As a starting point for investigating an approach, try hooking the ‘init’ action. Your action callback will check if the request involves your plugin, and if so sends the necessary headers.

    Should you be extending WP to do something beyond its intended scope? I personally think no, but obviously many developers have done just that. You can jump into the fray if you like. Is there a better platform? Probably, but I’m not seeing anything initially that you should not be able to do in WP.

    Requiring a theme would be a bad decision. It would make some things much easier, but there is usually a way around it, it just requires more work. There’s a definite learning curve working with WP, but you will find you can do most things that are worth doing once you have adequate understanding of how things work.

    Thread Starter DanRoller

    (@danroller)

    Thanks, with that it turned out to be easy!

    My entry routine now has the following.

    function xxx_httpheaders(){
      if ( isset( $_GET['sc_menu'] ) && $_GET['sc_menu'] == 'ShowAttachment' ) {
        ob_end_clean();
        header('Content-Description: File Transfer');
        header('Content-Type: ' . $_GET['mimetype']  );
        header('Content-Disposition: attachment; filename=' . $_GET['fname'] );
        header('Content-Transfer-Encoding: binary');
        header("Cache-control: private");
        header('Pragma: private');
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
      }
    }
    add_action( 'admin_init', 'xxx_httpheaders', 1 );

    and my ShowAttachment.php writes out the doc/txt/xls/… file.

    Thanks again.

    Thread Starter DanRoller

    (@danroller)

    The http header problem was definitely solved but I was fooled thinking I was done.

    My problem is that the entire contents of the wordpress the html stream is still written before my plugin’s output.
    All of my ob_clean efforts didn’t solve that.

    And the pdf reader didn’t mind!

    I have played with removing all menus, but there is so many other items.

    I’m stuck here and would appreciate any help.

    Moderator bcworkz

    (@bcworkz)

    I hate it when that happens!

    Unfortunately, there is not an easy answer because various themes do different things with the content. As mentioned, requiring a particular theme is not a good solution, a different strategy is needed. Worst case, you could bypass the entire theme by requesting your own php page that does what you need. You only need to require wp-load.php at the top so the page can access WP functions.

    That’s a desperate solution though, as your page will not have any theme styling, which is almost as bad as requiring a theme. The best approach depends on how this content is to appear in relation to the usual post or page display. Individual posts have hooks you can use if content is to appear for each post. There’s possibly a solution so it only appears with the first post, a variation on the sticky post feature.

    If your content only appears on a particular page, you could develop a template for the page post type and have your activation script add a page based on this template to the DB. Then the page is completely under your control, yet it will pick up the theme styling as a page post type.

    I’m just grasping in the dark with generic ideas. If you don’t mind sharing what you’re specifically trying to accomplish, I might be able to suggest a specific workable approach.

    Thread Starter DanRoller

    (@danroller)

    Here is the context.

    This is a simple business application (converted from asp.net/sqlserver) in which multiple people in an organization create items, track activity, and upload documents in support of that activity. Image a standalone application that can be launched within wordpress.

    Those uploaded documents are stored outside of the wordpress path and by clinking a link within the application, the document is retrieved. If it is a word doc/pdf/…, then the browser prompts you to open or save.

    In addition, extracting tabular data from the application can be done by clicking a link that generates a tab-separated values output suitable for an application like Excel. Again the user is prompted for open or save.

    In both of these situations, the plugin must tailor the http headers and the entire data stream so the user’s pc browser can ask about loading the right application. A wordpress theme is for a human to see in the browser, but this response is for an application such as MS Word.

    All of this works (setting mime types etc), except that the data stream in my wordpress version, starts with whatever text the theme generates. I need absolutely no leading characters in that data stream.

    You refer to having “Worst case, you could bypass the entire theme by requesting your own php page that does what you need. “. I don’t know how to do that in WordPress. In my case, it would need generate a zero length string. Please advise and I will give it a try.

    Thanks

    Moderator bcworkz

    (@bcworkz)

    I need absolutely no leading characters in that data stream.

    That’s what I needed to know! Thanks for the explanation, I still don’t fully see what’s going on, but it shouldn’t matter any more. You definitely need your own bypass page. I’ll assume these links that are clicked elsewhere pass the needed information for the external app as URL parameters. POST requests can work too, the only difference is the array you pull data from.

    Your bypass page is a standard .php page, residing in your plugin folder. To enable it to access WP functions, require_once('path/wp-load.php'); adjusting the path as necessary. If the user must be logged in to WP, require wp-admin/admin.php instead. Your PHP script can get the URL parameters from the super global $_GET. For example, a link to your page may look like this(the http munged intentionally):
    hxxp://example.com/wp-content/plugins/my-plugin/bypass.php?serial=any-data,that-your,app-needs

    Your page can get the data string passed with $_GET[‘serial’] and then explode it into components, or multiple parameters can be passed if that works better. Your script does whatever processing is necessary, including using WP functions and methods. The first thing sent of course is the header() calls. You can then echo out whatever stream your external app requires. After that, I’m not sure what happens, maybe nothing, the app takes over. At this point, unless you called a function that sends output, the only data sent is what your script sent, nothing has come from WP. You could now send other content or load a template or whatever. You just cannot redirect because data has been sent. In this situation, the only way to redirect is through javascript. I’m sure this approach will meet your needs, give it a go.

    Thread Starter DanRoller

    (@danroller)

    Solved. Thanks, I owe you another pint!
    And I learned a bit in the process.

    Thanks again.

    Thread Starter DanRoller

    (@danroller)

    I have changed this item back to unresolved because when I tried to submit the plugin, it was rejected because its use of wp-load.php.

    I’ll see if I can get around not have wp-load.php, but I expect to be lost in the woods for awhile.

    Moderator bcworkz

    (@bcworkz)

    Oh crud! I should have warned you about that. I didn’t really grasp this was headed to the repository. Apologies.

    One way around the wp-load.php restriction is to use AJAX like calls, I’m not sure if that’s possible for your situation. Another possibility is to hook some action from which you can do what you need to do. Again, I’m not sure this approach will work, and I’m not sure what a good action would be to hook. I guess pick one that looks good from Plugin API/Action Reference and see what happens.

    Using wp-load.php is a convenient hack for custom private processes but it’s not ready for prime time distribution to the public.

    Thread Starter DanRoller

    (@danroller)

    I appreciate your help and it got me though a lot of stuff.

    But then I made it more complex. I had taken all of the app to depend on wp-load because I couldn’t get Tools/Available Tools and Setting to behave. I now have the primary app working (minus the tools/setting issues).

    Now back to the original problem – tab separated download to excel. Removing wp-load quickly gets into __( and ABSPATH not found, probably can bypass, but I need to know who the user is
    is_user_logged, user name, get_current_blog_id,
    then DB_HOST, DB_USER, …
    and eventually escaping/sanitizing …

    As for picking a good hook presumes that I know something about hooks, but I’ll start reading from the top.
    Thanks again

    Thread Starter DanRoller

    (@danroller)

    And the init hook works! Just check for mimetype with $_GET and do the download of tsv or document starting with http headers.

    Thanks

    Moderator bcworkz

    (@bcworkz)

    You’re most welcome. Glad it worked out without too much pain!

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘Is full control of http response possible?’ is closed to new replies.