Invision Community 4: SEO, prepare for v5 and dormant account notifications By Matt Monday at 02:04 PM
Nakamura RTS Posted November 3, 2018 Posted November 3, 2018 Hello, I want to program one page, and add few functions for buttons by using onclick event and calling javascript function that carries some php code. But it seems that page reads all php code even though it is inside the function, some javascript functions got auto read. I tried to make seperated js code in templates and use it for the page and none of those functions got called or even work. Example of code: <a id="mybutton" onclick='alert({{header("Refresh:0");}});' >example</a> or <a id="mybutton" onclick='helloworld()'>example</a> <script>function helloworld(){alert({{header("Refresh:0");}});}</script> For this code, after someone clicks on the button it should simply refresh the page, though when you open the page it loops - the javascripts keeps on auto reading inside it (usually should be fine using php inside javascript function). Since we can't make any functions with php and I can't find a clue in Invision Community Guides & Support... How can I make the page stop auto reading scripts that i made?
Martin A. Posted November 4, 2018 Posted November 4, 2018 It doesn't quite work this way. Javascript can't read PHP, or even execute PHP in the way you want. The PHP code you've added will be interpreted by the output/template engine, and executed immediately when it reads those lines. There are JS functions available for this. Use those. window.location.reload(); <a id="mybutton" onclick='window.location.reload(); return false;' >example</a>
Nakamura RTS Posted November 5, 2018 Author Posted November 5, 2018 17 hours ago, Martin A. said: It doesn't quite work this way. Javascript can't read PHP, or even execute PHP in the way you want. The PHP code you've added will be interpreted by the output/template engine, and executed immediately when it reads those lines. There are JS functions available for this. Use those. window.location.reload(); <a id="mybutton" onclick='window.location.reload(); return false;' >example</a> Thanks for the reply. Made some progress. I want to know how to make php functions and call them in templates, so that I can have interaction between client & server on the buttons. I tried to make 2 php files and include them while calling them with Ajax JavaScript, thogh it seems that it doesn't recognise the file in the template. I am trying currently to make a plugin, though I really got lost. I just want to call those functions from the templates - they might need parameters too. How exactly can I make those functions and call them globally on templates? Example function of what I want to make <?php public function setitlivee( $id ) { $result = \IPS\Db::i()->update( 'cms_custom_database_26', array( 'field_113' => 'live' ), array( 'primary_id_field="'.$id.'"' ) ); header("Refresh:0"); } public function setitkill( $id ) { $result =\IPS\Db::i()->delete( 'cms_custom_database_26', array( 'primary_id_field="'.$id.'"' ) ); header("Refresh:0"); } ?>
bfarber Posted November 5, 2018 Posted November 5, 2018 You cannot call PHP from javascript, it just isn't possible. What you will need to do is make a PHP script on the backend (not in templates, but you could create a page in Pages for this), and then use javascript to make an AJAX request to the backend script you create.
Nakamura RTS Posted November 6, 2018 Author Posted November 6, 2018 10 hours ago, bfarber said: You cannot call PHP from javascript, it just isn't possible. What you will need to do is make a PHP script on the backend (not in templates, but you could create a page in Pages for this), and then use javascript to make an AJAX request to the backend script you create. Thanks for the response. Like I said in that last post, I made 2 php files and called them using javascript ajax. Is there any documentation on how this should be exactly done? Are you saying that I should make a "manual HTML" page, and add the code to content? Anyhow, this is what was done so far: Javascript: <script type="text/javascript" language="javascript"> $(document).ready(function() { $(".setitlive").click(function() { setitlive(1); }); }); function setitlive(value1) { var id=value1; jQuery.ajax({ type: "POST", url: 'interactionclientserverwithphpandjavascript.php', data: {functionname: 'setitlive', arguments: [id]}; } </script> PHP scripts: <?php include "interactionclientserverwithphpandjavascript1.php"; header('Content-Type: application/json'); $id = $_POST['arguments'][0]; switch($_POST["functionname"]){ case 'setitlive': setitlivee( $id ); break; } ?> <?php public function setitlivee( $id ) { $result = \IPS\Db::i()->update( 'cms_custom_database_26', array( 'field_113' => 'live' ), array( 'primary_id_field="'.$id.'"' ) ); header("Refresh:0"); } public function setitkill( $id ) { $result =\IPS\Db::i()->delete( 'cms_custom_database_26', array( 'primary_id_field="'.$id.'"' ) ); header("Refresh:0"); } ?>
bfarber Posted November 6, 2018 Posted November 6, 2018 You have an SQL injection there in your code by the way. You are taking the raw POST value (which could be a malicious value) and passing it directly to a database query without escaping. This is untested code but hopefully will help you get started. I would create a new block in Pages set to Manual PHP method, and for the code I would add something like switch( \IPS\Request::i()->function ) { case 'setitlive': // Note we are using prepared statements here to protect against SQL injection \IPS\Db::i()->update( 'cms_custom_database_26, array( 'field_113' => 'live' ), array( 'primary_id_field=?', \IPS\Request::i()->id ) ); break; // Add more case statements as needed } // This is just a basic output of "ok" json-encoded, nothing fancy since you don't seem to really need a return value \IPS\Output::i()->json( 'ok' ); Embed this block into a new page, we'll call it "mypage.php". Then for your javascript I'd use something like <a href='#' class='setitlive' data-id='123'>Set it live - data-id is the primary_id_field value for this link</a> <script> $(document).ready(function() { $(".setitlive").click(function() { setitlive( this.attr('data-id') ); }); }); function setitlive(id) { ips.getAjax()( ips.getSetting('baseURL') + 'mypage.php', { dataType: 'json', data: { function: 'setitlive', id: id } } ) .done( function (response) { alert('saved'); }) .fail( function (jqXHR) { alert('failed'); }); } </script>
Nakamura RTS Posted November 7, 2018 Author Posted November 7, 2018 21 hours ago, bfarber said: You have an SQL injection there in your code by the way. You are taking the raw POST value (which could be a malicious value) and passing it directly to a database query without escaping. This is untested code but hopefully will help you get started. I would create a new block in Pages set to Manual PHP method, and for the code I would add something like switch( \IPS\Request::i()->function ) { case 'setitlive': // Note we are using prepared statements here to protect against SQL injection \IPS\Db::i()->update( 'cms_custom_database_26, array( 'field_113' => 'live' ), array( 'primary_id_field=?', \IPS\Request::i()->id ) ); break; // Add more case statements as needed } // This is just a basic output of "ok" json-encoded, nothing fancy since you don't seem to really need a return value \IPS\Output::i()->json( 'ok' ); Embed this block into a new page, we'll call it "mypage.php". Then for your javascript I'd use something like <a href='#' class='setitlive' data-id='123'>Set it live - data-id is the primary_id_field value for this link</a> <script> $(document).ready(function() { $(".setitlive").click(function() { setitlive( this.attr('data-id') ); }); }); function setitlive(id) { ips.getAjax()( ips.getSetting('baseURL') + 'mypage.php', { dataType: 'json', data: { function: 'setitlive', id: id } } ) .done( function (response) { alert('saved'); }) .fail( function (jqXHR) { alert('failed'); }); } </script> Here's my test results: I added this to it javascript This is actually a block which will load some tables and they gets called by buttons which just do a simple hide and show. This is the exact place where i want to put the function to work - I gather the list where that field has request on it and that button should modify it and make it live. The page must be refreshed so the result get showing. These two will be my settings for the file names and database, and load the block i added Setup for the plugin that carries the functions Quote // This is just a basic output of "ok" json-encoded, nothing fancy since you don't seem to really need a return value \IPS\Output::i()->json( 'ok' ); This one I couldn't add when i tried to save it, it gives me page that has that value('ok'). I did try to test it, it seems that it doesn't load the function so we got maybe something missed in ajax ? Quick question about the code you posted, about that "?" question mark, will it be changed by value of the id ? Or should I be entering the desired one manually? Quote array( 'primary_id_field=?' , \IPS\Request::i()->id) );
Nakamura RTS Posted November 13, 2018 Author Posted November 13, 2018 @bfarber Just giving this a bump in case you forgot to reply by accident.
bfarber Posted November 14, 2018 Posted November 14, 2018 It's not so much that I forgot to reply - more that while I'm trying to help point you in the right direction, I don't really have enough time to check all of the bits on an individual case by case basis unfortunately. Couple things: The ? is not supposed to be manually replaced out, leave it as-is in the query. It's a placeholder when using prepared statements. The second array entry will be used as the value, and automatically escaped by the MySQL engine. I would recommend using the developer tools in your browser to see what's going on. Make sure your javascript code is being included and output correctly. See if clicking the link is actually triggering an AJAX request and work your way back from there.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.