Jump to content

Integrating a member / visitor login form


thetuningspoon

Recommended Posts

Friendly advice Jeff...posting the same question in different boards won't give you quicker answers :-)...One version should be enough :D....

Back to your question, see my suggestions in your other post. I also think that at this point your are not asking the more important question. Whilst the issue of whether to use a button or a input checkbox is a valid one, that's not the pressing question. Whichever way you want to signal the users intent (programmatically), at the end of the day, it's just an input in a form sent via a post. The more important questions are how do I safely capture what has been sent by the user (whether it's a button press, or a checkbox, etc.) and what do I do with that input? The answers to these questions are all here in the forums (IIRC, I have pointed you to some of them :-)). Check out $input and $sanitizer in the API docs and forums. I'd also suggest that you Google and thoroughly read about 'capturing, validating and processing form input php'. It will help you immensely rather than copy pasting code :-)....As to how best to signal the users intent? I would probably use a button clearly labelled delete this page! Oh, I forgot in the other post, how do you know what page the user wants to delete? At the very minimum, you must capture the ID of the page being edited....

  • Like 1
Link to comment
Share on other sites

Kongondo, yea sorry about that guys.  I got a little post happy! I would find a post related to what I needed help with and would post my questions.  Next time I will post in the correct areas as well as not double post. 

I will study further the API and see what I come up with. Ultimately I would like to recreate the delete button and functionality of the button but only for the front editor.   Im sure I can figure it out.  

Thanks for the guidance!

Link to comment
Share on other sites

@Jeff,

No worries. ProcessWire has the API to create the markup that you see in modules or the admin (e.g. buttons, collapsible panels etc.) Whilst you can use some of these in the frontend as well, it is probably an overkill to recreate the delete button for your frontend needs using PW API. You don't need anything fancy; just create a normal button using HTML (either <input type="submit"> or <button></button>. The important things here are the name and value of the button, maybe an ID as well. This is normal HTML stuff. You can then style it (copy the PW CSS basically) to fit in with the rest of the PW page edit style...If you need more info let us know :-).

When a HTML button is pressed (within a form), it will send it's name (e.g. name="delete") and the names and values of other relevant input types within than form, e.g. text fields, etc. In this case, since you want to delete the page, you are not interested in all that other information. What you want is the ID of the page that you want to delete. When requesting the page to be edited in the frontend (I don't know how you are doing it, Fredi? Custom form?). The id of that page is stored somewhere. Either in the URL...e.g. my-cool-page?id=2345 or it is stored probably in some hidden field. What you want is that ID. Use Dev tools in Chrome or similar to study how the delete button is structured. There is no magic really but I appreciate this might be difficult for a beginner. The other issue you will find if you read up on the subject of forms is whether values are sent via get or post. Using PW $input->get or $input->post covers both scenarios respectively. http://processwire.com/api/variables/input/ If using get to store the ID, the id is the id=2345 in my example above. $input->get->id will get you the 2345...

Sorry, I realise I might have confused rather than informed but hope this helps :-)

Edited for mistake:

the value of the page being edited is not the value of the submit button :-)...

Edited by kongondo
  • Like 1
Link to comment
Share on other sites

I guess first I need to check if a page is editable by that user. I'm using Ryan's module per page edit. Trying to write a script to first check the page if user has editing rights to the page not just editing permission, first since the page is using fedi front end editor. No success. :-(

Link to comment
Share on other sites

Kongondo, 

Below is the code used for the template the account manager page is using. 

As you can see, I am able to pull the page ID but not sure what else to do after this. 

I had written some other code on another template but decided this route would be better. 


<?php 

include("./head.inc"); 


?>

       
    <div class="row supersize">
    <div class="medium-12 columns" >
         <div class="medium-4 columns">
      <p> </p>
      </div>
    <div class="medium-4 columns">
    <div align="center">
     <h1>Account Manager</h1>
     <p>Welcome <?=$user->name?></p>

     <div class="panel callout radius">
     <p>Select your post to edit:</p>
     
     
     <!--Below will display the pages a user is assigned to edit or the pages they have created, they are also links to the page-->
 <ul class="side-nav">
     <?php
     foreach($user->editable_pages as $aPage){
    
  echo "<li><a href='$aPage->url'>$aPage->title</a></li><br>";
   echo "<li><a class='button alert tiny' href='$aPage->id'>DELETE POST</a></li><br><br><br>";
  
  //I would like to also echo a button that is tied to each page link being displayed that allows for the user to delete the page, un publish or republish.  Essentially it may be up to 3 buttons.//
  
}
?>
 </ul>
 
 

   
    </div>
        <?=$page->body?>
         
    </div>
  </dd>
</dl>
     
       
     
     
     
     
     
     
     
     
    </div>
      <div class="medium-4 columns">
        <p> </p>
      </div>
    
     </div>
</div>
   

   
   
   
   
   

<?php

include("./foot.inc"); 

?>
Link to comment
Share on other sites

OK...here is an example (rough-ish...and maybe even ugly code...) but it should give you an idea... ;)

