From 52d9438c8e2636307ddae0a5652e3f3ba005b498 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Fri, 17 Dec 2004 06:14:30 +0000 Subject: [PATCH] more asset stuff --- lib/WebGUI/Asset/Wobject/DataForm.pm | 966 +++++++++++++++ lib/WebGUI/Asset/Wobject/Layout.pm | 208 ++++ lib/WebGUI/Asset/Wobject/SyndicatedContent.pm | 384 ++++++ lib/WebGUI/Asset/Wobject/USS.pm | 1039 +++++++++++++++++ lib/WebGUI/Clipboard.pm | 21 + www/extras/adminConsole/small/bg.jpg | Bin 0 -> 472 bytes www/extras/assets/poll.gif | Bin 0 -> 2045 bytes www/extras/assets/sqlReport.gif | Bin 0 -> 2355 bytes www/extras/assets/survey.gif | Bin 0 -> 1888 bytes www/extras/draggable.css | 48 + 10 files changed, 2666 insertions(+) create mode 100644 lib/WebGUI/Asset/Wobject/DataForm.pm create mode 100644 lib/WebGUI/Asset/Wobject/Layout.pm create mode 100644 lib/WebGUI/Asset/Wobject/SyndicatedContent.pm create mode 100644 lib/WebGUI/Asset/Wobject/USS.pm create mode 100644 lib/WebGUI/Clipboard.pm create mode 100644 www/extras/adminConsole/small/bg.jpg create mode 100644 www/extras/assets/poll.gif create mode 100644 www/extras/assets/sqlReport.gif create mode 100644 www/extras/assets/survey.gif create mode 100644 www/extras/draggable.css diff --git a/lib/WebGUI/Asset/Wobject/DataForm.pm b/lib/WebGUI/Asset/Wobject/DataForm.pm new file mode 100644 index 000000000..05a69f4a1 --- /dev/null +++ b/lib/WebGUI/Asset/Wobject/DataForm.pm @@ -0,0 +1,966 @@ +package WebGUI::Asset::Wobject::DataForm; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2004 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use strict qw(vars subs); +use Tie::CPHash; +use Tie::IxHash; +use WebGUI::DateTime; +use WebGUI::Form; +use WebGUI::FormProcessor; +use WebGUI::HTMLForm; +use WebGUI::HTTP; +use WebGUI::Icon; +use WebGUI::International; +use WebGUI::Macro; +use WebGUI::MessageLog; +use WebGUI::Privilege; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::Style; +use WebGUI::TabForm; +use WebGUI::URL; +use WebGUI::Asset::Wobject; +use WebGUI::Utility; + +our @ISA = qw(WebGUI::Asset::Wobject); + +#------------------------------------------------------------------- +sub _createField { + my $data = $_[0]; + my %param; + $param{name} = $data->{name}; + $param{name} = "field_".$data->{sequenceNumber} if ($param{name} eq ""); # Empty fieldname not allowed + $session{form}{$param{name}} =~ s/\^.*?\;//gs ; # remove macro's from user input + $param{value} = $data->{value}; + $param{size} = $data->{width}; + $param{rows} = $data->{rows} || 5; + $param{columns} = $data->{width}; + $param{vertical} = $data->{vertical}; + $param{extras} = $data->{extras}; + + if ($data->{type} eq "checkbox") { + $param{value} = ($data->{defaultValue} =~ /checked/i) ? 1 : ""; + } + if (isIn($data->{type},qw(selectList checkList))) { + my @defaultValues; + if ($session{form}{$param{name}}) { + @defaultValues = $session{cgi}->param($param{name}); + } else { + foreach (split(/\n/, $data->{value})) { + s/\s+$//; # remove trailing spaces + push(@defaultValues, $_); + } + } + $param{value} = \@defaultValues; + } + if (isIn($data->{type},qw(selectList checkList radioList))) { + delete $param{size}; + my %options; + tie %options, 'Tie::IxHash'; + foreach (split(/\n/, $data->{possibleValues})) { + s/\s+$//; # remove trailing spaces + $options{$_} = $_; + } + $param{options} = \%options; + } + if ($data->{type} eq "yesNo") { + if ($data->{defaultValue} =~ /yes/i) { + $param{value} = 1; + } elsif ($data->{defaultValue} =~ /no/i) { + $param{value} = 0; + } + } + my $cmd = "WebGUI::Form::".$data->{type}; + return &$cmd(\%param); +} + +#------------------------------------------------------------------- +sub _fieldAdminIcons { + my $fid = $_[1]; + my $tid = $_[2]; + my $output; + $output = deleteIcon('func=deleteFieldConfirm&wid='.$_[0]->get("wobjectId").'&fid='.$fid.'&tid='.$tid,'',WebGUI::International::get(19,$_[0]->get("namespace"))) unless ($_[3]); + $output .= editIcon('func=editField&wid='.$_[0]->get("wobjectId").'&fid='.$fid.'&tid='.$tid) + .moveUpIcon('func=moveFieldUp&wid='.$_[0]->get("wobjectId").'&fid='.$fid.'&tid='.$tid) + .moveDownIcon('func=moveFieldDown&wid='.$_[0]->get("wobjectId").'&fid='.$fid.'&tid='.$tid); + return $output; +} +#------------------------------------------------------------------- +sub _tabAdminIcons { + my $tid = $_[1]; + my $output; + $output = deleteIcon('func=deleteTabConfirm&wid='.$_[0]->get("wobjectId").'&tid='.$tid,'',WebGUI::International::get(100,$_[0]->get("namespace"))) unless ($_[2]); + $output .= editIcon('func=editTab&wid='.$_[0]->get("wobjectId").'&tid='.$tid) + .moveLeftIcon('func=moveTabLeft&wid='.$_[0]->get("wobjectId").'&tid='.$tid) + .moveRightIcon('func=moveTabRight&wid='.$_[0]->get("wobjectId").'&tid='.$tid); + return $output; +} + + +#------------------------------------------------------------------- +sub _tonull { + return $_[1] eq "0" ? (undef, undef) : @_ ; +} + + +#------------------------------------------------------------------- +sub _createTabInit { + my $wid = $_[0]; + my @tabCount = WebGUI::SQL->quickArray("select count(DataForm_tabId) from DataForm_tab where wobjectId=".quote($wid)); + my $output = ''; + return $output; +} + +#------------------------------------------------------------------- +sub duplicate { + my ($w, %dataField, %dataTab, $sthField, $sthTab, $newTabId); + tie %dataTab, 'Tie::CPHash'; + tie %dataField, 'Tie::CPHash'; + $w = $_[0]->SUPER::duplicate($_[1]); + $w = WebGUI::Wobject::DataForm->new({wobjectId=>$w,namespace=>$_[0]->get("namespace")}); + $sthTab = WebGUI::SQL->read("select * from DataForm_tab where wobjectId=".quote($_[0]->get("wobjectId"))); + while (%dataTab = $sthTab->hash) { + $sthField = WebGUI::SQL->read("select * from DataForm_field where wobjectId=".quote($_[0]->get("wobjectId"))." AND DataForm_tabId=".quote($dataTab{DataForm_tabId})); + $dataTab{DataForm_tabId} = "new"; + $newTabId = $w->setCollateral("DataForm_tab","DataForm_tabId",\%dataTab); + while (%dataField = $sthField->hash) { + $dataField{DataForm_fieldId} = "new"; + $dataField{DataForm_tabId} = $newTabId; + $w->setCollateral("DataForm_field","DataForm_fieldId",\%dataField); + } + $sthField->finish; + } + $sthField = WebGUI::SQL->read("select * from DataForm_field where wobjectId=".quote($_[0]->get("wobjectId"))." AND DataForm_tabId='0'"); + while (%dataField = $sthField->hash) { + $dataField{DataForm_fieldId} = "new"; + $w->setCollateral("DataForm_field","DataForm_fieldId",\%dataField); + } + $sthField->finish; + $sthTab->finish; +} + +#------------------------------------------------------------------- +sub getIcon { + my $self = shift; + my $small = shift; + return $session{config}{extrasURL}.'/assets/small/dataForm.gif' if ($small); + return $session{config}{extrasURL}.'/assets/dataForm.gif'; +} + +#------------------------------------------------------------------- +sub getIndexerParams { + my $self = shift; + my $now = shift; + return { + DataForm_field => { + sql => "select DataForm_field.label as label, + DataForm_field.subtext as subtext, + DataForm_field.possibleValues as possibleValues, + DataForm_field.wobjectId as wid, + DataForm_field.DataForm_fieldId as fid, + wobject.namespace as namespace, + wobject.addedBy as ownerId, + page.urlizedTitle as urlizedTitle, + page.languageId as languageId, + page.pageId as pageId, + page.groupIdView as page_groupIdView, + wobject.groupIdView as wobject_groupIdView, + 7 as wobject_special_groupIdView + from DataForm_field, wobject, page + where DataForm_field.wobjectId = wobject.wobjectId + and wobject.pageId = page.pageId + and wobject.startDate < $now + and wobject.endDate > $now + and page.startDate < $now + and page.endDate > $now", + fieldsToIndex => ["label", "subtext", "possibleValues"], + contentType => 'wobjectDetail', + url => '$data{urlizedTitle}."#".$data{wid}', + headerShortcut => 'select label from DataForm_field where DataForm_fieldId = \'$data{fid}\'', + bodyShortcut => 'select subtext from DataForm_field where DataForm_fieldId = \'$data{fid}\'', + }, + DataForm_entryData => { + sql => "select distinct(DataForm_entryData.wobjectId) as wid, + wobject.namespace as namespace, + wobject.addedBy as ownerId, + page.urlizedTitle as urlizedTitle, + page.languageId as languageId, + page.pageId as pageId, + page.groupIdView as page_groupIdView, + wobject.groupIdView as wobject_groupIdView, + wobject.groupIdEdit as wobject_special_groupIdView + from DataForm_entryData, wobject, page + where DataForm_entryData.wobjectId = wobject.wobjectId + and wobject.pageId = page.pageId + and wobject.startDate < $now + and wobject.endDate > $now + and page.startDate < $now + and page.endDate > $now", + fieldsToIndex => ['select distinct(value) from DataForm_entryData where wobjectId = \'$data{wid}\''], + contentType => 'wobjectDetail', + url => 'WebGUI::URL::append($data{urlizedTitle}, "func=view&entryId=list&wid=$data{wid}")', + headerShortcut => 'select title from wobject where wobjectId = \'$data{wid}\'', + } + }; +} + + +#------------------------------------------------------------------- +sub getListTemplateVars { + my $self = shift; + my $var = shift; + my @fieldLoop; + $var->{"back.url"} = WebGUI::URL::page(); + $var->{"back.label"} = WebGUI::International::get(18,$self->get("namespace")); + my $a = WebGUI::SQL->read("select DataForm_fieldId,name,label,isMailField,type from DataForm_field + where wobjectId=".quote($self->get("wobjectId"))." order by sequenceNumber"); + while (my $field = $a->hashRef) { + push(@fieldLoop,{ + "field.name"=>$field->{name}, + "field.id"=>$field->{DataForm_fieldId}, + "field.label"=>$field->{label}, + "field.isMailField"=>$field->{isMailField}, + "field.type"=>$field->{type}, + }); + } + $a->finish; + $var->{field_loop} = \@fieldLoop; + my @recordLoop; + my $a = WebGUI::SQL->read("select ipAddress,username,userid,submissionDate,DataForm_entryId from DataForm_entry + where wobjectId=".quote($self->get("wobjectId"))." order by submissionDate desc"); + while (my $record = $a->hashRef) { + my @dataLoop; + my $b = WebGUI::SQL->read("select b.name, b.label, b.isMailField, a.value from DataForm_entryData a left join DataForm_field b + on a.DataForm_fieldId=b.DataForm_fieldId where a.DataForm_entryId=".quote($record->{DataForm_entryId})." + order by b.sequenceNumber"); + while (my $data = $b->hashRef) { + push(@dataLoop,{ + "record.data.name"=>$data->{name}, + "record.data.label"=>$data->{label}, + "record.data.value"=>$data->{value}, + "record.data.isMailField"=>$data->{isMailField} + }); + } + $b->finish; + push(@recordLoop,{ + "record.ipAddress"=>$record->{ipAddress}, + "record.edit.url"=>WebGUI::URL::page("func=view&entryId=".$record->{DataForm_entryId}."&wid=".$self->get("wobjectId")), + "record.edit.icon"=>editIcon("func=view&entryId=".$record->{DataForm_entryId}."&wid=".$self->get("wobjectId")), + "record.delete.url"=>WebGUI::URL::page("func=deleteEntry&entryId=".$record->{DataForm_entryId}."&wid=".$self->get("wobjectId")), + "record.delete.icon"=>deleteIcon("func=deleteEntry&entryId=".$record->{DataForm_entryId}."&wid=".$self->get("wobjectId"),'',WebGUI::International::get('Delete entry confirmation',$self->get('namespace'))), + "record.username"=>$record->{username}, + "record.userId"=>$record->{userId}, + "record.submissionDate.epoch"=>$record->{submissionDate}, + "record.submissionDate.human"=>WebGUI::DateTime::epochToHuman($record->{submissionDate}), + "record.entryId"=>$record->{DataForm_entryId}, + "record.data_loop"=>\@dataLoop + }); + } + $a->finish; + $var->{record_loop} = \@recordLoop; + return $var; +} + +#------------------------------------------------------------------- +sub getRecordTemplateVars { + my $self = shift; + my $var = shift; + $var->{error_loop} = [] unless (exists $var->{error_loop}); + $var->{canEdit} = ($self->canEdit); + $var->{"entryList.url"} = WebGUI::URL::page('func=view&entryId=list&wid='.$self->get("wobjectId")); + $var->{"entryList.label"} = WebGUI::International::get(86,$self->get("namespace")); + $var->{"export.tab.url"} = WebGUI::URL::page('func=exportTab&wid='.$self->get("wobjectId")); + $var->{"export.tab.label"} = WebGUI::International::get(84,$self->get("namespace")); + $var->{"delete.url"} = WebGUI::URL::page('func=deleteEntry&wid='.$self->get("wobjectId").'&entryId='.$var->{entryId}); + $var->{"delete.label"} = WebGUI::International::get(90,$self->get("namespace")); + $var->{"back.url"} = WebGUI::URL::page(); + $var->{"back.label"} = WebGUI::International::get(18,$self->get("namespace")); + $var->{"addField.url"} = WebGUI::URL::page('func=editField&wid='.$self->get("wobjectId")); + $var->{"addField.label"} = WebGUI::International::get(76,$self->get("namespace")); + # add Tab label, url, header and init + $var->{"addTab.label"}= WebGUI::International::get(105,$self->get("namespace"));; + $var->{"addTab.url"}= WebGUI::URL::page('func=editTab&wid='.$self->get("wobjectId")); + $var->{"tab.init"}= _createTabInit($self->get("wobjectId")); + $var->{"form.start"} = WebGUI::Form::formHeader() + .WebGUI::Form::hidden({name=>"wid",value=>$self->get("wobjectId")}) + .WebGUI::Form::hidden({name=>"func",value=>"process"}); + my @tabs; + my $select = "select a.name, a.DataForm_fieldId, a.DataForm_tabId,a.label, a.status, a.isMailField, a.subtext, a.type, a.defaultValue, a.possibleValues, a.width, a.rows, a.extras, a.vertical"; + my $join; + my $where = "where a.wobjectId=".quote($self->get("wobjectId")); + if ($var->{entryId}) { + $var->{"form.start"} .= WebGUI::Form::hidden({name=>"entryId",value=>$var->{entryId}}); + my $entry = $self->getCollateral("DataForm_entry","DataForm_entryId",$var->{entryId}); + $var->{ipAddress} = $entry->{ipAddress}; + $var->{username} = $entry->{username}; + $var->{userId} = $entry->{userId}; + $var->{date} = WebGUI::DateTime::epochToHuman($entry->{submissionDate}); + $var->{epoch} = $entry->{submissionDate}; + $var->{"edit.URL"} = WebGUI::URL::page('func=view&wid='.$self->get("wobjectId").'&entryId='.$var->{entryId}); + $where .= " and b.DataForm_entryId=".quote($var->{entryId}); + $join = "left join DataForm_entryData as b on a.DataForm_fieldId=b.DataForm_fieldId"; + $select .= ", b.value"; + } + my %data; + tie %data, 'Tie::CPHash'; + my %tab; + tie %tab, 'Tie::CPHash'; + my $tabsth = WebGUI::SQL->read("select * from DataForm_tab where wobjectId=".quote($self->get("wobjectId"))." order by sequenceNumber"); + while (%tab = $tabsth->hash) { + my @fields; + my $sth = WebGUI::SQL->read("$select from DataForm_field as a $join $where and a.DataForm_tabId=".quote($tab{DataForm_tabId})." order by a.sequenceNumber"); + while (%data = $sth->hash) { + my $formValue = $session{form}{$data{name}}; + if ((not exists $data{value}) && $session{form}{func} ne "editSave" && $session{form}{func} ne "editFieldSave" && defined $formValue) { + $data{value} = $formValue; + $data{value} = WebGUI::DateTime::setToEpoch($data{value}) if ($data{type} eq "date"); + } + if (not exists $data{value}) { + $data{value} = WebGUI::Macro::process($data{defaultValue}); + } + my $hidden = (($data{status} eq "hidden" && !$session{var}{adminOn}) || ($data{isMailField} && !$self->get("mailData"))); + my $value = $data{value}; + $value = WebGUI::DateTime::epochToHuman($value,"%z") if ($data{type} eq "date"); + $value = WebGUI::DateTime::epochToHuman($value,"%z %Z") if ($data{type} eq "dateTime"); + push(@fields, { + "tab.field.form" => _createField(\%data), + "tab.field.name" => $data{name}, + "tab.field.tid" => $data{DataForm_tabId}, + "tab.field.value" => $value, + "tab.field.label" => $data{label}, + "tab.field.isMailField" => $data{isMailField}, + "tab.field.isHidden" => $hidden, + "tab.field.isDisplayed" => ($data{status} eq "visible" && !$hidden), + "tab.field.isRequired" => ($data{status} eq "required" && !$hidden), + "tab.field.subtext" => $data{subtext}, + "tab.field.controls" => $self->_fieldAdminIcons($data{DataForm_fieldId},$data{DataForm_tabId},$data{isMailField}) + }); + } + $sth->finish; + push(@tabs, { + "tab.start" => '
', + "tab.end" =>'
', + "tab.sequence" => $tab{sequenceNumber}, + "tab.label" => $tab{label}, + "tab.tid" => $tab{DataForm_tabId}, + "tab.subtext" => $tab{subtext}, + "tab.controls" => $self->_tabAdminIcons($tab{DataForm_tabId}), + "tab.field_loop" => \@fields, + }); + } + + my @fields; + my $sth = WebGUI::SQL->read("$select from DataForm_field as a $join $where and a.DataForm_tabId = 0 order by a.sequenceNumber"); + while (%data = $sth->hash) { + my $formValue = $session{form}{$data{name}}; + if ((not exists $data{value}) && $session{form}{func} ne "editSave" && $session{form}{func} ne "editFieldSave" && defined $formValue) { + $data{value} = $formValue; + $data{value} = WebGUI::DateTime::setToEpoch($data{value}) if ($data{type} eq "date"); + } + if (not exists $data{value}) { + $data{value} = WebGUI::Macro::process($data{defaultValue}); + } + my $hidden = (($data{status} eq "hidden" && !$session{var}{adminOn}) || ($data{isMailField} && !$self->get("mailData"))); + my $value = $data{value}; + $value = WebGUI::DateTime::epochToHuman($value,"%z") if ($data{type} eq "date"); + $value = WebGUI::DateTime::epochToHuman($value) if ($data{type} eq "dateTime"); + my %fieldProperties = ( + "form" => _createField(\%data), + "name" => $data{name}, + "tid" => $data{DataForm_tabId}, + "inTab".$data{DataForm_tabId} => 1, + "value" => $value, + "label" => $data{label}, + "isMailField" => $data{isMailField}, + "isHidden" => $hidden, + "isDisplayed" => ($data{status} eq "visible" && !$hidden), + "isRequired" => ($data{status} eq "required" && !$hidden), + "subtext" => $data{subtext}, + "controls" => $self->_fieldAdminIcons($data{DataForm_fieldId},$data{DataForm_tabId},$data{isMailField}) + ); + push(@fields, { map {("field.".$_ => $fieldProperties{$_})} keys(%fieldProperties) }); + foreach (keys(%fieldProperties)) { + $var->{"field.noloop.".$data{name}.".$_"} = $fieldProperties{$_}; + } + } + $sth->finish; + $var->{field_loop} = \@fields; + $tabsth->finish; + $var->{tab_loop} = \@tabs; + $var->{"form.send"} = WebGUI::Form::submit({value=>WebGUI::International::get(73, $self->get("namespace"))}); + $var->{"form.save"} = WebGUI::Form::submit(); + $var->{"form.end"} = WebGUI::Form::formFooter(); + return $var; +} + +#------------------------------------------------------------------- +sub name { + return WebGUI::International::get(1,$_[0]->get("namespace")); +} + +#------------------------------------------------------------------- +sub definition { + my $class = shift; + my $definition = shift; + push(@{$definition}, { + tableName=>'DataForm', + className=>'WebGUI::Asset::Wobject::DataForm', + properties=>{ + acknowledgement=>{ + fieldType=>"textarea", + defaultValue=>undef + }, + emailTemplateId=>{ + fieldType=>"template", + defaultValue=>undef + }, + acknowlegementTemplateId=>{ + defaultValue=>undef, + fieldType=>"template" + }, + listTemplateId=>{ + defaultValue=>undef, + fieldType=>"template" + }, + mailData=>{ + defaultValue=>0, + fieldType=>"yesNo" + } + } + }); + return $class->SUPER::definition($definition); +} + +#------------------------------------------------------------------- +sub purge { + WebGUI::SQL->write("delete from DataForm_field where wobjectId=".quote($_[0]->get("wobjectId"))); + WebGUI::SQL->write("delete from DataForm_entry where wobjectId=".quote($_[0]->get("wobjectId"))); + WebGUI::SQL->write("delete from DataForm_entryData where wobjectId=".quote($_[0]->get("wobjectId"))); + WebGUI::SQL->write("delete from DataForm_tab where wobjectId=".quote($_[0]->get("wobjectId"))); + $_[0]->SUPER::purge(); +} + +#------------------------------------------------------------------- +sub sendEmail { + my $var = $_[1]; + my $message = WebGUI::Macro::process($_[0]->processTemplate($_[0]->get("emailTemplateId"),$var)); + my ($to, $subject, $from, $bcc, $cc); + foreach my $row (@{$var->{field_loop}}) { + if ($row->{"field.name"} eq "to") { + $to = $row->{"field.value"}; + } elsif ($row->{"field.name"} eq "from") { + $from = $row->{"field.value"}; + } elsif ($row->{"field.name"} eq "cc") { + $cc = $row->{"field.value"}; + } elsif ($row->{"field.name"} eq "bcc") { + $bcc = $row->{"field.value"}; + } elsif ($row->{"field.name"} eq "subject") { + $subject = $row->{"field.value"}; + } + } + if ($to =~ /\@/) { + WebGUI::Mail::send($to, $subject, $message, $cc, $from, $bcc); + } else { + my ($userId) = WebGUI::SQL->quickArray("select userId from users where username=".quote($to)); + my $groupId; + # if no user is found, try finding a matching group + unless ($userId) { + ($groupId) = WebGUI::SQL->quickArray("select groupId from groups where groupName=".quote($to)); + } + unless ($userId || $groupId) { + WebGUI::ErrorHandler::warn($_[0]->get("wobjectId").": Unable to send message, no user or group found."); + } else { + WebGUI::MessageLog::addEntry($userId, $groupId, $subject, $message, "", "", $from); + if ($cc) { + WebGUI::Mail::send($cc, $subject, $message, "", $from); + } + if ($bcc) { + WebGUI::Mail::send($bcc, $subject, $message, "", $from); + } + } + } +} + +#------------------------------------------------------------------- +sub uiLevel { + return 5; +} + +sub view { + return "DataForm"; +} + +#------------------------------------------------------------------- +sub www_deleteEntry { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + my $entryId = $session{form}{entryId}; + WebGUI::SQL->write("delete from DataForm_entry where DataForm_entryId=".quote($entryId)); + $session{form}{entryId} = 'list'; + return $_[0]->www_view(); +} + +#------------------------------------------------------------------- +sub www_deleteFieldConfirm { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->deleteCollateral("DataForm_field","DataForm_fieldId",$session{form}{fid}); + $_[0]->reorderCollateral("DataForm_field","DataForm_fieldId"); + return ""; +} + +#------------------------------------------------------------------- +sub www_deleteTabConfirm { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->deleteCollateral("DataForm_tab","DataForm_tabId",$session{form}{tid}); + $_[0]->deleteCollateral("DataForm_field","DataForm_tabId",$session{form}{tid}); + $_[0]->reorderCollateral("DataForm_tab","DataForm_tabId"); + return ""; +} + +#------------------------------------------------------------------- +sub www_edit { + my $layout = WebGUI::HTMLForm->new; + $layout->template( + -name=>"emailTemplateId", + -value=>$_[0]->getValue("emailTemplateId"), + -namespace=>$_[0]->get("namespace"), + -label=>WebGUI::International::get(80,$_[0]->get("namespace")), + -afterEdit=>'func=edit&wid='.$_[0]->get("wobjectId") + ); + $layout->template( + -name=>"acknowlegementTemplateId", + -value=>$_[0]->getValue("acknowlegementTemplateId"), + -namespace=>$_[0]->get("namespace"), + -label=>WebGUI::International::get(81,$_[0]->get("namespace")), + -afterEdit=>'func=edit&wid='.$_[0]->get("wobjectId") + ); + $layout->template( + -name=>"listTemplateId", + -value=>$_[0]->getValue("listTemplateId"), + -namespace=>$_[0]->get("namespace")."/List", + -label=>WebGUI::International::get(87,$_[0]->get("namespace")), + -afterEdit=>'func=edit&wid='.$_[0]->get("wobjectId") + ); + my $properties = WebGUI::HTMLForm->new; + $properties->HTMLArea( + -name=>"acknowledgement", + -label=>WebGUI::International::get(16, $_[0]->get("namespace")), + -value=>($_[0]->get("acknowledgement") || WebGUI::International::get(3, $_[0]->get("namespace"))) + ); + $properties->yesNo( + -name=>"mailData", + -label=>WebGUI::International::get(74,$_[0]->get("namespace")), + -value=>$_[0]->getValue("mailData") + ); + if ($_[0]->get("wobjectId") eq "new") { + $properties->whatNext( + -options=>{ + addField=>WebGUI::International::get(76,$_[0]->get("namespace")), + backToPage=>WebGUI::International::get(745) + }, + -value=>"addField" + ); + } + return $_[0]->SUPER::www_edit( + -properties=>$properties->printRowsOnly, + -layout=>$layout->printRowsOnly, + -helpId=>"data form add/edit", + -headingId=>7 + ); +} + +#------------------------------------------------------------------- +sub www_editSave { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->SUPER::www_editSave(); + if ($session{form}{wid} eq "new") { + $_[0]->setCollateral("DataForm_field","DataForm_fieldId",{ + DataForm_fieldId=>"new", + name=>"from", + label=>WebGUI::International::get(10,$_[0]->get("namespace")), + status=>"editable", + isMailField=>1, + width=>0, + type=>"email" + }); + $_[0]->setCollateral("DataForm_field","DataForm_fieldId",{ + DataForm_fieldId=>"new", + name=>"to", + label=>WebGUI::International::get(11,$_[0]->get("namespace")), + status=>"hidden", + isMailField=>1, + width=>0, + type=>"email", + defaultValue=>$session{setting}{companyEmail} + }); + $_[0]->setCollateral("DataForm_field","DataForm_fieldId",{ + DataForm_fieldId=>"new", + name=>"cc", + label=>WebGUI::International::get(12,$_[0]->get("namespace")), + status=>"hidden", + isMailField=>1, + width=>0, + type=>"email" + }); + $_[0]->setCollateral("DataForm_field","DataForm_fieldId",{ + DataForm_fieldId=>"new", + name=>"bcc", + label=>WebGUI::International::get(13,$_[0]->get("namespace")), + status=>"hidden", + isMailField=>1, + width=>0, + type=>"email" + }); + $_[0]->setCollateral("DataForm_field","DataForm_fieldId",{ + DataForm_fieldId=>"new", + name=>"subject", + label=>WebGUI::International::get(14,$_[0]->get("namespace")), + status=>"editable", + isMailField=>1, + width=>0, + type=>"text", + defaultValue=>WebGUI::International::get(2,$_[0]->get("namespace")) + }); + } + if ($session{form}{proceed} eq "addField") { + return $_[0]->www_editField(); + } + return ""; +} + +#------------------------------------------------------------------- +sub www_editField { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + my (%field, $f, %fieldStatus,$tab); + tie %field, 'Tie::CPHash'; + tie %fieldStatus, 'Tie::IxHash'; + + %fieldStatus = ( + "hidden" => WebGUI::International::get(4, $_[0]->get("namespace")), + "visible" => WebGUI::International::get(5, $_[0]->get("namespace")), + "editable" => WebGUI::International::get(6, $_[0]->get("namespace")), + "required" => WebGUI::International::get(75, $_[0]->get("namespace")) + ); + $session{form}{fid} = "new" if ($session{form}{fid} eq ""); + unless ($session{form}{fid} eq "new") { + %field = WebGUI::SQL->quickHash("select * from DataForm_field where DataForm_fieldId=".quote($session{form}{fid})); + } + $tab = WebGUI::SQL->buildHashRef("select DataForm_tabId,label from DataForm_tab where wobjectId=".quote($_[0]->get("wobjectId"))); + $tab->{0} = $_[0]->i18n("no tab"); + $f = WebGUI::HTMLForm->new; + $f->hidden("wid",$_[0]->get("wobjectId")); + $f->hidden("fid",$session{form}{fid}); + $f->hidden("func","editFieldSave"); + $f->text( + -name=>"label", + -label=>WebGUI::International::get(77,$_[0]->get("namespace")), + -value=>$field{label} + ); + $f->text( + -name=>"name", + -label=>WebGUI::International::get(21,$_[0]->get("namespace")), + -value=>$field{name} + ); + if($field{sequenceNumber} && ! $field{isMailField}) { + $f->integer( + -name=>"position", + -label=>WebGUI::International::get('Field Position',$_[0]->get("namespace")), + -value=>$field{sequenceNumber} + ); + } + $f->select( + -name=>"tid", + -options=>$tab, + -label=>WebGUI::International::get(104,$_[0]->get("namespace")), + -value=>[ $field{DataForm_tabId}] || [0] + ); + $f->text( + -name=>"subtext", + -value=>$field{subtext}, + -label=>WebGUI::International::get(79,$_[0]->get("namespace")), + ); + $f->select( + -name=>"status", + -options=>\%fieldStatus, + -label=>WebGUI::International::get(22,$_[0]->get("namespace")), + -value=>[ $field{status} ||= "editable" ] + ); + $f->fieldType( + -name=>"type", + -label=>WebGUI::International::get(23,$_[0]->get("namespace")), + -value=>[$field{type} ||= "text"] + ); + $f->integer( + -name=>"width", + -label=>WebGUI::International::get(8, $_[0]->get("namespace")), + -value=>($field{width} || 0) + ); + $f->integer( + -name=>"rows", + -value=>$field{rows} || 0, + -label=>WebGUI::International::get(27, $_[0]->get("namespace")), + -subtext=>WebGUI::International::get(28, $_[0]->get("namespace")), + ); + $f->yesNo( + -name=>"vertical", + -value=>$field{vertical}, + -label=>WebGUI::International::get('editField-vertical-label', $_[0]->get("namespace")), + -subtext=>WebGUI::International::get('editField-vertical-subtext', $_[0]->get("namespace")) + ); + $f->text( + -name=>"extras", + -value=>$field{extras}, + -label=>WebGUI::International::get('editField-extras-label', $_[0]->get("namespace")) + ); + $f->textarea( + -name=>"possibleValues", + -label=>WebGUI::International::get(24,$_[0]->get("namespace")), + -value=>$field{possibleValues}, + -subtext=>'
'.WebGUI::International::get(85,$_[0]->get("namespace")) + ); + $f->textarea( + -name=>"defaultValue", + -label=>WebGUI::International::get(25,$_[0]->get("namespace")), + -value=>$field{defaultValue}, + -subtext=>'
'.WebGUI::International::get(85,$_[0]->get("namespace")) + ); + if ($session{form}{fid} eq "new") { + $f->whatNext( + -options=>{ + addField=>WebGUI::International::get(76,$_[0]->get("namespace")), + backToPage=>WebGUI::International::get(745) + }, + -value=>"addField" + ); + } + $f->submit; + return $_[0]->adminConsole($f->print,'20',"data form fields add/edit"); +} + +#------------------------------------------------------------------- +sub www_editFieldSave { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $session{form}{name} = $session{form}{label} if ($session{form}{name} eq ""); + $session{form}{tid} = "0" if ($session{form}{tid} eq ""); + $session{form}{name} = WebGUI::URL::urlize($session{form}{name}); + $session{form}{name} =~ s/\-//g; + $session{form}{name} =~ s/\///g; + $_[0]->setCollateral("DataForm_field","DataForm_fieldId",{ + DataForm_fieldId=>$session{form}{fid}, + width=>$session{form}{width}, + name=>$session{form}{name}, + label=>$session{form}{label}, + DataForm_tabId=>$session{form}{tid}, + status=>$session{form}{status}, + type=>$session{form}{type}, + possibleValues=>$session{form}{possibleValues}, + defaultValue=>$session{form}{defaultValue}, + subtext=>$session{form}{subtext}, + rows=>$session{form}{rows}, + vertical=>$session{form}{vertical}, + extras=>$session{form}{extras}, + }, "1","1", _tonull("DataForm_tabId",$session{form}{tid})); + if($session{form}{position}) { + WebGUI::SQL->write("update DataForm_field set sequenceNumber=".quote($session{form}{position}). + " where DataForm_fieldId=".quote($session{form}{fid})); + } + $_[0]->reorderCollateral("DataForm_field","DataForm_fieldId", _tonull("DataForm_tabId",$session{form}{tid})) if ($session{form}{fid} ne "new"); + if ($session{form}{proceed} eq "addField") { + $session{form}{fid} = "new"; + return $_[0]->www_editField(); + } + return ""; +} + +#------------------------------------------------------------------- +sub www_editTab { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + my (%tab, $f); + tie %tab, 'Tie::CPHash'; + + $session{form}{tid} = "new" if ($session{form}{tid} eq ""); + unless ($session{form}{tid} eq "new") { + %tab = WebGUI::SQL->quickHash("select * from DataForm_tab where DataForm_tabId=".quote($session{form}{tid})); + } + $f = WebGUI::HTMLForm->new; + $f->hidden("wid",$_[0]->get("wobjectId")); + $f->hidden("tid",$session{form}{tid}); + $f->hidden("func","editTabSave"); + $f->text( + -name=>"label", + -label=>WebGUI::International::get(101,$_[0]->get("namespace")), + -value=>$tab{label} + ); + $f->textarea( + -name=>"subtext", + -label=>WebGUI::International::get(102,$_[0]->get("namespace")), + -value=>$tab{subtext}, + -subtext=>"" + ); + if ($session{form}{tid} eq "new") { + $f->whatNext( + -options=>{ + addTab=>WebGUI::International::get(103,$_[0]->get("namespace")), + + backToPage=>WebGUI::International::get(745) + }, + -value=>"addTab" + ); + } + $f->submit; + return $_[0]->adminConsole($f->print,'20',"data form fields add/edit"); +} + +#------------------------------------------------------------------- +sub www_editTabSave { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $session{form}{name} = $session{form}{label} if ($session{form}{name} eq ""); + $session{form}{name} = WebGUI::URL::urlize($session{form}{name}); + $session{form}{name} =~ s/\-//g; + $session{form}{name} =~ s/\///g; + $_[0]->setCollateral("DataForm_tab","DataForm_tabId",{ + DataForm_tabId=>$session{form}{tid}, + label=>$session{form}{label}, + subtext=>$session{form}{subtext} + }); + if ($session{form}{proceed} eq "addTab") { + $session{form}{tid} = "new"; + return $_[0]->www_editTab(); + } + return ""; +} + +#------------------------------------------------------------------- +sub www_exportTab { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + WebGUI::HTTP::setFilename(WebGUI::URL::urlize($_[0]->get("title")).".tab","text/plain"); + my %fields = WebGUI::SQL->buildHash("select DataForm_fieldId,name from DataForm_field where wobjectId=".quote($_[0]->get("wobjectId"))." order by sequenceNumber"); + my $select = "select a.DataForm_entryId as entryId, a.ipAddress, a.username, a.userId, a.submissionDate"; + my $from = " from DataForm_entry a"; + my $join; + my $where = " where a.wobjectId=".quote($_[0]->get("wobjectId")); + my $orderBy = " order by a.DataForm_entryId"; + my $columnCounter = "b"; + foreach my $fieldId (keys %fields) { + my $extension = ""; + $extension = "mail_" if (isIn($fields{$fieldId}, qw(to from cc bcc subject))); + $select .= ", ".$columnCounter.".value as ".$extension.$fields{$fieldId}; + $join .= " left join DataForm_entryData ".$columnCounter." on a.DataForm_entryId=".$columnCounter.".DataForm_entryId and " + .$columnCounter.".DataForm_fieldId=".quote($fieldId); + $columnCounter++; + } + return WebGUI::SQL->quickTab($select.$from.$join.$where.$orderBy); +} + +#------------------------------------------------------------------- +sub www_moveFieldDown { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->moveCollateralDown("DataForm_field","DataForm_fieldId",$session{form}{fid},_tonull("DataForm_tabId",$session{form}{tid})); + return ""; +} + +#------------------------------------------------------------------- +sub www_moveFieldUp { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->moveCollateralUp("DataForm_field","DataForm_fieldId",$session{form}{fid},_tonull("DataForm_tabId",$session{form}{tid})); + return ""; +} + +#------------------------------------------------------------------- +sub www_moveTabRight { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->moveCollateralDown("DataForm_tab","DataForm_tabId",$session{form}{tid}); + return ""; +} + +#------------------------------------------------------------------- +sub www_moveTabLeft { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->moveCollateralUp("DataForm_tab","DataForm_tabId",$session{form}{tid}); + return ""; +} + +#------------------------------------------------------------------- +sub www_process { + my $entryId = $_[0]->setCollateral("DataForm_entry","DataForm_entryId",{ + DataForm_entryId=>$session{form}{entryId}, + wobjectId=>$_[0]->get("wobjectId"), + userId=>$session{user}{userId}, + username=>$session{user}{username}, + ipAddress=>$session{env}{REMOTE_ADDR}, + submissionDate=>time() + },0); + my ($var, %row, @errors, $updating, $hadErrors); + $var->{entryId} = $entryId; + tie %row, "Tie::CPHash"; + my $sth = WebGUI::SQL->read("select DataForm_fieldId,label,name,status,type,defaultValue,isMailField from DataForm_field + where wobjectId=".quote($_[0]->get("wobjectId"))." order by sequenceNumber"); + while (%row = $sth->hash) { + my $value = $row{defaultValue}; + if ($row{status} eq "required" || $row{status} eq "editable") { + $value = WebGUI::FormProcessor::process($row{name},$row{type},$row{defaultValue}); + $value = WebGUI::Macro::filter($value); + } + if ($row{status} eq "required" && ($value =~ /^\s$/ || $value eq "" || not defined $value)) { + push (@errors,{ + "error.message"=>$row{label}." ".WebGUI::International::get(29,$_[0]->get("namespace")).".", + }); + $hadErrors = 1; + delete $var->{entryId}; + } + if ($row{status} eq "hidden") { + $value = WebGUI::Macro::process($row{defaultValue}); + } + unless ($hadErrors) { + my ($exists) = WebGUI::SQL->quickArray("select count(*) from DataForm_entryData where DataForm_entryId=".quote($entryId)." + and DataForm_fieldId=".quote($row{DataForm_fieldId})); + if ($exists) { + WebGUI::SQL->write("update DataForm_entryData set value=".quote($value)." + where DataForm_entryId=".quote($entryId)." and DataForm_fieldId=".quote($row{DataForm_fieldId})); + $updating = 1; + } else { + WebGUI::SQL->write("insert into DataForm_entryData (DataForm_entryId,DataForm_fieldId,wobjectId,value) values + (".quote($entryId).", ".quote($row{DataForm_fieldId}).", ".quote($_[0]->get("wobjectId")).", ".quote($value).")"); + } + } + } + $sth->finish; + $var->{error_loop} = \@errors; + $var = $_[0]->getRecordTemplateVars($var); + if ($hadErrors && !$updating) { + WebGUI::SQL->write("delete from DataForm_entryData where DataForm_entryId=".quote($entryId)); + $_[0]->deleteCollateral("DataForm_entry","DataForm_entryId",$entryId); + $_[0]->www_view($var); + } else { + $_[0]->sendEmail($var) if ($_[0]->get("mailData") && !$updating); + return $_[0]->processTemplate($_[0]->get("acknowlegementTemplateId"),$var); + } +} + +#------------------------------------------------------------------- +sub www_view { + $_[0]->logView() if ($session{setting}{passiveProfilingEnabled}); + my $var; + $var->{entryId} = $session{form}{entryId} if ($_[0]->canEdit); + if ($var->{entryId} eq "list" && $_[0]->canEdit) { + return $_[0]->processTemplate($_[0]->get("listTemplateId"),$_[0]->getListTemplateVars,"DataForm/List"); + } + # add Tab StyleSheet and JavaScript + WebGUI::Style::setLink('/extras/tabs/tabs.css', {"type"=>"text/css"}); + WebGUI::Style::setScript('/extras/tabs/tabs.js', {"language"=>"JavaScript"}); + $var = $_[1] || $_[0]->getRecordTemplateVars($var); + return $_[0]->processTemplate($_[0]->get("templateId"),$var); +} + + +1; + + diff --git a/lib/WebGUI/Asset/Wobject/Layout.pm b/lib/WebGUI/Asset/Wobject/Layout.pm new file mode 100644 index 000000000..b33104ffc --- /dev/null +++ b/lib/WebGUI/Asset/Wobject/Layout.pm @@ -0,0 +1,208 @@ +package WebGUI::Asset::Wobject::Layout; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2004 Plain Black Corporation. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use strict; +use WebGUI::Asset::Wobject; +use WebGUI::Icon; +use WebGUI::Session; +use WebGUI::Utility; + +our @ISA = qw(WebGUI::Asset::Wobject); + +=head1 NAME + +Package WebGUI::Asset::Wobject::Layout + +=head1 DESCRIPTION + +Provides a mechanism to layout multiple assets on a single page. + +=head1 SYNOPSIS + +use WebGUI::Asset::Wobject::Layout; + + +=head1 METHODS + +These methods are available from this class: + +=cut + + + +#------------------------------------------------------------------- + +=head2 definition ( definition ) + +Defines the properties of this asset. + +=head3 definition + +A hash reference passed in from a subclass definition. + +=cut + +sub definition { + my $class = shift; + my $definition = shift; + push(@{$definition}, { + tableName=>'layout', + className=>'WebGUI::Asset::Wobject::Layout', + properties=>{ + contentPositions => { + defaultValue=>undef, + fieldType=>"hidden" + } + } + }); + return $class->SUPER::definition($definition); +} + + + +#------------------------------------------------------------------- + +=head2 getEditForm () + +Returns the TabForm object that will be used in generating the edit page for this asset. + +=cut + +sub getEditForm { + my $self = shift; + my $tabform = $self->SUPER::getEditForm(); + if ($self->get("assetId") eq "new") { + $tabform->getTab("properties")->whatNext( + -options=>{ + gotoNewPage=>WebGUI::International::get(823), + backToPage=>WebGUI::International::get(847) + }, + ); + } + return $tabform; +} + + +#------------------------------------------------------------------- +sub getIcon { + my $self = shift; + my $small = shift; + return $session{config}{extrasURL}.'/assets/small/layout.gif' if ($small); + return $session{config}{extrasURL}.'/assets/layout.gif'; +} + +#------------------------------------------------------------------- + +=head2 getName () + +Returns the displayable name of this asset. + +=cut + +sub getName { + return "Layout"; +} + + +#------------------------------------------------------------------- + +=head2 getUiLevel () + +Returns the UI level of this asset. + +=cut + +sub getUiLevel { + return 5; +} + + +#------------------------------------------------------------------- +sub view { + my $self = shift; + my $children = $self->getLineage( + ["descendants"], + { + returnObjects=>1, + excludeClasses=>["WebGUI::Asset::Wobject::Layout"], + endingLineageLength=>$self->getLineageLength+1 + } + ); + my %vars; + # I'm sure there's a more efficient way to do this. We'll figure it out someday. + my @positions = split(/\./,$self->get("contentPositions")); + my $i = 1; + my @found; + foreach my $position (@positions) { + my @assets = split(",",$position); + foreach my $asset (@assets) { + foreach my $child (@{$children}) { + if ($asset eq $child->getId) { + push(@{$vars{"position".$i."_loop"}},{ + id=>$child->getId, + content=>$child->view + }); + push(@found, $child->getId); + } + } + } + $i++; + } + # deal with unplaced children + foreach my $child (@{$children}) { + unless (isIn($child->getId, @found)) { + push(@{$vars{"position1_loop"}},{ + id=>$child->getId, + content=>$child->view + }); + } + } + $vars{showAdmin} = ($session{var}{adminOn} && $self->canEdit); + if ($vars{showAdmin}) { + # under normal circumstances we don't put HTML stuff in our code, but this will make it much easier + # for end users to work with our templates + WebGUI::Style::setScript($session{config}{extrasURL}."/draggable.js",{ type=>"text/javascript", language=>"javascript" }); + WebGUI::Style::setLink($session{config}{extrasURL}."/draggable.css",{ type=>"text/css", rel=>"stylesheet", media=>"all" }); + $vars{"dragger.icon"} = WebGUI::Icon::dragIcon(); + $vars{"dragger.init"} = ' + + + + '; + } + + return $self->processTemplate(\%vars, "page"); +} + + +sub www_setContentPositions { + my $self = shift; + return WebGUI::Style::process(WebGUI::Privilege::insufficient(),$self->get("styleTemplateId")) unless ($self->canEdit); + $self->update({ + contentPositions=>$session{form}{map} + }); + return "Map set: ".$session{form}{map}; +} + + +1; + diff --git a/lib/WebGUI/Asset/Wobject/SyndicatedContent.pm b/lib/WebGUI/Asset/Wobject/SyndicatedContent.pm new file mode 100644 index 000000000..f19d11cf8 --- /dev/null +++ b/lib/WebGUI/Asset/Wobject/SyndicatedContent.pm @@ -0,0 +1,384 @@ +package WebGUI::Asset::Wobject::SyndicatedContent; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2004 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use HTML::Entities; +use strict; +use Storable; +use Tie::CPHash; +use WebGUI::Cache; +use WebGUI::DateTime; +use WebGUI::HTMLForm; +use WebGUI::HTML; +use WebGUI::International; +use WebGUI::Privilege; +use WebGUI::Session; +use WebGUI::Asset::Wobject; +use XML::RSSLite; +use LWP::UserAgent; +use WebGUI::ErrorHandler; +my $hasEncode=1; +eval " use Encode qw(from_to); "; $hasEncode=0 if $@; + +our @ISA = qw(WebGUI::Asset::Wobject); + + + +#------------------------------------------------------------------- +sub definition { + my $class = shift; + my $definition = shift; + push(@{$definition}, { + tableName=>'SyndicatedContent', + className=>'WebGUI::Asset::Wobject::SyndicatedContent', + properties=>{ + rssUrl=>{ + defaultValue=>undef, + fieldType=>"url" + }, + maxHeadlines=>{ + fieldType=>"integer", + defaultValue=>10 + }, + } + }); + return $class->SUPER::definition($definition); +} + + +#------------------------------------------------------------------- +sub getIcon { + my $self = shift; + my $small = shift; + return $session{config}{extrasURL}.'/assets/small/syndicatedContent.gif' if ($small); + return $session{config}{extrasURL}.'/assets/syndcatedContent.gif'; +} + +#------------------------------------------------------------------- +sub getName { + return WebGUI::International::get(2,"SyndicatedContent"); +} + +#------------------------------------------------------------------- +sub getUiLevel { + return 6; +} + + +#------------------------------------------------------------------- +sub getEditForm { + my $self = shift; + my $tabform = $self->SUPER::getEditForm(); + $tabform->getTab("properties")->url( + -name=>"rssUrl", + -label=>WebGUI::International::get(1,"SyndicatedContent"), + -value=>$self->getValue("rssUrl") + ); + $tabform->getTab("layout")->integer( + -name=>"maxHeadlines", + -label=>WebGUI::International::get(3,"SyndicatedContent"), + -value=>$self->getValue("maxHeadlines") + ); + return $tabform; +} + +# strip all html tags from the given data structure. This is important to +# prevent cross site scripting attacks +my $_stripped_html = {}; +sub _strip_html { + #my ($data) = @_; + + if (ref($_[0]) eq 'HASH') { + keys(%{$_[0]}); + while (my ($name, $val) = each (%{$_[0]})) { + $_[0]->{$name} = _strip_html($val); + } + } elsif (ref($_[0]) eq 'ARRAY') { + for (my $i = 0; $i < @{$_[0]}; $i++) { + $_[0]->[$i] = _strip_html($_[0]->[$i]); + } + } else { + if ($_[0]) { + $_[0] =~ s/\<//g; + $_[0] = WebGUI::HTML::filter($_[0], 'all'); + } + } + + return $_[0]; +} + +# horrible kludge to find the channel or item record +# in the varying kinds of rss structures returned by RSSLite +sub _find_record { + my ($data, $regex) = @_; + + if (ref($data) eq 'HASH') { + # reset the hash before calling each() + keys(%{$data}); + while (my ($name, $val) = each(%{$data})) { + if ($name =~ $_[1]) { + if ((((ref($val) eq 'HASH') && + ($val->{link} || $val->{title} || + $val->{description})) || + ((ref($val) eq 'ARRAY') && @{$val} && + (ref($val->[0]) eq 'HASH') && + ($val->[0]->{link} || + $val->[0]->{title} || + $val->[0]->{description})))) { + return $val; + } + } + if (my $record = _find_record($val, $regex)) { + return $record; + } + } + } + + return undef; +} + +# Copy the guid field to the link field if the guid looks like a link. +# This is a kludge that gets around the fact that some folks use the link +# field as the link to the story while others use it as the link +# to the story about which the story is written. The webuig templates seem +# to assume the former, so we should use the guid instead of the link, b/c +# the guid, if it is a link, always means the former. +# Also copy the first few words of the description into the title if +# there is no title +sub _normalize_items { + #my ($items) = @_; + + # max number of words to take from description to fill in an empty + # title + my $max_words = 10; + + for my $item (@{$_[0]}) { + if ($item->{guid} && ($item->{guid} =~ /^http:\/\//i)) { + $item->{link} = $item->{guid}; + } + if (!$item->{title}) { + my @description_words = split(/\s/, $item->{description}); + if (@description_words <= $max_words) { + $item->{title} = $item->{description}; + } else { + $item->{title} = join(" ", @description_words[0..$max_words-1]) . + " ..."; + } + } + + # IE doesn't recognize ' + $item->{title} =~ s/'/\'/; + $item->{description} =~ s/'/\'/; + } +} + +sub _get_rss_data { + my ($url) = @_; + + my $cache = WebGUI::Cache->new("url:" . $url, "RSS"); + my $rss_serial = $cache->get; + my $rss = {}; + if ($rss_serial) { + $rss = Storable::thaw($rss_serial); + } else { + my $ua = LWP::UserAgent->new(timeout => 5); + my $response = $ua->get($url); + if (!$response->is_success()) { + WebGUI::ErrorHandler::warn("Error retrieving url '$url': " . + $response->status_line()); + return undef; + } + my $xml = $response->content(); + + # Convert encoding if needed / Perl 5.8.0 or up required. + if ($] >= 5.008 && $hasEncode) { + $xml =~ /<\?xml.*?encoding=['"](\S+)['"]/i; + my $xmlEncoding = $1; + my $encoding = "UTF-8"; + if (lc($xmlEncoding) ne lc($encoding)) { + eval { from_to($xml, $xmlEncoding, $encoding) }; + WebGUI::ErrorHandler::warn($@) if ($@); + } + + } + + + # there is no encode_entities_numeric that I can find, so I am + # commenting this out. -hal + # $xml =~ s#()(.*?)()#$1.encode_entities_numeric(decode_entities($2)).$3#ges; + # $xml =~ s#()(.*?)()#$1.encode_entities_numeric(decode_entities($2)).$3#ges; + + my $rss_lite = {}; + eval { + XML::RSSLite::parseXML($rss_lite, \$xml); + }; + if ($@) { + WebGUI::ErrorHandler::warn("error parsing rss for url $url"); + } + + # make sure that the {channel} points to the channel + # description record and that {items} points to the list + # of items. without this voodoo, different versions of + # rss return the data in different places in the data + # structure. + $rss_lite = {channel => $rss_lite}; + if (!($rss->{channel} = + _find_record($rss_lite, qr/^channel$/))) { + WebGUI::ErrorHandler::warn("unable to find channel info for url $url"); + } + if (!($rss->{items} = _find_record($rss_lite, qr/^items?$/))) { + WebGUI::ErrorHandler::warn("unable to find item info for url $url"); + $rss->{items} = []; + } + + _strip_html($rss); + $rss->{items} = [ $rss->{items} ] unless (ref $rss->{items} eq 'ARRAY'); + + _normalize_items($rss->{items}); + + $cache->set(Storable::freeze($rss), 3600); + } + + return $rss; +} + +# rss items don't have a standard date, so timestamp them the first time +# we see them and use that timestamp as the date. Periodically nuke the +# whole database to keep the thing from growing too large +sub _assign_rss_dates { + my ($items) = @_; + + for my $item (@{$items}) { + my $key = 'dates:' . ($item->{guid} || $item->{title} || + $item->{description} || $item->{link}); + my $cache = WebGUI::Cache->new($key, "RSS"); + if (my $date = $cache->get()) { + $item->{date} = $date; + } else { + $item->{date} = time(); + $cache->set($item->{date}, '1 year'); + } + } + } + +sub _get_aggregate_items { + my $self = shift; + my $urls = shift; + my $maxHeadlines = shift; + + my $cache = WebGUI::Cache->new("aggregate:" . + $self->get("rssUrl"), "RSS"); + my $items = Storable::thaw($cache->get()); + if (!$items) { + $items = []; + my $items_remain = 1; + + my @rsss; + for my $url (@{$urls}) { + push(@rsss, _get_rss_data($url)); + } + + while ((@{$items} < $maxHeadlines) && $items_remain) { + $items_remain = 0; + for my $rss (@rsss) { + if ($rss->{items} && + (my $item = shift(@{$rss->{items}}))) { + push(@{$items}, + {site_title => $rss->{channel}->{title}, + site_link => $rss->{channel}->{link}, + link => $item->{link}, + title => $item->{title}, + description => $item->{description}, + }); + if (@{$rss->{items}}) { + $items_remain = 1; + } + } + } + } + + _assign_rss_dates($items); + + @{$items} = sort { $b->{date} <=> $a->{date} } @{$items}; + + #if (@{$items} > $_aggregate_size) { + # @{$items} = @{$items}[0..($_aggregate_size-1)]; + #} + + $cache->set(Storable::freeze($items), 3600); + } + + return $items; +} + +# interleave stories from each feed, up to a total of $_aggregate_size +sub _view_aggregate_feed { + my $self = shift; + my $urls = shift; + my $maxHeadlines = shift; + my %var; + $var{'channel.title'} = $self->get("title"); + $var{'channel.description'} = $self->get("description"); + $var{item_loop} = $self->_get_aggregate_items($urls, $maxHeadlines); + + return $self->processTemplate(\%var,"SyndactedContent"); +} + + +#------------------------------------------------------------------- +sub _view_single_feed { + my $self = shift; + my $maxHeadlines = shift; + my $rss = _get_rss_data($self->get("rssUrl")); + my %var; + $var{"channel.title"} = $rss->{channel}->{title}; + $var{"channel.link"} = $rss->{channel}->{link}; + $var{"channel.description"} = $rss->{channel}->{description}; + my @items; + $rss->{items} ||= []; + for (my $i = 0; ($i < @{$rss->{items}}) && ($i < $maxHeadlines);$i++) { + my $item = $rss->{items}->[$i]; + push (@items,{ + link=>$item->{link}, + title=>$item->{title}, + description=>$item->{description} + }); + } + $var{item_loop} = \@items; + return $self->processTemplate(\%var,"SyndicatedContent"); +} + +sub view { + my $self = shift; + $self->logView() if ($session{setting}{passiveProfilingEnabled}); + my $maxHeadlines = $self->get("maxHeadlines") || 1000000; + + my @urls = split(/\s+/,$self->get("rssUrl")); + if (@urls == 1) { + return $self->_view_single_feed($maxHeadlines); + } else { + return $self->_view_aggregate_feed(\@urls, $maxHeadlines); + } +} + + +#------------------------------------------------------------------- +sub www_edit { + my $self = shift; + return WebGUI::Privilege::insufficient() unless $self->canEdit; + $self->getAdminConsole->setHelp("syndicated content add/edit"); + return $self->getAdminConsole->render($self->getEditForm->print,WebGUI::International::get("4","SyndicatedContent")); +} + + +1; + diff --git a/lib/WebGUI/Asset/Wobject/USS.pm b/lib/WebGUI/Asset/Wobject/USS.pm new file mode 100644 index 000000000..77a76be34 --- /dev/null +++ b/lib/WebGUI/Asset/Wobject/USS.pm @@ -0,0 +1,1039 @@ +package WebGUI::Asset::Wobject::USS; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2004 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use strict; +use Tie::CPHash; +use WebGUI::Attachment; +use WebGUI::Cache; +use WebGUI::DateTime; +use WebGUI::Forum; +use WebGUI::Forum::UI; +use WebGUI::Grouping; +use WebGUI::HTML; +use WebGUI::HTMLForm; +use WebGUI::HTTP; +use WebGUI::Icon; +use WebGUI::Id; +use WebGUI::International; +use WebGUI::MessageLog; +use WebGUI::Operation; +use WebGUI::Page; +use WebGUI::Paginator; +use WebGUI::Privilege; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::Style; +use WebGUI::Template; +use WebGUI::URL; +use WebGUI::User; +use WebGUI::Utility; +use WebGUI::Asset::Wobject; + +our @ISA = qw(WebGUI::Asset::Wobject); + +#------------------------------------------------------------------- +# format the date according to rfc 822 (for RSS export) +my @_months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); +sub _get_rfc822_date { + my ($time) = @_; + my ($year, $mon, $mday, $hour, $min, $sec) = WebGUI::DateTime::localtime($time); + my $month = $_months[$mon - 1]; + return sprintf("%02d %s %04d %02d:%02d:%02d GMT", + $mday, $month, $year, $hour, $min, $sec); +} + +#------------------------------------------------------------------- +# encode a string to include in xml (for RSS export) +sub _xml_encode { + $_[0] =~ s/&/&/g; + $_[0] =~ s//\]\]>/g; + return $_[0]; +} + +sub definition { + my $class = shift; + my $definition = shift; + push(@{$definition}, { + tableName=>'USS', + className=>'WebGUI::Asset::Wobject::USS', + properties=>{ + submissionsPerPage=>{ + fieldType=>"integer", + defaultValue=>50 + }, + groupToContribute=>{ + fieldType=>"group", + defaultValue=>2 + }, + groupToApprove=>{ + fieldType=>"group", + defaultValue=>4 + }, + defaultStatus=>{ + fieldType=>"selectList", + defaultValue=>"Approved" + }, + submissionTemplateId=>{ + fieldType=>"template", + defaultValue=>undef + }, + submissionFormTemplateId=>{ + fieldType=>"template", + defaultValue=>undef + }, + karmaPerSubmission=>{ + fieldType=>"integer", + defaultValue=>0 + }, + filterContent=>{ + fieldType=>"filter", + defaultValue=>"javascript" + }, + sortBy=>{ + fieldType=>"selectList", + defaultValue=>"dateUpdated" + }, + sortOrder=>{ + fieldType=>"selectList", + defaultValue=>"desc" + }, + USS_id=>{ + fieldType=>"hidden", + autoId=>1 + }, + submissionFormTemplateId=>{ + fieldType=>"template", + defaultValue=>undef + } + } + }); + return $class->SUPER::definition($definition); +} + +#------------------------------------------------------------------- +sub deleteAllCachedSubmissions { + my $self = shift; + my $cache = WebGUI::Cache->new("USS_submission_"); + $cache->deleteByRegex(qr/USS_submission_/); +} + +#------------------------------------------------------------------- +sub deleteCachedSubmission { + my $self = shift; + my $submissionId = shift; + my $cache = WebGUI::Cache->new("USS_submission_".$submissionId); + $cache->delete; +} + + +#------------------------------------------------------------------- +sub duplicate { + WebGUI::ErrorHandler::warn("USS wobjects cannot be duplicated until after 6.3."); + return ""; + my %row; + tie %row, 'Tie::CPHash'; + my $w = $_[0]->SUPER::duplicate($_[1],1); + $w = WebGUI::Wobject::USS->new({wobjectId=>$w}); + my $sth = WebGUI::SQL->read("select * from USS_submission where USS_id=".quote($_[0]->get("USS_id"))); + while (%row = $sth->hash) { + my $newSubmissionId = WebGUI::Id::generate(); + my $file = WebGUI::Attachment->new($row{image},$_[0]->get("wobjectId"),$row{USS_submissionId}); + $file->copy($w,$newSubmissionId); + $file = WebGUI::Attachment->new($row{attachment},$_[0]->get("wobjectId"),$row{USS_submissionId}); + $file->copy($w,$newSubmissionId); + $row{USS_submissionId} = $newSubmissionId; + $w->setCollateral("USS_submission","USS_submissionId",\%row); + } + $sth->finish; +} + +#------------------------------------------------------------------- +sub getIcon { + my $self = shift; + my $small = shift; + return $session{config}{extrasURL}.'/assets/small/userSubmissionSystem.gif' if ($small); + return $session{config}{extrasURL}.'/assets/userSubmissionSystem.gif'; +} + +#------------------------------------------------------------------- +sub getIndexerParams { + my $self = shift; + my $now = shift; + return { + USS_discussion => { + sql => "select forumPost.forumPostId, + forumPost.username, + forumPost.subject, + forumPost.message, + forumPost.userId as ownerId, + forumThread.forumId as forumId, + USS_submission.USS_submissionId as sid, + wobject.namespace as namespace, + wobject.wobjectId as wid, + page.urlizedTitle as urlizedTitle, + page.languageId as languageId, + page.pageId as pageId, + page.groupIdView as page_groupIdView, + wobject.groupIdView as wobject_groupIdView, + 7 as wobject_special_groupIdView + from forumPost, forumThread, USS_submission, wobject, page, USS + where forumPost.forumThreadId = forumThread.forumThreadId + and forumThread.forumId = USS_submission.forumId + and USS_submission.USS_id = USS.USS_id + and USS.wobjectId = wobject.wobjectId + and wobject.pageId = page.pageId + and wobject.startDate < $now + and wobject.endDate > $now + and page.startDate < $now + and page.endDate > $now", + fieldsToIndex => ["username", "subject", "message"], + contentType => 'discussion', + url => 'WebGUI::URL::append($data{urlizedTitle},"func=viewSubmission&wid=$data{wid}&sid=$data{sid}&forumOp=viewThread&forumPostId=$data{forumPostId}&forumId=$data{forumId}")', + headerShortcut => 'select subject from forumPost where forumPostId = \'$data{forumPostId}\'', + bodyShortcut => 'select message from forumPost where forumPostId = \'$data{forumPostId}\'', + }, + USS_submission => { + sql => "select USS_submission.title as title, + USS_submission.username as username, + USS_submission.content as content, + USS_submission.image as image, + USS_submission.attachment as attachment, + USS.wobjectId as wid, + USS_submission.USS_submissionId as sid, + USS_submission.userId as ownerId, + wobject.namespace as namespace, + page.urlizedTitle as urlizedTitle, + page.languageId as languageId, + page.pageId as pageId, + page.groupIdView as page_groupIdView, + wobject.groupIdView as wobject_groupIdView, + 7 as wobject_special_groupIdView + from wobject, page, USS_submission, USS + where USS_submission.USS_id = USS.USS_id + and USS.wobjectId = wobject.wobjectId + and wobject.pageId = page.pageId + and USS_submission.status = 'Approved' + and wobject.startDate < $now + and wobject.endDate > $now + and page.startDate < $now + and page.endDate > $now", + fieldsToIndex => ["username", "title", "content", "image", "attachment"], + contentType => 'wobjectDetail', + url => 'WebGUI::URL::append($data{urlizedTitle}, "func=viewSubmission&wid=$data{wid}&sid=$data{sid}")', + headerShortcut => 'select title from USS_submission where USS_submissionId = \'$data{sid}\'', + bodyShortcut => 'select content from USS_submission where USS_submissionId = \'$data{sid}\'', + } + }; +} + +#------------------------------------------------------------------- +sub name { + return WebGUI::International::get(29,"USS"); +} + +#------------------------------------------------------------------- +sub purge { + my $sth = WebGUI::SQL->read("select forumId,pageId,USS_submissionId from USS_submission where USS_id=".quote($_[0]->get("USS_id"))); + while (my ($forumId, $pageId,$submissionId) = $sth->array) { + my ($inUseElsewhere) = WebGUI::SQL->quickArray("select count(*) from USS_submission where forumId=".quote($forumId)); + unless ($inUseElsewhere > 1) { + my $forum = WebGUI::Forum->new($forumId); + $forum->purge; + } + my $page = WebGUI::Page->new($pageId); + if (defined $page) { + $page->purge; + } else { + WebGUI::ErrorHandler::warn("Submission ".$submissionId." of USS ".$_[0]->get("USS_id")." didn't have real page attached to it. This could be a minor problem caused by a bug of old, or it could indicate major data corruption issues."); + } + } + $sth->finish; + WebGUI::SQL->write("delete from USS_submission where USS_id=".quote($_[0]->get("USS_id"))); + $_[0]->SUPER::purge(); +} + +#------------------------------------------------------------------- +sub status { + if ($_[0] eq "Approved") { + return WebGUI::International::get(560); + } elsif ($_[0] eq "Denied") { + return WebGUI::International::get(561); + } elsif ($_[0] eq "Pending") { + return WebGUI::International::get(562); + } +} + +sub view { + return "USS"; +} + +#------------------------------------------------------------------- +# NOTE: Not a method. Used by the page tree. +sub viewSubmissionAsPage { + my $params = shift; + my $properties = WebGUI::SQL->getRow("wobject","wobjectId",$params->{wobjectId}); + my $w = WebGUI::Wobject::USS->new($properties); + return $w->www_viewSubmission($params->{submissionId}); +} + + +#------------------------------------------------------------------- +sub www_approveSubmission { + my $self = shift; + my (%submission); + tie %submission, 'Tie::CPHash'; + if (WebGUI::Grouping::isInGroup(4,$session{user}{userId}) || WebGUI::Grouping::isInGroup(3,$session{user}{userId})) { + %submission = WebGUI::SQL->quickHash("select * from USS_submission where USS_submissionId=".quote($session{form}{sid})); + WebGUI::SQL->write("update USS_submission set status='Approved' where USS_submissionId=".quote($session{form}{sid})); + WebGUI::MessageLog::addInternationalizedEntry($submission{userId},'',WebGUI::URL::page('func=viewSubmission&wid='. + $session{form}{wid}.'&sid='.$session{form}{sid},1),4,$self->get("namespace")); + WebGUI::MessageLog::completeEntry($session{form}{mlog}); + $self->deleteCachedSubmission($session{form}{sid}); + return WebGUI::Operation::www_viewMessageLog(); + } else { + return WebGUI::Privilege::insufficient(); + } +} + +#------------------------------------------------------------------- +sub www_copy { + return "Copying of User Submission Systems has been disabled until 6.3."; +} + + +#------------------------------------------------------------------- +sub www_deleteFile { + my $self = shift; + my ($owner) = WebGUI::SQL->quickArray("select userId from USS_submission where USS_submissionId=".quote($session{form}{sid})); + if ($owner eq $session{user}{userId} || WebGUI::Grouping::isInGroup($self->get("groupToApprove"))) { + $self->setCollateral("USS_submission","USS_submissionId",{ + $session{form}{file}=>'', + USS_submissionId=>$session{form}{sid} + },0,0); + $self->deleteCachedSubmission($session{form}{sid}); + return $self->www_editSubmission(); + } else { + return WebGUI::Privilege::insufficient(); + } +} + +#------------------------------------------------------------------- +sub www_deleteSubmissionConfirm { + my $self = shift; + my ($owner, $forumId, $pageId) = WebGUI::SQL->quickArray("select userId,forumId,pageId from USS_submission where USS_submissionId=".quote($session{form}{sid})); + if ($owner eq $session{user}{userId} || WebGUI::Grouping::isInGroup($self->get("groupToApprove"))) { + my ($inUseElsewhere) = WebGUI::SQL->quickArray("select count(*) from USS_submission where forumId=".quote($forumId)); + unless ($inUseElsewhere > 1) { + my $forum = WebGUI::Forum->new($forumId); + $forum->purge; + } + my $page = WebGUI::Page->new($pageId); + $page->purge; + $self->deleteCachedSubmission($session{form}{sid}); + $self->deleteCollateral("USS_submission","USS_submissionId",$session{form}{sid}); + my $file = WebGUI::Attachment->new("",$session{form}{wid},$session{form}{sid}); + $file->deleteNode; + return ""; + } else { + return WebGUI::Privilege::insufficient(); + } +} + +#------------------------------------------------------------------- +sub www_denySubmission { + my $self = shift; + my (%submission); + tie %submission, 'Tie::CPHash'; + if (WebGUI::Grouping::isInGroup(4,$session{user}{userId}) || WebGUI::Grouping::isInGroup(3,$session{user}{userId})) { + %submission = WebGUI::SQL->quickHash("select * from USS_submission where USS_submissionId=".quote($session{form}{sid})); + WebGUI::SQL->write("update USS_submission set status='Denied' where USS_submissionId=".quote($session{form}{sid})); + WebGUI::MessageLog::addInternationalizedEntry($submission{userId},'',WebGUI::URL::page('func=viewSubmission&wid='. + $session{form}{wid}.'&sid='.$session{form}{sid},1),5,$self->get("namespace")); + WebGUI::MessageLog::completeEntry($session{form}{mlog}); + $self->deleteCachedSubmission($session{form}{sid}); + return WebGUI::Operation::www_viewMessageLog(); + } else { + return WebGUI::Privilege::insufficient(); + } +} + +#------------------------------------------------------------------- +sub www_edit { + my $layout = WebGUI::HTMLForm->new; + my $privileges = WebGUI::HTMLForm->new; + my $properties = WebGUI::HTMLForm->new; + $layout->template( + -name=>"submissionTemplateId", + -value=>$_[0]->getValue("submissionTemplateId"), + -namespace=>$_[0]->get("namespace")."/Submission", + -label=>WebGUI::International::get(73,$_[0]->get("namespace")), + -afterEdit=>'func=edit&wid='.$_[0]->get("wobjectId") + ); + $layout->template( + -name=>"submissionFormTemplateId", + -value=>$_[0]->getValue("submissionFormTemplateId"), + -namespace=>$_[0]->get("namespace")."/SubmissionForm", + -label=>WebGUI::International::get(87,$_[0]->get("namespace")), + -afterEdit=>'func=edit&wid='.$_[0]->get("wobjectId") + ); + $privileges->group( + -name=>"groupToApprove", + -label=>WebGUI::International::get(1,$_[0]->get("namespace")), + -value=>[$_[0]->getValue("groupToApprove")] + ); + $privileges->group( + -name=>"groupToContribute", + -label=>WebGUI::International::get(2,$_[0]->get("namespace")), + -value=>[$_[0]->getValue("groupToContribute")] + ); + $layout->integer( + -name=>"submissionsPerPage", + -label=>WebGUI::International::get(6,$_[0]->get("namespace")), + -value=>$_[0]->getValue("submissionsPerPage") + ); + $privileges->selectList( + -name=>"defaultStatus", + -options=>{ + Approved=>status('Approved'), + Denied=>status('Denied'), + Pending=>status('Pending') + }, + -label=>WebGUI::International::get(563), + -value=>[$_[0]->getValue("defaultStatus")] + ); + if ($session{setting}{useKarma}) { + $properties->integer( + -name=>"karmaPerSubmission", + -label=>WebGUI::International::get(30,$_[0]->get("namespace")), + -value=>$_[0]->getValue("karmaPerSubmission") + ); + } else { + $properties->hidden("karmaPerSubmission",$_[0]->getValue("karmaPerSubmission")); + } + $layout->filterContent( + -value=>$_[0]->getValue("filterContent") + ); + $layout->selectList( + -name=>"sortBy", + -value=>[$_[0]->getValue("sortBy")], + -options=>{ + sequenceNumber=>WebGUI::International::get(88,$_[0]->get("namespace")), + dateUpdated=>WebGUI::International::get(78,$_[0]->get("namespace")), + dateSubmitted=>WebGUI::International::get(13,$_[0]->get("namespace")), + title=>WebGUI::International::get(35,$_[0]->get("namespace")) + }, + -label=>WebGUI::International::get(79,$_[0]->get("namespace")) + ); + $layout->selectList( + -name=>"sortOrder", + -value=>[$_[0]->getValue("sortOrder")], + -options=>{ + asc=>WebGUI::International::get(81,$_[0]->get("namespace")), + desc=>WebGUI::International::get(82,$_[0]->get("namespace")) + }, + -label=>WebGUI::International::get(80,$_[0]->get("namespace")) + ); + return $_[0]->SUPER::www_edit( + -layout=>$layout->printRowsOnly, + -privileges=>$privileges->printRowsOnly, + -properties=>$properties->printRowsOnly, + -headingId=>18, + -helpId=>"user submission system add/edit" + ); +} + +#------------------------------------------------------------------- +sub www_editSave { + $_[0]->deleteAllCachedSubmissions; + $_[0]->SUPER::www_editSave() +} + + +#------------------------------------------------------------------- +sub www_editSubmission { + my ($output, $submission, $f, @submission, $sth); + $submission = $_[0]->getCollateral("USS_submission","USS_submissionId",$session{form}{sid}); + my %var; + if ($submission->{USS_submissionId} eq "new") { + $submission->{userId} = $session{user}{userId}; + $submission->{contentType} = "mixed"; + $var{'submission.isNew'} = 1; + } + return WebGUI::Privilege::insufficient() unless (WebGUI::Grouping::isInGroup($_[0]->get("groupToContribute")) + || $submission->{userId} eq $session{user}{userId} + || WebGUI::Grouping::isInGroup($_[0]->get("groupToApprove"))); + $var{'link.header.label'} = WebGUI::International::get(90,$_[0]->get("namespace")); + $var{'question.header.label'} = WebGUI::International::get(84,$_[0]->get("namespace")); + $var{'submission.header.label'} = WebGUI::International::get(19,$_[0]->get("namespace")); + $var{'user.isVisitor'} = ($session{user}{userId} eq '1'); + $var{'visitorName.label'} = WebGUI::International::get(438); + $var{'visitorName.form'} = WebGUI::Form::text({ + name=>"visitorName" + }); + $var{'form.header'} = WebGUI::Form::formHeader() + .WebGUI::Form::hidden({ + name=>"wid", + value=>$session{form}{wid} + }) + .WebGUI::Form::hidden({ + name=>"sid", + value=>$submission->{USS_submissionId} + }) + .WebGUI::Form::hidden({ + name=>"func", + value=>"editSubmissionSave" + }); + $var{'url.label'} = WebGUI::International::get(91,$_[0]->get("namespace")); + $var{'newWindow.label'} = WebGUI::International::get(92,$_[0]->get("namespace")); + $var{'userDefined1.form'} = WebGUI::Form::text({ + name=>"userDefined1", + value=>$submission->{userDefined1} + }); + $var{'userDefined1.form.yesNo'} = WebGUI::Form::yesNo({ + name=>"userDefined1", + value=>$submission->{userDefined1} + }); + $var{'userDefined1.form.textarea'} = WebGUI::Form::textarea({ + name=>"userDefined1", + value=>$submission->{userDefined1} + }); + $var{'userDefined2.form'} = WebGUI::Form::text({ + name=>"userDefined2", + value=>$submission->{userDefined2} + }); + $var{'userDefined2.form.yesNo'} = WebGUI::Form::yesNo({ + name=>"userDefined2", + value=>$submission->{userDefined2} + }); + $var{'userDefined2.form.textarea'} = WebGUI::Form::textarea({ + name=>"userDefined2", + value=>$submission->{userDefined2} + }); + $var{'userDefined3.form'} = WebGUI::Form::text({ + name=>"userDefined3", + value=>$submission->{userDefined3} + }); + $var{'userDefined3.form.yesNo'} = WebGUI::Form::yesNo({ + name=>"userDefined3", + value=>$submission->{userDefined3} + }); + $var{'userDefined3.form.textarea'} = WebGUI::Form::textarea({ + name=>"userDefined3", + value=>$submission->{userDefined3} + }); + $var{'userDefined4.form'} = WebGUI::Form::text({ + name=>"userDefined4", + value=>$submission->{userDefined4} + }); + $var{'userDefined4.form.yesNo'} = WebGUI::Form::yesNo({ + name=>"userDefined4", + value=>$submission->{userDefined4} + }); + $var{'userDefined4.form.textarea'} = WebGUI::Form::textarea({ + name=>"userDefined4", + value=>$submission->{userDefined4} + }); + $var{'userDefined5.form'} = WebGUI::Form::text({ + name=>"userDefined5", + value=>$submission->{userDefined5} + }); + $var{'userDefined5.form.yesNo'} = WebGUI::Form::yesNo({ + name=>"userDefined5", + value=>$submission->{userDefined5} + }); + $var{'userDefined5.form.textarea'} = WebGUI::Form::textarea({ + name=>"userDefined5", + value=>$submission->{userDefined5} + }); + $var{'userDefined1.form.htmlarea'} = WebGUI::Form::HTMLArea({ + name=>"userDefined1", + value=>$submission->{userDefined1} + }); + $var{'userDefined2.form.htmlarea'} = WebGUI::Form::HTMLArea({ + name=>"userDefined2", + value=>$submission->{userDefined2} + }); + $var{'userDefined3.form.htmlarea'} = WebGUI::Form::HTMLArea({ + name=>"userDefined3", + value=>$submission->{userDefined3} + }); + $var{'userDefined4.form.htmlarea'} = WebGUI::Form::HTMLArea({ + name=>"userDefined4", + value=>$submission->{userDefined4} + }); + $var{'userDefined5.form.htmlarea'} = WebGUI::Form::HTMLArea({ + name=>"userDefined5", + value=>$submission->{userDefined5} + }); + $var{'userDefined1.value'} = $submission->{userDefined1}; + $var{'userDefined2.value'} = $submission->{userDefined2}; + $var{'userDefined3.value'} = $submission->{userDefined3}; + $var{'userDefined4.value'} = $submission->{userDefined4}; + $var{'userDefined5.value'} = $submission->{userDefined5}; + $var{'question.label'} = WebGUI::International::get(85,$_[0]->get("namespace")); + $var{'title.label'} = WebGUI::International::get(35,$_[0]->get("namespace")); + $var{'title.form'} = WebGUI::Form::text({ + name=>"title", + value=>$submission->{title} + }); + $var{'title.form.textarea'} = WebGUI::Form::textarea({ + name=>"title", + value=>$submission->{title} + }); + $var{'title.value'} = $submission->{title}; + $var{'body.label'} = WebGUI::International::get(31,$_[0]->get("namespace")); + $var{'answer.label'} = WebGUI::International::get(86,$_[0]->get("namespace")); + $var{'description.label'} = WebGUI::International::get(85); + $var{'body.value'} = $submission->{content}; + $var{'body.form'} = WebGUI::Form::HTMLArea({ + name=>"body", + value=>$submission->{content} + }); + $var{'body.form.textarea'} = WebGUI::Form::textarea({ + name=>"body", + value=>$submission->{content} + }); + $var{'image.label'} = WebGUI::International::get(32,$_[0]->get("namespace")); + if ($submission->{image} ne "") { + $var{'image.form'} = ''.WebGUI::International::get(391).''; + } else { + $var{'image.form'} = WebGUI::Form::file({ + name=>"image" + }); + } + $var{'attachment.label'} = WebGUI::International::get(33,$_[0]->get("namespace")); + if ($submission->{attachment} ne "") { + $var{'attachment.form'} = ''.WebGUI::International::get(391).''; + } else { + $var{'attachment.form'} = WebGUI::Form::file({ + name=>"attachment" + }); + } + $var{'contentType.label'} = WebGUI::International::get(1007); + $var{'contentType.form'} = WebGUI::Form::contentType({ + name=>'contentType', + value=>[$submission->{contentType}] + }); + $var{'startDate.label'} = WebGUI::International::get(497); + $var{'endDate.label'} = WebGUI::International::get(498); + $var{'startDate.form'} = WebGUI::Form::dateTime({ + name => 'startDate', + value => ($submission->{startDate} || $_[0]->get("startDate")) + }); + $var{'endDate.form'} = WebGUI::Form::dateTime({ + name => 'endDate', + value => ($submission->{endDate} || $_[0]->get("endDate")) + }); + $var{'form.submit'} = WebGUI::Form::submit(); + $var{'form.footer'} = WebGUI::Form::formFooter(); + return $_[0]->processTemplate($_[0]->get("submissionFormTemplateId"),\%var,"USS/SubmissionForm"); +} + +#------------------------------------------------------------------- +sub www_editSubmissionSave { + my ($submission, %hash, $file, $u); + $submission = $_[0]->getCollateral("USS_submission","USS_submissionId",$session{form}{sid}); + if ($submission->{userId} eq $session{user}{userId} + || ($submission->{USS_submissionId} eq "new" + && WebGUI::Grouping::isInGroup($_[0]->get("groupToContribute"))) + || WebGUI::Grouping::isInGroup($_[0]->get("groupToApprove"))) { + if ($session{form}{sid} eq "new") { + my $parentPage = WebGUI::Page->new($_[0]->get("pageId")); + my $newPage = $parentPage->add; + $hash{pageId} = $submission->{pageId} = $newPage->get("pageId"); + my $forum = WebGUI::Forum->create({ + masterForumId=>$_[0]->get("forumId"), + forumId=>"new" + }); + $hash{forumId} = $forum->get("forumId"); + $hash{USS_id} = $_[0]->get("USS_id"); + $hash{username} = $session{form}{visitorName} || $session{user}{alias}; + $hash{userId} = $session{user}{userId}; + $hash{dateSubmitted} = WebGUI::DateTime::time(); + $hash{USS_submissionId} = "new"; + if ($session{setting}{useKarma}) { + $u = WebGUI::User->new($session{user}{userId}); + $u->karma($_[0]->get("karmaPerSubmission"),$_[0]->get("namespace")." (".$_[0]->get("wobjectId") + ."/".$session{form}{sid}.")","User submission."); + } + $session{form}{sid} = $_[0]->setCollateral("USS_submission","USS_submissionId",\%hash,1,0,"USS_id",$_[0]->get("USS_id")); + my %pageVars = %{$parentPage->get}; + delete $pageVars{pageId}; + delete $pageVars{nestedSetLeft}; + delete $pageVars{nestedSetRight}; + delete $pageVars{depth}; + delete $pageVars{parentId}; + delete $pageVars{sequenceNumber}; + $pageVars{hideFromNavigation} = 1; + $pageVars{isSystem} = 1; + $pageVars{subroutine} = "viewSubmissionAsPage"; + $pageVars{subroutinePackage} = "WebGUI::Wobject::USS"; + $pageVars{subroutineParams} = "{wobjectId=>'".$_[0]->wid."',submissionId=>'".$session{form}{sid}."'}"; + $pageVars{urlizedTitle} .= "/".$_[0]->get("title")."/".$session{form}{title}; + $pageVars{urlizedTitle} .= ".".$session{setting}{urlExtension} unless ($pageVars{urlizedTitle} =~ /\./ && $session{setting}{urlExtension} ne ""); + $pageVars{urlizedTitle} = WebGUI::Page::makeUnique(WebGUI::URL::urlize($pageVars{urlizedTitle},-999)); + $newPage->set(\%pageVars); + %hash = (); + } + $hash{title} = WebGUI::HTML::filter($session{form}{title},'all') || WebGUI::International::get(16,$_[0]->get("namespace")); + $hash{USS_submissionId} = $session{form}{sid}; + $hash{dateUpdated} = WebGUI::DateTime::time(); + $hash{content} = $session{form}{body}; + $hash{userDefined1} = $session{form}{userDefined1}; + $hash{userDefined2} = $session{form}{userDefined2}; + $hash{userDefined3} = $session{form}{userDefined3}; + $hash{userDefined4} = $session{form}{userDefined4}; + $hash{userDefined5} = $session{form}{userDefined5}; + $hash{startDate} = WebGUI::DateTime::humanToEpoch($session{form}{startDate}); + $hash{endDate} = WebGUI::DateTime::humanToEpoch($session{form}{endDate}); + $hash{contentType} = $session{form}{contentType}; + $file = WebGUI::Attachment->new("",$session{form}{wid},$session{form}{sid}); + $file->save("image"); + $hash{image} = $file->getFilename if ($file->getFilename ne ""); + $file = WebGUI::Attachment->new("",$session{form}{wid},$session{form}{sid}); + $file->save("attachment"); + $hash{attachment} = $file->getFilename if ($file->getFilename ne ""); + unless ($_[0]->get("defaultStatus") eq "Approved") { + unless (WebGUI::Grouping::isInGroup($_[0]->get("groupToApprove")) ) { + $hash{status} = $_[0]->get("defaultStatus"); + WebGUI::MessageLog::addInternationalizedEntry('',$_[0]->get("groupToApprove"), + WebGUI::URL::page('func=viewSubmission&wid='.$_[0]->get("wobjectId").'&sid='. + $session{form}{sid},1),3,$_[0]->get("namespace"),'pending'); + } else { + $hash{status} = "Approved"; + } + } + my %pageVars; + $pageVars{title} = $pageVars{menuTitle} = $hash{title}; + my $page = WebGUI::Page->new($submission->{pageId}); + $page->set(\%pageVars); + $_[0]->setCollateral("USS_submission", "USS_submissionId", \%hash, 1, 0, "USS_id", $_[0]->get("USS_id")); + $_[0]->deleteCachedSubmission($hash{USS_submissionId}); + return $_[0]->www_viewSubmission(); + } else { + return WebGUI::Privilege::insufficient(); + } +} + +#------------------------------------------------------------------- +sub www_moveSubmissionDown { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->moveCollateralDown("USS_submission","USS_submissionId",$session{form}{sid}, "USS_id", $_[0]->get("USS_id")); + $_[0]->deleteAllCachedSubmissions; + return ""; +} + +#------------------------------------------------------------------- +sub www_moveSubmissionUp { + return WebGUI::Privilege::insufficient() unless ($_[0]->canEdit); + $_[0]->moveCollateralUp("USS_submission","USS_submissionId",$session{form}{sid}, "USS_id", $_[0]->get("USS_id")); + $_[0]->deleteAllCachedSubmissions; + return ""; +} + + +#------------------------------------------------------------------- +sub www_view { + $_[0]->logView() if ($session{setting}{passiveProfilingEnabled}); + my (%var, $row, $page, $p, $constraints, @submission, @content, $image, $i, $numResults, $thumbnail, $responses); + $numResults = $_[0]->get("submissionsPerPage"); + $var{"readmore.label"} = WebGUI::International::get(46,$_[0]->get("namespace")); + $var{"responses.label"} = WebGUI::International::get(57,$_[0]->get("namespace")); + $var{canPost} = WebGUI::Grouping::isInGroup($_[0]->get("groupToContribute")); + $var{"post.url"} = WebGUI::URL::page('func=editSubmission&sid=new&wid='.$_[0]->get("wobjectId")); + $var{"post.label"} = WebGUI::International::get(20,$_[0]->get("namespace")); + $var{"addquestion.label"} = WebGUI::International::get(83,$_[0]->get("namespace")); + $var{"addlink.label"} = WebGUI::International::get(89,$_[0]->get("namespace")); + $var{"search.label"} = WebGUI::International::get(364); + $var{"search.Form"} = WebGUI::Search::form({wid=>$_[0]->get("wobjectId"),func=>'view',search=>1}); + $var{"search.url"} = WebGUI::Search::toggleURL("wid=".$_[0]->get("wobjectId")."&func=view"); + $var{"rss.url"} = WebGUI::URL::page('func=viewRSS&wid='.$_[0]->get("wobjectId"),1); + $var{canModerate} = WebGUI::Grouping::isInGroup($_[0]->get("groupToApprove"),$session{user}{userId}); + WebGUI::Style::setLink($var{"rss.url"},{ rel=>'alternate', type=>'application/rss+xml', title=>'RSS' }); + if ($session{scratch}{search}) { + $numResults = $session{scratch}{numResults}; + $constraints = WebGUI::Search::buildConstraints([qw(USS_submission.username USS_submission.title USS_submission.content USS_submission.userDefined1 USS_submission.userDefined2 USS_submission.userDefined3 USS_submission.userDefined4 USS_submission.userDefined5)]); + } + if ($constraints ne "") { + $constraints = "USS_submission.status='Approved' and ".$constraints; + } else { + $constraints = "(USS_submission.status='Approved' or (USS_submission.userId=".quote($session{user}{userId})." and USS_submission.userId<>1)"; + if ($var{canModerate}) { + $constraints .= " or USS_submission.status='Pending'"; + } + $constraints .= ")"; + } + $var{"title.label"} = WebGUI::International::get(99); + $var{"thumbnail.label"} = WebGUI::International::get(52,$_[0]->get("namespace")); + $var{"date.label"} = WebGUI::International::get(13,$_[0]->get("namespace")); + $var{"date.updated.label"} = WebGUI::International::get(78,$_[0]->get("namespace")); + $var{"by.label"} = WebGUI::International::get(21,$_[0]->get("namespace")); + $var{"submission.edit.label"} = WebGUI::International::get(27,$_[0]->get("namespace")); + $p = WebGUI::Paginator->new(WebGUI::URL::page('func=view&wid='.$_[0]->get("wobjectId")),$numResults); + $p->setDataByQuery("select USS_submission.USS_submissionId, USS_submission.content, USS_submission.title, + USS_submission.userId, USS_submission.status, USS_submission.image, USS_submission.dateSubmitted, + USS_submission.dateUpdated, USS_submission.username, USS_submission.contentType, USS_submission.forumId, + USS_submission.userDefined1, USS_submission.userDefined2, USS_submission.userDefined3, + USS_submission.userDefined4, USS_submission.userDefined5, USS_submission.startDate, + USS_submission.endDate, page.urlizedTitle + from USS_submission left join page on USS_submission.pageId=page.pageId + where USS_submission.USS_id=".quote($_[0]->get("USS_Id"))." + and $constraints order by USS_submission.".$_[0]->getValue("sortBy")." ".$_[0]->getValue("sortOrder")); + $page = $p->getPageData; + $i = 0; + my $imageURL = ""; + foreach $row (@$page) { + my $cache = WebGUI::Cache->new("USS_submission_".$row->{USS_submissionId}); + my $submission = $cache->get; + unless (defined $submission) { + $page->[$i]->{content} = WebGUI::HTML::filter($page->[$i]->{content},$_[0]->get("filterContent")); + $page->[$i]->{content} =~ s/\n/\^\-\;/ unless ($page->[$i]->{content} =~ m/\^\-\;/); + $page->[$i]->{content} = WebGUI::HTML::format($page->[$i]->{content},$page->[$i]->{contentType}); + @content = split(/\^\-\;/,$page->[$i]->{content}); + if ($page->[$i]->{image} ne "") { + $image = WebGUI::Attachment->new($page->[$i]->{image},$_[0]->get("wobjectId"),$page->[$i]->{USS_submissionId}); + $thumbnail = $image->getThumbnail; + $imageURL = $image->getURL; + } else { + $thumbnail = ""; + $imageURL = ""; + } + ($responses) = WebGUI::SQL->quickArray("select count(*) from forumPost left join forumThread on + forumThread.forumThreadId=forumPost.forumThreadId where forumThread.forumId=".quote($row->{forumId}),WebGUI::SQL->getSlave); + my $quickurl = 'wid='.$_[0]->get("wobjectId").'&sid='.$page->[$i]->{USS_submissionId}.'&func='; + my $controls = deleteIcon($quickurl.'deleteSubmissionConfirm','',WebGUI::International::get(17,$_[0]->get("namespace"))) + .editIcon($quickurl.'editSubmission'); + if ($_[0]->get("sortBy") eq "sequenceNumber") { + if ($_[0]->get("sortOrder") eq "desc") { + $controls .= moveUpIcon($quickurl.'moveSubmissionDown') + .moveDownIcon($quickurl.'moveSubmissionUp'); + } else { + $controls .= moveUpIcon($quickurl.'moveSubmissionUp') + .moveDownIcon($quickurl.'moveSubmissionDown'); + } + } + my $inDateRange; + if ($page->[$i]->{startDate} < WebGUI::DateTime::time() && + $page->[$i]->{endDate} > WebGUI::DateTime::time()) + { + $inDateRange = 1; + } + else { $inDateRange = 0; } + $submission = { + "submission.id"=>$page->[$i]->{USS_submissionId}, + "submission.url"=>WebGUI::URL::gateway($page->[$i]->{urlizedTitle}), + "submission.content"=>$content[0], + "submission.content.full"=>join("\n",@content), + "submission.responses"=>$responses, + "submission.title"=>$page->[$i]->{title}, + "submission.userDefined1"=>$page->[$i]->{userDefined1}, + "submission.userDefined2"=>$page->[$i]->{userDefined2}, + "submission.userDefined3"=>$page->[$i]->{userDefined3}, + "submission.userDefined4"=>$page->[$i]->{userDefined4}, + "submission.userDefined5"=>$page->[$i]->{userDefined5}, + "submission.userId"=>$page->[$i]->{userId}, + "submission.username"=>$page->[$i]->{username}, + "submission.status"=>$page->[$i]->{status}, + "submission.thumbnail"=>$thumbnail, + "submission.image"=>$imageURL, + "submission.date"=>epochToHuman($page->[$i]->{dateSubmitted}), + "submission.date.updated"=>epochToHuman($page->[$i]->{dateUpdated}), + "submission.userProfile"=>WebGUI::URL::page('op=viewProfile&uid='.$page->[$i]->{userId}), + "submission.edit.url"=>WebGUI::URL::page($quickurl.'editSubmission'), + "submission.secondColumn"=>(($i+1)%2==0), + "submission.thirdColumn"=>(($i+1)%3==0), + "submission.fourthColumn"=>(($i+1)%4==0), + "submission.fifthColumn"=>(($i+1)%5==0), + 'submission.controls'=>$controls, + 'submission.inDateRange'=>$inDateRange + }; + $cache->set($submission,3600); + } + $submission->{"submission.currentUser"}=($session{user}{userId} eq $submission->{"submission.userId"} && $session{user}{userId} != 1); + push(@submission,$submission); + $i++; + } + $var{submissions_loop} = \@submission; + $p->appendTemplateVars(\%var); + return $_[0]->processTemplate($_[0]->get("templateId"),\%var); +} + +#------------------------------------------------------------------- +# print out RSS 2.0 feed describing the items visible on the first page +sub www_viewRSS { + $_[0]->logView() if ($session{setting}{passiveProfilingEnabled}); + my $wid = $_[0]->get("wobjectId"); + my $numResults = $_[0]->get("submissionsPerPage"); + + my $encTitle = _xml_encode($_[0]->get("title")); + my $encDescription = _xml_encode($_[0]->get("description")); + my $encUrl = _xml_encode(WebGUI::URL::page("wid=$wid")); + + my $xml = qq~ + + +$encTitle +$encUrl +$encDescription +~; + + my $res = WebGUI::SQL->read + ("select USS_submissionId, content, title, " . + "dateSubmitted, username from USS_submission " . + "where USS_id = " .quote($_[0]->get("USS_id")) . " and status='Approved' " . + "order by ".$_[0]->getValue("sortBy")." ".$_[0]->getValue("sortOrder")." limit " . $numResults,WebGUI::SQL->getSlave); + + while (my $row = $res->{_sth}->fetchrow_arrayref()) { + my ($sid, $content, $title, $dateSubmitted, $username) = + @{$row}; + + my $encUrl = _xml_encode + (WebGUI::URL::page + ("wid=$wid&func=viewSubmission&sid=$sid")); + my $encTitle = _xml_encode($title); + my $encPubDate = _xml_encode + (_get_rfc822_date($dateSubmitted)); + my $encDescription = _xml_encode($content); + + $xml .= qq~ + +$encTitle +$encUrl +$encDescription +$encUrl +$encPubDate + +~; + } + + $xml .=qq~ + + +~; + WebGUI::HTTP::setMimeType("text/xml"); + return $xml; +} + +#------------------------------------------------------------------- +sub www_viewSubmission { + my $self = shift; + my $submissionId = shift || $session{form}{sid}; + $self->logView() if ($session{setting}{passiveProfilingEnabled}); + return "" unless ($submissionId); + my ($file, @data, %var, $replies); + my $submission = $self->getCollateral("USS_submission","USS_submissionId",$submissionId); + return "" unless ($submission->{USS_submissionId}); + return "" unless ($submission->{status} eq 'Approved' || + ($submission->{userId} eq $session{user}{userId} && $session{user}{userId} != 1) || + WebGUI::Grouping::isInGroup($self->getValue("groupToApprove"))); + my $parentsPage = WebGUI::Page->new($self->get("pageId")); + my $callback = WebGUI::URL::gateway($parentsPage->get("urlizedTitle"),"func=viewSubmission&wid=".$self->wid."&sid=".$submission->{USS_submissionId}); + if ($session{form}{forumOp} ne "" && $session{form}{forumOp} ne "viewForum") { + return WebGUI::Forum::UI::forumOp({ + callback=>$callback, + title=>$submission->{title}, + forumId=>$submission->{forumId} + }); + } + WebGUI::SQL->write("update USS_submission set views=views+1 where USS_submissionId=".quote($submissionId)); + $var{title} = $submission->{title}; + $var{content} = WebGUI::HTML::filter($submission->{content},$self->get("filterContent")); + $var{content} =~ s/\^\-\;//g; + $var{content} = WebGUI::HTML::format($var{content},$submission->{contentType}); + $var{"user.label"} = WebGUI::International::get(21,$self->get("namespace")); + $var{"user.Profile"} = WebGUI::URL::page('op=viewProfile&uid='.$submission->{userId}); + $var{"user.Id"} = $submission->{userId}; + $var{"user.username"} = $submission->{username}; + $var{"date.label"} = WebGUI::International::get(13,$self->get("namespace")); + $var{"date.epoch"} = $submission->{dateSubmitted}; + $var{"date.human"} = epochToHuman($submission->{dateSubmitted}); + $var{"date.updated.label"} = WebGUI::International::get(78,$self->get("namespace")); + $var{"date.updated.human"} = epochToHuman($submission->{dateUpdated}); + $var{"date.updated.epoch"} = $submission->{dateUpdated}; + $var{"status.label"} = WebGUI::International::get(14,$self->get("namespace")); + $var{"status.status"} = status($submission->{status}); + $var{"views.label"} = WebGUI::International::get(514); + $var{"views.count"} = $submission->{views}; + $var{canPost} = WebGUI::Grouping::isInGroup($self->get("groupToContribute")); + $var{"post.url"} = WebGUI::URL::gateway($parentsPage->get("urlizedTitle"),'func=editSubmission&sid=new&wid='.$self->wid); + $var{"post.label"} = WebGUI::International::get(20,$self->get("namespace")); + @data = WebGUI::SQL->quickArray("select USS_submissionId from USS_submission + where USS_id=".quote($self->get("USS_id"))." and dateSubmitted<".quote($submission->{dateSubmitted})." + and (userId=".quote($submission->{userId})." or status='Approved') order by dateSubmitted desc",WebGUI::SQL->getSlave); + $var{"previous.more"} = ($data[0] ne ""); + if ($var{"previous.more"}) { + my $previousSubmission = $self->getCollateral("USS_submission","USS_submissionId",$data[0]); + my $previousPage = WebGUI::Page->new($previousSubmission->{pageId}); + $var{"previous.url"} = WebGUI::URL::gateway($previousPage->get("urlizedTitle")); + } + $var{"previous.label"} = WebGUI::International::get(58,$self->get("namespace")); + @data = WebGUI::SQL->quickArray("select USS_submissionId from USS_submission + where USS_id=".quote($submission->{USS_id})." and dateSubmitted>".quote($submission->{dateSubmitted})." + and (userId=".quote($submission->{userId})." or status='Approved') order by dateSubmitted asc",WebGUI::SQL->getSlave); + $var{"next.more"} = ($data[0] ne ""); + if ($var{"next.more"}) { + my $nextSubmission = $self->getCollateral("USS_submission","USS_submissionId",$data[0]); + my $nextPage = WebGUI::Page->new($nextSubmission->{pageId}); + $var{"next.url"} = WebGUI::URL::gateway($nextPage->get("urlizedTitle")); + } + $var{"next.label"} = WebGUI::International::get(59,$self->get("namespace")); + $var{canEdit} = (($submission->{userId} eq $session{user}{userId} || WebGUI::Grouping::isInGroup($self->get("groupToApprove"))) && $session{user}{userId} != 1); + $var{"delete.url"} = WebGUI::URL::gateway($parentsPage->get("urlizedTitle"),'func=deleteSubmissionConfirm&wid='.$self->wid.'&sid='.$submissionId); + $var{"delete.label"} = WebGUI::International::get(37,$self->get("namespace")); + $var{"edit.url"} = WebGUI::URL::gateway($parentsPage->get("urlizedTitle"),'func=editSubmission&wid='.$self->wid.'&sid='.$submissionId); + $var{"edit.label"} = WebGUI::International::get(27,$self->get("namespace")); + $var{canChangeStatus} = WebGUI::Grouping::isInGroup($self->get("groupToApprove"),$session{user}{userId}); + $var{"approve.url"} = WebGUI::URL::gateway($parentsPage->get("urlizedTitle"),'func=approveSubmission&wid='.$self->wid.'&sid='.$submissionId.'&mlog='.$session{form}{mlog}); + $var{"approve.label"} = WebGUI::International::get(572); + $var{"leave.url"} = WebGUI::URL::page('op=viewMessageLog'); + $var{"leave.label"} = WebGUI::International::get(573); + $var{"deny.url"} = WebGUI::URL::gateway($parentsPage->get("urlizedTitle"),'func=denySubmission&wid='.$self->wid.'&sid='.$submissionId.'&mlog='.$session{form}{mlog}); + $var{"deny.label"} = WebGUI::International::get(574); + $var{"canReply"} = ($self->get("allowDiscussion")); + $var{"reply.url"} = WebGUI::Forum::UI::formatNewThreadURL($callback,$submission->{forumId}); + $var{"reply.label"} = WebGUI::International::get(47,$self->get("namespace")); + $var{"search.url"} = WebGUI::Search::toggleURL("",$parentsPage->get("urlizedTitle")); + $var{"search.label"} = WebGUI::International::get(364); + $var{"back.url"} = WebGUI::URL::gateway($parentsPage->get("urlizedTitle")); + $var{"back.label"} = WebGUI::International::get(28,$self->get("namespace")); + $var{'userDefined1.value'} = $submission->{userDefined1}; + $var{'userDefined2.value'} = $submission->{userDefined2}; + $var{'userDefined3.value'} = $submission->{userDefined3}; + $var{'userDefined4.value'} = $submission->{userDefined4}; + $var{'userDefined5.value'} = $submission->{userDefined5}; + if ($submission->{image} ne "") { + $file = WebGUI::Attachment->new($submission->{image},$self->wid,$submissionId); + $var{"image.url"} = $file->getURL; + $var{"image.thumbnail"} = $file->getThumbnail; + } + if ($submission->{attachment} ne "") { + $file = WebGUI::Attachment->new($submission->{attachment},$self->wid,$submissionId); + $var{"attachment.box"} = $file->box; + $var{"attachment.url"} = $file->getURL; + $var{"attachment.icon"} = $file->getIcon; + $var{"attachment.name"} = $file->getFilename; + } + if ($self->get("allowDiscussion")) { + $var{"replies"} = WebGUI::Forum::UI::www_viewForum( + {callback=>$callback,title=>$submission->{title},forumId=>$submission->{forumId}}, + $submission->{forumId}); + } + return $self->processTemplate($self->get("submissionTemplateId"),\%var,"USS/Submission"); +} + + + +1; + diff --git a/lib/WebGUI/Clipboard.pm b/lib/WebGUI/Clipboard.pm new file mode 100644 index 000000000..6ee7adbee --- /dev/null +++ b/lib/WebGUI/Clipboard.pm @@ -0,0 +1,21 @@ +package WebGUI::Clipboard; + +use strict; +use WebGUI::Session; +use WebGUI::SQL; + +sub getAssetsInClipboard { + my @assets; + my $sth = WebGUI::SQL->read("select assetId, title from asset where state='clipboard' order by lastUpdated desc"); + while (my ($assetId, $title) = $sth->array) { + push(@assets, { + title => $title, + assetId => $assetId + }); + } + $sth->finish; + return \@assets; +} + +1; + diff --git a/www/extras/adminConsole/small/bg.jpg b/www/extras/adminConsole/small/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5b45cd48a4622a39992549339720ac4870358c8b GIT binary patch literal 472 zcmex=SNlY@&#gqMe#n@3Vem|sLzN?uM@N=8OOMNeHpNk>^mM#EfF$H36U#6(`*($>Pr zM$g#92xJH&CnqNlH;)7_uY{4JjG__A;Qs*zK@NuN3|!2NN(@YbjLd?J|Bo<80-eeX zbUzYcVrF3lNofi&FfubUF>xd07zKrd6%(15MJ^gTIt2zL7d1{?^Z{fFBLfpNiXjY) zAY*`1;)1~7L6s5$+I)+F2dIHbkXewyo?&m9x!N|@Yb)RGnDd{ZWa7iJ>sxotXwt6j zTk^%&?R?3Hm6oqQP1lzGGuP{NuTAmf%G~Nns~4~LTmDsD*|<~aNJ;WBwS#Tm5{70x zjAlF$$0rJ|>F7*xamki21d_Q12ikbAurf()iq(=3F(_HFykK!tS7zI*q?zlOSfws% PFH-Ulh=BN!`TtD-_2h8S literal 0 HcmV?d00001 diff --git a/www/extras/assets/poll.gif b/www/extras/assets/poll.gif new file mode 100644 index 0000000000000000000000000000000000000000..042427777e2c546aa44f16ada9568829566891ee GIT binary patch literal 2045 zcmVCG zi<+96`9>a?Rz3KhUj0%b`IS}7%*?CE%1)4}g4N;ps%@g8qQ0t``I%UUhlkz6wBEg~ z`eh&gnNj6gCA+-5`F%M0ZY}z0Amc3wIE1Bnd3pJ+bi=r``EDe7)#4U&oBmrM>_`=( z=J)DiB>QI`r{eOK*W;ty=aSXob;8d2U>^ChdZFIwXJ=w z{$v^XwSKGK>iLsVmD=U_q-XofqW)za|FwDkVji|lH1=E@$Ij9HY$3F?wD_WAiPGQt zYa~3EwE1T#`gkw-v3E0FaByQ_17wi;t91XXZSzVa17na2aGeHfmIr5&G&DDdgLV65 z8~B@B`LulbTPcy3=Xe0liTK9%V`G`lA*5{eq>hp6j^?f{)%iN3F>!Z)p z;JT%z*50?!&E{4a!^+L-nQrB$h1S#3yWZtTWNkljgH~#8(mfE5*yKE3ZvLNLgK}c} zVjS(3Sof%F^`mV6VHxtOaTsip`D`TaZ8QICApdbDu6k?6V=?oYV63yIu;uS`$JT|b zy!E4I_?lT7VSy)lpv5Z)z&sN4m08DTQEq5v)6>&TIyBYP)BtCf1Y?l@qhSGJkEGb; zRC$1N$kh3OI{twlij|-8JV+b!#gPC62p}>&=p>v4A3eFaaRbeYsY(T^ ze3Ahqfr|_XG>kR)gw`n^APh{vG+~09Dptn40Kz!I5U*?mh~4|o$*TeS0vj-ZiLl{H zbn7M<1OO%i8cQiF#C*z~Ybu*NUkW`Mz&HVHn*2~Qg|d^M`sx+%P@sTo1MV&{u4`fw z?k2q{3$zn%zyg&cJZLvw0MPQsnP!ie|X8-H?v`yqLO=9n?j z*D1xJLn#C}f(14#mjD28AduQbMT9WNgAhhIM?6vZ-~$nU_<PMBqt!rwHNX zjDDm7gbYIp{uB$322c`O6M3sjo_Fb)Du*mR;gH?T5=2`F44&Jsq1p^Fd;;4w)aci^Cf z7D?oh$_voaN5W(jiEw~AXb{lA72KkL0yxw(a11?(B%*94YGjg09ALaKL=XZZ&ucq<^K1g9{lNSeY(gHR$TtG-9kAOjp0t)P- zKs0$Ms|G4+*Z{2*<>WOMy%k_XhAtUZ5{VqUfP)XTuV|qxDi^#!!52Z0LPAJP(c3}| zhO81mA7fZyMI>CL@dX8!n5)Gka!^14%B1|ba>NzXz{483_(O;l&{RQK8mT-&#i}+u z(#RJsa6kh&dp!g88a(j-u*wq6Kr_K+aZ!*)GKbV-cr$NszyTaJea%T7YsA8XEVs-u z4JHN*=fNe1S7Adkjfmm+|;0HISj6TK~rpSRn2M7EfyiL|(PzNH$8*j@s1vr0-9?Kk(%=Cm* z6ATBUXulV|41K#{rw*pEqfB_~np*Bvi2RdjV0LyrX82WL72Vg*fBK#UC z9#T%Sp9`Ja^C_>QzGwy{K&xpY&K;Z=k z81j&aOr#euFp3x)U;~h&%pML9iUW)S1DMRDCO0{X1H>Q(#t=X$@U|C8w4ocJ2*oE? z$;wuKG8E4U##bD+7Y!hw4VvhHE_bQRT=KF5nrH(81V975kcS*U$N~wL$;@UtlLT4F b0vu#QwEI}|n%K;yHn+*mZhF(30RaFzEg!_W literal 0 HcmV?d00001 diff --git a/www/extras/assets/sqlReport.gif b/www/extras/assets/sqlReport.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9fe65a5a5d47310daf82da564fc587109842add GIT binary patch literal 2355 zcmV-33C#9KNk%w1VK4wN0Qdg@ZES3l&D_4-=eyzQqSW91|Nq3^>A=9i&dtr+wwCny z`tJAn*4EXltE$E7@jTKosG)b>h$*G$*;81;laSLkhsIIudlhexUAXY zn3$N+(b2HI!Ood$e978yO$;f47W6Rmsn%3l<(%#UAOrqN7dUlCS|pps=s4@$vDx*X6>kk?#5W$=>RZjg9p7_N3O~rnakkdU?g>?5Dc3v)SzV`TE(% zvD)eG-rnAv$IZav>gMtEwcY2nwY9#!zQV!1iS;iq)}=-0$<_?(n<1xxwV>g@uKU zjf#+ujq>{ZiOANWpPIV5v6YjOv$M0NrJ&i_*u%rX;_~&+>hEEouC1%4h=+uhmX?;n z*KlubuiNE?gMppd=6`>F#l*q2wXl|zk#ux%*y{1ldxWnJV{HK#Mhq2*?FO@-1YyvySsdRciY*|x!>nquE@Nwn&jf**XQrs+uNYX+u7gT z+2P#T@b_oF)^WYiz`nbSjElhM@2#z_t*)-Ft*x=w=Bur%addURz`wWHXOzN|Z}PJn)gW(#Oj_aTF+M zktE521xk`;!@%dEG-(|=AV3hPY9Iv5mPPdur%#_2QCeIodUOE=3f69jNQAIMpii8v!ERd%NWa8-1p@v9=b#8lU;KXl} z0-Mi;5>7%0DdHR}Uj2yGN`$|(#M5yxsZ^`V23s~Kg@ z9iRvS2@jzd(T)$jh#`nC_h`@y0@2VB!I%*&5={p&91spC^w~GdYAxsh(@RS#a0UfK zKmtjXjmQHHClc(&Nj_mL!vGzN5JAKsgDm0+ng=+8OMPj~GL{Z^n1IHnCUn}V1)vHL zN-TEBqXI4x^cBJr{OA!#I>5#M5eFHA(7`|;$~6IjFKO7BgaU+c@xriN5Hkl7BaDEE z0oshRY2?!_aITyVq> zYs4+B7FckL3x#4_aSAs6q<~E!MTC%rAcABOLMjyKDFhd=lmN>d?Reou6*fE~$2gAs zumS-$Xf6Q`OHkba7R=a^LI}QS(7__XdC9CAwU0=YpdBSZ1PT_Y4+kj13kk4+5Wukx za~xw0HK2j~PO*w7aG(?7C4!2(xENE56GLhJ~%jNpI^RN)cru)zu5K!X5GU>ab^z$ji(2mlnp6@s8e8}RXpBH&;Zf~W)*uy6=K zFai*V*aRfpU<7Tr!3~Xwq#Xuu0w;XH5solJ9Rd)5T}&a4%lLyB3{eR{Xdw&A$io48 z!OC77;FZppM|}zxi2>MQ5*si@H%x&7avVVuCs4!*%)o{qOkfvO*hL%#!hjASV-!Vr zh99!P0hIlZ2y)T^t>_?)2B6~z(|xPylCH{0uVH#8O0EWBod+r2*jfZbsSPHY9Wrs zYJml*z()$6@qo%&_Oh6*EH_Be0f}^A8B__xGU8K@U(_Q588~e{#&FsUuyzcv%|H|W Z(Akv`*!H%#&8=>C%iG@i*0%ux06S$FtT_Mx literal 0 HcmV?d00001 diff --git a/www/extras/assets/survey.gif b/www/extras/assets/survey.gif new file mode 100644 index 0000000000000000000000000000000000000000..d93163a4aa8d442378a46eda738dccf857e2af99 GIT binary patch literal 1888 zcmV-m2cP&yNk%w1VK4wN0Qdg@bXgO$vZ+Ktf@fuRPD*s-d=EA^jK5b3K|NBEig%86 zVwrLdIys8Pj0>)19PEG&-QC^!i4UY`EYolfO-Xq}J$34R3vqFCd}}FHfBvpYm0(q%xw_H#>U-y6BY_chIm%BQ3}%1(ZOvNJULoq zRw-jxH!LbgMniv>n4*SN7NVk}&u$LAyS1Bi6q`u^Iy;jk8BT;{3`a68gI^f4f)Leq z6SZIsq*oAmb%v^{s+EW~4~dD2P)uz0 zhYxgOEc}TN%F4=wijit-ZMnI*N=i>>VOw5YTs$~AxrGq_j1ECRgmyz0pmq&*VI$#l z4baZa$;idf(9i#h3e3#Rtf`$wLR&pHN}*H{qFWPfTOh!S5S332NJWIQva&rnPLp>z zL_k)=#KeAtj4~@#_Ja<5Z$pw>Bx_X{FE)vFc6obyd&b1Snw5f)k&#M9W5Q+)udJa* zMsxFp5AcEyY*`akRaCx+5Xfo`s-~E#rIsTbVn9Mhm2eNt%gHq|OW=79jcX8MVq;85 zbY)Z*RaICwHb6*3UpF|5JUfX0kq@J9OMFu&&us=`J}4detZ!FE-+Y>Z-6#Ixk}I zAt75f=>i>`*e0ZNE*q0IJsPkXOgJeVP&!8FMfga=J7AwY*eC)APLaztK)KW4uG->* zp9<6g~hjd^T7@2(Aod>MXm~hTE1cCQOi<5GD5Pf-`X83Y0-b z87p?$L})YS(kL1~0H8Qda7ZB~GdL9gDnrdqg!9uLT>r6%D|dmBG64J1NQt5H=OawJ zM2^OkMR~pVPcO|h!_OCiEaQrK=Y^pjELog_l7K2)@C+)B2vdp)W8`Pa1LTkpAt#V< zhtWU2gd@^75NdZ1cBLgM?oN`p$jyhNOfbof03>qU z27LekfIIHoVg?AX$nn4fmpo8Fh*A842PbPC*NGSa^nro`nM9L@1LRoXg9+DdGDSH8 z3N%LmkNo3GG0&{CP7=JNk;D=-Oj67oc@k949&%uFOA>2zAqzX>O!5N}jS^%{3irsd z1Ro9*^NJ!%{7{TIoeK2DAGyf?bHD`005L@hQ)KZ=GOY%}4?246VT&}j$f4v4D;&dX zqZ^p<1R9@N5B9BAeFojf&n;$081-SJi&r2_?-AzAgO#{ z3Jh-KlTQb3z<>@q6@>6ZD^bw%L=%L(`xzNsfbnq$46MR{0jzWY2p6K*^T!x_nA3y^ zP3RHHXBVh~a0mMMBeg#U=+l7!AB6CRH*atOh6qS^QG#BDJn?}R0x&T3+WNS01T(Qf zvja0Cm|_YTc{HL|(*zv<0rlEb8;}nS6s&Q>4t5`*g()ATLIzt`*bGAls{lSV18xAK z$2^1}EC38z5Rk_gY}I_T+Llwz3LvVqqYNM+Urhl4y0A5b9%l={iUFzn!@$)qfXs?M zZHIn^#ygpj#|I!s-TNx6FrbYAyst9&2Z98`mI|my!aUBs`{M)_&Nv}8^n@b-j9zu1 zAp!xD@7z22=KEtk3?Cq{v|ePmkFXojvz#`ZQ9i1*?Fa-AL5CZ4`D^|ff zscFL#o^S&3e5M63bO9O1F@qpJ;5h&eZxvWLfhTB@kI!`w4ET5tWW0wk2zI~->Nvp( z)KLK~d?0`OID>#aN^k)|sDgxAsK6|Ac!C_TKm-W50_i$M1rFc?0fb<|AzqM!9K1jf aQpf=ET7`^w1YrOJSVj=)(T$x11OPiYfCqj6 literal 0 HcmV?d00001 diff --git a/www/extras/draggable.css b/www/extras/draggable.css new file mode 100644 index 000000000..fba7174dc --- /dev/null +++ b/www/extras/draggable.css @@ -0,0 +1,48 @@ +div.dragable:hover { + border: 1px dashed #aaaaaa; +} +.dragable{ + position: relative; + border: 1px dotted #cccccc; +} +.dragTrigger{ + position: absolute; + cursor: move; + right: 0px; + top: 0px; +} +.dragging{ + position: relative; + cursor: hand; + z-index: 2000; +} +.draggedOverTop{ + position: relative; + border: 1px dotted #aaaaaa; + border-top: 8px #aaaaaa dotted; +} +.draggedOverBottom { + position: relative; + border: 1px dotted #aaaaaa; + border-bottom: 8px #aaaaaa dotted; +} +.hidden{ + display: none; +} +.blank { + position: relative; + cursor: hand; + background-color: white; +} +.blankOver { + position: relative; + cursor: hand; + background-color: black; +} +.empty { + position: relative; + padding: 25px; + width: 50px; + height: 100px; +} +