From d5a8488026f246a577446bd3926530335c32df72 Mon Sep 17 00:00:00 2001 From: Axel Stohn Date: Sun, 12 Jun 2022 13:46:25 -0700 Subject: [PATCH] initial work for search capability --- Controller/GrouperGroupsController.php | 113 ++++++++++++++++++++ View/Elements/Components/subscriberList.ctp | 4 +- 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/Controller/GrouperGroupsController.php b/Controller/GrouperGroupsController.php index 6160c14..6d1ea22 100644 --- a/Controller/GrouperGroupsController.php +++ b/Controller/GrouperGroupsController.php @@ -27,6 +27,7 @@ App::uses('Validator', 'Vendor/cakephp/Validation'); App::uses('CoGrouperLite', 'GrouperLite.Model/'); +App::uses('GrouperGroup', 'GrouperLite.Model/'); App::uses('Identifier', 'Model'); /** @@ -37,6 +38,7 @@ class GrouperGroupsController extends GrouperLiteAppController { public $helpers = array('Html', 'Form', 'Flash'); + public $uses = array('GrouperLite.GrouperGroup', 'CoPerson'); public $components = array('Flash', 'Paginator', 'RequestHandler', 'Security' => array( 'validatePost' => false, 'csrfUseOnce' => false @@ -212,6 +214,116 @@ public function addSubscriber() } + /** + * The majority of this code is copied from the find() function in the CoPeopleController that was added by + * Arlen. Eventually this will become a component, so for now just tweaking the code needed for the Grouper plugin + * to work. + * + */ + public function findSubscriber() + { + + if ($this->request->is('ajax')) { + $this->response->disableCache(); + } + + $groupName = urldecode($this->request->query['group']); + $findUserId = urldecode($this->request->query['userId']); + $co = urldecode($this->request->query['co']); + + $mode = urldecode($this->request->query['mode']); + + // jquery Autocomplete sends the search as url?term=foo + $coPersonIds = array(); + if(!empty($findUserId)) { + // Leverage model specific keyword search + + // Note EmailAddress and Identifier don't support substring search + foreach(array('Name', 'EmailAddress', 'Identifier') as $m) { + $hits = $this->CoPerson->$m->search($co, $findUserId, 25); + + $coPersonIds = array_merge($coPersonIds, Hash::extract($hits, '{n}.CoPerson.id')); + } + } + + $coPersonIds = array_unique($coPersonIds); + + // Look up additional information to provide hints as to which person is which. + // We only do this when there are relatively small numbers of results to + // avoid making a bunch of database queries early in the search. + + $matches = array(); + + if(count($coPersonIds) > 100) { + // We don't return large sets to avoid slow performance + + $this->response->type('json'); + $this->response->statusCode(401); + $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'Too Many Results'))); + $this->response->send(); + $matches = ''; + } else { + $people = $this->CoPerson->filterPicker($co, $coPersonIds, $mode); + $pickerEmailType = $this->Co->CoSetting->getPersonPickerEmailType($co); + $pickerIdentifierType = $this->Co->CoSetting->getPersonPickerIdentifierType($co); + $pickerDisplayTypes = $this->Co->CoSetting->getPersonPickerDisplayTypes($co); + + foreach($people as $p) { + $label = generateCn($p['Name'][0]); + $idArr = $p['Identifier']; + $emailArr = $p['EmailAddress']; + $email = ''; + $emailLabel = ''; + $id = ''; + $idLabel = ''; + + // Iterate over the email array + if(!empty($emailArr) && !empty($pickerEmailType)) { + if(!empty($pickerDisplayTypes)) { + $emailLabel = _txt('fd.extended_type.generic.label', array(_txt('fd.email_address.mail'), $pickerEmailType)); + } + else { + $emailLabel = _txt('fd.email_address.mail') . ': '; + } + foreach($emailArr as $e) { + if($e['type'] == $pickerEmailType) { + $email = $e['mail'] . ' ' . $pickerDisplayTypes; + break; + } + } + } + + // Set the identifier for display (and limit it to 30 characters max) + if(!empty($idArr[0]['identifier']) && !empty($pickerIdentifierType)) { + if(!empty($pickerDisplayTypes)) { + $idLabel = _txt('fd.extended_type.generic.label', array(_txt('fd.identifier.identifier'), $pickerIdentifierType)); + } + else { + $idLabel = _txt('fd.identifier.identifier') . ': '; + } + foreach($idArr as $i) { + if($i['type'] == $pickerIdentifierType) { + $id = mb_strimwidth($i['identifier'], 0, 30, '...'); + break; + } + } + } + + $matches[] = array( + 'value' => $p['CoPerson']['id'], + 'label' => $label, + 'email' => $email, + 'emailLabel' => $emailLabel, + 'identifier' => $id, + 'identifierLabel' => $idLabel + ); + } + } + + $this->set(compact('matches')); + $this->set('_serialize', 'matches'); + } + /** * Remove a member from a group * Called from all pages via AJAX call @@ -664,6 +776,7 @@ function isAuthorized() $p['groupmember'] = true; $p['groupSubscribers'] = true; $p['addSubscriber'] = true; + $p['findSubscriber'] = true; $p['removeSubscriber'] = true; $p['groupoptin'] = true; $p['emaillistsoptin'] = true; diff --git a/View/Elements/Components/subscriberList.ctp b/View/Elements/Components/subscriberList.ctp index d73e2b5..53ce214 100644 --- a/View/Elements/Components/subscriberList.ctp +++ b/View/Elements/Components/subscriberList.ctp @@ -73,7 +73,7 @@ array( 'plugin' => "grouper_lite", 'controller' => 'grouper_groups', - 'action' => 'addSubscriber' + 'action' => 'findSubscriber' ) ); ?>'; $('.members-btn').click(function(ev) { @@ -202,7 +202,7 @@ function onAddUser(user, group, field, data) { $.ajax({ method: 'POST', - url: addUrl + '?group=' + group + '&userId=' + user, + url: addUrl + '?co=1&mode=AL&group=' + group + '&userId=' + user, dataType: 'json', data: data, success: function(data) {