How to assert form action attribute url with phpunit and selenium2? - php

I have a html form that has this markup.
<form id="login-form" action="/post/login">
<input name="username" type="text">
<input name="password" type="password">
</form>
I want to be able to assert this form action.
I try with this inside the test method, note I extended \PHPUnit_Extensions_Selenium2TestCase
$form = $this->byId('login-form');
$this->assertEqual('/post/login', $form->attribute('action'));
It seems like action always null.
Does anyone know how to test the form action attribute?
Thank you.

Unfortunately, $form->attribute('action') returns action with base url (http://localhost/post/login).
I did not find a way to get action without base and did not find how to get base url. There is my solution:
function testForm(){
$this->url('/test.html');
$form = $this->byId('login-form');
$this->assertEquals('/post/login', $this->getRelativeFormAction($form));
}
function getRelativeFormAction($form){
$action = $form->attribute('action');
$action = str_replace($this->getBaseUrl(), '', $action);
return $action;
}
function getBaseUrl(){
$urlComponents = parse_url($this->url());
$url = "{$urlComponents['scheme']}://{$urlComponents['host']}";
return $url;
}
There is successful full test code.

Related

PHP OOP using setter and getter methods on form elements

I'm coming from Java programming and I know a little when it comes with PHP OOP style. In Java Server Faces I got used with setters and getters which I use to set values of fields from data entered on form.
So for instance,
Person.java
Class Person{
private String firstname;
public setFirstName(String aFirstName){
this.firstname = aFirstName;
}
public getFirstName(){
return this.firstname;
}
}
PersonForm.xhtml
First Name: <input type="text" name="firstname" value="#{person.firstname}"/>
#{person.firstname} is what calls the setFirstName(); method from the class Person
So I did some google to see how it's done in PHPs OOP style.
So on PHP I thought it would look something like this.
Person.php
class Person{
private $firstname;
public function setFirstName($aFirstName){
$this->firstname = $aFirstName;
}
public function getFirstName(){
return $this->firstname;
}
}
PersonForm.php
<?php
$person = new $Person();
?>
<form>
First Name: <input type="text" name="firstname" value="<?php echo $person->firstname ?>"/>
</form>
I want to store the value entered on input text field using the setFirstName() method of Person class.
Does writing the value="<?php echo $person->firstname ?>" call the setFirstName() method?
Or should I do value="<?php echo $person->setFirstName() ?>"?
I'd appreciate any explanation or example.
PHPs OOP style is very similar with Java that's why I decided to study PHP using the OOP style instead of procedural.
Thank you.
Does writing the value="<?php echo $person->firstname ?>" call the setFirstName() method?
$firstname is a private property of Person class, so you can't access it outside of the class like that. And no, it won't call setFirstName() method.
Or should I do value="<?php echo $person->setFirstName() ?>"?
No, this will give you error since setFirstName() method is expecting an argument with the method call i.e. you're not passing any argument in this method, like $person->setFirstName('My first name'). Having said that, even though you do this, still you won't be able to set any user inputted first name unless you call this method with the user input value, like this: $person->setFirstName($_POST['firstname']);. Later, you can use getFirstName() method in your form to display the user inputted first name accordingly.
Here's a code example to accomplish your task,
PHP
class Person{
private $firstname = null;
public function setFirstName($aFirstName){
$this->firstname = $aFirstName;
}
public function getFirstName(){
return $this->firstname;
}
}
$person = new Person();
if(isset($_POST['submit'])){
$person->setFirstName($_POST['firstname']);
}
HTML
<form action="" method="post">
First Name: <input type="text" name="firstname" value="<?php if($person->getFirstName() != null){ echo $person->getFirstName(); } ?>"/>
<input type="submit" name="submit" value="Submit" />
</form>
The above example assumes that both HTML and PHP code should be on the same page.
You will be able to use the class you have defined inside the script being called by the form (at least that's the way I would do it).
person.html
<form action="savePerson.php" method="post">
First Name: <input type="text" name="firstname" id="firstname">
<button type="submit">Submit</button>
</form>
savePerson.php
<?php
class Person{
private $firstname;
public function setFirstName($aFirstName){
$this->firstname = $aFirstName;
}
public function getFirstName(){
return $this->firstname;
}
}
$person = new Person();
$person->setFirstName($_POST['firstname']);
//do something on the person object
?>
In this instance, you can't really declare the Firstname in the HTML form before it has been declared unless you already had this value stored somewhere else e.g. Database. You would need to use a client side language like Javascript to store and output data in real time. In terms of PHP, if you was making a call to a database or variable $aFirstName was predefined, your PHP would probably look something like this:
Person.php
class Person{
private $isSet; //Is Name Set on Object Creation
private $firstname;
public function __construct($aFirstName = false) { //Check if name is created on object creation.
if ($aFirstName === false) {
$this->isSet = false;
$this->firstname = 'No Data'; //Set so your field will always have predefined data.
} else {
$this->isSet = true;
$this->setFirstName($aFirstName);
}
}
private function setFirstName($aFirstName){
$this->firstname = $aFirstName;
}
public function getFirstName(){
return $this->firstname;
}
}
PersonForm.php
<?php //Check if Post data is set, if so then set name constructor
if (isset($_POST['firstname'])) {
$person = new Person($_POST['firstname']);
} else {
$person = new Person();
}
?>
<form method="post" action="">
First Name: <input type="text" name="firstname" value="<?php echo $person->getFirstName() ?>"/>
<input type="submit" value="submit">
</form>
This will output 'No Data' if the form input is not set or 'YOUR INSERTED DATA' if the value is set.
The important point to understand is PHP is working on server-side. So when you run your PHP script via a request it runs and finishes. When you hit that PersonForm.php script, it will generate the HTML document and send it to your browser, for example. That it there is no more chance to run PHP on your browser (frontend).
To store what is entered in a form you must use JavaScript/jQuery and make AJAX calls to a PHP script. So that JavaScript reads the form input and sends it to a PHP script on your backend, which will process the data like inserting it in a database etc.
I recommend you to read more about Javascript/jQuery and AJAX calls to achieve this.
A simple way to achieve it by using jQuery.
main.js
$("#submit").click(function(){
personName = $("input[name=firstname]").val();
$.ajax({
type: 'POST',
url: 'SavePerson.php',
data: {name: personName},
success: function(result, status, xhr) {
popup("Success!");
}
});
});
SavePerson.php
<?php
include_once('Person.php');
$person = new Person();
$person->setFirstName($_POST['name']);
// Do whatever you want with person...
?>
PersonForm.html
<!DOCTYPE html>
<html>
<form>
First Name: <input type="text" name="firstname" placeholder="Enter your name"/><br />
<button id="submit" value="Submit">Submit</button>
</form>
<script src='main.js'></script>
</html>

How to pass input value to Request validation class in Laravel 5.2?

I have one controller and one Form Request Validation class: app\Http\Controllers\GuestController.php and app\Http\Requests\ItemValidation.php. In GuestController.php I use storeItem(ItemValidation $request) method to store item data which comes from <form> .
And in ItemValidation.php request class I redirect back to the form with following method if validation fails.
public function response(array $errors){
return Redirect::back()->withErrors($errors)->withInput()->with('type', '2');
}
The main thing I want is to pass value from <form> (which is entered by user in form) to response method. I tried with following but it did not work:
public function response(array $errors, Request $request){
return Redirect::back()->withErrors($errors)->withInput()->with('type', '2')->with('sub_menu_id',$request->sub_menu_id);
}
->withInput() flashes the previous input to the session.
In your form view, you should use the old() helper to repopulate the value if a previous input exists.
Blade:
<input type="text" name="username" value="{{ old('username') }}">
Plain PHP:
<input type="text" name="username" value="<?= e(old('username')) ?>">
If there is no previous input, it returns null, which echoes as an empty string.
Documentation: https://laravel.com/docs/5.3/requests#old-input

CodeIgniter Custom URI Routing

I want to create custom permalinks on CodeIgniter, actually i bought the script but the developer left that project due to some indifference. so now the problem is i have no idea how to change permalinks on that script. The main permalinks issue is when i search anything on searchbar i get this url:
domain.com/?s=xxxxx%20yyyyy
instead of that i want this url structure:
domain.com/search/xxxxxx-yyyyy/
application/config/routes.php
$route['default_controller'] = "music";
$route['404_override'] = '';
$route['search/(:any)'] = "music/index/$0/$1/$2";
$route['search/music/(:any)'] = "music/$1";
I guess what you are asking for is not possible (directly).
Assuming your form to be,
<form action="" method="GET">
<input type="text" name="s" value="" placeholder="Search music..." />
</form>
And since the method is GET the default functionality says to add the parameter in the URL as query string.
As the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) state:
If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.
So, basically what you can do here is apply a hack to this. Redirect the user to the required URL when the search is applied. Here's how you can go,
Controller (controllers/music.php)
<?php
class Music extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('xyz_model');
}
public function index()
{
if($this->input->get('s'))
{
$s = $this->input->get('s');
redirect('/search/'$s);
}
$this->load->view('home.php');
}
public function search()
{
$s = $this->uri->segment(2);
/*
Now you got your search parameter.
Search in your models and display the results.
*/
$data['search_results'] = $this->xyz_model->get_search($s);
$this->load->view('search_results.php', $data);
}
}

