Jump to content

How to use $input->whitelist() with Checkboxes (or any array)


apeisa
 Share

Recommended Posts

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

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.

  • Like 1
Link to comment
Share on other sites

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;
}
}
  • Like 2
Link to comment
Share on other sites

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. :)

  • Like 4
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
 Share

  • Recently Browsing   0 members

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