Events Made Easy Forums Bug fixed or feature request implemented Accepting Payments for Events

Viewing 45 posts - 1 through 45 (of 45 total)
  • Author
    Posts
  • #48050
    Anonymous
    Inactive

    Most of our events are free, but we have an event coming up next month for which we’d like to collect an admission charge via Paypal. I know I need to start looking into the RSVP hooks. But we want to have three different prices (non-member, member, and student). Is there a way to set that up within EME, since there’s no way yet to add items to the booking form?

    Franky, can you point me in the right direction for how to automatically approve the booking upon Paypal success?

    And if anyone has successfully gotten EME and Paypal working together, I’d love to talk to you about it and get your advice. I’m very comfortable with coding, but I don’t really know anything about the backend interface of Paypal. jamesf at jamesf dot com

    Thanks!

    #43227
    Anonymous
    Inactive

    Is there any hand-off back from PayPal, after payment is made there, for the current version of EME?

    That is, is there any kind of communication back to EME (or to the user’s e-mail) to confirm payment? Or should we just track things manually for now…

    #48051
    Anonymous
    Inactive

    James,

    Just thought I’d point you to this topic as I came across it the other day: http://www.e-dynamics.be/bbpress/topic.php?id=353#post-1600

    Might help you out a bit.

    You can use attributes for the different member levels.

    Hope that helps

    Thanks

    Tom

    #48052
    Anonymous
    Inactive

    Yes, I’ve seen that thread. It’s just enough to let me know that it can be done, but vague enough to leave me with the questions I’ve posed.

    For instance, how do I make the attributes (member levels) part of the booking record in the database and/or pass that information over to Paypal?

    #48053
    Franky
    Keymaster

    The rsvp hook allows you to get the whole event info as well (using the eme_get_event($event_id) function), so you do can have event attributes and use those values in the hook.

    The url for rsvp approval is simple: you can get it from firebug when doing an approval via web, but the thing is that wordpress (and eme) checks for permissions, so if you script this you need a script that first logs in into wordpress, retains the pph session value and then does the same action. Maybe easier would be a small php script that updates the mysql booking table for that booking id. I’ll try to write a demo script later on for this.

    Custom form fields are not yet possible, I hope to get around to that next …

    #48054
    Anonymous
    Inactive

    OK, I’ve spent the day working on this project, and I’ve almost got it working. My three biggest remaining hurdles are getting the price type into the booking_comment table field, cleaning up the display of the EME fields on the Paypal form page, and making it more customizable and user friendly. Franky, do you think you might have some advice?

    It all goes into the custom_functions.php of my theme, and then I have two pages in my WordPress that each call a single shortcode to run the Paypal form (seen by the user) and the Paypal IPN listener (not seen by the user). Like I said, it’s not very elegant, but it’s getting the job done (I hope!)

    It looks for custom attributes with “PRICE” in the name to build options for the Paypal form.

    <?php session_start();

    add_action('eme_insert_rsvp_action','do_my_stuff');
    function do_my_stuff($booking) {

    $eventinfo = eme_get_event($booking['event_id']);
    if($eventinfo['registration_requires_approval']) {
    //redirect to accept payment page, using post of event_id
    $_SESSION['booking_id']=$booking['booking_id'];
    $_SESSION['event_id'] = $booking['event_id'];
    header("Location: http://www.something.com/event-registration-payment-page/"); /* Redirect browser */

    /* Make sure that code below does not get executed when we redirect. */
    exit;

    } else {
    // DON'T DO ANYTHING, SINCE THIS FUNCTION IS JUST FOR PAYPAL
    }
    }

    function build_paypal_buttons_page () {
    $event_id=$_SESSION['event_id'];
    $eventinfo = eme_get_event($event_id);
    // print_r($eventinfo);

    $display = "";

    $display .= $eventinfo['event_name']."<br>n";
    $display .= $eventinfo['event_start_date']."<br>n";
    $display .= $eventinfo['event_start_time']."<br>n";
    $display .= $eventinfo['location_name']."<br>n";
    $display .= $eventinfo['location_address']."<br>n";
    $display .= $eventinfo['location_town']."<br>n";

    //add Paypal form, based on sample code from https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_formbasics
    $display .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">'."n";
    $display .= ' <!-- Identify your business so that you can collect the payments. -->'."n";
    // $display .= '<input type="hidden" name="business" value="paypaldev@something.com">'."n";
    $display .= '<input type="hidden" name="business" value="paypal_1310754343_biz@something.com">'."n";
    $display .= ' <!-- Specify a Buy Now button. -->'."n";
    $display .= '<input type="hidden" name="cmd" value="_xclick">'."n";
    $display .= '<input type="hidden" name="notify_url" value="http://www.something.com/event-payment-complete">'."n";

    $display .= ' <!-- Specify details about the item that buyers will purchase. --> '."n";
    $display .= '<input type="hidden" name="item_name" value="'.$eventinfo['event_name'].'">'."n";
    $display .= '<input type="hidden" name="item_number" value="'.$_SESSION['booking_id'].'">'."n";
    $display .= '<input type="hidden" name="currency_code" value="USD">'."n";

    $display .= '<!-- Provide a dropdown menu option field with prices. -->'."n";
    $display .= '<input type="hidden" name="on0" value="Registration_Type">Registration Type<br />'."n";
    $display .= '<select name="os0">'."n";

    $dis2 = "";
    $attrib_counter = 0;
    foreach ($eventinfo['event_attributes'] as $attrib_name => $attrib_value) {
    if (strpos($attrib_name,"PRICE") !== FALSE) {
    $attrib_name = str_ireplace ("_PRICE","",$attrib_name);
    $display .= '<option value="'.$attrib_name.'">'.$attrib_name.' - $'.$attrib_value.' USD</option>'."n";

    $dis2 .= '<input type="hidden" name="option_select'.$attrib_counter.'" value="'.$attrib_name.'">'."n";
    $dis2 .= '<input type="hidden" name="option_amount'.$attrib_counter.'" value="'.$attrib_value.'">'."n";

    } // close if PRICE
    $attrib_counter++;
    } // close foreach

    $display .= '</select>'."n";
    $display .= '<br />'."n";
    $display .= '<!-- Specify the price that PayPal uses for each option. -->'."n";
    $display .= '<input type="hidden" name="option_index" value="0">'."n";

    $display .= $dis2;

    $display .= '<!-- Display the payment button. -->'."n";
    $display .= '<input type="image" name="submit" border="0"'."n";
    $display .= 'src="https://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"'."n";
    $display .= 'alt="PayPal -The safer, easier way to pay online">'."n";
    $display .= '<img alt="" border="0" width="1" height="1"'."n";
    $display .= 'src="https://www.paypal.com/en_US/i/scr/pixel.gif" >'."n";
    $display .= '</form>'."n";

    echo $display;

    }
    add_shortcode ('eme_paypal_buttons','build_paypal_buttons_page');

    function eme_add_comment_from_paypal ($newcomment, $booking_id) {
    //THIS FUNCTION DOES NOT WORK
    global $wpdb;
    $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
    $sql = "SELECT * FROM $bookings_table WHERE booking_id = $booking_id";
    $bookings = $wpdb->get_results($sql, ARRAY_A);
    if ($bookings) {
    foreach ($bookings as $booking) {
    $oldcomment = $booking['booking_comment'];
    }
    }
    $oldcomment = $oldcomment . ", " . $newcomment;

    $sql = "UPDATE $bookings_table SET booking_comment = $oldcomment WHERE booking_id = $booking_id";
    $wpdb->query($sql);
    }

    function eme_paypal_listener () {

    error_reporting(E_ALL ^ E_NOTICE);

    $email = 'me@something.com';
    $header = "";
    $emailtext = "";
    // Read the post from PayPal and add 'cmd'
    $req = 'cmd=_notify-validate';
    if(function_exists('get_magic_quotes_gpc'))
    {
    $get_magic_quotes_exits = true;
    }
    foreach ($_POST as $key => $value)
    // Handle escape characters, which depends on setting of magic quotes
    {
    if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1){
    $value = urlencode(stripslashes($value));
    } else {
    $value = urlencode($value);
    }
    $req .= "&$key=$value";
    }
    // Post back to PayPal to validate
    $header .= "POST /cgi-bin/webscr HTTP/1.0rn";
    $header .= "Content-Type: application/x-www-form-urlencodedrn";
    $header .= "Content-Length: " . strlen($req) . "rnrn";

    $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
    //$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);

    // Process validation from PayPal
    // TODO: This sample does not test the HTTP response code. All
    // HTTP response codes must be handles or you should use an HTTP
    // library, such as cUrl

    if (!$fp) { // HTTP ERROR
    } else {
    // NO HTTP ERROR
    fputs ($fp, $header . $req);
    while (!feof($fp)) {
    $res = fgets ($fp, 1024);
    if (strcmp ($res, "VERIFIED") == 0) {
    // TODO:
    // Check the payment_status is Completed
    // Check that txn_id has not been previously processed
    // Check that receiver_email is your Primary PayPal email
    // Check that payment_amount/payment_currency are correct
    // Process payment
    // If 'VERIFIED', send an email of IPN variables and values to the
    // specified email address

    eme_approve_booking($_POST['item_number']);
    eme_add_comment_from_paypal ($_POST['item_name'], $_POST['item_number']);

    foreach ($_POST as $key => $value){
    $emailtext .= $key . " = " .$value ."nn";
    }
    // echol( "Live-VERIFIED IPN". $emailtext . "nn" . $req);
    // mail($email, "Live-VERIFIED IPN", $emailtext . "nn" . $req);
    } else if (strcmp ($res, "INVALID") == 0) {
    // If 'INVALID', send an email. TODO: Log for manual investigation.
    foreach ($_POST as $key => $value){
    $emailtext .= $key . " = " .$value ."nn";
    }
    // echo( "Live-INVALID IPN". $emailtext . "nn" . $req);
    // mail($email, "Live-INVALID IPN", $emailtext . "nn" . $req);
    }

    }
    }
    fclose ($fp);
    }

    add_shortcode ('eme_paypal_listener','eme_paypal_listener');

    ?>

    #48055
    Franky
    Keymaster

    A quick solution to be able to add extra data/html to the form would be to add a filter after the form creation. The trunk version has these now:

    eme_add_booking_form_filter

    eme_delete_booking_form_filter

    so you can edit the generated html to your liking. Not perfect (I hate editing html directly in a script personally) but it should help you.

    #48056
    Anonymous
    Inactive

    So could I use the eme_add_booking_form_filter to replace the normal booking form with the output from build_paypal_buttons_page () without having to redirect to a new WordPress page? Then all of the information about what the event is (event_name, event_start_date, location, etc.) would already be displayed. That would be nice — I’m not really happy with the browser redirect solution.

    I’m new to filters — I’ll start researching them now. But could I trigger that filter from within the rsvp hook, so that the user making the reservation sees the normal booking form, and then after they submit their reservation then the booking form gets replaced with the paypal form?

    Also, I couldn’t figure out where the user-defined attributes are stored in the settings files or MySQL database, to manually add my *_PRICE attributes. I had to add them into a display field where I didn’t really want them…

    #48057
    Anonymous
    Inactive

    Or maybe I’m going about this all wrong, and I should replace the whole booking form with a form that goes straight to Paypal before it goes to the EME database. The booking record won’t get added until there’s a verified payment to Paypal, and we get the name, phone number, and email back from Paypal via the IPN. Now that I know about the add_booking_form_filter, maybe I can do it that way…

    #48058
    Franky
    Keymaster

    Attributes are serialized and then stored in one column in the events table, column event_attributes

    These filters should best be used to add custom fields, so as to be able to give them to paypal in the background after submit.

    #48059
    Anonymous
    Inactive

    Ah, I think I see. I’m not looking to pass extra data over to Paypal at this point, since that has to go from its own form in its own submittal, hence the separate second payment page.

    My problem is getting the Paypal data into the EME database upon approval. I’ve been able to use the eme_approve_booking function, but I also want to insert the item_name (which is where I’m storing the type of ticket) into the comment field along with whatever is already there.

    I tried to write a eme_add_comment_from_paypal function, but it’s not working.

    I also would love to utilize EME’s functions for displaying event data in the user-specified formats instead of just echoing the data from the database — can you point me towards those?

    #48060
    Franky
    Keymaster

    The html output for a single event was created in a function eme_display_single_event_shortcode, but in trunk I made the function eme_display_single_event(), that takes the event ID as single argument and returns the html output for that event.

    #48061
    Anonymous
    Inactive

    Thanks! But that will pull the html for the entire single event page, including the add and cancel booking forms that I have coded into my single event page format.

    What I’m looking for, I think, is the handlers for the shortcodes like #_12HSTARTTIME or #M #j #Y so I can include something like that in my function instead of using the raw:

    $eventinfo = eme_get_event($event_id);
    $display .= $eventinfo['event_start_date']."<br>n";
    $display .= $eventinfo['event_start_time']."<br>n";

    #48062
    Franky
    Keymaster

    Then try the eme_replace_placeholders function, e.g.:

    eme_replace_placeholders("#_12HSTARTTIME", $event);

    The first string can be whatever you want (normally it’s one of the formats you enter in the admin section)

    #48063
    Anonymous
    Inactive

    Perfect! That was just what I needed. Thanks!

    I think my last step for my hacked-together version is fixing the function that updates the comment field in the bookings table to append the ticket type (passed as $newcomment). Do you have any insight into why this isn’t working?

    function eme_add_comment_from_paypal ($newcomment, $booking_id) {
    //THIS FUNCTION DOES NOT WORK
    global $wpdb;
    $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
    $sql = "SELECT * FROM $bookings_table WHERE booking_id = $booking_id";
    $bookings = $wpdb->get_results($sql, ARRAY_A);
    if ($bookings) {
    foreach ($bookings as $booking) {
    $oldcomment = $booking['booking_comment'];
    }
    }
    $oldcomment = $oldcomment . ", " . $newcomment;

    $sql = "UPDATE $bookings_table SET booking_comment = $oldcomment WHERE booking_id = $booking_id";
    $wpdb->query($sql);
    }

    #48064
    Franky
    Keymaster

    You miss signle quotes around the “$oldcomment” in the update statement.

    But best (and I need to change the code in general accordingly) is to use $wpdb->prepare.

    I already have one example on the usage in the trunk code.

    #48065
    Franky
    Keymaster

    Just for your information: basic paypal integration will be in the next version

    #48066
    Anonymous
    Inactive

    Hey! Just wondering if there’s a way to put in a simple page re-direct so I can place in my own paypal button? Having the registration at the bottom of a page, gets really confusing for people when they register and then have to pay ! (it auto takes them to the top of the page as well!! )

    Not sure if this is what is planned for the next plug in, but help would be great!

    Thanks

    #48067
    Franky
    Keymaster

    You can put the registration form wherever you want it, just change the event format setting and place the #_ADDBOOKINGFORM where you want it to be.

    #48068
    Anonymous
    Inactive

    Thanks for the response. I understand about the #_ADDBOOKINGFORM – perhaps I should rephrase my question.

    I want people to see at the bottom of the event page, that they can register. Once they ‘sign up’ the page is refreshed, and goes back to the top of the page. It is on the BOTTOM of this page that the tiny ‘pay via paypal’ link sites (where the registration previously was) This is a bit too hidden for people to see!

    Is there a way that if I create my own ‘register now’ button, when clicked will take them to the registration ONLY for that event ? Meaning does each even have a ‘register URL’ associated with it?

    OR is there a way that once someone puts in their information to register, when they click the button they are taken to a NEW PAGE that has the ‘pay via paypal’ ONLY on the page, thus making it much easier for people to know they have to pay.

    Sorry if this is confusing, I’ve been trying to deal with this issue for over a week now so my mind is all over the place about it.

    Thanks,

    Natasha

    #48069
    Franky
    Keymaster

    Normally it works like this: is there a way that once someone puts in their information to register, when they click the button they are taken to a NEW PAGE that has the 'pay via paypal' ONLY on the page, thus making it much easier for people to know they have to pay.

    if not, it seems to me the theme you’re using for the events page is messing things up.

    #48070
    Anonymous
    Inactive

    Franky,

    I haven’t updated EME in a bit, but I thought that in the first revision that included Paypal, the behavior was to load the Pay Via Paypal button in the same page as the Registration form. Is the going-to-a-new-page behavior a new functionality that might require Natasha to install the newest version of EME?

    –James

    #48071
    Franky
    Keymaster

    The paypal button has always shown on a separate page. If not, something in my mind is seriously derailed …

    #48072
    Anonymous
    Inactive

    Hey, it definitely just stays on the same page! I’ve included it now so it at least appears at the top of the page, but cannot get it to direct elsewhere? I only downloaded EME a few weeks ago, I don’t think there’s been a new version since?

    #48073
    Franky
    Keymaster

    Yes there’s a new version, it even changed names. See http://www.e-dynamics.be/bbpress/topic.php?id=1603

    #48074
    Franky
    Keymaster

    Not reproducible here: paypal button appears on seperate page.

    #48075
    Anonymous
    Inactive

    I’d like the “Send Your Booking” button to send them directly to PayPal, then return with the “thanks for your booking page”, send the confirmation email, etc.

    Possible? Or, how could I hook the code to do it?

    #48076
    Franky
    Keymaster

    Not possible (for now): the button is constructed using the info on the page before. Using some jquery it could be done, but … not now 🙂

    #48077
    Anonymous
    Inactive

    After thinking about it, I think the behavior is almost right as it is… The person registers, then they’re taken to “Pay with Paypal” page. I’d like to be able to change the language on this page.

    The one thing I think it should do differently is not send any confirmation emails until after returning from a successful PayPal transaction.

    #48078
    Franky
    Keymaster

    Payment in paypal changes the payed status for the booking, paypal itself makes it very clear that the payment has succeeded

    #48079
    Anonymous
    Inactive

    Good, thank you. I’ve got to test it with a live payment.

    In the future, a useful feature might be to distinguished between RESERVED (currently “booked”) attendees and CONFIRMED/PAID attendees –for purposes of event planning and determining available seating.

    #48080
    Anonymous
    Inactive

    Going a different way, is there any way to say “user cannot even RESERVE a seat unless payment confirmation was received”?

    #48081
    Franky
    Keymaster

    No, that will always be a manual process (well, at least for now). No real cron-integration exists for wordpress, so “timeouts” are difficult.

    #48082
    Anonymous
    Inactive

    Okay, I guess, but I was just thinking you could increment #_BOOKEDSEATS only when a “unique number” registration switched to “Paid”.

    #48083
    Franky
    Keymaster

    Well, for each booking a unique number is already being generated. The thing is: I’ve never seen asynchronous payment using paypal yet. People would need to “log in” to EME again in one way or another and then click the button. That’s possible of course … I could always regenerate the payment code for each unpaid booking for a user. Hmmm … interesting ….

    #48084
    Anonymous
    Inactive

    Let me be more clear — My “going a different way” suggestion was, for the regular existing real time order process:

    1. User registers/requests event seats, just as happens now. EME Unique Number generated, just as happens now. But #_BOOKEDSEATS does NOT increment yet.

    2. User then clicks the provided PayPal link and immediately pays for seats (via PayPal or new method). EME Unique Number switches to PAID, just as happens now.

    3. Only THEN, with the EME Unique Switched to PAID, does the #_BOOKEDSEATS get incremented.

    This way we could track “registered” (requested) spots versus actual confirmed/paid spots. This behavior for #BOOKEDSEATS could be controlled by a new “require payment confirmation” toggle WITHOUT having to deploy a separate #_CONFIRMEDSEATS counter, which was my original thought.

    As to the “asynchronous payment” idea, my related wishlist item was having a few variables (either replacing or in addition to #_BOOKEDSEATS) that would tell not only who had “registered” for (requested) the event but also who had PAID (or been approved for) the event. Right now EME seems to treat every unconfirmed request as reducing the number of available seats. This is not realistic for many purposes.

    The asynchronous payment idea is similar to GuiltyCol’s request #4 at PayPal Integration Feedback

    Ideally the email confirmation should contain a url that allows the user to return and pay at some point in the future (the url of the Thank You page in (3) above would do….”

    Anyhow, just food for thought for your future road map.

    #48085
    Anonymous
    Inactive

    Hi Franky. You wrote that “Payment in paypal changes the payed status for the booking”.

    We finally got our first live payment, and it did NOT work that way. The reservation still shows as pending, with a paid status of “No”.

    It was paid via PayPal “e-check” — is that why? Does the automatic EME update only work with credit card transactions?

    Hmm, you have an IPN.php file, but I don’t see any log directories where I can track what happened, and the IPN script seems to have everything set at defaults? Am I looking in the right place? Do I need to change this code manually?

    class IPN {

    // Official url: https://www.paypal.com/cgi-bin/webscr
    // Testing urls: (do test!)
    // - https://www.sandbox.paypal.com/cgi-bin/webscr
    // - http://www.eliteweaver.co.uk/testing/ipntest.php
    public $paypal_url = 'https://www.paypal.com/cgi-bin/webscr';

    // your paypal email (the one that receives the payments)
    public $paypal_email = 'paypal@example.com';

    // log to file options
    public $log_to_file = true; // write logs to file
    public $log_filename = '/path/to/ipn.log'; // the log filename (should NOT be web accessible)

    // log to e-mail options
    public $log_to_email = true; // send logs by e-mail
    public $log_email = 'log@example.com'; // where you want to receive the logs
    public $log_subject = 'IPN Log: '; // prefix for the e-mail subject

    // database information
    public $log_to_db = true; // false not recommended
    public $db_host = 'localhost';
    public $db_user = 'some_user';
    public $db_pass = 'some_password';
    public $db_name = 'ipn';

    #48086
    Franky
    Keymaster

    See the function “eme_paypal_ipn” in eme_rsvp.php if you want to activate logging. I never tried an e-check though …

    #48092
    Anonymous
    Inactive

    [ Very strange; the forum wouldn’t let me post this here until I created a dummy post and then edited the below in… ]

    Thanks, I’m doing that now. (Maybe the option should be in Settings.) I guess these are the only two fields I should touch:

    // log to file options
    $ipn->log_to_file = true; // write logs to file
    $ipn->log_filename = '/paypal-ipn.log'; // the log filename (should NOT be web accessible and should be writable)

    Apparently the library you’ve used supports e-mail notification and database integration… I’m assuming the log comes into play ONLY during active PayPal sessions, and doesn’t log any other part of the reservation process.

    I’m guessing the slow echeck is by definition NOT an “instant payment” so that’s why our payment didn’t register in EME… But it’s still the case that the stock EME setup is supposed to automagically update the “Paid” status, correct?

    Looking into what “IPN” is, I find a nice tutorial at http://www.micahcarrick.com/paypal-ipn-with-php.html

    Hmm, looks like there’s at least one Google Checkout routine on phpkode.com too. Too bad I can’t really program PHP…

    #48093
    Anonymous
    Inactive

    Wait a second; do I need to specifically enable “IPN” for our PayPal account? This site implies that I do…

    http://net.tutsplus.com/tutorials/php/using-paypals-instant-payment-notification-with-php/

    #48094
    Franky
    Keymaster

    sometimes the forum does act strange … I should switch to something else 🙂

    Did you got it working ok now?

    #48095
    Anonymous
    Inactive

    Apparently not! I created the log file, with 755 (user writable) permissions, but even after two additional purchases the log file is still blank.

    #48096
    Anonymous
    Inactive

    It just occurred to me that I might need to use /home/myaccount/paypal-ipn.log as the path, because I’m on a shared hosting account. (I was assuming that my account’s root was considered root but perhaps that’s wrong.) I was just trying to keep it out of www/mydomain, as instructed. I’ll let you know if it starts logging now.

    On the bright side, the automated “Paid:Yes” function is working now, even for that “echeck”, which took a couple of days but now shows Paid, somehow.

    A minor bug to report — in the “Respondents” sidebar in the Event setup screen, there are little “x” circles next to each reservation. These highlight when hovered over, but clicking them does NOT delete the reservation…

    #48097
    Franky
    Keymaster

    That’s fixed in the current dev, see here: http://www.e-dynamics.be/bbpress/topic.php?id=1767#post-6852

    #48098
    Anonymous
    Inactive

    Yay, my new path worked and my IPN log is functioning now.

    And thank you for the pointer to the bug fix. I can certainly wait for the next release.

Viewing 45 posts - 1 through 45 (of 45 total)
  • The forum ‘Bug fixed or feature request implemented’ is closed to new topics and replies.
Scroll to Top