Zend FrameWork - Form input from Layout to Controller

I have a small form, where user's can Subscribe to my newsletter.
How can i pass the email address from my Layout to my Controller?
My Layout name is Footer.phtml, here's the code:
<div id="subscribe">
<form name="newsletterRegister" method="post" action="">
<span>Subscribe to the Newsletter</span>
<input class="subscribeNewsletter" name="email" type="text">
<input id="subscribe_ok" type="image" src="/www/assets/newImages/footer/Ok.png" value="">
</form>
</div>
I have a controller called NewsletterController.php
I'm kinda lost with Zend Framework, can anyone help me figuring out what i have to do??
Well change this
<form name="newsletterRegister" method="post" action="">
To this
<form name="newsletterRegister" method="post" action="NewsletterController/YOURACTION">
And in your controller just get the data like this
$request = $this->getRequest();
$request->getPost()
If the action of your form is empty, it will post to itself.
But maybe you dont want to check on every page if the newsletter is send.
Try using a Controller Plugin, check the request object for the input field, name it unique like email_newsletter, if is not empty, do your logic.
File: application/plugins/Newsletter.php
class Application_Plugin_Newsletter extends Zend_Controller_Plugin_Abstract {
//before dispatching starts
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$email = $request->getParam('email_newsletter',NULL);
if(!is_null($mail)) {
//check if is valid
if(Zend_Validate::is($email,'')) {
//do your logic
}
else {
//set some error messages
//maybe use helper flashMessenger
}
}
}
}
File: Bootrap.php
protected function _initPlugins() {
$this->bootstrap('frontController');
//Get FrontController Instance
$frontController = $this->getResource('frontController');
$frontController->registerPlugin(new Application_Plugin_Newsletter());
return $frontController;
}
OR
Set a form action like '/newsletter/subscribe'.
Then in controller 'newsletter' action 'subscribe' check the form and redirect to the sending page.
Maybe you should store sth like a last page visited to the session, or add a hidden input to that newsletter form, representing the current page you want to redirect to after the newsletter subscription is done.