//was a delete request sent...
if ($input->post->delete) {
	//this will be in the form of delete=xxxx where xxxx is the page ID. Check in Firebug
	$deletePage = $input->post->delete;
	$id = (int) $deletePage;//sanitize post value to integer
	$p = $pages->get($id);//get this one page whose ID was sent over using its delete button
	$title = $p->title;
	$p->trash();//as a backup in the interim, we trash the page instead of deleting it.
	echo '<p>The page ' . $title . ' was successfully deleted</p>';//there are better ways to check!
}

else {
        //list of pages - this is only an example...modify to return your particular user's pages!
	$out = '<form action="./" method="post"><ol>';//this form posts to self
	foreach ($page->children('limit=10') as $child) {
		   $out .= '<li>' . $child->title . '<button type="submit" name="delete" value="' . $child->id . '">delete</button></li>';
	
	}

	$out .= '</ol></form>';
	echo $out;

}

There are better ways to catch errors and check if this page was actually deleted. Here also we haven't checked if this user has permission to actually delete this page....but this should get you on your way... :-)

Link to comment
Share on other sites

Kongondo, 

Absolutely wonderful! Not only did you help, you really explained things clearly. I successfully added the delete button! 

Now I need to figure out the publish and unpublished or as the user see's it undelete by the very least. 

Thanks soooooo much! O0

Link to comment
Share on other sites

@Kongondo

Ran into an issue.  As I was testing the security side of things, if a user were to login to their account, go to their page to delete the page, the user is successful once they delete the page.  

However, if a user is dev savvy and attempts to use inspect element or firebug, they can view the source and type in another id and then hit submit, guess what happens next?   :'( They can delete the page associated with the id they just replaced in the source code via firebug or inspect element. This puts the site at risk of a malicious user.

Any suggestions to verify the user is indeed assigned to the page before the page is actually deleted?

Thanks.  

Link to comment
Share on other sites

@Jeff,

Here the critical point is to check if the user has the right permissions. There are various ways of controlling access in PW, e.g. using permissions and roles at user level, at template level, and with some modules, at page level. For now, Google this and have read: "permission delete site:processwire.com" then let's talk...I need to run :-)

Link to comment
Share on other sites

Awesome! Thanks for the guidance. I did check permissions on the user role I created, this user is assigned frontend_editor which I enabled to only edit or view certain pages, yet they are able to delete. I need to have a deeper dive and verify the delete doesn't work just for anyone. I also need to make sure the user cannot delete others page and only his assigned pages.

Thanks again.

Link to comment
Share on other sites

If many users can be assigned the role frontend_editor, then it means you need to go further in your checks. Is there a maximum number of pages each user can create? Is there a limit to the number of users? Answers to these questions will help determine the approach needed to control access - e.g. for a site with 100K users, controlling access by giving them individual templates may not be very workable....:-) Just loud musings here..

Link to comment
Share on other sites

Kongondo,

Thanks for the response, basically no limit at the moment for users. Also haven't set a max limit of pages the users can create, I haven't even thought about the limit yet. I guess my next silly question would be, how and where would I be able to limit the user page creation? :-( Also the frontend_editor role is assigned to a user that registers to post pages on the site. They register to post pages, similar to craigslist. As soon as the user is created, they are assigned the role of frontend_editor.

Link to comment
Share on other sites

In that case, one way is to only allow them to delete the pages that they have created. I'll let others more knowledgeable chime in here :-)

The property $page->createdUser will get you the user 

In a selector you can search using created_users_id

  • Like 1
Link to comment
Share on other sites

Still having a hard time checking to make sure the user has been assigned to delete the page he is deleting. I need to figure a way to check to verify that the user has been assigned to the page he is deleting. Since I am displaying the pages a user has created on their account manager page, and simply pulling the id from those pages and using Kongondos suggestion of deleting a page, I cannot figure how to verify the page they are deleting is indeed their assigned page. The reason I wan to verify is because I used inspect element tool from Google Chrome and changed the ID in the code and was able to delete another page another user created. :-( I use the module Ryan buit per user per page edit to assign users first off. Anyone? :-(

Link to comment
Share on other sites

Okay, so after trying multiple things I still cannot get the form to validate the page id that is being submitted. By validate I mean, check that the page id, that is being submitted,  is indeed a page that the user has been assigned too.  (Pages assigned via MODULE: PageEditPerUser). 

Please note, this form is not located on the page a user can edit, it is on another page I have as their account manager page.  It displays every page they can edit.

Here is the code so far, thanks to Kongondo major major help!!!

Note:  If its easier to add two buttons, one unpublish and the other publish, I am good with that route for now. 

<?php

//was a delete request sent...


if($input->post->delete) {
	//this will be in the form of delete=xxxx where xxxx is the page ID. Check in Firebug
	$deletePage = $input->post->delete;
	$id = (int) $deletePage;//sanitize post value to integer
	$p = $pages->get($id);//get this one page whose ID was sent over using its delete button
	$title = $p->title;
	$p->trash();//as a backup in the interim, we trash the page instead of deleting it.
	echo '<div data-alert class="alert-box success radius">
  The post ' . $title . ' was successfully deleted!
  <br><br><a href="/profile" class="button small secondary" style="color:#000;">CONTINUE</a>
</div>';//there are better ways to check!
}

else {
	$out = '<form action="./" method="post"><ul>';//this form posts to self
	foreach ($user->editable_pages as $aPage){
		   $out .= '<li><a style="color:#000;" href=' . $aPage->url . '><span class="label success radius">View / Edit</span> <br><br>  <strong>' . $aPage->title . '</strong></a></span><br><button type="submit" class="button tiny alert radius" name="delete" value="' . $aPage->id . '">DELETE</button></li><br><br><br>';
	
	}

	$out .= '</ul></form>';
	echo $out;

}

?>
Link to comment
Share on other sites

You could just test the page's created user against the current user. Using your code:

if($input->post->delete) {
	$deletePage = $input->post->delete;
	$id = (int) $deletePage; //sanitize post value to integer
	$p = $pages->get($id); //get this one page whose ID was sent over using its delete button
	$title = $p->title;
 
        // TEST IF THE CURRENT USER IS THE PERSON WHO CREATED THE PAGE
        if($p->createdUser == $user){
	   $p->trash();
	   echo '<div data-alert class="alert-box success radius">
             The post ' . $title . ' was successfully deleted!
             <br><br><a href="/profile" class="button small secondary" style="color:#000;">CONTINUE</a>
             </div>';//there are better ways to check!
        }
        else{
           .......DO SOMETHING ELSE HERE
        }
}

I do think these posts should try to stay along the lines of the original topic, so as to not clutter this very useful thread.

  • Like 2
Link to comment
Share on other sites

  • 4 months later...

What a coincidence that this thread turns up now. I've just finished a system for managing users and was wondering how best to share it. 

It consists of five template files, one stylesheet and a slightly modified InputfieldPassword module (I changed the validation and some text). You setup a page for each template, all of them children of a hidden /access/ page. The various forms are made with InputfieldForm. Each template sets $page->body and then includes a basic-page.php template file, like we see in many of the processwire profiles.

 /access/login/

 /access/profile/    (for changing your password, username or email address)

 /access/logout/

 /access/register/    (for creating a new user account)

 /access/reset/        (for when you've forgotten your password)

  • Each user acount must have a unique username.
  • An email address is collected for each user but does not need to be unique (it's okay for someone to have more than one account).
  • When setting an email address we verify it by emailing a message to that address. Confirm by clicking a link or pasting a code into a form (an 'email-confirmed' role is added).
  • Requests to reset a forgotten password are verified by emailing a message to the account's email address. Confirm by clicking a link or pasting a code into a form.
  • To close the registration process set the /access/register/ page status to Hidden.

@SteveB

would you mind sharing your code as is (github/zip file/PM)? That would be awesome.

I've been digging through the forum to accomplish the same thing and am halfway into some working code. It would be great to have some additional example code.

Cheers

Gerhard

  • Like 1
Link to comment
Share on other sites

I'm not sure what login you mean but for custom login using $session->login(user,password) you'd have to code it like this:

//..
try{
    $u = $session->login($username, $pass);
    if($u && $u->id){
        $session->redirect("/somepage/");
    }
} catch(Exception $e) {
    echo $e->getMessage();
}
 

Running 2.5 stable, I tried Soma's code for error handling but the catch statement seems to be ignored when I enter a wrong username or password.

Is this normal behaviour or am I missing something?

Link to comment
Share on other sites

The try catch is only a workaround for the Login Throttle...

If the login isn't correct, you would do output a message somwhere in the

if($u && $u->id){
        $session->redirect("/somepage/");
    }

Like

if($u && $u->id){
        $session->redirect("/somepage/");
} else {
   $error = "Login failed";
}
  • Like 1
Link to comment
Share on other sites

Thank you Soma, now I know how to get around the throttle.

I took some code from renobird

	if($session->login($user, $pass)) {
		// login successful
		$session->redirect($page->path);
	}  else {
		$session->login_error = 'Login Failed. Please try again, or use the forgot password link below.';
	}

It is working fine. Any advantage of storing the error in $session over your example with $error? Or is this just personal preference?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...