From fd008b434faa8f5a5832b2e33ed3d63cf41b5977 Mon Sep 17 00:00:00 2001 From: Brad Shuttleworth Date: Thu, 14 Sep 2006 11:49:19 +0000 Subject: [PATCH] re-enable notification-specification on workflows. --- lib/widgets/forms.inc.php | 5 ++++- plugins/ktcore/KTCorePlugin.php | 2 ++ plugins/ktcore/KTValidators.php | 23 +++++++++++++++++++++++ plugins/ktcore/KTWidgets.php | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ plugins/ktcore/admin/workflowsv2.php | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ resources/js/jsonlookup.js | 408 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ templates/ktcore/forms/widgets/descriptor.smarty | 47 +++++++++++++++++++++++++++++++++++++++++++++++ templates/ktcore/workflow/admin/effects_overview.smarty | 2 +- 8 files changed, 594 insertions(+), 206 deletions(-) create mode 100644 templates/ktcore/forms/widgets/descriptor.smarty diff --git a/lib/widgets/forms.inc.php b/lib/widgets/forms.inc.php index 94d8ced..494c797 100644 --- a/lib/widgets/forms.inc.php +++ b/lib/widgets/forms.inc.php @@ -237,7 +237,10 @@ class KTForm { return $this->renderContaining($sWidgets . ' ' . $sButtons); } - function renderPage($sTitle, $sDescription = null) { + function renderPage($sTitle = null, $sDescription = null) { + if ($sTitle == null) { + $sTitle = $this->sLabel; + } $pageval = $this->render(); $sHelpText = ''; if (!is_null($sDescription)) { diff --git a/plugins/ktcore/KTCorePlugin.php b/plugins/ktcore/KTCorePlugin.php index a663505..2640458 100644 --- a/plugins/ktcore/KTCorePlugin.php +++ b/plugins/ktcore/KTCorePlugin.php @@ -139,6 +139,7 @@ class KTCorePlugin extends KTPlugin { $this->registerWidget('KTCoreTransparentFieldsetWidget', 'ktcore.widgets.transparentfieldset', 'KTWidgets.php'); $this->registerWidget('KTCoreCollectionWidget', 'ktcore.widgets.collection', 'KTWidgets.php'); $this->registerWidget('KTCoreTreeMetadataWidget', 'ktcore.widgets.treemetadata', 'KTWidgets.php'); + $this->registerWidget('KTDescriptorSelectionWidget', 'ktcore.widgets.descriptorselection', 'KTWidgets.php'); $this->registerPage('collection', 'KTCoreCollectionPage', 'KTWidgets.php'); @@ -154,6 +155,7 @@ class KTCorePlugin extends KTPlugin { $this->registerValidator('KTFieldsetValidator', 'ktcore.validators.fieldset', 'KTValidators.php'); $this->registerValidator('KTFileValidator', 'ktcore.validators.file', 'KTValidators.php'); $this->registerValidator('KTRequiredFileValidator', 'ktcore.validators.requiredfile', 'KTValidators.php'); + $this->registerValidator('KTArrayValidator', 'ktcore.validators.array', 'KTValidators.php'); // criterion $this->registerCriterion('NameCriterion', 'ktcore.criteria.name', KT_LIB_DIR . '/browse/Criteria.inc'); diff --git a/plugins/ktcore/KTValidators.php b/plugins/ktcore/KTValidators.php index ebd8e3f..c0042d5 100644 --- a/plugins/ktcore/KTValidators.php +++ b/plugins/ktcore/KTValidators.php @@ -397,4 +397,27 @@ class KTFileValidator extends KTValidator { } } + +class KTArrayValidator extends KTValidator { + var $sNamespace = 'ktcore.validators.array'; + + function validate($data) { + $results = array(); + $errors = array(); + + // very simple if we're required and not present, fail + // otherwise, its ok. + $val = KTUtil::arrayGet($data, $this->sInputVariable); + //var_dump($data); exit(0); + if ($this->bProduceOutput) { + $results[$this->sOutputVariable] = $val; + } + + return array( + 'errors' => $errors, + 'results' => $results, + ); + } +} + ?> diff --git a/plugins/ktcore/KTWidgets.php b/plugins/ktcore/KTWidgets.php index 0f88f97..8a36ddb 100644 --- a/plugins/ktcore/KTWidgets.php +++ b/plugins/ktcore/KTWidgets.php @@ -272,6 +272,55 @@ class KTCoreEntitySelectionWidget extends KTCoreSelectionWidget { } } + +class KTDescriptorSelectionWidget extends KTWidget { + var $sNamespace = 'ktcore.widgets.descriptorselection'; + var $sTemplate = 'ktcore/forms/widgets/descriptor'; + + var $aJavascript = array('resources/js/jsonlookup.js'); + + function configure($aOptions) { + $res = parent::configure($aOptions); + if (PEAR::isError($res)) { + return $res; + } + + + } + + function getWidget() { + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate($this->sTemplate); + + $src_location = $this->aOptions['src']; + $sJS = sprintf("addLoadEvent(initJSONLookup(\"%s\", \"%s\"));", $this->sBasename, $src_location); + + + // its bad, but that's life. + $oPage =& $GLOBALS['main']; + $oPage->requireJSStandalone($sJS); + + $this->aOptions['multi'] = true; + + $aTemplateData = array( + "context" => $this, + "label" => $this->sLabel, + "description" => $this->sDescription, + "name" => $this->sName, + "required" => $this->bRequired, + "has_id" => ($this->sId !== null), + "id" => $this->sId, + "has_value" => ($this->value !== null), + "value" => $this->value, + "has_errors" => $bHasErrors, + "errors" => $this->aErrors, + 'short_name' => $this->sBasename, + "options" => $this->aOptions, + ); + return $oTemplate->render($aTemplateData); + } +} + class KTCoreTreeMetadataWidget extends KTWidget { var $sNamespace = 'ktcore.widgets.treemetadata'; var $iFieldId; diff --git a/plugins/ktcore/admin/workflowsv2.php b/plugins/ktcore/admin/workflowsv2.php index 252d3e6..d454baf 100644 --- a/plugins/ktcore/admin/workflowsv2.php +++ b/plugins/ktcore/admin/workflowsv2.php @@ -1696,6 +1696,270 @@ class KTWorkflowAdminV2 extends KTAdminDispatcher { exit(0); } + function do_managenotifications() { + $oTemplate =& $this->oValidator->validateTemplate("ktcore/workflow/admin/manage_notifications"); + $oTemplate->setData(array( + 'context' => $this, + 'states' => KTWorkflowState::getByWorkflow($this->oWorkflow), + )); + return $oTemplate->render(); + } + + function describeStateNotifications($oState) { + $aAllowed = KTWorkflowUtil::getInformedForState($oState); + + $aUsers = array(); + $aGroups = array(); + $aRoles = array(); + + foreach (KTUtil::arrayGet($aAllowed,'user',array()) as $iUserId) { + $oU = User::get($iUserId); + if (PEAR::isError($oU) || ($oU == false)) { + continue; + } else { + $aUsers[] = $oU->getName(); + } + } + + foreach (KTUtil::arrayGet($aAllowed,'group',array()) as $iGroupId) { + $oG = Group::get($iGroupId); + if (PEAR::isError($oG) || ($oG == false)) { + continue; + } else { + $aGroups[] = $oG->getName(); + } + } + + foreach (KTUtil::arrayGet($aAllowed,'role',array()) as $iRoleId) { + $oR = Role::get($iRoleId); + if (PEAR::isError($oR) || ($oR == false)) { + continue; + } else { + $aRoles[] = $oR->getName(); + } + } + + $sNotify = ''; + if (!empty($aUsers)) { + $sNotify .= '' . _kt('Users:') . ' '; + $sNotify .= implode(', ', $aUsers); + } + + if (!empty($aGroups)) { + if (!empty($sNotify)) { $sNotify .= ' — '; } + $sNotify .= '' . _kt('Groups:') . ' '; + $sNotify .= implode(', ', $aGroups); + } + + if (!empty($aRoles)) { + if (!empty($sNotify)) { $sNotify .= ' — '; } + $sNotify .= '' . _kt('Roles:') . ' '; + $sNotify .= implode(', ', $aRoles); + } + + if (empty($sNotify)) { $sNotify = _kt('No notifications.'); } + + return $sNotify; + } + + function descriptorToJSON($aAllowed) { + $values = array(); + + foreach (KTUtil::arrayGet($aAllowed,'user',array()) as $oU) { + if (!is_object($oU)) { + $iUserId = $oU; + $oU = User::get($iUserId); + } else { + $iUserId = $oU->getId(); + } + + if (PEAR::isError($oU) || ($oU == false)) { + continue; + } else { + $values[sprintf("users[%d]", $iUserId)] = sprintf('User: %s', $oU->getName()); + } + } + + foreach (KTUtil::arrayGet($aAllowed,'group',array()) as $oG) { + if (!is_object($oG)) { + $iGroupId = $oG; + $oG = Group::get($iGroupId); + } else { + $iGroupId = $oG->getId(); + } + if (PEAR::isError($oG) || ($oG == false)) { + continue; + } else { + $values[sprintf("groups[%d]", $iGroupId)] = sprintf('Group: %s', $oG->getName()); + } + } + + foreach (KTUtil::arrayGet($aAllowed,'role',array()) as $oR) { + if (!is_object($oR)) { + $iRoleId = $oR; + $oR = Role::get($iRoleId); + } else { + $iRoleId = $oR->getId(); + } + + if (PEAR::isError($oR) || ($oR == false)) { + continue; + } else { + $values[sprintf("roles[%d]", $iRoleId)] = sprintf('Role: %s', $oR->getName()); + } + } + + return $values; + } + + function form_editnotifications($oState) { + $oForm = new KTForm; + $oForm->setOptions(array( + 'context' => $this, + 'label' => _kt("Edit State Notifications."), + 'identifier' => 'ktcore.workflow.notifications', + 'submit_label' => _kt("Update Notifications"), + 'cancel_action' => 'managenotifications', + 'action' => 'savenotifications', + 'fail_action' => 'editnotifications', + )); + $preval = KTWorkflowUtil::getInformedForState($oState); + $oForm->setWidgets(array( + array('ktcore.widgets.descriptorselection', array( + 'label' => _kt("Users to inform"), + 'description' => _kt("Select which users, groups and roles to be notified."), + 'name' => 'users', + 'src' => KTUtil::addQueryStringSelf($this->meldPersistQuery(array('json_action'=> 'notificationusers'), "json")), + 'value' => $this->descriptorToJSON($preval), + )), + )); + $oForm->setValidators(array( + array('ktcore.validators.array', array( + 'test' => 'users', + 'output' => 'users', + )), + )); + return $oForm; + } + + function do_editnotifications() { + $oForm = $this->form_editnotifications($this->oState); + return $oForm->renderPage(); + } + + function do_savenotifications() { + + + $oForm = $this->form_editnotifications($this->oState); + $res = $oForm->validate(); + + if (!empty($res['errors'])) { + return $oForm->handleError(); + } + + $data = $res['results']; + // now, an annoying problem is that we do *not* have the final set. + // so we need to get the original, add the new ones, remove the old ones. + // + // because its not *really* isolated properly, we need to post-process + // the data. + + // we need the old one + $aAllowed = KTWorkflowUtil::getInformedForState($this->oState); + + $user_pattern = '|users\[(.*)\]|'; + $group_pattern = '|groups\[(.*)\]|'; + $role_pattern = '|roles\[(.*)\]|'; + + $user = KTUtil::arrayGet($aAllowed, 'user', array()); + $group = KTUtil::arrayGet($aAllowed, 'group', array()); + $role = KTUtil::arrayGet($aAllowed, 'role', array()); + + // do a quick overpass + $newAllowed = array(); + if (!empty($user)) { $newAllowed['user'] = array_combine($user, $user); } + else { $newAllowed['user'] = array(); } + if (!empty($group)) { $newAllowed['group'] = array_combine($group, $group); } + else { $newAllowed['group'] = array(); } + if (!empty($role)) { $newAllowed['role'] = array_combine($role, $role); } + else { $newAllowed['role'] = array(); } + + $added = explode(',', $data['users']['added']); + $removed = explode(',', $data['users']['removed']); + + foreach ($added as $akey) { + $matches = array(); + if (preg_match($user_pattern, $akey, $matches)) { $newAllowed['user'][$matches[1]] = $matches[1]; } + else if (preg_match($group_pattern, $akey, $matches)) { $newAllowed['group'][$matches[1]] = $matches[1]; } + else if (preg_match($role_pattern, $akey, $matches)) { $newAllowed['role'][$matches[1]] = $matches[1]; } + } + + foreach ($removed as $akey) { + $matches = array(); + if (preg_match($user_pattern, $akey, $matches)) { unset($newAllowed['user'][$matches[1]]); } + else if (preg_match($group_pattern, $akey, $matches)) { unset($newAllowed['group'][$matches[1]]); } + else if (preg_match($role_pattern, $akey, $matches)) { unset($newAllowed['role'][$matches[1]]); } + } + + // FIXME check that these are all users. + + $res = KTWorkflowUtil::setInformedForState($this->oState, $newAllowed); + if (PEAR::isError($res)) { + return $oForm->handleError($res->getMessage()); + } + + $this->successRedirectTo("managenotifications", _kt("Notifications updated.")); + } + + function json_notificationusers() { + $sFilter = KTUtil::arrayGet($_REQUEST, 'filter', false); + if ($sFilter == false) { + $values = array('off'=>'-- Please filter --'); // default + } + $sFilter = trim($sFilter); + $values = array('off'=>'-- Please filter --'); // default + + if (!empty($sFilter)) { + $allowed = array(); + $q = sprintf('name like "%%%s%%"', DBUtil::escapeSimple($sFilter)); + + $aUsers = User::getList($q); + $aGroups = Group::getList($q); + $aRoles = Role::getList($q); + + $empty = true; + + if (!PEAR::isError($aUsers)) { + $allowed['user'] = $aUsers; + if (!empty($aUsers)) { + $empty = false; + } + } + + if (!PEAR::isError($aGroups)) { + $allowed['group'] = $aGroups; + if (!empty($aGroups)) { + $empty = false; + } + } + + if (!PEAR::isError($aRole)) { + $allowed['role'] = $aRoles; + if (!empty($aRoles)) { + $empty = false; + } + + } + + if ($empty) { + $values = array('off'=>'-- No results --'); // default + } else { + $values = $this->descriptorToJSON($allowed); + } + } + + return $values; + } } ?> diff --git a/resources/js/jsonlookup.js b/resources/js/jsonlookup.js index ffe31ed..e553f16 100644 --- a/resources/js/jsonlookup.js +++ b/resources/js/jsonlookup.js @@ -2,9 +2,9 @@ var _aLookupWidgets = {}; function getJSONLookupWidget(name) { if(!isUndefinedOrNull(_aLookupWidgets[name])) { - return _aLookupWidgets[name]; + return _aLookupWidgets[name]; } else { - return false; + return false; } } @@ -16,260 +16,260 @@ JSONLookupWidget.prototype = { /* bind_add and bind_remove are functions to be called with the key:value's of selected items */ 'initialize' : function(name, action) { - bindMethods(this); + bindMethods(this); - this.sName = name; - this.sAction = action; + this.sName = name; + this.sAction = action; - - this.oSelectAvail = $('select_' + name + '_avail'); - this.oSelectAssigned = $('select_' + name + '_assigned'); - this.oFilterAvail = $('filter_' + name + '_avail'); - this.oFilterAssigned = $('filter_' + name + '_assigned'); - - this.savedFilter = this.oFilterAvail.value; - this.savedSelector = this.oFilterAssigned.value; - this.filterTimer = null; - - this.aItemsAdded = []; - this.aItemsRemoved = []; - - connect(this.oFilterAvail, 'onkeyup', this, 'onchangeFilter'); - connect(this.oFilterAssigned, 'onkeyup', this, 'onchangeSelector'); - connect(name + '_add', 'onclick', this, 'onclickAdd'); - connect(name + '_remove', 'onclick', this, 'onclickRemove'); - connect(name + '_show_all', 'onclick', this, 'onclickShowAll'); - - this.triggers = {}; - this.triggers['add'] = null; - this.triggers['remove'] = null; + + this.oSelectAvail = $('select_' + name + '_avail'); + this.oSelectAssigned = $('select_' + name + '_assigned'); + this.oFilterAvail = $('filter_' + name + '_avail'); + this.oFilterAssigned = $('filter_' + name + '_assigned'); + + this.savedFilter = this.oFilterAvail.value; + this.savedSelector = this.oFilterAssigned.value; + this.filterTimer = null; + + this.aItemsAdded = []; + this.aItemsRemoved = []; + + connect(this.oFilterAvail, 'onkeyup', this, 'onchangeFilter'); + connect(this.oFilterAssigned, 'onkeyup', this, 'onchangeSelector'); + connect(name + '_add', 'onclick', this, 'onclickAdd'); + connect(name + '_remove', 'onclick', this, 'onclickRemove'); + connect(name + '_show_all', 'onclick', this, 'onclickShowAll'); + + this.triggers = {}; + this.triggers['add'] = null; + this.triggers['remove'] = null; - this.initialValuesLoaded = false; - var d = this.getValues(); - d.addCallback(this.postInitialize); + this.initialValuesLoaded = false; + var d = this.getValues(); + d.addCallback(this.postInitialize); }, 'addTrigger' : function(event, func) { - this.triggers[event] = func; + this.triggers[event] = func; }, // values handling 'getValues' : function(all) { - var act = this.sAction; - if(!isUndefinedOrNull(all)) { - act += '&' + queryString({'filter' : '%'}); - } else if(this.savedFilter) { - act += '&' + queryString({'filter' : this.savedFilter}); - } else if(!this.initialValuesLoaded) { - act += '&' + queryString({'selected' : '1'}); - } - - var d = loadJSONDoc(act); - d.addErrback(this.errGetValues); - d.addCallback(checkKTError); - d.addCallback(this.saveValues); - d.addCallback(this.renderValues); - return d; + var act = this.sAction; + if(!isUndefinedOrNull(all)) { + act += '&' + queryString({'filter' : '%'}); + } else if(this.savedFilter) { + act += '&' + queryString({'filter' : this.savedFilter}); + } else if(!this.initialValuesLoaded) { + act += '&' + queryString({'selected' : '1'}); + } + + var d = loadJSONDoc(act); + d.addErrback(this.errGetValues); + d.addCallback(checkKTError); + d.addCallback(this.saveValues); + d.addCallback(this.renderValues); + return d; }, 'errGetValues' : function(res) { - alert('There was an error retrieving data. Please check connectivity and try again.'); - this.oValues = {'off':'-- Error fetching values --'}; - this.renderValues(); + alert('There was an error retrieving data. Please check connectivity and try again.'); + this.oValues = {'off':'-- Error fetching values --'}; + this.renderValues(); }, 'saveValues' : function(res) { - this.oValues = res; - return res; + this.oValues = res; + return res; }, 'renderValues' : function() { - var aOptions = []; - var bSelFound = false; - for(var k in this.oValues) { - var found = false; - for(var i=0; i + + + + +   + + + + + + + + + + +

{i18n}Show All{/i18n}
+ + + + + +

+ + + + + + + +
+ + + + + + + diff --git a/templates/ktcore/workflow/admin/effects_overview.smarty b/templates/ktcore/workflow/admin/effects_overview.smarty index 518618f..cd716b0 100644 --- a/templates/ktcore/workflow/admin/effects_overview.smarty +++ b/templates/ktcore/workflow/admin/effects_overview.smarty @@ -8,5 +8,5 @@ with the role "Reviewer" on that document are informed.

-- libgit2 0.21.4