Jump to content

pwFoo

Members
  • Posts

    708
  • Joined

  • Last visited

Everything posted by pwFoo

  1. I write a login / register module. Basic login / logout / register works fine. Also a simple PersistLogin and ProcessForgotPassword integration. https://processwire.com/talk/topic/8001-frontenduserlogin/?p=92083 Testing repo: https://bitbucket.org/pwFoo/frontenduser/overview Requires FormHelper module testing branch: https://bitbucket.org/pwFoo/formhelper/src/baa9fc92d08103775626ed931e1b6af02bbb8cba/?at=testing InputfieldText as password field from my module. protected function password() { $field = $this->modules->get('InputfieldText'); $field->skipLabel = 4; // Inputfield::skipLabelBlank; $field->placeholder = $this->_('Password'); $field->attr('id+name', 'password'); $field->attr('type','password'); $field->required = 1; return $field; }
  2. Latest update to my local testing branch... Moved totally from custom callbacks to PW hooks (core and module own hookable methods) Have a working minimal FrontendUserLogin and FrontendUserRegister module. Added FormHelper dependency again (instead of a extended wrapper FormHelper is changed to extend InputfieldForm object) FrontendUserLogin / FrontendUserRegister (simple use) // login echo $modules->get('FrontendUserLogin')->render($redirectAfterLogin); // register echo $modules->get('FrontendUserRegister')->render($redirectAfterRegister); The method render() is a shortcut. Long form with chance to modify parameters, form, ... $fu->form(); $fu->validate(); $fu->process($redirect); $fu->renderForm(); How to add plugins? After $fu->form() define the plugin field and needed processing validation code as a PW hook RememberMe plugin to integrate LoginPersist module // RememberMe field / persistLogin integration $remember = $modules->get('InputfieldCheckboxes'); $remember->name = 'persist'; $remember->attr('id+name', 'persist'); $remember->skipLabel = 4; $remember->addoption('persist', 'Remember me?'); $remember->addHookAfter('processInput', function($event) { $field = $event->object; if (isset($field->value[0]) && $field->value[0] === 'persist') { wire()->addHookAfter('Session::login', function($event) { wire('modules')->get('LoginPersist')->persist(); }); } }); $fu->attr('form')->add($remember); Or an integration of core module ProcessForgotPassword // ForgotPassword integration $forgot = $modules->get('InputfieldMarkup'); $forgot->value = "<a href='{$page->url}?forgot=1'>{$this->_('Forgot password?')}</a>"; $fu->attr('form')->add($forgot); if ($input->get->forgot) { function processForgot($event) { wire('config')->styles->add('/pw/wire/modules/AdminTheme/AdminThemeDefault/styles/main-classic.css'); $event->return = wire('modules')->get('ProcessForgotPassword')->execute(); $event->replace = true; } $fu->addHookBefore('FrontendUserLogin::login', null, 'processForgot'); } Login with email address instead of username? // Email login instead of username $fieldUser = $fu->attr('form')->get('username'); $fieldUser->addHookBefore('FrontendUserLogin::auth', function($event) { $fu = $event->object; $email = $fu->attr('form')->fhValue('username', 'email'); $loginUser = wire('users')->get("email={$email}"); if ($loginUser instanceof User && !$loginUser->isGuest()) { $event->arguments(0, $loginUser->name); } }); You have added a nickname field to user template? The plugin to use the nickname (sanitized text instead of username) to login // Nickname login instead of username $fieldUser = $fu->attr('form')->get('username'); $fieldUser->addHookBefore('FrontendUserLogin::auth', function($event) { $fu = $event->object; $nick = $fu->attr('form')->fhValue('username', 'text'); $loginUser = wire('users')->get("nickname={$nick}"); if ($loginUser instanceof User && !$loginUser->isGuest()) { $event->arguments(0, $loginUser->name); } }); The plugins are tested and working fine, but I don't know how to ship plugins. At the moment it's code inside the template login.php, but should be moved to a separate plugin file or the FrontendUserLogin module... Any suggestions? *Added nickname login plugin and fixed a nickname / email login bug*
  3. *UPDATE* tokenReset() works fine. My bad...
  4. Updated post above. Also updated the Bitbucket repo link callbacks moved to PW hooks additional callback arguments supported
  5. Sorry... haven't seen it... Thanks!!! I'll try it. *UPDATE* Works fine!
  6. Hi, your way should work fine, but I tried to reduce the overhead. The dynamic function should be added to the current form field object ("$myField", any Inputfield) instead of each instance of a class ("myClass::method"). If there isn't a way I'll do it like you suggested it above.
  7. Is it possible to add a method to the current $field via addHook()? I try to add dynamic functions to fields, but each field will have a custom dynamic function.
  8. While look deeper and deeper inside Processwire and hooks I'll have a new reduced FormHelper testing branch... FormHelper TESTING branch extends InputfieldForm. So you can use the pw form api with some extensions. How FormHelper could be used. // Load FormHelper module and also set wire('fh') variable $fh = $modules->get('FormHelper'); // Create a (first) form $form = $fh->create(); // Add some fields to the PW form object // Add default sanitizer $field->fhSanitizer = 'text'; // Add preprocess and processed callbacks $field->addHook('fhCallbackPreprocess', function($event) { // called before form processing }); $field->addHook('fhCallbackProcessed', function($event) { // called after form processing }); // Your callbacks need more arguments than $event or $this (class inside the callback is written)? Set additional arguments as array $field->fhCallbackArgs = array($arg1, $arg2); // access arguments via $event->arguments // process form // adds submit button, callback execution, CSRF check + reset and processInput() // error handling, also WireUpload errors if ($form->fhProcessForm()) { // true = submitted without errors // false = submitted with errors // null = not submitted // Get value sanitized (fhSanitizer) echo $form->fhValue($fieldname); // Get value sanitized with given sanitizer echo $form->fhValue($fieldname, 'pageName'); // Get raw value and ignore fhSanitizer setting echo $form->fhValue($fieldname, false); } Submit button is added in the beginning of the fhProcessForm() method. Get the submit button to modify it previously... // Get submit button $submitBtn = $form->fhSubmitBtn; Missing features will be moved to FormHelperExtra (if needed) pwImage plugin InputfieldCKEditor stuff (hidden page id field...) form by template / type "Field" fields with a hidden storage page to get file uploads working without saved page ... FormHelper testing branch https://bitbucket.org/pwFoo/formhelper/src/2a7e7261cf347622a82612d381cabdc63bed4c08?at=testing *UPDATED*
  9. Hi mr-fan, good idea, but maybe with each 2-5 cons / pros (1-2 sentences) it could be a lot of pages. UI should be the best (out of the box). So I'll test it!. Thanks! *UPDATE* Add new item is also a textarea with with one line per pro / con. So input new values isn't an improved UI, but have a sorting feature. Select box isn't needed because no duplicates expected.
  10. To buy ProField Multiplier is over-sized for the planed small private project / tool. Backend solution with textarea and textformatter should do it. Frontend could be a simple form to submit entries. So text field with some javascript could do the job. I take a look how to build it that way. Thanks!
  11. I try to build a small tool and need one or two inputfields to collect examples (like a defined count of pros and cons). The simple way could be two textareas (pros and cons) with the textformatter module Newlines to Unordered List. So the input will be converted to lists. But is there a better way? A more comfortable UI / inputfield?
  12. First (simple) tests with Padloper and the minimal install profile are done. Nice basic stuff Can't wait to see some example shops and the full featured shop profile with improved UI and maybe cart handling. Is it possible to save user information as pages or pw user? Logged in user could skip checkout form.
  13. It doesn't support an active class. You can set outerTpl and innerTpl used for each row. Instead of use the module own render() method you could parse and get the data to handle it your own... $mtc = $modules->get('MarkupTagcloud'); // parent, tag field $mtc->parse('1003', 'tag'); // all used tags, sort by title (for example) $tags = $mtc->getTags('sort=title'); foreach ($tags as $tag) { $nArticles = $tag->useCount; // your code here... } If you also need the tagged pages you could add a third param "true" to the parse() method, but it will have some overhead. $mtc = $modules->get('MarkupTagcloud'); // parent, tag field, get tagged pages $mtc->parse('1003', 'tag', true); // all used tags, sort by title (for example) $tags = $mtc->getTags('sort=title'); foreach ($tags as $tag) { $nArticles = $tag->useCount; $taggedPages = $tag->use; // your code here foreach ($taggedPages as $taggedPage) { // page object of tagged pages... } } Examples are untested! But why use the overhead with the MarkupTagcloud module if your code works fine?
  14. I have a local testing version with field callbacks ("prepare" before added to form and "process" after form "basic" process) and preLogin / postLogin callbacks Possible usage: // Integrate LoginPersist module (manual mode) after sucessfully logged in $callback['postLogin'] = function ($fulObj) { if ($fulObj->attr('result')) { wire('modules')->get('LoginPersist')->persist(); } }; // optional login with email address instead of an username... (could also be done as username form field callback "process"! Just an example!!!) $callback['preLogin'] = function ($fulObj) { // callback defined outside the module class, so $this and private class attributes won't work! // module object hand over as function param. Get / set attributes with the attr() method. $email = $fulObj->attr('form')->get('username')->value; $userObj = wire('users')->get("email={$email}"); if ($userObj instanceof User) $fulObj->attr('user', $userObj->name); }; // login call with optional callback echo $ful->login("{$config->urls->root}login", $callback)->render(); Internal field process callback (sanitize input value) /** * Username form field * @return object Username field */ protected function fieldUsername() { $field = $this->modules->get('InputfieldText'); $field->label = $this->_('Username'); $field->attr('id+name', 'username'); $field->required = 1; // Set a "callbackProcess" to sanitize the input value or a "callbackPrepare" executed just before the field will be added to the form $field->fulOption = array( 'callbackProcess' => function ($field) { // 'callbackProcess' => function ($field, $obj) { // to get module object also outside the module class use an additional param // callback defined inside the module class and $this will work here. Also wire() could be used $this->user = wire('sanitizer')->username($field->value); }, 'callbackPrepare' => function ($field) { // Your code here... will be executed before field added to form } ); return $field; } What do you think about the change and usage of dynamic functions as callbacks?
  15. Bump version to 0.5.3 Replaced fhOption "callback" with "callbackPrepare" (executed before field added to form) and callbackProcess (executed after form process to do additional processing). Examples callbackProcess // You can use "$field" (current field object) and "wire()") $fhOptions['title']['callbackProcess'] = function ($field) { // Modify a form field (wire('fh') is the FormHelper instance / object which is added to "wire()") wire('fh')->form->get('body')->error('CALLBACK-ERROR to another field...'); // modify current field by callback $field->error("CALLBACK {$field->name} ERROR"); }; callbackPrepare $fhOptions['title']['callbackPrepare'] = function ($field) { // replace field value (executed after clear / value / unformatted feature) $field->value = "TEST PREPARE CALLBACK"; // or skip the field just before it will be added to the form... wire('fh')->fhOptions($field, array('skip' => true)); }; FormHelper creates forms by Page, Template, Fields, Inputfields, InputfieldForm (fields) or an array with field data with 371 lines of code. Maybe it could be separated into a basic form process module and an sub module to handle additional features (Template based form with file upload, CKEditor image plugin, ...) but I don't know if it should be necessary.
  16. At the moment I have no usage for FCM module, but after FormHelper 0.5.2 is finished I've done a quick FCM rewrite. Only few tests done yet!
  17. merged testing to the master branch as version 0.5.1. Added a state() function to get the form submit state.
  18. New testing branch commit with a shortcut to combine source() with create() // Set source, optional $fhOptions and $refPage and chain it with form render $fh->form($source, $fhOptions = null, $refPage = null)->render(); Thought about field save / create page feature, but should be done with another module because it would unnecessary overhead if you sending a mail or something else. Current version: https://bitbucket.org/pwFoo/formhelper/src/99d0ea09a8012446fd8fba71e7b34ede319551ad/?at=testing
  19. New testing branch (readme file includes an example usage / template fiel): https://bitbucket.org/pwFoo/formhelper/src/14d3cf18768b?at=testing *UPDATE* Supports forms based on Page Template Fields InputfieldForm (form fields) and should also work with array (PW 2.5.5+). You can define optional field settings callback (additional field processing via dynamic function) set / clear form field value or get unformatted page field value skip a field (not added to form) ignore a field (no additional field processing, skip field after form process in getForm() function) set the CKEditor pwImage plugin page id (plugin image source) set a sanitizer to field and you will get a sanitized value with getValue() function FormHelper prepare file fields and give you a file array to work with (path + filename)
  20. Hi Adrian, thank you for help with that problem. Solved it with the hidden page workaround. Should be fine for me. protected function prepareTypeField($field) { if ($field->type == 'FieldtypeImage' || $field->type == 'FieldtypeFile') { return $this->prepareFieldTypeFile($field); } return $field->getInputfield($this->imgRefPage); } protected function prepareFieldTypeFile($field) { $f = $this->modules->get($field->inputfieldClass); $f->name = $field->name; $f->maxFiles = $field->maxFiles; $f->overwrite = $field->overwrite; $f->extensions = $field->extensions; $f->maxFilesize = $field->maxFilesize; $f->destinationPath = "{$this->config->paths->files}{$this->imgRefPage->id}/"; $f->attr("value", new Pageimages($this->imgRefPage)); return $f; } Tested with a image field. Upload works without warnings or errors. $this->imgRefPage is a simple title only page (hidden).
  21. setDestinationPath() is used by WireUpload object, but I added it to the form field as destinationPath (as variable. not method) and the upload works. Verified upload via console. Correct file, correct date / time and also correct directory. ls -lh /volume1/web/pw/site/assets/files/.temp/2015-02-07-20.jpg -rw-r--r-- 1 http http 2.9M Feb 20 14:29 /volume1/web/pw/site/assets/files/.temp/2015-02-07-20.jpg So all should be fine, but... 1023 is the current page id and should be replaced with ".temp" as you can see above. Warning: filemtime(): stat failed for /volume1/web/pw/site/assets/files/1023/2015-02-07-20.jpg in /volume1/web/pw/wire/core/Pagefile.php on line 311 ls -lh /volume1/web/pw/site/assets/files/1023/2015-02-07-20.jpg ls: /volume1/web/pw/site/assets/files/1023/2015-02-07-20.jpg: No such file or directory So the best way should be to set the correct path to Pagefile? Searching for that file at my ".temp" and not the current page and all should be fine? Upload the file to "any page" could / should work, but it feels wrong. Why upload to any page instead a temp folder? After the form is processed I create and save the needed page. Next step the file from temp folder will be added. Or I have to create a hidden page to work with that context page if no page exists during upload. Tested with a simple page (template with title field only). Better upload all the files to an hidden "fileUpload" page instead of a random (current) page... To post the full code I should clean it up first... To much comments, tests ...
  22. Hi adrian, thanks. This solution works with an existing page context ($page->getInputfields() the solution above). But with an existing page context there is no need for that solution if the form is generated by $page->getInputfields() or $pageField->getInputfield($page). I build my form from template fields without an existing page (context). $tplFields = $pages->get('id=1024')->template->fields; Some fields simply added to the form in context to an unsaved page object (fakePage). $fakePage = new Page(); $fakePage->template = $template; // Template object fields based from // InputfieldImage won't work?! So workaround use InputfieldFile... $img = $modules->get('InputfieldFile'); $img->attr('id+name', 'image'); // image will be uploaded to the given path! Works correct. $img->destinationPath = "{$config->paths->files}.temp/"; $img->extensions = 'JPG JPEG'; $form->add($img); // Won't work because isn't an existing / saved page //$img->attr("value", new Pageimages($fakePage)); Field is added without an error, but after submit form the image is expected in the current page ($page) path instead of defined destinationPath. Sounds like a bug Warning: filemtime(): stat failed for /volume1/web/pw/site/assets/files/1023/2015-02-07-4.jpg in /volume1/web/pw/wire/core/Pagefile.php on line 311 title Use an existing page is ok, but I try to create a new page. That's why I upload to a temp dir. After form submit and validation a page will be created and saved before the file is handled / moved to the correct location. Form processing fails... Maybe I have to skip the image field and handle the file upload without WireUpload?
  23. Any solution to fix the wrong page id / upload path described by chrizz? Replaced InputfieldImage with InputfieldFile to get around the first problem, but after file uploaded (correct to temp directory) during form process the uploaded image is assumed in the current page directory... Warning: filemtime(): stat failed for /volume1/web/pw/site/assets/files/1023/2015-02-07-16.jpg in /volume1/web/pw/wire/core/Pagefile.php on line 311 title File uploaded to the correct location... /volume1/web/pw/site/assets/files/.temp/2015-02-07-16.jpg
  24. Thank's, will be changed in the next release, but a major redesign is planned.
  25. Module is deprecated! The current module code won't be supported or updated.
×
×
  • Create New...