From 957c0bc2fe31fb1305d721ae29725b88552fa64f Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Thu, 4 Jun 2009 19:48:42 +0000 Subject: [PATCH] 6 bugs fixed in Shortcut. Added missing POD and i18n'ed some error messages. Set the UI level on a tab to work with the form elements it contains. Change the title bar ajax edit form so that people can't accidently change Visitor's profile. Remove overrides caching if admin mode is on. Have caching consider the user's last updated time to check if profile settings are updated, too. --- docs/changelog/7.x.x.txt | 1 + lib/WebGUI/Asset/Shortcut.pm | 213 ++++++++++++++-------- lib/WebGUI/i18n/English/Asset_Shortcut.pm | 10 + 3 files changed, 148 insertions(+), 76 deletions(-) diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 62425cde6..25acd9146 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -27,6 +27,7 @@ - fixed #10355: Thingy: dirty delete FileField value - fixed #10095: Widget Macro (syndication) - templateing broken - fixed #10473: Fwd: Album Bug? + - fixed #10088: ##userPref:firstName## doesn't work in Dashboard 7.7.8 - fixed: Basic Auth doesn't work if password contains colon (Arjan Widlak, diff --git a/lib/WebGUI/Asset/Shortcut.pm b/lib/WebGUI/Asset/Shortcut.pm index 5b0fe168e..4ff94f042 100644 --- a/lib/WebGUI/Asset/Shortcut.pm +++ b/lib/WebGUI/Asset/Shortcut.pm @@ -20,6 +20,7 @@ use WebGUI::ProfileField; use WebGUI::ProfileCategory; use WebGUI::Macro; use HTML::Entities qw(encode_entities); +use Data::Dumper; our @ISA = qw(WebGUI::Asset); @@ -309,7 +310,7 @@ sub getEditForm { $tabform->addTab('overrides',$i18n->get('Overrides')); $tabform->getTab('overrides')->raw('' . $self->getOverridesList . ''); if ($self->isDashlet) { - $tabform->addTab('preferences',$i18n->get('Preferences')); + $tabform->addTab('preferences',$i18n->get('Preferences'), 9); $tabform->getTab('preferences')->raw($self->getFieldsList); $tabform->getTab("properties")->yesNo( -value=>$self->getValue("showReloadIcon"), @@ -324,19 +325,23 @@ sub getEditForm { #------------------------------------------------------------------- sub getFieldsList { - my $self = shift; - my $i18n = WebGUI::International->new($self->session, "Asset_Shortcut"); - my $output = ''.$i18n->get('Manage Profile Fields').'

'; + my $self = shift; + my $session = $self->session; + my $i18n = WebGUI::International->new($session, "Asset_Shortcut"); + my $output = ''.$i18n->get('Manage Profile Fields').'

'; my %fieldNames; tie %fieldNames, 'Tie::IxHash'; - foreach my $field (@{WebGUI::ProfileField->getFields($self->session)}) { + use Data::Dumper; + foreach my $field (@{WebGUI::ProfileField->getFields($session)}) { my $fieldId = $field->getId; next if $fieldId =~ /contentPositions/; + $session->log->warn($fieldId); $fieldNames{$fieldId} = $field->getLabel.' ['.$fieldId.']'; } $output .= '
'; - my @prefFieldsToShow = split("\n",$self->getValue("prefFieldsToShow")); - $output .= WebGUI::Form::CheckList->new($self->session, + my @prefFieldsToShow = $self->getPrefFieldsToShow; + $session->log->warn('fieldsToShow: '.Dumper \@prefFieldsToShow); + my $list = WebGUI::Form::CheckList->new($session, -name=>"prefFieldsToShow", -value=>\@prefFieldsToShow, -options=>\%fieldNames, @@ -344,10 +349,13 @@ sub getFieldsList { -hoverHelp=>$i18n->get('pref fields to show description'), -vertical=>1, -uiLevel=>9 - )->toHtmlWithWrapper; + ); + $session->log->warn($list->get('uiLevel')); + $session->log->warn($list->passUiLevelCheck); + $output .= $list->toHtmlWithWrapper; $output .= '
'; - my @prefFieldsToImport = split("\n",$self->getValue("prefFieldsToImport")); - $output .= WebGUI::Form::CheckList->new($self->session, + my @prefFieldsToImport = $self->getPrefFieldsToImport; + $output .= WebGUI::Form::CheckList->new($session, -name=>"prefFieldsToImport", -value=>\@prefFieldsToImport, -options=>\%fieldNames, @@ -394,7 +402,7 @@ sub getOverridesList { $output .= encode_entities($overrides{overrides}{$prop}{newValue}, '<>&"^'); $output .= ''; + $output .= "\n"; } } $output .= '
'; $output .= $overrides{overrides}{$prop}{parsedValue}; - $output .= '
'; @@ -402,6 +410,14 @@ sub getOverridesList { } #------------------------------------------------------------------- + +=head2 _overridesCacheTag + +Overrides are cached by this shortcut's assetId, the session user userId, and whether or not +admin mode is on. + +=cut + sub _overridesCacheTag { my $self = shift; #cache by userId, assetId of this shortcut, and whether adminMode is on or not. @@ -409,54 +425,74 @@ sub _overridesCacheTag { } #------------------------------------------------------------------- + +=head2 getOverrides + +Return overrides for the original asset. If this is a dashlet (child of a Dashboard), then +overrides can pick up values from the user's profile. + +Overrides are cached, unless you are in admin mode. The cache is invalidated if it has +expired, or if the user's profile field has changed. + +=cut + sub getOverrides { - my $self = shift; - my $i = 0; - my $cache = WebGUI::Cache->new($self->session,$self->_overridesCacheTag); + my $self = shift; + my $session = $self->session; + my $cache = WebGUI::Cache->new($self->session,$self->_overridesCacheTag); + my $u = WebGUI::User->new($self->session, $self->discernUserId); + my $overridesRef = $cache->get; - unless ($overridesRef->{cacheNotExpired}) { - my %overrides; - my $orig = $self->getShortcutOriginal; - if (defined $orig) { - unless ( exists $orig->{_propertyDefinitions}) { - my %properties; - foreach my $definition (@{$orig->definition($self->session)}) { - %properties = (%properties, %{$definition->{properties}}); - } - $orig->{_propertyDefinitions} = \%properties; - } - $overrides{cacheNotExpired} = 1; - my $sth = $self->session->db->read("select fieldName, newValue from Shortcut_overrides where assetId=? order by fieldName",[$self->getId]); - while (my ($fieldName, $newValue) = $sth->array) { - $overrides{overrides}{$fieldName}{fieldType} = $orig->{_propertyDefinitions}{$fieldName}{fieldType}; - $overrides{overrides}{$fieldName}{origValue} = $orig->get($fieldName); - $overrides{overrides}{$fieldName}{newValue} = $newValue; - $overrides{overrides}{$fieldName}{parsedValue} = $newValue; - } - $sth->finish; - } else { - $self->session->errorHandler->warn("Original asset could not be instanciated by shortcut ".$self->getId); - } - if ($self->isDashlet) { - my $u = WebGUI::User->new($self->session, $self->discernUserId); - my @userPrefs = $self->getPrefFieldsToImport; - foreach my $fieldId (@userPrefs) { - my $field = WebGUI::ProfileField->new($self->session,$fieldId); - next unless $field; - my $fieldName = $field->getId; - my $fieldValue = $u->profileField($field->getId); - $overrides{userPrefs}{$fieldName}{value} = $fieldValue; - $overrides{userPrefs}{$fieldName}{parsedValue} = $fieldValue; - # 'myTemplateId is ##userPref:myTemplateId##', for example. - foreach my $overr (keys %{$overrides{overrides}}) { - $overrides{overrides}{$overr}{parsedValue} =~ s/\#\#userPref\:${fieldName}\#\#/$fieldValue/gm; - } - } - } - $cache->set(\%overrides, 60*60); - $overridesRef = \%overrides; - } - return %$overridesRef; + ##If admin mode is not on, and the cache is valid, and not expired, and the user object was not updated, + ##return the cached value. + if ( ! $session->var->isAdminOn + && $overridesRef + && $overridesRef->{cacheNotExpired} + && $overridesRef->{userLastUpdated} >= $u->get('lastUpdated')) { + return %{ $overridesRef }; + } + my %overrides; + my $orig = $self->getShortcutOriginal; + if (defined $orig) { + unless ( exists $orig->{_propertyDefinitions}) { + my %properties; + foreach my $definition (@{$orig->definition($self->session)}) { + %properties = (%properties, %{$definition->{properties}}); + } + $orig->{_propertyDefinitions} = \%properties; + } + $overrides{cacheNotExpired} = 1; + my $sth = $self->session->db->read("select fieldName, newValue from Shortcut_overrides where assetId=? order by fieldName",[$self->getId]); + while (my ($fieldName, $newValue) = $sth->array) { + $overrides{overrides}{$fieldName}{fieldType} = $orig->{_propertyDefinitions}{$fieldName}{fieldType}; + $overrides{overrides}{$fieldName}{origValue} = $orig->get($fieldName); + $overrides{overrides}{$fieldName}{newValue} = $newValue; + $overrides{overrides}{$fieldName}{parsedValue} = $newValue; + } + $sth->finish; + } + else { + $self->session->errorHandler->warn("Original asset could not be instanciated by shortcut ".$self->getId); + } + if ($self->isDashlet) { + my @userPrefs = $self->getPrefFieldsToImport; + foreach my $fieldId (@userPrefs) { + my $field = WebGUI::ProfileField->new($self->session,$fieldId); + next unless $field; + my $fieldName = $field->getId; + my $fieldValue = $u->profileField($field->getId); + $overrides{userPrefs}{$fieldName}{value} = $fieldValue; + $overrides{userPrefs}{$fieldName}{parsedValue} = $fieldValue; + # 'myTemplateId is ##userPref:myTemplateId##', for example. + foreach my $overr (keys %{$overrides{overrides}}) { + $overrides{overrides}{$overr}{parsedValue} =~ s/\#\#userPref\:${fieldName}\#\#/$fieldValue/gm; + } + } + } + $overrides{userLastUpdated} = $session->user->get('lastUpdated'); + $cache->set(\%overrides, 60*60); + $overridesRef = \%overrides; + return %{ $overridesRef }; } #------------------------------------------------------------------- @@ -800,20 +836,27 @@ sub www_edit { #------------------------------------------------------------------- sub www_getUserPrefsForm { #This is a form retrieved by "ajax". - my $self = shift; - return 'You are no longer logged in' if $self->session->user->isVisitor; - return 'You are not allowed to personalize this Dashboard.' unless $self->getParent->canPersonalize; + my $self = shift; + my $session = $self->session; + my $i18n = WebGUI::International->new($session); + return $i18n->get('not logged in') if $session->user->isVisitor; + return $i18n->get('cannot personalize') unless $self->getParent->canPersonalize; my $output; my @fielden = $self->getPrefFieldsToShow; my $f = WebGUI::HTMLForm->new($self->session,extras=>' onsubmit="submitForm(this,\''.$self->getId.'\',\''.$self->getUrl.'\');return false;"'); $f->raw(''); - $f->hidden( - -name => 'func', - -value => 'saveUserPrefs' - ); - foreach my $fieldId (@fielden) { - my $field = WebGUI::ProfileField->new($self->session,$fieldId); - next unless $field; + my $allowedToSave = ( ! $session->var->isAdminOn && $self->getParent->canPersonalize ) + || ( $session->var->isAdminOn && $session->user->isInGroup($session->setting->get('groupIdAdminUser')) ); + if ($allowedToSave) { + $f->hidden( + -name => 'func', + -value => 'saveUserPrefs' + ); + } + my $u = WebGUI::User->new($session, $self->discernUserId); + FIELD: foreach my $fieldId (@fielden) { + my $field = WebGUI::ProfileField->new($session,$fieldId); + next FIELD unless $field; my $params = {}; if (lc($field->get("fieldType")) eq 'textarea') { $params->{rows} = 4; @@ -822,11 +865,16 @@ sub www_getUserPrefsForm { if (lc($field->get("fieldType")) eq 'text') { $params->{size} = 20; } - $f->raw($field->formField($params,1)); + if (! $allowedToSave) { + $params->{extras} = ' disabled '; + } + $f->raw($field->formField($params,1, $u)); } - $f->submit({extras=>'className="nothing"'}); + if ($allowedToSave) { + $f->submit({extras=>'className="nothing"'}); + } $f->raw('
'); - my $tags = $self->session->style->generateAdditionalHeadTags(); + my $tags = $session->style->generateAdditionalHeadTags(); $output .= $tags.$f->print; return $output; @@ -858,16 +906,29 @@ sub www_deleteOverride { } #------------------------------------------------------------------- + +=head2 www_saveUserPrefs + +Updates the user's profile from the inline form displayed on the dashlet. Only users +who are allowed to personalize the Dashboard, or who are in admin mode and are in groupIdAdminUser +are allowed to call this method. The last restriction is due to the following: +When admin mode is turned on, the form displays the profile fields for Visitor. Saving +the form would allow someone who is not a User Admin to alter Visitor's profile. + +=cut + sub www_saveUserPrefs { - my $self = shift; - return '' unless $self->getParent->canPersonalize; + my $self = shift; + my $session = $self->session; + return '' unless $self->getParent->canPersonalize + || ( $session->var->isAdminOn && $session->user->isInGroup($session->setting->get('groupIdAdminUser')) ); my @fellowFields = $self->getPrefFieldsToShow; my %data = (); $self->uncacheOverrides; - my $i18n = WebGUI::International->new($self->session); - my $u = WebGUI::User->new($self->session, $self->discernUserId); - foreach my $fieldId ($self->session->form->param) { - my $field = WebGUI::ProfileField->new($self->session,$fieldId); + my $i18n = WebGUI::International->new($session); + my $u = WebGUI::User->new($session, $self->discernUserId); + foreach my $fieldId ($session->form->param) { + my $field = WebGUI::ProfileField->new($session,$fieldId); next unless $field; $data{$field->getId} = $field->formProcess; if ($field->getId eq 'email' && $field->isDuplicate($data{$field->getId})) { diff --git a/lib/WebGUI/i18n/English/Asset_Shortcut.pm b/lib/WebGUI/i18n/English/Asset_Shortcut.pm index e9db700dd..bd7dd45f5 100644 --- a/lib/WebGUI/i18n/English/Asset_Shortcut.pm +++ b/lib/WebGUI/i18n/English/Asset_Shortcut.pm @@ -393,6 +393,16 @@ A property or value must be quoted if it contains spaces. Feel free to use the c lastUpdated => 1243698146, }, + 'not logged in' => { + message => q|The asset this shortcut is linked to no longer exists. You need to delete this shortcut.|, + lastUpdated => 1244131773, + }, + + 'cannot personalize' => { + message => q|You are not allowed to personalize this Dashboard.|, + lastUpdated => 1244131772, + }, + }; 1;