pwFoo
Members-
Posts
708 -
Joined
-
Last visited
Everything posted by pwFoo
-
FrontendContentManager: add and edit pages as frontend user
pwFoo replied to pwFoo's topic in Module/Plugin Development
Solved file / image handling (not commited yet). Added file handling to FormHelper module and get add() (create page) working. -
Fine
-
Could you also post the generated html source code (header, scripts)?
-
Hi Ryan, tried that conditional autoload with a module is loaded check, but doesn't work... 'autoload' => function () { return class_exists('UserFrontendRegister',false); }, Would be a way to auto load a submodule / plugin only if needed Isn't the module loaded during execute that code? How to get it work?
-
@adrian Found it here. Also a function can be used. Something like that should be work to load submodules / plugins only if a module is loaded (class exists, should be in use...). 'autoload'=> function(){ return class_exists('<MainModule>',false); }
-
I started a simple module / test to create / edit pages. Create and edit simple pages works fine, but frontend create pages with file / image field failed with an error. I think it's missing file upload / handling. I'll do some more tests, but no time at the moment..
-
@adrian Good to know this one... autoload' => 'template=admin', Are there some more selectors like template here? Module, page or something else?
-
Maybe custom code? Check the users role(s) and redirect to an error page or something else if a frontend user try to access the backend.
-
Integrating a member / visitor login form
pwFoo replied to thetuningspoon's topic in General Support
I posted a dev version a few days before. Login, Logout with ProcessForgotPassword Integration and error handling. Form based in form API (m also here posted FormHelper dev module). https://processwire.com/talk/topic/6326-user-module-for-login-logout-register/?p=74994 Planned additional features - register, email activation and user profiles -
FrontendContentManager: add and edit pages as frontend user
pwFoo replied to pwFoo's topic in Module/Plugin Development
After loading jquery and set "jsconfig" WYSIWYG editor works fine, but there are some more modules needed to get a full styled form. For example image field? How can I determine and load needed modules to get a full styled form (like backend forms) with autocomplete page reference for example (JqueryCore, JqueryUI,...)? But first problem to solve should be file / image field handling from post above... Error: Exception: Invalid image (in /volume1/web/pwdev/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module line 273) #0 [internal function]: InputfieldFile->___processInputAddFile('tk_passbild_and...') #1 /volume1/web/pwdev/wire/core/Wire.php(359): call_user_func_array(Array, Array) #2 /volume1/web/pwdev/wire/core/Wire.php(317): Wire->runHooks('processInputAdd...', Array) #3 /volume1/web/pwdev/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module(360): Wire->__call('processInputAdd...', Array) #4 /volume1/web/pwdev/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module(360): InputfieldImage->processInputAddFile('tk_passbild_and...') #5 [internal function]: InputfieldFile->___processInput(Object(WireInputData)) #6 /volume1/web/pwdev/wire/core/Wire.php(359): call_user_func_array(Array, Array) #7 /volume1/web/pwdev/wire/core/Wire.php(317): Wire->runHooks('processInput', Array) #8 /volume1/web/pwdev/wire/core/InputfieldWrapper.php(436): Wire->__call('processInput', Array) #9 /volume1/web/pwdev/wir No problem with images during frontend page edit, only during page add... So I think I have to set some more values or change my page presave / save method... -
Hello, is there a recommend way how to add / save new pages via frontend? Could I use/ integrate some core modules to do it (field sanitizing and saving)? With my FormHelper module I can create forms from pages and templates. That works fine for edit a page. To add a new page is tricky... Before I execute my save function I have to do some preSave actions (save the fake page! Set parent and name!). Now also add and save pages works... until there is a file / image field... Error: Exception: Invalid image (in /volume1/web/pwdev/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module line 273) #0 [internal function]: InputfieldFile->___processInputAddFile('tk_passbild_and...') #1 /volume1/web/pwdev/wire/core/Wire.php(359): call_user_func_array(Array, Array) #2 /volume1/web/pwdev/wire/core/Wire.php(317): Wire->runHooks('processInputAdd...', Array) #3 /volume1/web/pwdev/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module(360): Wire->__call('processInputAdd...', Array) #4 /volume1/web/pwdev/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module(360): InputfieldImage->processInputAddFile('tk_passbild_and...') #5 [internal function]: InputfieldFile->___processInput(Object(WireInputData)) #6 /volume1/web/pwdev/wire/core/Wire.php(359): call_user_func_array(Array, Array) #7 /volume1/web/pwdev/wire/core/Wire.php(317): Wire->runHooks('processInput', Array) #8 /volume1/web/pwdev/wire/core/InputfieldWrapper.php(436): Wire->__call('processInput', Array) #9 /volume1/web/pwdev/wir Here the page add method which basically works without file / image fields. public function add($parent, $options = null) { // ignore admin pages and check permissions! if ($this->input->urlSegment1 != 'add' || $page->template == 'admin' || !$parent->addable()) return false; $tpl = ($options['tpl'] ? $options['tpl'] : $parent->template); $fh = $this->modules->get('FormHelper'); $fh->createForm($parent, array('clearValues' => true)); // process form $processedForm = $fh->formProcess(); if ($sanitizedForm = $this->checkFormValues($processedForm)) { // sanitizing is skipped with always true! $title = $sanitizedForm->get('title')->value; $page = new Page(); $page->template = $tpl $page->parent = $parent; $page->name = $this->sanitizer->pageName($title); $page->title = $title; $page->save(); $this->pageSave($page, $processedForm, true); } else { return $fh->render(); } } // Set page values and save it... private function pageSave($page, $processedForm, $changed = false) { foreach ($processedForm->children as $field) { if ($field->value != $page->get($field->name)) { $page->set($field->name, $field->value); $changed = true; } } if ($changed) { // Save and reload to show changed page... $page->of(false); $page->save(); $page->of(true); } } Would like to reuse backend page save function (validate and sanitize form values before save the new page).
-
First public repo of UserLogin module (dev! unstable!) based on my FormHelper module. https://bitbucket.org/pwFoo/userlogin/src/02d405031f26c1d55b08db93f23eae8ca144ecc2/UserLogin/UserLogin.module?at=master Demo usage see readme file. Basic features are login and logout. If ProcessForgotPassword core module is installed the link is added to login form.
-
And again some changes Some bugs fixed and repo is updated. At the moment I prefer as parameters to build a form parameter 1: fields as objects or array data parameter 2: only module options like "clearValues", "skipFields", ... (but additional field data like change submit button, form attributes or also fields is still possible until now...) Build the form and then modify could be done in two steps. Here an example. $fh->createForm($templates->get('register'), array('clearValues' => false, 'jquery' => false)); $modifyFields['username'] = array( //'module' => 'InputfieldText', 'pos' => array('method' => 'insertAfter', 'refObj' => $fh->form->get('email')), 'vars' => array('name' => 'username', 'label' => 'Username123'), ); $modifyFields['submit'] = array( 'vars' => array('name' => 'submit'), 'attr' => array('value' => 'Login'), ); echo "Before modify: " . $fh->form->get('submit')->value . "<br />"; foreach ($modifyFields as $modifyField) { $fh->field($modifyField); } echo "After modify: " . $fh->form->get('submit')->value . "<br />";
-
The above linked version internal adds all fields (field objects and also field array data) with one function. public function field($field, $method = 'add', $refPosObj = null, $bypass = null) $field: field object OR array of field information to add (inputfield module and field name required) OR update (also field name required) if exists $method: add, insertBefore, remove, ... to build the "$form->$method()" call. $refPosObj: is needed by $method insertAfter or insertBefore. Have to be a field object $bypass: Skip hookable prepare / validate function (used tro handle "skipFields", or "clearValues") before add to form So after create the form it should be possible to modify it with a $fh->field(...) call or directly change the form object $fh->form from outside. This two cases are untested, but forms fine from inside...
-
Bitbucket FormHelper Repo is online... dev / unstable !!! https://bitbucket.org/pwFoo/formhelper/src/8ca0b543d87b5534ac476d2e240466a216d34be6/FormHelper/FormHelper.module?at=master Sorry, readme file isn't readable online... It's a simple example usage php file. I paste it here... <?php $fh = $modules->get('FormHelper'); ////////////////////// ////// EXAMPLES ////// // form based on template object $fh->createForm($templates->get('myTemplate')); // form based on page object $fh->createForm($pages->get('myPage')); // form based on a page, but clear field values and remove the fields headline, sidebar $fh->createForm($pages->get('myPage'), array('clearValues' => true, 'skipFields' => array('headline', 'sidebar'))); // Build form from template register and then modifiy username field label... $formFields['username'] = array( 'module' => 'InputfieldText', 'vars' => array('name' => 'username', 'label' => 'Username123', 'required' => true), 'attr' => array('id+name' => 'username'), ); $fh->createForm($templates->get('register'), array('fields' => $formFields)); // Create a login form from array data only and change default "Submit" to "Login" $formSubmit = array('vars' => array('name' => 'submit'), 'attr' => array('value' => 'Login')); $formFields = array( 'username' => array( 'module' => 'InputfieldText', 'vars' => array('name' => 'username', 'label' => 'Username', 'required' => true), 'attr' => array('id+name' => 'username'), ), 'password' => array( 'module' => 'InputfieldText', 'vars' => array('name' => 'password', 'label' => 'Password', 'required' => true, 'type' => 'password'), 'attr' => array('id+name' => 'password', 'type' => 'password'), ), ); $fh->createForm($this->formFields, array('submit' => $this->formSubmit)); ////// EXAMPLES ////// ////////////////////// // process form $process = $fh->formProcess(); if ($process === NULL) { // form not sent } elseif ($process == true) { // form sent, without errors... do something } elseif ($process === false) { // form sent, but with errors! ... } $form = $fh->render(); // returns rendered form echo '<html><head>'; // jsConfig needed by wysiwyg editors echo $fh->jsConfig() . "\n"; // outpunt needed scripts for inputfield modules, ... foreach ($config->scripts as $file) { echo "<script type='text/javascript' src='$file'></script>\n"; } foreach ($config->styles as $file) { echo "<link type='text/css' href='$file' rel='stylesheet' />\n"; } echo '</head><body>'; echo $form; echo '</body></html>';
-
Both fields I tried to use are shown correct in the form So that code should work. $form->insertAfter($field, $posRef); ... Found and fixed two bugs in my code. Because of the special behavior most tests ok, but sometimes... Thank you very much! To know the error isn't that piece of code helped me much.
-
Mh, ok. Both (input)fields works fine inside the form... This one was generated from a page. $fields = $myPage->getInputfields(); foreach ($fields as $field) { $this->form->add($field); } I'll try it with other form sources...
-
Tested it without success... Recoverable Fatal Error: Argument 2 passed to InputfieldWrapper::insertAfter() must be an instance of Inputfield, null given, called in /volume1/web/pwdev/site/modules/FormHelper/FormHelper/FormHelper.module on line 98 and defined (line 201 of /volume1/web/pwdev/wire/core/InputfieldWrapper.php) Get field from form isn't a object instance of Inputfield... Works if I use a field object. So that not work: $this->form->insertAfter($this->form->get('title'), $this->form->get('headline')); Could form field object be converted to an Inputfield object?
-
@Soma To easy... Works also and looks better. Thanks again!
-
Found a solution... Maybe there is a better one, but it works... $form->find("type=submit")->get("type=submit")->name; Tried also // not working $form->get("type=submit")->name; $form->find("type=submit")->name; And with a single find I have to use a loop to get it...
-
Please post your modules at: modules.processwire.com
pwFoo replied to ryan's topic in Module/Plugin Development
Before I release first modules... Some questions Where could be information about naming convention, coding standards, .... found? And is a github accound needed or could I add a bitbucket repo instead? -
Simple ProcessForgotPassword (core module) integration done. "Forgot password?" link added as form field after login form password field if ForgotPassword module is installed.
-
Here an updated / reworked module version... <?php /** * Processwire 'FormHelper' module * * Generate forms from pages, templates or input data * * @author pwFoo * @since 2014-09-13 * * ProcessWire 2.x * Copyright (C) 2011 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * * http://www.processwire.com * http://www.ryancramer.com */ class FormHelper extends WireData implements Module { protected $form; protected $submitBtn; protected $cfg = array( 'page' => null, 'template' => null, 'clearFormValues' => null, 'jquery' => null, 'jsconfig' => null, // form default settings 'form' => array( 'module' => 'InputfieldForm', 'vars' => array('method' => 'post', 'action' => ''), 'attr' => array('id+name' => 'formhelper'), ), 'submit' => array( 'module' => 'InputfieldSubmit', 'attr' => array ('id' => 'submit', 'name' => 'submit', 'value' => 'Submit'), ), 'fields' => null, /* * 'fields' => array( * 'username' => array( * 'module' => 'InputfieldText', * 'position' => 'insertBefore:password', // "insert method" [":" "reference field"] * 'vars' => array('name' => 'username', 'label' => 'Username', 'required' => true), // var "name" required! * 'attr' => array('id+name' => 'username'), * ), * ), */ ); /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * @return array */ public static function getModuleInfo() { return array( 'title' => 'FormHelper', 'summary' => 'Generate and process forms from page / template fields or given field parameters', 'version' => '0.0.2', ); } protected function setCfg ($arr, $reset = null) { if ($reset === null) { $this->cfg = array_replace_recursive($this->cfg, $arr); } else { $this->cfg = $arr; } } /** * Generate the form object from given fields * @return object Generated form */ public function ___createForm (array $cfg = null, $reset = null) { // merge or overwrite default config if ($cfg !== null) $this->setCfg($cfg, $reset); // create form field / wrapper $this->form = $this->setObj($this->cfg['form']); // Get inputfields from page object or given template if ($this->cfg['page'] || $this->cfg['template']) $this->getFormInputfields(); // create or merge form with given field data array if ($this->cfg['fields'] !== null && is_array($this->cfg['fields'])) $this->createFormFields(); // add submit button $this->submitBtn = $this->setObj($this->cfg['submit']); $this->form->add($this->submitBtn); return $this->form; } /** * ToDo: implement method / field positioning ? */ public function formField ($field, $method = 'add', $posRefField = null) { $field = $this->prepareField($field); $this->form->$method($field); } /** * */ protected function ___prepareField($field) { if(in_array($field->name, $this->cfg['skipFields'])) return null; // remove field if ($this->cfg['clearFormValues']) $field->value = null; // set value to empty return $field; } /** * Generate inputfields from given page object fields * @return object Generated field */ protected function getFormInputfields () { if ($this->cfg['template'] && !$this->cfg['page']) { $this->cfg['page'] = $this->fakePage($this->cfg['template']); } foreach ($this->cfg['page']->getInputfields() as $field) { $this->formField($field); } } /** * Generate form fields based on given data array * @return object Generated field */ protected function createFormFields() { foreach ($this->cfg['fields'] as $formField) { // Update form field if exists if ($exists = $this->form->get($formField['vars']['name'])) { $this->setObjValues($exists, $formField); } // Doesn't exist? Create and add it to form... else { $field = $this->setObj($formField); $this->formField($field); } } } /** * Rendering the current form * @return string Rendered form as html code */ public function ___render() { return $this->form->render(); } /** * Process form data if send * @return object Processed form data */ public function ___formProcess() { $submit = $this->submitBtn->get('name'); if(!$this->input->post->$submit) return NULL; // form NOT submitted... $processedForm = $this->form->processInput($this->input->post); // form api process form values if(!$this->form->getErrors()) return $processedForm; // form processed: OK else return false; // form send with errors } /** * Generate a field / form object * @param array $arr Needed values to create the object * @return object Generated field object */ private function setObj($arr) { $obj = $this->modules->get($arr['module']); $this->setObjValues($obj, $arr); return $obj; } /** * Update form / field variables and values * @param object $obj field object by reference * @param array $arr field variables/ properties and attributes */ private function setObjValues(&$obj, $arr) { if (is_array($arr['vars'])) { foreach ($arr['vars'] as $key => $value) { $obj->set($key, $value); } } elseif (is_array($arr['attr'])) { foreach ($arr['attr'] as $key => $value) { $obj->set($key, $value); } } } /** * Make fake page and assign needed template * @param string $tpl Template to assign * @return object Generated fake page to work with */ private function fakePage($tpl) { $fakePage = new Page(); $fakePage->template = $tpl; return $fakePage; } /** * jsConfig settings needed by wysiwyg editor * @return string Basic JavaScript config */ public function ___jsConfig () { $jsConfig = $this->config->js(); $jsConfig['debug'] = $this->config->debug; $jsConfig['urls'] = array( 'root' => $this->config->urls->root, 'admin' => $this->config->urls->admin, 'modules' => $this->config->urls->modules, 'core' => $this->config->urls->core, 'files' => $this->config->urls->files, 'templates' => $this->config->urls->templates, 'adminTemplates' => $this->config->urls->adminTemplates, ); return '<script type="text/javascript">var config = ' . json_encode($jsConfig) . '</script>'; } } Some features (jquery, jsconfig, ...) missing, but it works with a simple page / template... My testing template code (also with form field overwrite (for example field username). <?php $fh = $modules->get('FormHelper'); $formFields['username'] = array( 'module' => 'InputfieldText', 'vars' => array('name' => 'username', 'label' => 'Username123', 'required' => true), 'attr' => array('id+name' => 'username'), ); $fh->createForm(array('template' => 'register', 'fields' => $formFields)); // process form $process = $fh->formProcess(); if ($process === NULL) { echo "Nicht abgeschickt<br /> <br />"; } elseif ($process == true) { echo "Abgeschickt, ohne Fehler<br /> <br />"; } elseif ($process === false) { echo "Abgeschickt, mit Fehlern<br /> <br />"; } $form = $fh->render(); // returns rendered form echo '<html><head>'; // jsConfig needed by wysiwyg editors echo $fh->jsConfig() . "\n"; // outpunt needed scripts for inputfield modules, ... foreach ($config->scripts as $file) { echo "<script type='text/javascript' src='$file'></script>\n"; } foreach ($config->styles as $file) { echo "<link type='text/css' href='$file' rel='stylesheet' />\n"; } echo '</head><body>'; echo $form; echo '</body></html>'; Be careful... don't use "$fields" as variable to build the form fields data array. I should change the array key 'fields' again because it lead to use $fields as variable to build the sub array... UPDATE Latest version also fixed a bug during set field properties / attributes...
-
Hello fmgujju, after diving deeper into form api I rewrite the module code again. I try to get it more flexible and easier / much shorter... Minor options / parameter changes Feature to merge (maybe also replace and insert at position...) page / template fields with additional values / overwrite from array data get the form object and do whatever you want via form api (before render the form) At the moment you can copy the module code above to do some tests... https://processwire.com/talk/topic/7508-template2form-module-helper/?p=73255 Maybe I can update the module code or maybe build a release until the end of the week...
-
Ok, thanks. At the moment I work with simple forms, but handle nested fields, repeater fields or multi language fields would be nice... I try to get the submit field "name" attr like this $btn = $form->find('type=submit'); $btn->name; // $btn->get('name'); // $btn->attr('name'); // ... How should I get the submit button name (attr)? Need it to get the input post value to check without hardcode it... Workaround is to save it during generate the submit button, but I think it should be "readable" from the form object...?