apeisa Posted September 27, 2012 Share Posted September 27, 2012 I'm building the user search and I have filter for role filters. Wanted to build it using multiple selections, so one could search for all "editors" and "members" with one search. Since I need pagination I want to use $input->whitelist. But for some reason I cannot figure how to whitelist arrays properly. I have tried these: // Whole array $this->input->whitelist('roles[]', $this->input->get->roles); // Whole array (without []) $this->input->whitelist('roles', $this->input->get->roles); // Each on their own foreach(...) { $this->input->whitelist('roles[]', $roleName); } // etc... All I try produce get params like this (after clicking pagination): roles[]=rolename1%2Crolename2 etc... or the looping one leaves only the last value, like: roles[]=rolename2 What I need is the same like the form submit, ie: roles[]=rolename1&roles[]=rolename2 etc Is this shortcoming using whitelist or am I doing this wrong? Link to comment Share on other sites More sharing options...
apeisa Posted September 27, 2012 Author Share Posted September 27, 2012 There seems to be a way to add array like this: $this->input->whitelist($array); but of course that doesn't work, since it produces get params like 1=rolename1&2=rolename2 etc... Link to comment Share on other sites More sharing options...
nik Posted September 27, 2012 Share Posted September 27, 2012 See: http://processwire.c...fly/#entry16017 Now you just need to get that "arrayToCSV => false"-option down to MarkupPagerNav =). If you're calling $somePageArray->renderPager() yourself, you can just pass options array as an argument. But if you're using ProcessPageType::renderList() (reading minds here...) then it would be another thing to ask Ryan to modify. So maybe not renderList($selector) but renderList($selector, $pagerOptions=null) and $pagerOptions as an argument to render() here: https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Process/ProcessPageType/ProcessPageType.module#L119 Or something like that, no time to try that out at the moment. 1 Link to comment Share on other sites More sharing options...
apeisa Posted September 27, 2012 Author Share Posted September 27, 2012 Thanks Nik, that did the trick! Here is the current version, which seems to work nicely. It duplicates the renderList() and executeList() methods until Ryan makes those two improvements to the renderList() method. This allows to search users (username requires direct hit, other fields use ^= operator). It searches those fields that are chosen from module settings (the same ones that are visible). You can also combine text search and role filters. To try this out, just install the module and then edit your /processwire/access/users/ page and change the process to ProcessUserExtended (page is locked by default, so open the lock). You cannot create new page with different name (like users-extended) and try it there, since ProcessPageType excepts to have pageName which is also fuel (like users, roles etc). Grab the code: <?php class ProcessUserExtended extends ProcessUser { static public function getModuleInfo() { return array( 'title' => __('Users extended', __FILE__), // getModuleInfo title 'version' => 100, 'summary' => __('Extended view for user management', __FILE__), // getModuleInfo summary 'permanent' => false, 'permission' => 'user-admin', ); } public function ___execute() { $out = ''; $wrapper = new InputfieldWrapper; $fields = $this->modules->get("InputfieldFieldset"); $form = $this->modules->get("InputfieldForm"); $form->attr('method', 'get'); $form->attr('id', 'userSearch'); $form->label = $this->_("Filter users"); if (!$this->input->get->roles && !$this->input->get->search) { $form->collapsed = Inputfield::collapsedYes; } $field = $this->modules->get("InputfieldText"); $field->attr('name', 'search'); $field->label = $this->_("Search"); if ($this->input->get->search) { $this->input->whitelist('search', $this->input->get->search); $field->attr('value', htmlentities($this->input->get->search, ENT_QUOTES, 'UTF-8')); } $form->add($field); $field = $this->modules->get("InputfieldCheckboxes"); $field->attr('name', 'roles'); $field->optionColumns = 5; foreach(wire('roles') as $role) { if ($role->name == "guest") continue; $attrs = array(); $this->input->whitelist("roles", $this->input->get->roles); if (is_array($this->input->get->roles)) { if(in_array($role->name, $this->input->get->roles)) { $attrs['selected'] = 'selected'; } } $field->addOption($role->name, $role->get('title|name'), $attrs); } $field->label = $this->_("Filter by role"); $form->add($field); $field = $this->modules->get("InputfieldSubmit"); $field->attr('value', $this->_("Search")); $form->add($field); $fields->add($form); $out .= $fields->render(); $selector = "limit=10, status<" . Page::statusMax; if ($this->input->get->roles) { $roles = new PageArray; foreach($this->input->get->roles as $roleName) { $roles->add($this->roles->get($roleName)); } if ($role->id) $selector .= ", roles=$roles"; } if ($this->input->get->search) { $fieldNames = implode("|", array_diff($this->showFields, array('name', 'created', 'modified', 'roles'))); $search = $this->sanitizer->selectorValue($this->input->get->search); $directHit = $this->pages->get("name=$search"); if ($directHit->id) $out .= "<h3>". $this->_('Found by username') .": <a href='./edit/?id=$directHit->id'>$directHit->name</a></h3>"; $selector .= ", $fieldNames^=$search"; } return $out . $this->renderList($selector, array("arrayToCSV" => false)); } public function ___executeList() { return $this->renderList("limit=25, status<" . Page::statusMax); } protected function renderList($selector, $pagerOptions = null) { $out = ''; if(!$this->pages->getTemplate()) { $form = $this->getTemplateFilterForm(); $out = $form->render(); } $table = $this->modules->get("MarkupAdminDataTable"); $table->setEncodeEntities(false); $fieldNames = $this->showFields; $fieldLabels = $fieldNames; foreach($fieldLabels as $key => $name) { if($name == 'name') { $fieldLabels[$key] = $this->_('Name'); // Label for 'name' field continue; } $field = wire('fields')->get($name); $languageID = wire('user')->language ? wire('user')->language->id : ''; $label = $field->get('label' . $languageID); if(!$label) $label = $field->label; if(!$label) $label = $name; $fieldLabels[$key] = htmlentities($label, ENT_QUOTES, "UTF-8"); } $table->headerRow($fieldLabels); $pages = $this->pages->find($selector); foreach($pages as $page) { if(!$page->editable()) continue; $n = 0; $row = array(); foreach($fieldNames as $name) { if(!$n) $row[$page->get($name) . ' '] = "edit/?id={$page->id}"; else $row[] = $this->renderListFieldValue($name, $page->get($name)); $n++; } $table->row($row); } if($this->page->addable()) $table->action(array($this->_('Add New') => 'add/')); if($pages->getTotal() > count($pages)) { $pager = $this->modules->get("MarkupPagerNav"); $out .= $pager->render($pages, $pagerOptions); } $out .= $table->render(); return $out; } } 2 Link to comment Share on other sites More sharing options...
ryan Posted September 28, 2012 Share Posted September 28, 2012 I've updated renderList to include the pagerOptions here too in the dev branch. I've got to be honest and say that arrays in GET vars have always bothered me. They are so darn verbose and ugly. Why have a query string like this: var[]=1&var[]=2&var[]=3 When you can do this: var=1,2,3 All it takes is encoding your array like this: $input->whitelist('var', implode(',', $var)); and decoding it like this: $var = explode(',', $input->get->var); That's just my preference anyway, but not suggesting it should be anyone else's unless these things also keep you up at night. 4 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now