Merge branch 'master' into 8-merge
Conflicts: docs/gotcha.txt lib/WebGUI.pm lib/WebGUI/Asset.pm lib/WebGUI/Asset/File/GalleryFile/Photo.pm lib/WebGUI/Asset/Post.pm lib/WebGUI/Asset/Story.pm lib/WebGUI/Asset/Template.pm lib/WebGUI/Asset/Wobject/Calendar.pm lib/WebGUI/Asset/Wobject/GalleryAlbum.pm lib/WebGUI/Asset/Wobject/Navigation.pm lib/WebGUI/AssetLineage.pm lib/WebGUI/AssetTrash.pm lib/WebGUI/Config.pm lib/WebGUI/Form/Template.pm lib/WebGUI/Group.pm lib/WebGUI/Inbox.pm lib/WebGUI/Workflow/Activity/DeleteExpiredSessions.pm lib/WebGUI/Workflow/Activity/TrashExpiredEvents.pm sbin/testEnvironment.pl t/AdSpace.t t/AdSpace/Ad.t t/Asset/Asset.t t/Asset/AssetExportHtml.t t/Asset/AssetLineage.t t/Asset/EMSSubmissionForm.t t/Asset/Event.t t/Asset/File/GalleryFile/Photo/00base.t t/Asset/File/GalleryFile/Photo/comment.t t/Asset/File/GalleryFile/Photo/download.t t/Asset/File/GalleryFile/Photo/edit.t t/Asset/File/GalleryFile/Photo/exif.t t/Asset/File/GalleryFile/Photo/makeResolutions.t t/Asset/File/GalleryFile/Photo/makeShortcut.t t/Asset/File/Image/setfile.t t/Asset/File/setfile.t t/Asset/Post.t t/Asset/Post/Thread/getAdjacentThread.t t/Asset/Sku.t t/Asset/Sku/ProductCollateral.t t/Asset/Story.t t/Asset/Template.t t/Asset/Template/HTMLTemplateExpr.t t/Asset/Wobject/Gallery/00base.t t/Asset/Wobject/GalleryAlbum/00base.t t/Asset/Wobject/GalleryAlbum/ajax.t t/Asset/Wobject/GalleryAlbum/delete.t t/Asset/Wobject/Matrix.t t/Asset/Wobject/StoryArchive.t t/Asset/Wobject/Survey/ExpressionEngine.t t/Asset/Wobject/Survey/Reports.t t/AssetAspect/RssFeed.t t/Auth/mech.t t/Config.t t/Group.t t/Help/isa.t t/International.t t/Mail/Send.t t/Operation/AdSpace.t t/Operation/Auth.t t/Pluggable.t t/Session.t t/Session/DateTime.t t/Session/ErrorHandler.t t/Session/Scratch.t t/Session/Stow.t t/Shop/Cart.t t/Shop/Pay.t t/Shop/PayDriver/ITransact.t t/Shop/PayDriver/PayPalStd.t t/Shop/Ship.t t/Shop/ShipDriver.t t/Shop/TaxDriver/EU.t t/Shop/TaxDriver/Generic.t t/Shop/Transaction.t t/Shop/Vendor.t t/VersionTag.t t/Workflow/Activity/ArchiveOldStories.t t/Workflow/Activity/ExpireIncompleteSurveyResponses.t t/lib/WebGUI/Test.pm
This commit is contained in:
commit
babfa74209
238 changed files with 4557 additions and 1287 deletions
|
|
@ -241,12 +241,36 @@ sub _listViewPageInterval_builder {
|
|||
}
|
||||
|
||||
property icalFeeds => (
|
||||
noFormPost => 1,
|
||||
fieldType => "textarea",
|
||||
default => sub { return []; },
|
||||
traits => ['Array', 'WebGUI::Definition::Meta::Property::Serialize',],
|
||||
isa => 'WebGUI::Type::JSONArray',
|
||||
coerce => 1,
|
||||
fieldType => "JsonTable",
|
||||
defaultValue => [],
|
||||
serialize => 1,
|
||||
tab => "feeds",
|
||||
fields => [
|
||||
{
|
||||
name => 'feedId',
|
||||
type => 'id',
|
||||
},
|
||||
{
|
||||
name => 'url',
|
||||
type => 'text',
|
||||
size => '40',
|
||||
label => $i18n->get('Feed URL'),
|
||||
},
|
||||
{
|
||||
name => 'status',
|
||||
type => 'readonly',
|
||||
label => $i18n->get('434','WebGUI'),
|
||||
},
|
||||
{
|
||||
name => 'lastUpdated',
|
||||
type => 'readonly',
|
||||
label => $i18n->get('454', 'WebGUI'),
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
property icalInterval => (
|
||||
|
|
@ -511,169 +535,17 @@ sub deleteFeed {
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getEditForm
|
||||
=head2 getEditTabs ( )
|
||||
|
||||
Adds an additional tab for feeds.
|
||||
|
||||
TODO: Abstract the Javascript enough to export into extras/yui-webgui for use
|
||||
in other areas.
|
||||
Add the feeds tab to the edit form
|
||||
|
||||
=cut
|
||||
|
||||
override getEditForm => sub {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $form = super();
|
||||
my $i18n = WebGUI::International->new($session,"Asset_Calendar");
|
||||
|
||||
my $tab = $form->addTab("feeds",$i18n->get("feeds"), 6);
|
||||
$tab->raw("<tr><td>");
|
||||
|
||||
$tab->raw(<<'ENDJS');
|
||||
<script type="text/javascript">
|
||||
var FeedsManager = new Object();
|
||||
|
||||
FeedsManager.addFeed = function (table,rowId,params) {
|
||||
// TODO: Verify that feed URL is valid
|
||||
|
||||
var table = document.getElementById(table);
|
||||
|
||||
// If id is "new"
|
||||
// Add a number on the end.
|
||||
if (rowId == "new")
|
||||
rowId = "new" + Math.round(Math.random() * 10000000000000000);
|
||||
|
||||
// Create 5 cells
|
||||
var cells = new Array();
|
||||
for (var i = 0; i < 5; i++)
|
||||
cells[i] = document.createElement("td");
|
||||
|
||||
|
||||
/*** [0] - Delete button */
|
||||
var button = document.createElement("img");
|
||||
button.setAttribute("src","/extras/wobject/Calendar/images/delete.gif");
|
||||
button.setAttribute("border","0");
|
||||
|
||||
var deleteLink = document.createElement("a");
|
||||
deleteLink.setAttribute("href","#");
|
||||
YAHOO.util.Event.addListener(deleteLink, "click", function (e, rowId) {
|
||||
FeedsManager.deleteFeed('feeds',rowId);
|
||||
YAHOO.util.Event.preventDefault(e);
|
||||
}, rowId);
|
||||
deleteLink.appendChild(button);
|
||||
|
||||
cells[0].appendChild(deleteLink);
|
||||
|
||||
|
||||
/*** [1] - Feed link for teh clicking and form element for teh saving */
|
||||
var feedLink = document.createElement("a");
|
||||
feedLink.setAttribute("href",params.url);
|
||||
feedLink.setAttribute("target","_new"); // TODO: Use JS to open window. target="" is deprecated
|
||||
feedLink.appendChild(document.createTextNode(params.url));
|
||||
|
||||
var formElement = document.createElement("input");
|
||||
formElement.setAttribute("type","hidden");
|
||||
formElement.setAttribute("name","feeds-"+rowId);
|
||||
formElement.setAttribute("value",params.url);
|
||||
|
||||
cells[1].appendChild(feedLink);
|
||||
cells[1].appendChild(formElement);
|
||||
|
||||
|
||||
/*** [2] - Result (new) */
|
||||
if (params.lastResult == undefined)
|
||||
params.lastResult = "new";
|
||||
var lastResult = document.createTextNode(params.lastResult);
|
||||
|
||||
cells[2].appendChild(lastResult);
|
||||
|
||||
|
||||
/*** [3] - Last updated */
|
||||
if (params.lastUpdated == undefined)
|
||||
params.lastUpdated = "never";
|
||||
var lastUpdated = document.createTextNode(params.lastUpdated);
|
||||
|
||||
cells[3].appendChild(lastUpdated);
|
||||
|
||||
|
||||
/*** [4] - Update now! */
|
||||
/* TODO */
|
||||
|
||||
|
||||
/* Add the row to the table */
|
||||
var row = document.createElement("tr");
|
||||
row.setAttribute("id",rowId);
|
||||
for (var i = 0; i < cells.length; i++)
|
||||
row.appendChild(cells[i]);
|
||||
|
||||
var tbody = table.getElementsByTagName('tbody')[0];
|
||||
if (tbody)
|
||||
tbody.appendChild(row);
|
||||
else
|
||||
table.appendChild(row);
|
||||
FeedsManager.updateFeed(table.getAttribute("id"),rowId);
|
||||
}
|
||||
|
||||
|
||||
FeedsManager.updateFeed = function (table,rowId) {
|
||||
/* TODO */
|
||||
|
||||
}
|
||||
|
||||
|
||||
FeedsManager.deleteFeed = function (table,rowId) {
|
||||
row = document.getElementById(rowId);
|
||||
|
||||
row.parentNode.removeChild(row);
|
||||
}
|
||||
|
||||
|
||||
FeedsManager.setFeed = function (table,rowId,params) {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
ENDJS
|
||||
|
||||
|
||||
my $addFeed = $i18n->get('Add a feed');
|
||||
my $add = $i18n->get('Add');
|
||||
my $feedUrl = $i18n->get('Feed URL');
|
||||
my $status = $i18n->get('434', 'WebGUI');
|
||||
my $lastUpdated = $i18n->get('454', 'WebGUI');
|
||||
$tab->raw(<<"ENDHTML");
|
||||
<label for="addFeed">$addFeed</label>
|
||||
<input type="text" size="60" id="addFeed" name="addFeed" value="" />
|
||||
<input type="button" value="$add" onclick="FeedsManager.addFeed('feeds','new',{ 'url' : this.form.addFeed.value }); this.form.addFeed.value=''" />
|
||||
|
||||
<table id="feeds" style="width: 100%;">
|
||||
<thead>
|
||||
<th style="width: 30px;"> </th>
|
||||
<th style="width: 50%;">$feedUrl</th>
|
||||
<th>$status</th>
|
||||
<th>$lastUpdated</th>
|
||||
<th> </th>
|
||||
</thead>
|
||||
</table>
|
||||
ENDHTML
|
||||
|
||||
|
||||
|
||||
# Add the existing feeds
|
||||
my $feeds = $self->getFeeds();
|
||||
$tab->raw('<script type="text/javascript">'."\n");
|
||||
for my $feed (@{ $feeds }) {
|
||||
my $feedId = $feed->{feedId};
|
||||
$tab->raw("FeedsManager.addFeed('feeds','".$feedId."',".JSON->new->encode( $feed ).");\n");
|
||||
}
|
||||
$tab->raw('</script>');
|
||||
|
||||
|
||||
$tab->raw("</td></tr>");
|
||||
return $form;
|
||||
};
|
||||
sub getEditTabs {
|
||||
my ( $self ) = @_;
|
||||
my $i18n = WebGUI::International->new($self->session,"Asset_Calendar");
|
||||
return $self->SUPER::getEditTabs, ["feeds",$i18n->get("feeds"), 6];
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -769,7 +641,7 @@ sub getEventsIn {
|
|||
&& Event.endTime IS NULL
|
||||
&&
|
||||
!(
|
||||
Event.startDate > '$endDate'
|
||||
Event.startDate > SUBDATE('$endDate', INTERVAL 1 DAY)
|
||||
|| Event.endDate < '$startDate'
|
||||
)
|
||||
)
|
||||
|
|
@ -794,7 +666,7 @@ sub getEventsIn {
|
|||
my $orderby = join ',', @order_priority;
|
||||
|
||||
my $events
|
||||
= $self->getLineage(["descendants"], {
|
||||
= $self->getLineage(["children"], {
|
||||
returnObjects => 1,
|
||||
includeOnlyClasses => ['WebGUI::Asset::Event'],
|
||||
joinClass => 'WebGUI::Asset::Event',
|
||||
|
|
@ -1004,37 +876,6 @@ override processPropertiesFromFormPost => sub {
|
|||
$self->createSubscriptionGroup();
|
||||
}
|
||||
|
||||
$self->session->errorHandler->info( "DEFAULT VIEW:" . $self->defaultView );
|
||||
|
||||
### Get feeds from the form
|
||||
# Workaround WebGUI::Session::Form->param bug that returns duplicate
|
||||
# names.
|
||||
my %feeds;
|
||||
for my $feedId ( grep /^feeds-/, ($form->param()) ) {
|
||||
$feedId =~ s/^feeds-//;
|
||||
$feeds{$feedId}++;
|
||||
}
|
||||
my @feedsFromForm = keys %feeds;
|
||||
|
||||
# Delete old feeds that are not in @feeds
|
||||
my @oldFeeds = map { $_->{feedId} } @{ $self->getFeeds };
|
||||
|
||||
for my $feedId (@oldFeeds) {
|
||||
if (!isIn($feedId, @feedsFromForm)) {
|
||||
$self->deleteFeed($feedId);
|
||||
}
|
||||
}
|
||||
|
||||
# Create new feeds
|
||||
for my $feedId (grep /^new(\d+)/, @feedsFromForm) {
|
||||
$self->addFeed({
|
||||
url => $form->param("feeds-".$feedId),
|
||||
feedType => "ical",
|
||||
lastUpdated => 'never',
|
||||
lastResult => '',
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1176,7 +1176,7 @@ sub getThreadsPaginator {
|
|||
$sortBy =~ s/^\w+\.//;
|
||||
# Sort by the thread rating instead of the post rating. other places don't care about threads.
|
||||
$sortBy = $sortBy eq 'rating' ? 'threadRating' : $sortBy;
|
||||
if (! WebGUI::Utility::isIn($sortBy, qw/userDefined1 userDefined2 userDefined3 userDefined4 userDefined5 title lineage revisionDate creationDate karmaRank threadRating/)) {
|
||||
if (! WebGUI::Utility::isIn($sortBy, qw/userDefined1 userDefined2 userDefined3 userDefined4 userDefined5 title lineage revisionDate creationDate karmaRank threadRating views replies lastPostDate/)) {
|
||||
$sortBy = 'revisionDate';
|
||||
}
|
||||
if ($sortBy eq 'assetId' || $sortBy eq 'revisionDate') {
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ sub view {
|
|||
$rules{assetToPedigree} = $current if (isIn("pedigree",@includedRelationships));
|
||||
$rules{ancestorLimit} = $self->ancestorEndPoint;
|
||||
$rules{orderByClause} = 'rpad(asset.lineage, 255, 9) desc' if ($self->reversePageLoop);
|
||||
my $assets = $start->getLineage(\@includedRelationships,\%rules);
|
||||
my $assetIter = $start->getLineageIterator(\@includedRelationships,\%rules);
|
||||
my $currentLineage = $current->lineage;
|
||||
my $lineageToSkip = "noskip";
|
||||
my $absoluteDepthOfLastPage;
|
||||
|
|
@ -419,7 +419,15 @@ sub view {
|
|||
my %lastChildren;
|
||||
my $previousPageData = undef;
|
||||
my $eh = $self->session->errorHandler;
|
||||
while ( my $asset = $assets->() ) {
|
||||
while ( 1 ) {
|
||||
my $asset;
|
||||
eval { $asset = $assetIter->() };
|
||||
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
|
||||
$self->session->log->error($x->full_message);
|
||||
next;
|
||||
}
|
||||
last unless $asset;
|
||||
|
||||
# skip pages we shouldn't see
|
||||
my $pageLineage = $asset->lineage;
|
||||
next if ($pageLineage =~ m/^$lineageToSkip/);
|
||||
|
|
|
|||
|
|
@ -288,9 +288,14 @@ sub getFolder {
|
|||
##For a fully automatic commit, save the current tag, create a new one
|
||||
##with the commit without approval workflow, commit it, then restore
|
||||
##the original if it exists
|
||||
my $oldVersionTag = WebGUI::VersionTag->getWorking($session, 'noCreate');
|
||||
my $newVersionTag = WebGUI::VersionTag->create($session, { workflowId => 'pbworkflow00000000003', });
|
||||
$newVersionTag->setWorking;
|
||||
my ($oldVersionTag, $newVersionTag);
|
||||
$oldVersionTag = WebGUI::VersionTag->getWorking($session, 'noCreate');
|
||||
|
||||
if ($self->hasBeenCommitted) {
|
||||
$newVersionTag = WebGUI::VersionTag->create($session, { workflowId => 'pbworkflow00000000003', });
|
||||
$newVersionTag->setWorking;
|
||||
$newVersionTag->set({ name => 'Adding folder '. $folderName. ' to archive '. $self->getUrl});
|
||||
}
|
||||
|
||||
##Call SUPER because my addChild calls getFolder
|
||||
$folder = $self->addChild({
|
||||
|
|
@ -301,7 +306,7 @@ sub getFolder {
|
|||
isHidden => 1,
|
||||
styleTemplateId => $self->styleTemplateId,
|
||||
});
|
||||
$newVersionTag->commit();
|
||||
$newVersionTag->commit() if $newVersionTag;
|
||||
##Restore the old one, if it exists
|
||||
$oldVersionTag->setWorking() if $oldVersionTag;
|
||||
|
||||
|
|
|
|||
|
|
@ -996,20 +996,8 @@ sub getFormPlugin {
|
|||
eval { WebGUI::Pluggable::load($class) };
|
||||
if ($class->isa('WebGUI::Form::List')) {
|
||||
delete $param{size};
|
||||
|
||||
my $values = WebGUI::Operation::Shared::secureEval($session,$data->{possibleValues});
|
||||
if (ref $values eq 'HASH') {
|
||||
$param{options} = $values;
|
||||
}
|
||||
else{
|
||||
my %options;
|
||||
tie %options, 'Tie::IxHash';
|
||||
foreach (split(/\n/x, $data->{possibleValues})) {
|
||||
s/\s+$//x; # remove trailing spaces
|
||||
$options{$_} = $_;
|
||||
}
|
||||
$param{options} = \%options;
|
||||
}
|
||||
$param{options} = $values;
|
||||
}
|
||||
|
||||
if ($data->{fieldType} eq "YesNo") {
|
||||
|
|
@ -2408,6 +2396,8 @@ sub editThingData {
|
|||
my $thingId = shift || $session->form->process('thingId');
|
||||
my $thingDataId = shift || $session->form->process('thingDataId') || "new";
|
||||
my $thingProperties = shift || $self->getThing($thingId);
|
||||
my $errors = shift;
|
||||
my $resetForm = shift;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
|
||||
|
||||
my $canEditThingData = $self->canEditThingData($thingId, $thingDataId, $thingProperties);
|
||||
|
|
@ -2417,7 +2407,7 @@ sub editThingData {
|
|||
my (%thingData, $fields,@field_loop,$fieldValue, $privilegedGroup);
|
||||
my $var = $self->get;
|
||||
my $url = $self->getUrl;
|
||||
my $errors = shift;
|
||||
|
||||
$var->{error_loop} = $errors if ($errors);
|
||||
|
||||
$var->{canEditThings} = $self->canEdit;
|
||||
|
|
@ -2465,14 +2455,17 @@ sub editThingData {
|
|||
,[$self->getId,$thingId]);
|
||||
while (my %field = $fields->hash) {
|
||||
my $fieldName = 'field_'.$field{fieldId};
|
||||
if ($session->form->process("func") eq "editThingDataSave"){
|
||||
$fieldValue = $session->form->process($fieldName,$field{fieldType},$field{defaultValue});
|
||||
$fieldValue = undef;
|
||||
unless ($resetForm) {
|
||||
if ($session->form->process("func") eq "editThingDataSave"){
|
||||
$fieldValue = $session->form->process($fieldName,$field{fieldType},$field{defaultValue});
|
||||
}
|
||||
else{
|
||||
$fieldValue = $thingData{"field_".$field{fieldId}};
|
||||
}
|
||||
}
|
||||
else{
|
||||
$fieldValue = $thingData{"field_".$field{fieldId}};
|
||||
}
|
||||
$field{value} = $fieldValue || $field{defaultValue};
|
||||
my $formElement .= $self->getFormElement(\%field);
|
||||
$field{value} = $fieldValue || $field{defaultValue};
|
||||
my $formElement .= $self->getFormPlugin(\%field,($resetForm eq ""))->toHtml;
|
||||
|
||||
my $hidden = ($field{status} eq "hidden" && !$self->session->var->isAdminOn);
|
||||
my $value = $field{value};
|
||||
|
|
@ -2546,7 +2539,7 @@ sub www_editThingDataSave {
|
|||
return $self->www_viewThingData($thingId,$newThingDataId);
|
||||
}
|
||||
elsif ($thingProperties->{afterSave} eq "addThing") {
|
||||
return $self->www_editThingData($thingId,"new");
|
||||
return $self->www_editThingData($thingId,"new",undef,undef,"resetForm");
|
||||
}
|
||||
elsif ($thingProperties->{afterSave} =~ m/^searchOther_/x){
|
||||
$otherThingId = $thingProperties->{afterSave};
|
||||
|
|
@ -2556,7 +2549,7 @@ sub www_editThingDataSave {
|
|||
elsif ($thingProperties->{afterSave} =~ m/^addOther_/x){
|
||||
$otherThingId = $thingProperties->{afterSave};
|
||||
$otherThingId =~ s/^addOther_//x;
|
||||
return $self->www_editThingData($otherThingId,"new");
|
||||
return $self->www_editThingData($otherThingId,"new",undef,undef,"resetForm");
|
||||
}
|
||||
# if afterSave is thingy default or in any other case return www_view()
|
||||
else {
|
||||
|
|
@ -3233,7 +3226,7 @@ $self->session->form->process($_) eq "") {
|
|||
sequenceNumber');
|
||||
while (my $field = $fields->hashRef) {
|
||||
if ($field->{searchIn}){
|
||||
my $searchForm = $self->getFormElement($field);
|
||||
my $searchForm = $self->getFormPlugin($field, 1);
|
||||
my $searchTextForm = WebGUI::Form::Text($self->session, {
|
||||
name=>"field_".$field->{fieldId},
|
||||
size=>25,
|
||||
|
|
@ -3248,9 +3241,10 @@ sequenceNumber');
|
|||
push(@searchFields_loop, {
|
||||
"searchFields_fieldId" => $field->{fieldId},
|
||||
"searchFields_label" => $field->{label},
|
||||
"searchFields_form" => $searchForm,
|
||||
"searchFields_form" => $searchForm->toHtml,
|
||||
"searchFields_textForm" => $searchTextForm,
|
||||
"searchFields_is".$fieldType => 1,
|
||||
"searchFields_listType" => $searchForm->isa('WebGUI::Form::List'),
|
||||
});
|
||||
|
||||
my @searchValue = $session->form->process("field_".$field->{fieldId});
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ sub view {
|
|||
my $url = $self->session->url;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_UserList");
|
||||
my (%var, @users, @profileField_loop, @profileFields);
|
||||
my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField);
|
||||
my ($user, $sth, $sql, $profileField);
|
||||
|
||||
my $currentUrlWithoutSort = $self->getUrl();
|
||||
foreach ($form->param) {
|
||||
|
|
@ -505,9 +505,6 @@ sub view {
|
|||
$sortBy = join '.', map { $self->session->db->quoteIdentifier($_) } split /\./, $sortBy;
|
||||
$sql .= " order by ".$sortBy." ".$sortOrder;
|
||||
|
||||
($defaultPublicProfile) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicProfile'");
|
||||
($defaultPublicEmail) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicEmail'");
|
||||
|
||||
my $paginatePage = $form->param('pn') || 1;
|
||||
my $currentUrl = $self->getUrl();
|
||||
foreach ($form->param) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue