Jump to content

Martijn Geerts

PW-Moderators
  • Posts

    2,769
  • Joined

  • Last visited

  • Days Won

    31

Everything posted by Martijn Geerts

  1. Reduce the amount of requests. Combine js & css files. PW is pretty quick it self... And external js % injected js can be slow sometimes...
  2. Had no time till now to check it all out... It was indeed the wrong hook i Had...
  3. The random image example is in the basic install, from there you can figure it out I think.
  4. wild guess .... execution time of scripts ?
  5. $image = $page->images->getRandom(); echo $image->url ---------------------------------------------------- <style> #home { -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover } </style>
  6. echo "<div id='home' style='background: url($image->url});' title='what ever' />";
  7. have no answer to your question, but why you don't just write the url in an inline-style ?
  8. This is very very good info... pity that i have to work now, gonna figure it out later... tnx
  9. from text apeisa wrote, There's no methode render in the class Page, but there is sucha thing though, he said... ( I don't know cause this is my first OOP project ever ) But I think he is right. And I learned alot from his code, some of it should go in the wiki I think. About the hooks, it's still a bit tenuous for me what it does. And how to handle with it. your example: protected function login(HookEvent $event) { // $event->return would be the html string rendered return $event->return; } HookEvent is that a static somewhere divined, or is it a class.... & $event, is that the $this... Man, lack of knowledge here... Big thanks Soma for all your help....
  10. oké, I think (not able to test now) that the problem lays in: $this->addHookAfter('Page::render', $this, $this->used_methode); Maybe need the addHookBefore.
  11. $this->message('thank you Soma'); object(Notices)[8] protected 'data' => array 0 => object(NoticeMessage)[168] protected 'data' => array 'text' => string 'thank you Soma' (length=14) 'class' => string 'FrontMembers' (length=12) 'timestamp' => int 1346793966 'flags' => int 0 protected 'localHooks' =>
  12. After watching the formbuilder video, I get the idea of putting the error messages in a "hidden" inputField. Gonna try that later...
  13. Man, this HUGE in the history of big...
  14. NO errors in debug mode, no notices. Don't know, gonna try the public function ( thought I don't like to have it public, cause it needs init to initialize first ) lol, you're right about error , gonna fix those install errors first
  15. Oké, i'll drop the whole code. Code is not nearly finished. But you get a clue, when you see. It's all about the echo "messages"in login() methode for example. It's installable/uninstallable, <?php class FrontMembers extends WireData implements Module, ConfigurableModule { /** * Return general info about the module for ProcessWire * */ public static function getModuleInfo() { return array( 'title' => 'FrontMembers', 'summary' => 'front-end member management', 'version' => 1, 'href' => 'http://processwire.com/talk/index.php/topic,56.0.html', 'author' => 'Martijn Geerts', 'autoload' => true, 'singular' => true ); } /** * Defining defaults * */ protected static $defaultSettings = array( 'controller' => 'controller', 'email' => '', 'f_submit' => 'fm_submit', 'loggedin' => false, 'used_methode' => false, 'all_methodes' => array( 'changePassword', 'confirmRegister', 'forgotPassword', 'login', 'logout', 'profile', 'register', 'resetPassword', 'updateProfile' ), 'postData' => array(), 'getData' => array(), 'requestData' => array(), 'messages' => array( 'succes' => array(), 'error' => array() ), 'seconds' => 10, 'maxSeconds' => 300, 'attempts' => 5 ); /** * set our default values before ProcessWire configures the module * __construct() is the first call within this Class * */ public function __construct() { foreach(self::$defaultSettings as $key => $value) $this->set($key, $value); } /** * Initialize the module and setup hooks * * The init method of a module is called right after ProcessWire is bootstrapped, when all * API vars are ready. Whereas the __construct() is called DURING bootstrap, so the init() * method is a better place to attach hooks to API vars. * * In this method, we'll use an 'after' hook since we want to modify the output of the * rendered page template. * * Note also that the 'Class::method' syntax means it hooks into ALL Page instances. * The syntax for hooking to a single instance would be: * $page->addHookAfter('render', $this, 'pageRender'); * * Also note that there isn't actually a Page::render method, it was instead added by * another module (wire/modules/PageRender.module). Not that it matters here, but just * wanted to mention in case you look in the Page class and don't see a render method. * * text by: apeisa, thanks * */ public function ready() { if( $this->loggedin && $this->page->template == 'admin') $this->session->redirect('/'); if($this->input->urlSegment(1) == 'logout') $this->logout(); if($this->input->urlSegment(2) == 'logout') $this->logout(); if($this->input->urlSegment(3) == 'logout') $this->logout(); } public function init() { // check if user is logged in as member if($this->user->hasRole('front-member')) $this->set('loggedin', true); // no get or post, nothing to do if (!isset($_REQUEST[$this->controller])) return false; // create empty array $init = array(); $key = array_search($_REQUEST[$this->controller], $this->all_methodes); $init['used_methode'] = is_int($key) ? $this->all_methodes[$key] : false; // populate the postData & getData arrays if($init['used_methode']) { // post exists, but could be blank; if ($this->input->post) { foreach($this->input->post as $key => $val) { $key = strtolower($this->sanitizer->fieldName($key)); $val = $this->sanitizer->text($val); $init['postData'][$key] = $val; $init['requestData'][$key] = $val; } } // get exists, but could be blank; if ($this->input->get) { foreach($this->input->get as $key => $val) { $key = strtolower($this->sanitizer->fieldName($key)); $val = $this->sanitizer->text($val); $init['getData'][$key] = $val; $init['requestData'][$key] = $val; } } } // set & overwrite (manipulated) defaults to $this foreach($init as $key => $value) $this->set($key, $value); // when nothing todo $controller = "nothingToDo". if($this->used_methode) { $this->addHookAfter('Page::render', $this, $this->used_methode); } else { $text['error'] = "{$_REQUEST[$this->controller]} is not a usable methode in {$this->config->urls->modules}{$this->className}.module"; $this->set('messages', $text); return false; } } /** * controller value has past the test, so now we know what to handle. * */ protected function changePassword($event) { echo 'changePassword'; } // listen to get protected function confirmRegister() { echo 'confirmRegister'; } protected function forgotPassword() { echo 'forgotPassword'; } /** * * Login * * --------------------------------------------------------------------------------- * * *name="username" may have the value of the members email address * * <form action="./" method="POST"> * <input type="text" name="username" /> * * <input type="text" name="password" /> * <input type="hidden" name="controller" value="login" /> * <button type="submit">submit</button /> * </form> * */ protected function login() { // exit when already loggedin if ($this->loggedin) return true; // clean it again with username sanitizer / don't know if needed $name = $this->sanitizer->username($this->postData['username']); $pass = $this->postData['password']; if (empty($name) || empty($pass)) { // this here is not working: $error = $this->_('One or more fields are empty'); $text['error'] = $this->_('One or more fields are empty'); $this->set('messages', $text); return false; } // check if user logging in with email $u = $this->users->get("email=$name"); if($u->get('id') > 0) { if( $u->hasRole('front-member')) { $name = $u->name; } } $u = $this->users->get("name=$name"); // returns 0 or the ID ( 0 means false ) if(!$u->get('id')) { echo $this->_('I think you made a typo'); return false; } if(!$u->hasRole('front-member')) { echo $this->_('Your account is non active'); return false; } $now = time(); $database = $this->fuel('db'); $name = $database->escape_string($name); $result = $database->query("SELECT attempts, last_attempt FROM session_login_throttle WHERE name='$name'"); $allowAccess = ($result->num_rows == 0) ? true : false; $blocked = $u->hasRole("blocked") ? true : false; if(!$allowAccess && !$blocked) { list($attempts, $lastAttempt) = $result->fetch_row(); if($attempts > $this->attempts) { $u->setOutputFormatting(false); $u->removeRole("front-member"); $u->addRole("blocked"); $u->save(); $u->setOutputFormatting(true); $database->query("DELETE FROM session_login_throttle WHERE name='$name'"); if(!empty($this->email)) $this->sendNotificationEmail($u); echo $this->_('Your account is set to non active'); return false; } $elapsedSeconds = $now - $lastAttempt; $requireSeconds = ($attempts * $attempts) * $this->seconds ; $allowAccess = $elapsedSeconds < $requireSeconds ? false : true; $attempts++; if(!$allowAccess) { $database->query("UPDATE session_login_throttle SET attempts=$attempts, last_attempt=$now WHERE name='$name'"); echo sprintf($this->_("Please wait at least %d seconds before attempting another login."), $requireSeconds); } else { // session_login_throttle won't delete entries on it's own ( is this intended ? ) $database->query("DELETE FROM session_login_throttle WHERE name='$name'"); } } if ($allowAccess) { $u = $this->session->login($name, $pass); if($u !== null) $this->session->redirect($this->page->url); } } /** * 3 ways to logout * * via get: ?controller=logout * via posts: <input type="hidden" name="controller" value="logout" /> * via urlSegment: /logout/ * */ public function logout() { $this->session->logout(); $this->session->redirect($this->page->url); } protected function register() { echo 'register'; } protected function resetPassword() { echo 'resetPassword'; } protected function updateProfile() { echo 'updateProfile'; } // send notification email needs user object protected function sendNotificationEmail($user) { $headers = "From: ".get_class($this).".module <members@".$this->config->httpHost.">\n"; $headers .= "MIME-Version: 1.0\n"; $headers .= "Content-type: text/html; charset=UTF-8\n"; $headers .= "Reply-To: info@".$this->config->httpHost."\n"; $headers .= 'X-Mailer: PHP/' . phpversion(); $subject = "Blocked: {$user->name} on " . $this->config->httpHost; $body = "<p>Member: <strong>{$user->name}</strong><br />"; $body .= "Email: <strong>{$user->email}</strong><br />"; $body .= "Status: <strong>blocked</strong></p>"; $body .= "<p>Member {$user->name} blocked by ".get_class($this).".module<br />"; $body .= "You can uncheck <strong>blocked</strong> and check <strong>front-member</strong> <a href=\""; $body .= $this->config->httpHost . $this->config->urls->admin ."access/users/edit/?id={$user->id}\">here</a><br />"; $body .= "to enable the account again.</p>"; return mail($this->email, $subject, $body, $headers); } /** * Provide fields for configuring this module * */ static public function getModuleConfigInputfields(array $data) { /** * After install, the input fields in the admin/modules config are not set. So, * populate the fields with the data from self::$defaultSettings. * */ foreach(self::$defaultSettings as $key => $value) { if(!isset($data[$key])) $data[$key] = $value; } $fields = new InputfieldWrapper(); $modules = wire("modules"); $field = $modules->get("InputfieldText"); $field->attr('name', 'controller'); $field->attr('size', 15); $field->attr('value', $data['controller']); $field->label = "input name attribute name (controller)"; $field->description = "Front-Members listen to the specified name & uses it's value as method name. " . "example: <input type=\"hidden\" name=\"{$data['controller']}\" value=\"login\" />" . " available values: " . implode(', ', $data['all_methodes']) . ". "; $fields->append($field); $field = $modules->get("InputfieldEmail"); $field->attr('name', 'email'); $field->attr('size', 0); $field->attr('value', $data['email']); $field->label = "email"; $field->description = 'send a "blocked user message" to this address or leave empty'; $fields->append($field); $field = $modules->get("InputfieldText"); $field->attr('name', 'f_submit'); $field->attr('size', 15); $field->attr('value', $data['f_submit']); $field->label = "Label text for submit field, most likely empty."; $field->description = "Label value for label attached to password field"; $fields->append($field); return $fields; } public function ___install() { // adding role $role = $this->roles->add('front-member'); $role->title = "Members role"; $role->save(); // adding role $role = $this->roles->add('blocked'); $role->title = "Members blocked role"; $role->save(); // create field $field = new Field(); $field->type = $this->modules->get("FieldtypePassword"); $field->name = 'tmp_pass'; $field->label = 'temporary password field for front-members'; $field->save(); // assign field to user template $template = $this->templates->get("user"); $template->fields->add("tmp_pass"); $template->fields->save(); // $sql = // "CREATE TABLE `front_members_ban` ( " . // "`name` varchar(128) NOT NULL, " . // "`ip` varchar(128) NOT NULL, " . // "`attempts` int(10) unsigned NOT NULL default '0'," . // "`last_attempt` int(10) unsigned NOT NULL," . // "PRIMARY KEY (`name`))"; // // $this->db->query($sql); } public function ___uninstall() { // delete the role $role = $this->roles->get('front-member'); if ($role->id > 0) $this->roles->delete($role); // delete the role $role = $this->roles->get('blocked'); if ($role->id > 0) $this->roles->delete($role); // delete field from field group $user_tpl = $this->templates->get("user"); $user_tpl->fields->remove("tmp_pass"); $user_tpl->fields->save(); // get rid of tmp_pass field $tmp_pass = $this->fields->get("tmp_pass"); if($tmp_pass->name) $this->fields->delete($tmp_pass); // $this->db->query("DROP TABLE IF EXISTS front_members_ban"); } } to try it: // suppress notices $output = ''; $username = false; $password = false; $controller = false; // create variable if($_REQUEST) foreach($_REQUEST as $key => $value) $$key = $value; // set module data to variable $data = $modules->get("FrontMembers")->data; $output .= "<form action='./' method='POST'>\n"; $output .= " <fieldset>\n"; $output .= " <label for='username'>username:</label>\n"; $output .= " <input type='text' id='username' name='username' value='{$username}'>\n"; $output .= " <br />\n"; $output .= " <label for='password'>password:</label>\n"; $output .= " <input type='password' id='password' name='password' value='{$password}'>\n"; $output .= " <br />\n"; $output .= " <select name='controller'>\n"; foreach($data['all_methodes'] as $methode) { $selected = $input->post('controller') == $methode ? " selected='selected'" : ''; $output .= " <option value='{$methode}'{$selected}>{$methode}</option>\n"; } $output .= " <option value='DoingTheDishes'{$selected}>DoingTheDishes</option>"; $output .= " </select>\n"; $output .= " </fieldset>\n"; $output .= " <button type='submit'>submit</button>\n"; $output .= "</form>\n"; $output .= "<hr />"; // see if logged in foreach($session as $name => $value) $output .= "<p>$name = $value</p>"; $output .= "<hr />"; echo $output; // just to see what info is available var_dump($data); fixed the notices when instal / uninstall
  16. In a module i'm writing I want to use the data array to store data. This data I can pick up in the module & in the template. $this->set($key, $value); works fine in the init(), but in other methodes I create I can't get it working. * Or can I use an other way to set data available voor the template. Wished I know a way to put "error" & "succes" messages in a variable for later output in the template.
  17. tnx for your advise ! Will take a look ! Slowly learning & I hope I can manage to complete the module. ( first OOP project for me )
  18. ryan said: 1. In Admin > Setup > Fields, create a new text field called 'tmp_pass' and add it to the 'user' template. I wished to do this from within the "public function ___install()" in the module. But I can't find anything on creating new fields, can someone help me out? dumb me:
  19. very nice site ! Nice to see the PW link in the footer to !
  20. Thank you Ryan & renobird. I love the big explanations & the time you took to write this all down. Total Right ! continue with the fight now....
  21. I agree with nik, that that is useful. But wire('session')->login activates more things and somehow I think it's good to get respond back from PW. SessionLoginThrottle for example, throttles the time up to 300 seconds,after that you're be able tp login again. Actually I'm trying to write a module for frontend members. covering: 'changePassword', 'confirmRegister', 'forgotPassword', 'login', 'logout', 'profile', 'register', 'resetPassword', 'updateProfile' I'm kinda stuck on the "login" due the lack of OOP knowledge. I don't know how to retrieve the data back from for instance "SessionLoginThrottle.module" or any other classes. Figured out SELF:: for example, but don't know where PARENT:: references to for example.... Realy have no clue, maybee I even start wrong class FrontMembers extends WireData implements Module, ConfigurableModule { } I'll continue fighting this week...
  22. Sorry that I missed your post. Next time when i'm in the same scenario hopefully I think of what you said. Big THANX for the explaining.
  23. What a timing, I just started trying to build a module. This community is remarkable !
  24. I think it's all about the user who manages the site. If I build a little site for my self, I wouldn't use a CMS at all. I will build a little controller, thats all. But on normal circumstances other people fill the site and it should be as obvious as possible. (no explanation needed) So If that wil give performance issues, I think I'll go for the cache and the remarkable MarkupCache module.
×
×
  • Create New...