Support » Developing with WordPress » How to PHP script run “post self”

  • Dear Friends,
    I’d like to add an html page generate from php program. I need to make
    a simple form with select and an action. All form and other html code are
    inside PHP.

    To do that I’ve added a new shortcode in a child theme so to show it I just
    put this shortcode in a new wordpress page but I’ve discovered the big problem !

    The value selected inside form must to be used to the same code to run query
    sql and show the result.

    How can I run the same PHP program with POST_SELF ? Are there any other solutions ?

    Any ideas about it ? Somebody can post an example ?
    Thanks a lot !
    Best Regards
    Willy

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

    (@bcworkz)

    Why must the form post to self? If instead you post to wp-admin/admin-post.php, you can process the posted data from a custom action callback. The action tag is composed in part from an “action” value that your form posts. It’s similar to how Ajax works but you do not need JavaScript.

    If you must post to self, you need to create a custom page template that displays the content containing the shortcode. The template code can then handle POST submits depending on the value of $_SERVER[‘REQUEST_METHOD’].

    Thread Starter willy70

    (@willy70)

    Dear bcworkz,
    I think post to self due to manage data passed through form because I’ve read some articles but I’m not sure about it.
    If you more time for this question I’ll tell you others details.

    I need to create a page (html plus php) for showing two select.
    In the first user choose the year and in the second choose en event,
    after that there is button to confirm all data and run sql query on my
    custom table.

    The result , for example un array , must to be show in a new or in the
    same html page.

    Above I show you my script:
    <?php
    global $wpdb;
    $gare_2016 = $wpdb->get_results(“SELECT id,nome,luogo,data FROM “.$wpdb->prefix.”gpaltvt_gare WHERE data like ‘2016%’ order by data”);
    .. omissis…
    $anni = $wpdb->get_results(“SELECT DISTINCT(date_format(data, ‘%Y’)) AS id FROM “.$wpdb->prefix.”gpaltvt_gare order by id”);
    <!DOCTYPE html>
    <html>
    <head>
    <script>
    function populate(s1,s2){
    var s1 = document.getElementById(s1);
    var s2 = document.getElementById(s2);
    s2.innerHTML = “”;
    if(s1.value == “2016”){
    var optionArray = [<?php foreach ( $gare_2016 as $gara ) { echo chr(34);echo $gara->id;echo chr(124);echo $gara->nome;
    echo chr(34); } ?> ];
    } else if(s1.value == “2017”){
    var optionArray = [<?php foreach ( $gare_2017 as $gara ) { echo chr(34);echo $gara->id;echo chr(124);echo $gara->nome;
    echo chr(34);echo chr(44); } ?>];
    }
    for(var option in optionArray){
    var pair = optionArray[option].split(“|”);
    var newOption = document.createElement(“option”);
    newOption.value = pair[0];
    newOption.innerHTML = pair[1];
    s2.options.add(newOption);
    }
    }
    </script>
    </head>
    <body>
    <h2>Visualizza Classifica. Anno:
    <select id=”slct1″ name=”slct1″ onchange=”populate(this.id,’slct2′)”>
    <option value=””></option>
    <?php
    foreach ($anni as $anno)
    {
    $year=$anno->id;
    echo “<option value=”.$year.”>”.$year.”</option>”;
    }
    ?>
    </select>
    Gara:
    <select id=”slct2″ name=”slct2″></select>
    <input type=”submit” name=”submit” value=”Enter”>
    <hr />
    </body>
    </html>

    I’m not so fluent with PHP and to realize my little project with wp-admin/admin-post.php
    so you help is very very appreciate but think that this page can be used by non-logged users.

    Thank you so much for this suggestion.
    Best Regards

    • This reply was modified 4 years, 10 months ago by willy70.
    • This reply was modified 4 years, 10 months ago by willy70.
    Thread Starter willy70

    (@willy70)

    Are there someone that help me ?

    Thanks

    Best Regards
    Willy

    Moderator bcworkz

    (@bcworkz)

    Either option can be used by users not logged in, even though the target file is in wp-admin (unless you have more security added to that folder). But using admin-post.php with little fluency in PHP will be confusing, so a custom page template is your best option.

    You can use your existing file as the starting point. Add the required Template Name: comment header right after the first <?php. Save your file in the main folder of your theme. To avoid the need to replace the file after theme updates, consider creating a child theme.

    The other required changes are theme dependent. My instructions below are based on the way most themes setup their template files. If your theme departs from the norm, the changes needed may be different than what I describe.

    Remove <!DOCTYPE html><html><head> and replace it with get_header();?>
    The code you posted is missing a closing ?> before <!DOCTYPE html>. Remove that as well because get_header() is also PHP and the closing ?> is immediately after that. Also remove </head><body>. The HTML you are removing here should already occur in your theme’s header file.

    Remove </body></html> and replace with <?php get_footer();. Save your changes.

    Log in to your WP admin area and pick Add New under the Pages menu item. Give the new page a title. The slug WP creates based on the title will be how your page will be requested from browsers. You do not need to enter any content, it is not used. In the Page Attributes box, select the template you named with the Template Name: comment header of your custom page template. Publish the page.

    If your page was working before, the new WP page based on your template should work the same way. I’m not so sure it’s working correctly. The missing ?> is one problem. I don’t see where the user selections are being used for anything. While your form will work, it will not validate because there is no <form> element containing the fields.

    Anyway, this is how to setup a page in WP to submit to self.

    Andrew Nevins

    (@anevins)

    WCLDN 2018 Contributor | Volunteer support

    Thread Starter willy70

    (@willy70)

    Dear All,
    I think bcworkz’s suggestion is right and is the most professional one but
    reading that post I got an idea. Let me explain.

    I would like to avoid adding wordpress elements because unfortunately I am not a programmer and I have difficulty if I have to use complex objects or structures so
    what do you thing about this example:

    <script>
    function showresults(){
    alert (‘test’);
    }
    </script>
    <form name=XXXX action=”” onsubmit=”return showresults()”>

    the idea is to run javsacript routine that is already inside in the same PHP file.
    Now when user clicks on submit show test but I could change alert “….” with my
    sql and foreach statements for showing my array with values.

    Is correct ? Can it works ?

    Many thanks in adavnce for your help !!
    Bet Regards
    Willy

    Moderator bcworkz

    (@bcworkz)

    It depends on what you need to do with the submitted data and whether you need WP resources to process that data and serve the results. I was assuming you needed to use WP resources to process the submittal and give results. If you need server resources but not WP resources, you could create any generic PHP page to process the data. It’s when you need WP resources when your options are limited. Besides the two I’ve mentioned, Ajax is the only other option for WP.

    If you don’t need server resources at all, if all the necessary data can be included in the page output, then yes, you should use JavaScript or jQuery and avoid any additional server requests. If your intention is to display a limited number of messages, that is a classic example of using JavaScript to provide a good user experience.

    The script you provided utilizes SQL and PHP. These are server side resources. You cannot execute these in a browser. But you could execute them ahead of time and include all possible results in the page output, selectively displayed with JavaScript. It depends on the volume of data involved. If all the data significantly increases the page load time, it would be an inferior approach.

    Your SQL uses the $wpdb object, a WP resource. With that you still are limited to the options I mentioned. However, those queries do not require other WP resources, you could accomplish the queries with PHP mysqli functions and leave WP out of it.

    Thread Starter willy70

    (@willy70)

    Der Friend,
    your suggestion is correct and professional so I’ve decided to follow you but
    if you have more time for this case I’d like to tell my new problem.

    As you suggested I’ve created a new page template for Twentyeleven theme.
    To make this new template I’ve copied a php file , sidebar-page.php , and
    after that I made some changes.

    First I inserted a new name keeping the same scheme:

    <?php
    /**
    * Template Name: GrandPrix Template
    *
    * Description: My custom pages.
    *
    * @package WordPress
    * @subpackage Twenty_Eleven
    * @since Twenty Eleven 1.0
    */
    get_header();

    then I wrote my php original wordpress theme plus div statements. This second
    part of the code have a class for using db, some sql statement and some html
    because I’d like to run all of them in a server side. In this way I can
    make query and produce html form/select with the right values:

    global $wpdb;
    // load all GrandPrix races
    $gare_2016 = $wpdb->get_results(“SELECT id,nome,luogo,data FROM “.$wpdb->prefix.”gpaltvt_gare WHERE data like ‘2016%’ order
    by data”);
    $gare_2017 = $wpdb->get_results(“SELECT id,nome,luogo,data FROM “.$wpdb->prefix.”gpaltvt_gare WHERE data like ‘2017%’ order
    by data”);
    //load all GrandPrix Years
    $anni = $wpdb->get_results(“SELECT DISTINCT(date_format(data, ‘%Y’)) AS id FROM “.$wpdb->prefix.”gpaltvt_gare order by id”
    );
    // start javascript to populate the second select using reltation with slct1
    //
    echo ‘<script type=”text/javascript”>’;
    echo ” function populate(s1,s2){“;
    echo ” var s1 = document.getElementById(s1);”;
    echo ” var s2 = document.getElementById(s2);”;
    echo ‘ s2.innerHTML = “”; ‘;
    echo ” alert(‘prova’);”;
    echo ” if(s1.value == 2016 ){“;
    echo ” var optionArray = [“;
    foreach ( $gare_2016 as $gara ) {
    echo chr(34);echo $gara->id;echo chr(124);echo $gara->nome; echo chr(34);
    }
    echo ” } else if(s1.value == 2017 ){“;
    echo ” var optionArray = [“;
    foreach ( $gare_2017 as $gara ) {
    echo chr(34);echo $gara->id;echo chr(124);echo $gara->nome;echo chr(34);echo chr(44);
    }
    echo ” }”;
    echo ” for (var option in optionArray){ “;
    echo ‘ var pair = optionArray[option].split(“|”); ‘;
    echo ‘ var newOption = document.createElement(“option”); ‘;
    echo ” newOption.value = pair[0]; “;
    echo ” newOption.innerHTML = pair[1]; “;
    echo ” s2.options.add(newOption); “;
    echo ” }”;
    echo ” }”;
    echo “</script>”;
    // —- DIV —
    echo ” <div id=\”primary\”> “;
    echo ” <div id=\”content\” role=\”main\”> “;
    echo ‘<form method=”post” action=”” >’;
    echo ” <h2>Visualizza Classifica. Anno: “;
    echo ” <select id=slct1 name=slct1 onchange=populate(this.id,’slct2′)> “;
    echo ‘ <option value=””></option> ‘;
    foreach ($anni as $anno)
    {
    $year=$anno->id;
    // “<option value=”.$year.”>”.$year.”</option> ” ;
    $optionh=”<option value=”;
    $optionm=”>”;
    $optiont=”</option>”;
    $optionf=$optionh.$year.$optionm.$year.$optiont ;
    echo “$optionf”;
    }
    echo “</select>”;
    echo “Gara:”;
    echo “<select id=slct2 name=slct2></select>”;
    echo “</form>”;
    echo “<hr />”;
    echo ” </div><!– #content –>”;
    echo ” </div><!– #primary –>”;

    get_footer();
    ?>

    The problem is the second select didn’t populate and I don’t hunderstant
    why. Any suggestions ?

    A logical flow of this code is correct or not ?

    Thanks a lot !!
    Best Regards
    Willy

    Moderator bcworkz

    (@bcworkz)

    Yes, you code appears correct. Having it fail to work is not unusual, there’s probably just a silly mistake somewhere that needs to be found. When you make the first selection, do you at least see the alert box with “prova”? After the first selection, and clearing the alert if it appears, check you browser’s console for JavaScript errors. You’ll need to correct any that are listed.

    For one thing, when you terminate the var optionArray definition, you do echo " }";. It should be echo " ]"; because you are declaring an array, not an object.

    In case there’s more bugs than the ], examine your JS script as output in the page’s HTML source. Is the var optionArray properly assigned values from the DB query?

    Once that all checks out, and you still have difficulty, the problem is likely in how you build the select options. It appears OK to me, but I’m not that good with JS. Add an alert line to examine each variable in the for loop and ensure it has the value it is supposed to have.

    Debugging script is an important skill to develop. Everyone makes mistakes, it’s being able to find and correct them that makes one a good coder. It’s mainly about being patient and methodical. Remembering to check the browser console helps a lot 🙂 Sometimes you just need a fresh set of eyes to take a look, that’s when these forums are useful!

    BTW, I keep forgetting to mention that when you post code in these forums, please demarcate the code with backticks, or highlight the code when editing and click the code button. When you post code without doing that, it’s essentially unusable for others to use to check your work them selves because all the quotes are wrong. And when we copy your code to show a correction, it too will not work unless we go through and fix all the quotes, which is rather annoying. You don’t want to annoy people trying to help you 🙂 Using backticks solves everything.

    Thread Starter willy70

    (@willy70)

    Dear bcworkz,
    with your suggestions now this program works fine and as you can
    imagine I had some problems with close routine and others special
    charecters ‘ ” :

    <?php
    /**
     * Template Name: GrandPrix Template
     *
     * Description: A Page Template that adds a sidebar to pages.
     *
     * @package WordPress
     * @subpackage Twenty_Eleven
     * @since Twenty Eleven 1.0
     */
    
    get_header(); 
    
    global $wpdb;
    
    // carica tutte le gare del GrandPrix
    $gare_2016 = $wpdb->get_results("SELECT id,nome,luogo,data FROM ".$wpdb->prefix."gpaltvt_gare WHERE data like '2016%' order 
    by data");
    $gare_2017 = $wpdb->get_results("SELECT id,nome,luogo,data FROM ".$wpdb->prefix."gpaltvt_gare WHERE data like '2017%' order 
    by data");
    
    $anni = $wpdb->get_results("SELECT DISTINCT(date_format(<code>data</code>, '%Y')) AS id FROM ".$wpdb->prefix."gpaltvt_gare order by id"
    ); 
    
    echo '<script  type="text/javascript">';
    echo "	function populate(s1,s2){";
    echo "		var s1 = document.getElementById(s1);";
    echo "		var s2 = document.getElementById(s2);";
    echo "		s2.innerHTML = ''; ";
    echo "		if( s1.value == 2016 ){";
    echo "                  var optionArray = [";
    			foreach ( $gare_2016 as $gara ) {
    				echo chr(34);echo $gara->id;echo chr(124);echo $gara->nome; echo chr(34); 
    			}
    echo "                  ];"; 
    echo "		} ";
    echo "            else if(s1.value == 2017 ){  var optionArray = [";
    			foreach ( $gare_2017 as $gara ) { 
    				echo chr(34);echo $gara->id;echo chr(124);echo $gara->nome;echo chr(34);echo chr(44);
    			}
    echo "                  ];";
    echo "          }";
    echo "		for (var option in optionArray){ ";
    echo "			var pair = optionArray[option].split('|'); ";
    echo "			var newOption = document.createElement('option'); ";
    echo "			newOption.value = pair[0]; ";
    echo "			newOption.innerHTML = pair[1]; ";
    echo "			s2.options.add(newOption); ";
    echo "		}";
    //
    echo "	}";
    echo "</script>";
    // ----  DIV  ---
    echo "                <div id=\"primary\"> ";
    echo "                        <div id=\"content\" role=\"main\"> ";
    echo '<form method="post" action="" >';
    echo "	<h2>Visualizza Classifica. Anno: ";
    echo "	<select id=slct1 name=slct1 onchange=populate(this.id,'slct2')> ";
    echo '	<option value=””></option> ';
    foreach ($anni as $anno)
    	{
    		$year=$anno->id;
    		// “<option value=".$year.">".$year."</option> ” ;
    		$optionh="<option value=";
    		$optionm=">";
    		$optiont="</option>";
    		$optionf=$optionh.$year.$optionm.$year.$optiont ;	
    		echo "$optionf";
    	}
    echo "</select>";
    echo "Gara:";
    echo "<select id=slct2 name=slct2></select>";
    echo "</form>";
    echo "<hr />";
    echo "			</div><!-- #content -->";
    echo "		</div><!-- #primary -->";
    get_footer(); 
    ?>
    

    Now I’ve fix them but to produce the final result I must run
    an sql query and I’d like introduce a “RETURN” button to run
    this query. The results obtaining from wpdb must to be show
    inside this page.

    Your new help would be really appreciated !
    Many thanks for everythings !!!

    Best Regards
    Willy

    Moderator bcworkz

    (@bcworkz)

    Add a normal HTML input button to your form. When you select items and click the button, the page will reload, but unseen will also be POST values of the form field selections. You can get the selected values with PHP using $_POST['slct1'] etc. It’s useful to separate code that runs on initial page load (a GET request) from code that processes submitted values (POST request). A useful conditional for this is

    if ( 'POST' == $_SERVER['REQUEST_METHOD']) {
      // do stuff with form POSTed values
    }

    You should sanitize and validate all values coming from a user, even from dropdown forms because the values are easily spoofed. Dropdown values might easily be validated by placing all possible values in an array, then using in_array() to verify the POSTed value is in the array.

    Once validated, you can use the submitted values to construct and run a SQL query, then do something with the results such as generating output for the page.

    Thread Starter willy70

    (@willy70)

    Dear bcworkz ,
    My script works fine ! I see values selected with form !!!!
    Now I do the checks to sanitize the data and then I have to try to see the results of the query inserted within the “if (‘POST’ == $ _SERVER [‘REQUEST_METHOD’])” opening a new tab.
    Thanks so much for everything !!!
    Best Regards
    Willy

    Moderator bcworkz

    (@bcworkz)

    Great news! Always happy to help 🙂

    Thread Starter willy70

    (@willy70)

    Dear bcworkz,
    hello enrico,
    if you are still interested in this post I would like to have your opinion on sanitization data.

    In my definitive php script there are two POST variable, race_id and name_athlete.
    As you can imagne the first was choosed by user throught form (select on change
    and so on) and is numeric value, the second variabile is a free text,
    first and last name , and was choosed by user throught input area.

    To sanitize the first I think to use this code:

    	$race_id=$_REQUEST['slct2'];
    	if ( !is_numeric($race_id) || $race_id ==0  ) {
    		echo "ERROR RACE ID .";
    		 exit();
    	}
    

    and to check the second variable I’m thinking to this code:

    
    '$title = sanitize_text_field( $_POST['title'] );
    update_post_meta( $post->ID, 'title', $title );
    

    sanitize_text_field isn’t so clear for me , Can you give
    an example ?

    Are they secure ? What do you think about them ?
    Thank you so much !
    Best Regards
    Willy

    • This reply was modified 4 years, 10 months ago by willy70.
    • This reply was modified 4 years, 10 months ago by willy70.
Viewing 14 replies - 1 through 14 (of 14 total)
  • The topic ‘How to PHP script run “post self”’ is closed to new replies.