HTML POST form submit is mangling URL

I am trying to get a HTML/PHP form to submit properly. Some details:
base url = http://localhost/directory
page = page/add
complete address = http://localhost/directory/page/add
Using htaccess to rewrite urls so http://localhost/directory/page/add is actually http://localhost/directory/index.php?q=page/add
My HTML POST action is "page/add" so that the front controller knows which function to fire to sanitize and submit the data (it acts as a 'form id').
The page loads fine at http://localhost/directory/page/add but when I click on the submit button, the URL gets mangled to page/page/add. And every time I press "submit" I get another "page" added to the url. So 5 clicks will get "page/page/page/page/page/page/add"
I can't seem to find why I am getting that "extra" "page".
The actual PHP error (page/page/add doesn't exist in $routes since it isn't a valid route):
Notice: Undefined index: page/page/add in C:\xampp\htdocs\script\includes\common.inc on line 92
Here is the function at line 92:
function route_path($path = NULL) {
$routes = get_routes(); //Returns array: approved "urls => function callbacks"
if($path === NULL) {
$path = get_path(); //Returns $_GET['q'] with trim and strip_tags
}
$function = $routes[$path]; <<<<<----This is LINE 92
if(isset($function)) {
$form_name = str_replace('/', '_', $path); // page/add = function page_add()
}
if(function_exists($function)) {
call_user_func($function, $form_name);
}
else {
//TODO: Redirect to Login screen.
}
}
The basic HTML is:
<form action="page/add" method="post" />
//Form elements
<input type="submit" value="Submit" />
</form>
Thanks for the help.
UPDATE: What I did was add the <base> tag to my HTML templates. This allows me to keep the action as page/add (since it is also a route in my simple router/dispatcher).
By using a relative path, you're telling the form to submit at the existing path plus your action. So if you are at http://example.com/page/add, the form uses http://example.com/page/ as a base and adds the action page/add resulting in a POST to http://example.com/page/page/add.
You can still use a relative path, just change the action accordingly:
<form action="add" method="post" />

Categories