Search

Hi

I've been trying to see if it is possible to send post values from a web application on a different server. I found a post in this forum that seemed to show that it is possible but unfortunately I am not having any luck getting it to work.

Here is the previous post that I used examples from:

http://www.getsymphony.com/discuss/thread/68411/

My situation is slightly different. I am not waiting for a post to come back from a transaction system. I am basically just trying to have a web application POST form values to my Symphony server.

here is a snippet of code I used in the event:

public function load()
    {
        if (isset($_POST['ext-save-image-data'])) {
            return $this->__trigger();
        }

        /*if (isset($_POST['action']['ext-save-image-data'])) {
            return $this->__trigger();
        }*/
    }

   protected function __trigger(){

        // cache the original POST array then reset it
        $ext = $_POST;
        $_POST = array();

        // map Paymate POST into Symphony fields
        $_POST['fields']['name'] = $ext['name'];

        // redirect user on completion
        $_POST['redirect'] = 'http://localhost/univers/dashboard/d2';

        include_once(TOOLKIT . '/events/class.event.section.php');
        return $result;
    }

Any help on this would be great.

Thanks. Sam

If you create a new "save" event in Symphony, you will see some example code for a frontend form that will make the browser send the needed POST request. For saving data, it doesn't make any difference if this POST request was generated by a browser or by a different server. That means: You might even use a standard event without any modifications if you manage to create the expected POST request and send it to a page that has the event attached.

If you want to use a different POST request (e.g using a different field name), you will have to translate the data/fields using custom code. This is described in the POST you mentioned. You must double-check that you create the correct $_POST['fields']['something'] items for Symphony.

The other thing to worry about is the trigger condition. Are you sure that your event gets triggered? Is $_POST['ext-save-image-data'] really set?

You should debug this systematically. As long as you use a browser, or Rested for OS X, or cURL in the Shell to send the POST request, you can see Symphony's response. So you should be able to use var_dump in your event for debugging.

Hi Michael.

Thanks for responding.

The tip to debug with vardump was very helpful. It's been a while since I've done any development and I totally didn't think about using vardump to debug.

I realized that I went down the wrong path right from the start, assuming that because I was posting from an outside application that I needed to reformat the form data to get it to work. So, now I've just adjusted the form variables to match the expected format (as you suggested from the example code) and it works.

However, I have 2 situations, the first where I can control the format of the POST data, and the second where I need to translate the data being received by POST. In the second case I have not been able to get it to work.

I followed the example in the "Use Post Values..." link. The __trigger condition is functioning and I am able to format the the POST data correctly. However the event seems to return an empty result.

I initially ran into a couple of errors because I think the remapping Post variables example was using an older version of symphony. I'm using the latest, v2.62. The first error I encountered was with the include:

include(TOOLKIT . '/events/event.section.php');

I got this error from symphony:

Symphony Warning: include(/Users/sam/Sites/univers/symphony/lib/toolkit/events/event.section.php)

I saw that the new class had a different file name (class.event.section.php), so I changed it to reflect the new file name.

This cause a second PHP error:

PHP Fatal error:  Cannot redeclare class SectionEvent in /Users/sam/Sites/univers/symphony/lib/toolkit/events/class.event.section.php on line 745

So I changed the include to include_once.

I didn't get any more errors after this, but when I check the $result variable, it's empty.

Perhaps there is a new method to triggering the section event in Symphony 2.6?

Hi Michael.

I just figured out a simple work around by remapping the POST variables in the load() function of the event versus the __trigger() function.

public function load()
{
    if (isset($_POST['action']['ext-save-image-data'])) {
        // cache the original POST array then reset it
        $ext = $_POST;
            $_POST = array();

            // map POST into Symphony fields
            $_POST['fields']['name'] = $ext['fields']['name'];

        return $this->__trigger();
    }
}

I'm not sure why there would need to create the __trigger() function if it's possible to put everything before the trigger.

This solution seems to work though. Would there be any reason I would need to figure out how to make the __trigger() function work? It might be good though to understand why __trigger() doesn't work.

Sam

In Symphony 2.6, you don't need to include the class, because the autoloader cares for it. Create a new standard event and you will see that there is no include. In other words: The code in the other thread is outdated.

Apart from that, I have no idea what goes wrong, sorry.

Ah, and by the way, if you edit an event manually, remember to change the allowEditorToParse function to return false:

public static function allowEditorToParse()
{
    return false;
}

This will prevent the Symphony backend from overwriting the event with "default code".

Thanks. The allowEditorToParse() function will save me from having to figure that one out.

So as I understand it, it's best to remap the POST variables in the load() function instead of hijacking the trigger() function. It seems that by using the trigger() function it overrides the automated functionality and it is mostly for customized usage of the classes.

Out of curiosity, I tested the new method of how to execute a remap the POST variables through the __trigger() function:

protected function __trigger(){

        $ext = $_POST;
        $_POST = array();
        $_POST['fields']['name'] = $ext['name'];

        return $this->execute();

        return $result;
    }

This seems to work but there is no documentation on this change in the API for Symphony v2.62.

Sam

As long as you need the (default) functionality of saving entries, you shouldn't extend/overwrite the __trigger function or the execute function of an event. Everything you need can be done in the load function as well.

Thanks for your help.

One other question, would you know how to return an http status code from the event. I can't seem to get the event to return any response to the server that is sending the POST.

Sam

Which status code would you need? Symphony's "200" is not sufficient?

Symphony has built-in functionality to add headers to a page or remove them, but I haven't used that. My demands were much more brutal. :-) So I have sometimes used code like the following in events:

// We remove Symphony's 'cache control' headers which
// have already been set at this point
header_remove();

// Now we add cache control, see:
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
header('Pragma: no-cache');
header('Cache-Control: no-cache, must-revalidate, max-age=0');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
// We __must__ add the Expires header to tell mod_expires that
// it must not manipulate headers
header('Expires: Mon, 12 Dec 1982 06:14:00 GMT');

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Length: ' . filesize($file));

As said, this is the hard way, so I suggest to try the "Symphony way" first:

The page object can be retrieved using Frontend::Page(), and you can find some interesting methods in /symphony/lib/toolkit/class.page.php. You should be able to do things like the following (untested):

  • Frontend::Page()->addHeaderToPage('Content-Disposition', 'attachment');
  • Frontend::Page()->removeHeaderFromPage('Content-Disposition');
  • Frontend::Page()->setHttpStatus(403);

Hi Michael.

It turns out that I did not have my xmlhttprequest in the external POST set up properly and I wasn't receiving the 200 code. I've got it now to receive the code properly and it all works.

The suggestion for using Frontend::Page() will help though for other aspects of my application. Thanks for pointing me in the right direction.

There is one last thing I am trying to test out now that I can't get to work. Is it possible to use the Membership extension to add user name and password protection for the pages I'd like to send POST requests to from my external application. I can't seem to validate a username and password from an external site. This is the HTML form I am using and it doesn't seem to work from outside the Symphony CMS. I've got it working internally with the same form. Is there something I am doing wrong or is this not possible for security reasons?

    <form method="post" action="http://site.com/login" autocomplete='off'>
        <label>Username
            <input name="fields[username]" type="text" />
        </label>
        <label>Password
            <input name="fields[password]" type="password" />
        </label>

        <input name="redirect" type="hidden" value="http://site.com/login/login-resp" />
        <input name="member-action[login]" type="submit" value="Login" />
    </form>

Thanks, Sam

I figured it out. As usual it was something very simple but took forever to figure out. I did not have a trailing "/" at the end of the URL I wanted to post to.

All works now.

Sam

Great, glad you got it working!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details