Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums Other Can someone recommend a customizable contact form, please?

  • This topic is empty.
Viewing 15 posts - 76 through 90 (of 225 total)
  • Author
    Posts
  • #172801
    __
    Participant

    Okay, let’s move on to validating the form submission.
    (Remember our validate() method?)

    If you recall, we have a property $_validation that tells us how each form field needs to be validated. Right now, we have only two needs: some fields are required, and one field must also be an email address.

        protected function _validateRequired( $value,&$m="" ){
            if( ! $value ){
                $m = "This field is required.";
                return false;
            }
            return true;
        }
    

    Very straightforward. If the value is empty, it fails validation.

    You may not have seen &$someVariable before —the & makes it a reference. Instead of getting a copy of whatever variable we pass to the method, we get the actual variable. So, when we assign an error message to $m inside the method, that message exists in $m outside the method. Don’t worry if you don’t quite “get” this, for now. It works.

    Same thing for email addresses:

        protected function _validateEmail( $value,&$m="" ){
            // {@see http://php.net/filter_var}
            if( ! filter_var( $value,FILTER_VALIDATE_EMAIL ) ){
                $m = "Please provide a valid email address.";
                return false;
            }
            return true;
        }
    

    Checking the anti-spam challenge is a little different. First, we have to get the proper question from the session, and then we can check if the answer is correct.

        protected function _validateAntispam( $value ){
            // get antispam key from session, make sure the value is the correct answer
            $correct = (
                isset( $_SESSION[__CLASS__]["antispam"] )
                && isset( $this->_antispam[$_SESSION[__CLASS__]["antispam"]] )
                && $this->_antispam[$_SESSION[__CLASS__]["antispam"]] === $value
            );
            // remove used questions from session to prevent re-use
            unset( $_SESSION[__CLASS__]["antispam"] );
            if( ! $correct ){
                $this->_errors["antispam"] = "Please try the antispam challenge again.";
                return false;
            }
            return true;
        }
    

    Checking the security token follows a similar process, but we also check that the token “age” is valid.

        protected function _validateToken( $token ){
            // aside from simply including an issued token,
            // the submission should not be too fast nor too slow
            $valid = (
                isset( $_SESSION[__CLASS__][$token] )
                && $this->_time > ($_SESSION[__CLASS__][$token] + $this->_option["token.min"])
                && $this->_time < ($_SESSION[__CLASS__][$token] + $this->_option["token.max"])
            );
            // remove used tokens from session (prevents duplicate submissions)
            unset( $_SESSION[__CLASS__][$token] );
            return $valid;
        }
    

    Last thing is to make a method that actually runs all this validation when the form is submitted. A class’ __construct method is run automatically when the class instance is created, so we’ll use that.

        public function __construct( array $_post=null ){
            // set the current time in microseconds
            $this->_time = microtime( true );
            // validate the form submission if present
            if( $_post ){
                if( $this->validate( $_post ) ){ $this->_sendEmail(); }
            }
        }
    

    Updated Gist.

    #172813
    Anonymous
    Inactive

    Greetings un-traq-ed,

    Added the new Gist and when submitted I get: Fatal error: Call to undefined method contactMichael1961::_sendEmail() in /form-test/class/contactMichael1961.php on line 156

    Also, someone submitted the original form, but I’m not sure how it was received as there was no email address associated with it to be sent to.

    I have to be honest and admit I’m lost on this at this point.

    Best Regards.

    #172815
    __
    Participant

    when submitted I get: Fatal error: Call to undefined method contactMichael1961::_sendEmail()

    Right; we didn’t write that method yet. It’s next on the list.

    Also, someone submitted the original form, but I’m not sure how it was received as there was no email address associated with it to be sent to.

    I was looking at it (the copy on your website) earlier. I saw two options in the “Send To” box, so you obviously added something to the $_recipients property.

    I don’t see how you would have actually received an email (from this project, anyway), since we didn’t yet write any code that sends an email.

    #172817
    Anonymous
    Inactive

    Greetings un-traq-ed,

    I was looking at it (the copy on your website) earlier. I saw two options in the “Send To” box, so you obviously added something to the $_recipients property.

    The only two things there are “Please Select” and Display Name.”

    Is this form designed to provide the IP address of the sender, because an IP was shown however it was submitted.

    Best Regards.

    #172853
    __
    Participant

    The only two things there are “Please Select” and Display Name.”

    Well, that sounds right. I didn’t remember exactly (you had taken it down by the time I double-checked last night). Did you put a real email address in the script under “Display Name”?

    Is this form designed to provide the IP address of the sender, because an IP was shown however it was submitted.

    No, it is not. You actually got an email? I don’t see how that is possible. As I said above, we haven’t yet written any code that sends emails. You don’t have another contact page on this server (perhaps something StableHost offers as a “one-click install app”)?

    #172915
    Anonymous
    Inactive

    I took it down out of concern after receiving the email. I don’t have any real concerns about it as the IP shows it from Bosnia and the email given checks out as legit and fits with the IP. The message was gibberish like it was a test.

    I didn’t add any active emails and did not change the example emails you gave in fact. I knew in doing so it would make the form active.

    There was a form similar in appearance to what we are doing, in another file on my server, which has now been deleted. It wasn’t an active form either, but removed none-the-less. These were the only two forms that might have been available, but it seems finding either by chance online a long-shot. I just thought someone saw the link to the form were are working on in a prior post of mine, clicked it, and gave it a try.

    I’ve not installed any contact forms from Stablehost, if available.

    I would like the finished form to display the senders IP address as part of the received communication as this could be helpful.

    I’ve been looking over the coding since yesterday and am not quite as lost as yesterday. Still some questions but will wait until everything in place and then ask anything outstanding. I like to try to figure things out on my own while seeing how things like this are put together. I want to know what each function and code does and why.

    Best Regards.

    #173221
    Anonymous
    Inactive

    Greetings un-traq-ed,

    I think I understand the coding as much as I am going to at this point without getting confused.

    I do have a question about a script/code used in the contactPage.php, specifically “{$_SERVER[‘DOCUMENT_ROOT’]}/””/””/contactMichael1961.php”;

    I’ve read some on the “{$_SERVER[”]}…..”; array but am still uncertain. I believe this “imports” the class contactMichael1961.php, but is this also useful for “importing” parts of a page, say a menu bar? It would be much easier to make changes to one element such as copyright year, menu bar, and other elements and be able to use a script/code on a page to “import” the one example instead of having to make changes to each individual page. I digress from our contact form, but was just wondering.

    Looking forward to the next step in the form.

    Many Thanks!!!

    #173307
    __
    Participant

    include (and require) basically get another file on your server, and “insert” it into the current script.

    We are using this to make our class definition available, so we can use it.

    You’re right that it is also very common to use it as a templating tool, i.e., to store bits of HTML in separate files and “assemble” them as desired.

    I’ll get back to the next step a bit later this afternoon. I’ve had a few things to deal with this morning. : )

    #173352
    __
    Participant

    I’ve read some on the “$_SERVER” array but am still uncertain…

    Missed this earlier. The $_SERVER superglobal is a collection of values that came from your server (e.g., Apache). REQUEST_URI is probably one of the most common/useful: it what the user actually typed into the address bar. Other values (all of the HTTP_{something} values, for example) are other info taken from the actual HTTP request, such as the hostname, the user agent string, the accept-language header, and so forth.

    One fix before we start: <select required> must become <select name=recipient required>.

    We’ll also need to add the recipient field to the validation list:

    $_validation = array(
        "name"    => "required",
        "email"   => array("required","email"),
        "message" => null,
        "recipient" => "recipient"
    );
    

    and make a validation method for it:

    protected function _validateRecipient( $value,&$m="" ){
        if( ! isset( $this->_recipients[$value] ) ){
            // because "recipient" is a drop-down list of good options, 
            // there should _never_ be a bad option submitted
            $this->_spamTrap();
        }
        $this->_to = $this->recipients[$value];
        return true;
    }
    

    Here’s a basic idea for our _sendEmail method:

    protected function _sendEmail(){
            // parse email message template
            $message = $this->_message;
            foreach( $this->_values as $k=>$v ){
                $pr["%$k%"] = $v;
            }
            $message = str_replace( array_keys( $pr ),array_values( $pr ),$message );
            // append additional info based on options (e.g., IP address)
            foreach( (array)$this->_option["append"] as $opt ){
                $method = "_messageAppend$opt";
                if( is_callable( [$this,$method] ) ){
                    $message .= $this->$method();
                }
            }
            // send the message
            $to = $this->_recipients[$this->_values["recipient"]];
            $subject = $this->_subject;
            $headers = "From: {$this->_values["email"]}\r\n";
            $headers .= "Sender: noreply@{$_SERVER["HTTP_HOST"]}\r\n";
            $sent = mb_send_mail( $to,$subject,$message,$headers );
            if( $sent ){
                $this->_notice = "Your message was sent successfully.";
                // unset values now that they've been sent
                foreach( $this->_values as $k=>$v ){
                    $this->_values[$k] = "";
                }
            }
            else{
                $this->_notice = "There was a problem: please try again.";
            }
        }
    

    I’ve done some testing. This allows us to add additional info to the message, such as the IP address as you mentioned earlier. Simply add a name to the $_option["append"] array:

    $_option = array(
        "append" => array( "IP" );
    );
    

    and then write a method that composes the line you want to append to the message:

        protected function _messageAppendIP(){
            return "Sent from IP: {$_SERVER["REMOTE_ADDR"]}";
        }
    

    We can add other info if you desire. Just let me know!

    #173357
    Anonymous
    Inactive

    Greetings un-traq-ed,

    I had some trouble getting it to work and had several warning messages again until I realized that you hadn’t added the following to your Gist contactPage.php

    include_once "{$_SERVER['DOCUMENT_ROOT']}/””/””/contactMichael1961.php"; 
    

    I copied and pasted all again instead of adding new parts to the coding as I’m still unsure. I felt good that I realized this though, albeit a small thing.

    Some confusion on my part.

    I’m getting a syntax error here:

    if( is_callable( [$this,$method] ) ){
    $message .= $this->$method();
    

    This seems to be missing from your updated Gist:

    protected function _validateRecipient( $value,&$m="" ){
        if( ! isset( $this->_recipients[$value] ) ){
            // because "recipient" is a drop-down list of good options, 
            // there should _never_ be a bad option submitted
            $this->_spamTrap();
        }
        $this->_to = $this->recipients[$value];
        return true;
    }
    

    The following doesn’t appear exactly on your Gist as it does in your example above, is that OK?:

    $_option = array(
        "append" => array( "IP" );
    );
    

    I forgot how to add contact names and addresses to the “send to” section.

    include (and require) basically get another file on your server, and “insert” it into the current script.

    I will want to talk more about the above later as it will help in not having to edit each page as I mentioned previously.

    Best Regards.

    #173395
    __
    Participant

    "{$_SERVER['DOCUMENT_ROOT']}/””/””/contactMichael1961.php"

    What’s with the “/””/””/” part? Based on your previous test page, it should be something like

    "{$_SERVER["DOCUMENT_ROOT"]}/form-test/class/contactMichael1961.php"

    I’m getting a syntax error here

    Sorry – the [] syntax only works in PHP 5.4+. We’ll replace it with this:

    if( is_callable( array($this,$method) ) ){
    

    This seems to be missing from your updated Gist

    So it is!
    …dunno how that happened.

    The following doesn’t appear exactly on your Gist as it does in your example above, is that OK?

    Yes, it’s okay. Our functions convert this value to an array if it is not, so if there is only one item to append you can just do "append" => "item". If there are several items to append, you’d need to do like "append" => array( "item1","item2" ).

    Sorry for the confusion. I’ll update the gist now.

    I will want to talk more about the above later …

    of course.

    #173409
    Anonymous
    Inactive

    What’s with the “/””/””/” part? Based on your previous test page, it should be something like

    I have it correct, I just took out the first part to post here, don’t ask me why.

    Sorry – the [] syntax only works in PHP 5.4+. We’ll replace it with this:

    I’m using PHP 5.6 or 5.8, so shouldn’t it work?

    I thought I knew how to add the missing part, but still am not confident enough to be certain at this point.

    I’ve added the latest Gist to the class and made minor additions to the form. I forget how to add the selections and email addresses associated to each however.

    What’s next?

    Many Thanks!!

    #173439
    __
    Participant

    I have it correct, I just took out the first part to post here

    ahh, I understand.

    the [] syntax only works in PHP 5.4+

    I’m using PHP 5.6 or 5.8, so shouldn’t it work?

    I would double-check that info.

    5.6 is a release candidate (i.e., it is still under testing and is not yet recommend for production). It seems odd that a shared hosting company would offer 5.6 to its customers at this stage of development. I would recommend using 5.5 or 5.4 (the current “stable” releases) until 5.6 is officially released.

    version 5.8 does not exist.

    edit: the response headers from your website claim you’re using “PHP/5.5.13”. So, yes, the [] array syntax should work. Are you still getting that syntax error? If so, what, specifically, does it say?

    I thought I knew how to add the missing part, but still am not confident enough to be certain at this point.

    I added all the changes we discussed to the gist. Have you tested the new version (since my last post)?

    I forget how to add the selections and email addresses associated to each however.

    In the class definition, look for the $_recipients property and add new recipients to the array (in {display name}=>{email address} format):

    protected $_recipients = array(
        "Alice"   => "[email protected]",
        "Bob"     => "[email protected]",
        "Mallory" => "[email protected]"
    );
    

    Also, on your test page, you might notice it shows “please select�” instead of “please select…“. This is because your server is not sending a default charset and so the ellipsis (and other unicode characters) may not be displayed correctly.

    You can fix this by adding UTF-8 as the default charset in your php.ini file (best solution), or by setting the header manually:

    header( "Content-type: text/html; charset=UTF-8" );
    

    Use UTF-8. Don’t let anyone convince you otherwise.

    What’s next?

    Should work, at this point. (Works for me.) If you want to tweak settings or add other features, let me know.

    The class could use some utility + convenience methods to make it more fully featured, but I’ll do that when I have a chance and turn it into a full-on tutorial.

    #173461
    Anonymous
    Inactive

    Greetings un-traq-ed,

    Well, I’ve screwed myself up and confused myself big-time. I’ve been trying to add some styles to the form to get it a bit closer to this one, which was an early concept.

    I goofed myself up by trying to get the function of the submit button to look and function like the concept one above. I know JS is involved but got confused on the shadowing of the button (stupid I know). Being away from the CSS styling too long has taken its toll I guess. Anyway, after that confusion I tried to get the field backgrounds to change to the light-grey color when selected using the same “textarea:focus” as in the concept, but nope and that confused me even more. I then tried to adjust the message area to match that of the concept, and to add a radius to the “Send To” box, its drop-down button, and to change the gradient colour of said button to match the submit button. The gradient is seemingly the only thing I got right before the mental block.

    I also tried to shift the anti-spam question area to the left to align with everything above, again a massive fail! With all of this I can’t even enter the protected $_recipients = array( in the right place it appears as I tried and nothing showed in the dropdown list.

    The finished form will need to fit to the right of the text on this page, so don’t let the concept page size concern you.

    I think I’ve addressed everything, but at this point I am so confused I can’t be sure.

    What’s the best approach to getting the “look” more to the concept?

    Oh, Stablehost says the php.ini file has UTF-8 as default, so I’m not sure why the characters aren’t showing as they should.

    Also, I checked my current PHP version and it is 5.4. The newest available for my server is 5.6. Sorry for the confusion on the version. How I thought I had the versions stated is beyond me!

    Best Regards.

    #173503
    __
    Participant

    Oh, Stablehost says the php.ini file has UTF-8 as default, so I’m not sure why the characters aren’t showing as they should.

    That’s on the server. You need to specify UTF-8 in the HTTP Headers, so the browser also knows what charset to use.

    Well, I’ve screwed myself up and confused myself big-time …

    Is your confusion just over how to achieve that styling? or did something else get mixed up? Remember, you can always start over. That’s the great part about git: if you mess things up, just revert.

    I also tried to shift the anti-spam question area to the left to align with everything above

    It’s shifted over because each fieldset has a padding on the left and right. You could do fieldset.antispam{ padding: .8em 0; } to override it.

    I know JS is involved but got confused on the shadowing of the button

    There’s no JS styling that button: it’s just border: 2px outset buttonface;. There is a bit of a gradient on the button backgrounds, which you could add without trouble (though I honestly couldn’t tell the difference).

    The javascript is all form validation. We can put it in if you wish, but consider:

    1. All of your validation can be handled in modern browsers (IE10+) natively with HTML5.
    2. Everything is validated server-side.

    If you need to support IE<9, or if you wanted some fancy functionality, then you’d need to use JS. Otherwise, you could leave it out with no ill effect.

    I tried to get the field backgrounds to change to the light-grey color when selected using the same “textarea:focus” as in the concept

    textarea:focus should work. To get the text inputs, we should probably add type=text (text is the default type, but if we add it explicitly we can use it for styling) and then use input[type=text], input[type=email].

    The color is #e7e7e7.

    I’ll add these changes to the gist.

Viewing 15 posts - 76 through 90 (of 225 total)
  • The forum ‘Other’ is closed to new topics and replies.