Merge commit 'v7.10.15' into 8
Conflicts: docs/gotcha.txt docs/previousVersion.sql docs/templates.txt lib/WebGUI.pm lib/WebGUI/Asset.pm lib/WebGUI/Asset/Event.pm lib/WebGUI/Asset/File.pm lib/WebGUI/Asset/MapPoint.pm lib/WebGUI/Asset/RichEdit.pm lib/WebGUI/Asset/Sku/Product.pm lib/WebGUI/Asset/Snippet.pm lib/WebGUI/Asset/Story.pm lib/WebGUI/Asset/Template.pm lib/WebGUI/Asset/Template/TemplateToolkit.pm lib/WebGUI/Asset/Wobject/Calendar.pm lib/WebGUI/Asset/Wobject/Carousel.pm lib/WebGUI/Asset/Wobject/Collaboration.pm lib/WebGUI/Asset/Wobject/Dashboard.pm lib/WebGUI/Asset/Wobject/DataForm.pm lib/WebGUI/Asset/Wobject/Folder.pm lib/WebGUI/Asset/Wobject/Map.pm lib/WebGUI/Asset/Wobject/Search.pm lib/WebGUI/Asset/Wobject/Shelf.pm lib/WebGUI/Asset/Wobject/StockData.pm lib/WebGUI/Asset/Wobject/StoryTopic.pm lib/WebGUI/Asset/Wobject/SyndicatedContent.pm lib/WebGUI/Asset/Wobject/Thingy.pm lib/WebGUI/Asset/Wobject/WeatherData.pm lib/WebGUI/AssetClipboard.pm lib/WebGUI/AssetCollateral/DataForm/Entry.pm lib/WebGUI/AssetExportHtml.pm lib/WebGUI/AssetLineage.pm lib/WebGUI/AssetMetaData.pm lib/WebGUI/AssetTrash.pm lib/WebGUI/AssetVersioning.pm lib/WebGUI/Auth.pm lib/WebGUI/Cache/CHI.pm lib/WebGUI/Content/AssetManager.pm lib/WebGUI/Fork/ProgressBar.pm lib/WebGUI/Form/JsonTable.pm lib/WebGUI/Form/TimeField.pm lib/WebGUI/Form/Zipcode.pm lib/WebGUI/Group.pm lib/WebGUI/International.pm lib/WebGUI/Macro/AssetProxy.pm lib/WebGUI/Macro/FileUrl.pm lib/WebGUI/Operation/SSO.pm lib/WebGUI/Operation/User.pm lib/WebGUI/Role/Asset/Subscribable.pm lib/WebGUI/Shop/Cart.pm lib/WebGUI/Shop/Transaction.pm lib/WebGUI/Shop/TransactionItem.pm lib/WebGUI/Test.pm lib/WebGUI/URL/Content.pm lib/WebGUI/URL/Uploads.pm lib/WebGUI/User.pm lib/WebGUI/Workflow/Activity/ExtendCalendarRecurrences.pm lib/WebGUI/Workflow/Activity/SendNewsletters.pm lib/WebGUI/i18n/English/Asset.pm lib/WebGUI/i18n/English/WebGUI.pm sbin/installClass.pl sbin/rebuildLineage.pl sbin/search.pl sbin/testEnvironment.pl t/Asset/Asset.t t/Asset/AssetClipboard.t t/Asset/AssetLineage.t t/Asset/AssetMetaData.t t/Asset/Event.t t/Asset/File.t t/Asset/File/Image.t t/Asset/Post/notification.t t/Asset/Sku.t t/Asset/Story.t t/Asset/Template.t t/Asset/Wobject/Collaboration/templateVariables.t t/Asset/Wobject/Collaboration/unarchiveAll.t t/Asset/Wobject/Shelf.t t/Auth.t t/Macro/EditableToggle.t t/Macro/FilePump.t t/Shop/Cart.t t/Shop/Transaction.t t/Storage.t t/User.t t/Workflow.t
This commit is contained in:
commit
277faae8a1
783 changed files with 32041 additions and 25495 deletions
|
|
@ -1,4 +1,163 @@
|
|||
7.10.15
|
||||
- fixed #12117: Thingy - www_searchViaAjax broken
|
||||
- fixed #12116: JsonTable form control needs i18n
|
||||
- fixed #12102: User profiling field extras information
|
||||
- fixed #12106: CalendarUpdateFeeds activity does not handle time zones correctly
|
||||
- fixed #11213: Gooey on the Go format problem
|
||||
- mark makeUrlCompliant as deprecated.
|
||||
- fixed #12059: WebGUI::Asset::Wobject::Map - Set Default Viewing Area button does not work.
|
||||
- added: Setting MapPoint locations via address.
|
||||
- added: Make Thing data searchable
|
||||
- added: AssetProxy like macro for Thing data, ViewThingData
|
||||
|
||||
7.10.14
|
||||
- fixed #12094: Cannot enter in Macros in URLs inside TinyMCE.
|
||||
- rfe #12093: Remotely stored photos for Story assets
|
||||
- fixed #12088: Organization left out of transaction
|
||||
- fixed #12095: Shop admin screen has JS errors?
|
||||
- fixed #12097: GroupManager pop-up not working
|
||||
- fixed #12098: Missing template breaks WebGUI password recovery by email
|
||||
- remove extra Underground style templates that were part of the 7.10.13 upgrade.
|
||||
- fixed #12056: Adding a Thing always creates a table
|
||||
- fixed #11955: Rich Text Editor for Forums doesn't work on the iPad
|
||||
- fixed #11992: html source editor
|
||||
- fixed #12100: Carousel and/or RichEdit
|
||||
- fixed #12103: PayPalStd driver fails occasionally
|
||||
- rfe #12105: Make shortcuts related for export purposes
|
||||
- rfe #12108: Mail to Group preference field
|
||||
- fixed #12107: Viewing an individual transaction item fails
|
||||
- fixed #12104: Calendar iCal feed status and lastUPdated fields missing
|
||||
|
||||
7.10.13
|
||||
- added #12079: Carousel Auto Play
|
||||
- fixed #12075: Underground Style - Search does not search
|
||||
- fixed #12084: Greenportal links are sometimes white on white
|
||||
- rfe #618: Syndicated Content Asset: Make images in the downloaded RSS-feeds available in the template.
|
||||
- fixed #12086: Shop Billing Address Unpopulated
|
||||
- Snippets can now select a template parser (instead of being restricted to the configured default)
|
||||
- fixed #12081: addrees not in addressbook after user change in session
|
||||
- fixed #12089: Cannot refund item in transaction if the sku no longer exists.
|
||||
- rfe #12085: Export Related Story Topics
|
||||
- fixed #12076: Paginator shows no results with cached page index
|
||||
- fixed #12087: Extend WebGUI tests to check template attachments
|
||||
- fixed #12091: Survey Statistical Overview display
|
||||
|
||||
7.10.12
|
||||
- fixed #12072: Product, related and accessory assets
|
||||
- added: Add Asset Dashlets to Dashboard
|
||||
- added: Required and Static properties to assets in a dashboard.
|
||||
- added: Caching to StockData and WeatherData asset.
|
||||
- added: LastModifiedBy macro
|
||||
- added: Group Manager form control
|
||||
- fixed #12050: Thing query caching #1
|
||||
- added: Let CHI cache request $dbh via an "args" : [ "dbh" ] cache conf
|
||||
- added: lineage increment_step and increment_offset for multi-master DB clusters
|
||||
- Change Group INSERT to REPLACE to prevent merge problems in multi-master DB clusters
|
||||
- added #12078: Add alt tag to default Image template
|
||||
- fixed #12077: Carousel update not possible
|
||||
- Try to reconnect to MySQL if sbin/rebuildLineage.pl takes too long
|
||||
|
||||
7.10.11
|
||||
- fixed #12057: WebGUI::Search, assetIds search clause
|
||||
- fixed #12051: Prevent Proxy Caching Breaks Edit/Add Thing
|
||||
- fixed #12053: Thingy: View Thing Data
|
||||
- fixed #12062: Thingy: column headers missing from exported file
|
||||
- fixed #12063: Return URL from export doesn't work on non-default Thingy's
|
||||
- fixed #12054: Thingy: Time fields and formatting
|
||||
- fixed #12061: TimeField form plugin doesn't work with all names.
|
||||
- fixed #12055: Thingy pagination breaks after editing data
|
||||
- fixed #12066: Thingy CSV export overrides ExportHTML
|
||||
- fixed #12068: www_editSave not strict enough in permission checks
|
||||
- fixed #12060: Thingy: importAssetCollateralData and asset checking
|
||||
|
||||
7.10.10
|
||||
- fixed #12035: Story Manager - make keywords from Story view work
|
||||
- fixed #12042: userDefined variables have no template variable help
|
||||
- fixed #12045: Job listing template, missing summary
|
||||
- fixed #12043: Collaboration Systems don't pull mail that fast!
|
||||
- fixed #12044: Spectre::Cron and non-integer time units
|
||||
- fixed #12046: Empty AssetProxy creates infinite loop (Dale Trexel)
|
||||
- Metadata is now versioned
|
||||
- Metadata fields can be restricted by asset class
|
||||
- fixed #12049: gotcha: 7.10.9 needs perl > 5.8.8
|
||||
- fixed #12048: Asset Manager Search
|
||||
|
||||
7.10.9
|
||||
- fixed #12030: Calendar Feed Time Zone Issue
|
||||
- fixed: Permission on who can create a shortcut of an Asset.
|
||||
- fixed #12032: deleting forum posts
|
||||
- fixed #12033: scratch variable problems during export
|
||||
- fixed: Underground label style forces radio buttons and check boxes to render vertically.
|
||||
- fixed #11704: JavaScript::Packer, HTML::Packer, and CSS::Packer use $& variable
|
||||
- fixed #12038: Incorrect caching of groups with 0 second cache setting (Dale Trexel)
|
||||
|
||||
7.10.8
|
||||
- rfe #12016 for the top story as well
|
||||
- fixed #12029: issue with keywords
|
||||
- fixed #11965: Friend Manager only shows 15 people
|
||||
- fixed #12023: International URLs of aattachments & files in folder
|
||||
- fixed #12024: Copied Collaboration System re-sends subscription mail
|
||||
- fixed #12027: Wiki Search and Keyword security, pages visible to visitors when wiki is restricted.
|
||||
- fixed #12020: Event Recurrend end date field is always active
|
||||
- fixed #11991: calendar view event formatting
|
||||
- fixed #11990: calendar event view
|
||||
- fixed #12028: i18n Account_Shop
|
||||
- fixed #11989: calendar list view
|
||||
- fixed #12024: Copied Collaboration System re-sends subscription mail
|
||||
|
||||
7.10.7
|
||||
- rfe #10521: Use monospaced font in template edit textarea
|
||||
- rfe #12016: add more functionality to story_loop
|
||||
- Added a Preview button the the Template asset's edit page
|
||||
- fixed #12009: Export JS errors in IE7
|
||||
- added #11968: use the language override in the registration form (Jukka Raimovaara / Mentalhouse Oy)
|
||||
- Changed Carousel to use TinyMCE with WebGUI plugins
|
||||
- fixed #11984: No JS allows invalid dates in Event asset
|
||||
- fixed bug in shopping cart where in some cases the shipper selectbox would
|
||||
be empty ( Martin Kamerbeek / Oqapi )
|
||||
- fixed bug where an invalid address ids would prevent a customer from ever
|
||||
checking out again ( Martin Kamerbeek / Oqapi )
|
||||
- fixed #11997: maximumAssets in config is ignored (Arjan Widlak / United Knowledge)
|
||||
- fixed #11998: maximumAssets affects not only new assets, but als prevents editing existing assets if maximum is reached
|
||||
- fixed #12003: WebGUI::User->delete leaves around cache data
|
||||
- fixed #12007: Hardcoded js in cart view ( Martin Kamerbeek / Oqapi )
|
||||
- fixed #12010: Related URLs are not copied for events created through recurrence
|
||||
- fixed #12012: WebGUI Account system does not present login to visitors for proper redirect
|
||||
- fixed #12015: Thingy: Custom 'File' form fields get deleted upon save
|
||||
- fixed #11994: recurring calendar entries
|
||||
- fixed #11995: recurring calendar entries in trash
|
||||
- fixed #11986: Finance::Quote can give invalid dates to StockData asset
|
||||
- fixed #12001: Shelf product import mangles price
|
||||
- fixed #11945: Slow SQL access for duplicate e-mail address lookups
|
||||
- fixed #11960: Billing address mandatory fields not specified
|
||||
- fixed #11975: Cannot paste threads: "Cannot call method isa()"
|
||||
- fixed #11976: Use Container URL in search gives user Permission Denied
|
||||
- fixed #11985: Search.pl should warn on bad assets
|
||||
- fixed #12008: Activity CleanLoginHistory is too slow
|
||||
- fixed #12004: SSO operation vulnerable to session fixation attacks
|
||||
- fixed #11996: Mandatory field in Thingy saves empty
|
||||
- fixed #11987: Map displays white text on white background
|
||||
- fixed #11988: Dataform list view doesn't allow moving fields
|
||||
- fixed #11989: Calendar list view isn't uniform and missing fields
|
||||
- fixed: Calendar list view sections don't use timezones
|
||||
|
||||
7.10.6
|
||||
- fixed #11974: Toolbar icons unclickable in Webkit using HTML5
|
||||
- fixed #11978: Pasting links into TinyMCE
|
||||
- fixed #11980: DataForm broken
|
||||
- fixed #11971: Still subscribed to forums you no longer have privilege to view
|
||||
|
||||
7.10.5
|
||||
- fixed #11950: Username set to 0 when edit user
|
||||
- fixed #11946: Double time zone correction when addding an event
|
||||
- fixed #11952: Navigation template help error
|
||||
- fixed #11951: Privacy setting of new profile field
|
||||
- fixed #11947: PayPal does not register in-state sales taxes
|
||||
- fixed #11956: ExtendCalenderRecurrence bug
|
||||
- fixed #11965: FriendManager pagination and getUsersNotIn
|
||||
- fixed #11964: files show in trash and in old revisions
|
||||
- fixed #11954: Can't clear packed head tags
|
||||
- fixed #11957: finBrokenAsset --fix does not fix per se
|
||||
|
||||
7.10.4
|
||||
- Added WebGUI::Fork api
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ Contributing Developers..............C.J. Adams-Collier / <cjac@colliertech.org>
|
|||
Stephen Opal / Plain Black
|
||||
Tavis Parker / Plain Black
|
||||
Daniel Quinlan
|
||||
Jukka Raimovaara / Axxion Oy
|
||||
Jukka Raimovaara / Mentalhouse Oy
|
||||
Alan Ritari / DonorWare
|
||||
Hal Roberts / Harvard
|
||||
Luke Robinson / Orchard Solutions
|
||||
|
|
@ -83,6 +83,7 @@ Contributing Developers..............C.J. Adams-Collier / <cjac@colliertech.org>
|
|||
Bernd Kalbfuß-Zimmermann
|
||||
Tabitha Zipperer / Plain Black
|
||||
Rory Zweistra / Oqapi
|
||||
Chris Hanson / Plain Black
|
||||
|
||||
The following are people/companies who didn't directly contribute
|
||||
to WebGUI, but whose work has made WebGUI possible:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,50 @@ save you many hours of grief.
|
|||
Account Macro template
|
||||
Admin Toggle Macro template
|
||||
|
||||
7.10.15
|
||||
--------------------------------------------------------------------
|
||||
* WebGUI now depends on Geo::Coder::Googlev3 for it's Map asset
|
||||
|
||||
7.10.13
|
||||
--------------------------------------------------------------------
|
||||
* WebGUI now depends on XML::FeedPP::MediaRSS.
|
||||
|
||||
7.10.12
|
||||
--------------------------------------------------------------------
|
||||
* The Dashboard has been extended to include Asset Dashlets. This gives
|
||||
Assets fine control over which properties can be extended and which can't.
|
||||
Assets in the Dashboard can be set to be required, which prevents them from
|
||||
being deleted, and fixed, which prevents them from moved.
|
||||
* The StockData and WeatherData assets now include cache settings to reduce
|
||||
server side load. The browser interface for the StockData asset still does
|
||||
real time lookups.
|
||||
* A new macro has been added, LastModifiedBy. This returns the username of
|
||||
the user who last modified an Asset. If the asset in question is a Page
|
||||
Layout or Folder, then querying that asset will also check all children.
|
||||
* The Group form control has been extended to add a simple interface for
|
||||
adding new Groups and changing their membership.
|
||||
|
||||
7.10.11
|
||||
--------------------------------------------------------------------
|
||||
* Modified TimeField, now provides popupless immediate validation with
|
||||
an alert if the value is not interpretable when the user leaves that field
|
||||
|
||||
7.10.10
|
||||
--------------------------------------------------------------------
|
||||
* Asset metadata is now versioned.
|
||||
|
||||
* The updated versions of HTML::Packer, JavaScript::Packer and CSS::Packer
|
||||
added for 7.10.9 require perl 5.8.9 or higher to run.
|
||||
|
||||
7.10.9
|
||||
--------------------------------------------------------------------
|
||||
* WebGUI now depends on Data::ICal for making and reading iCal feeds
|
||||
for the Calendar.
|
||||
|
||||
* WebGUI now depends on updated versions of the HTML::Packer, JavaScript::Packer and
|
||||
CSS::Packer modules. These new versions have much better performance than their
|
||||
earlier incarnations.
|
||||
|
||||
7.10.4
|
||||
--------------------------------------------------------------------
|
||||
* WebGUI now depends on Monkey::Patch for doing sanely scoped
|
||||
|
|
|
|||
2525
docs/previousVersion.sql
Normal file
2525
docs/previousVersion.sql
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,7 @@
|
|||
This is a running list of template changes made during upgrades. If you have copied the default
|
||||
templates, you will need to apply these changes manually to your copies.
|
||||
|
||||
<<<<<<< HEAD
|
||||
|
||||
7.8.0
|
||||
|
||||
|
|
@ -12,6 +13,51 @@ templates, you will need to apply these changes manually to your copies.
|
|||
toggle.url => toggle_url
|
||||
toggle.text => toggle_text
|
||||
|
||||
7.10.15
|
||||
* Gallery CSS - root/import/gallery-templates/gallery.css
|
||||
Remove float:left on .wgAlbum.
|
||||
* Email Receipt (Default) - shopping-cart-collateral-items/email-receipt-default
|
||||
Added code to prevent links to items with bad skus to both templates.
|
||||
|
||||
7.10.14
|
||||
* My Purchases Detail (Default) - shopping-cart-collateral-items/my-purchases-detail-default
|
||||
* Email Receipt (Default) - shopping-cart-collateral-items/email-receipt-default
|
||||
Added code to prevent links to items with bad skus to both templates.
|
||||
|
||||
7.10.13
|
||||
* Cart (Default) - default-shopping-cart-template
|
||||
In 7.10.7, hardcoded JavaScript was removed from the Cart code and migrated to the Cart template. The list of Javascript and files which are needed is below. Please add it to the Attachments or Extra Head Tags for any customized Cart templates.
|
||||
^Extras(/yui/build/yahoo-dom-event/yahoo-dom-event.js);
|
||||
^Extras(/yui/build/json/json-min.js);
|
||||
^Extras(/yui/build/connection/connection-min.js);
|
||||
^Extras(/underscore/underscore-min.js);
|
||||
^Extras(/shop/cart.js);
|
||||
|
||||
7.10.11
|
||||
* Default View Thing Data Template - templates/thingy-default-view-thing
|
||||
Change how the title is rendered. If no fields are set to be displayed in the title, show the internationalized word View.
|
||||
If fields are set, then display the viewScreenTitle variable instead.
|
||||
|
||||
7.10.9
|
||||
|
||||
* Underground style template CSS - style-underground/css/underground-webgui-css
|
||||
Make labels render inline.
|
||||
|
||||
7.10.8
|
||||
|
||||
* Friend Manager view template - root/import/account/friendmanager/view
|
||||
Add a div to hold the pagination.
|
||||
|
||||
* Event Template - root/import/calendar-templates/default-calendar-event
|
||||
Add foreground/font color to the CSS for the details.
|
||||
Move border property to the table instead of assigning it to the body of the page.
|
||||
|
||||
* EU VAX Template
|
||||
Internationalized the text in the template.
|
||||
|
||||
* Calendar Event List template - root/import/calendar-templates/default-calendar-list-view
|
||||
Only display changes in new months, not months AND years AND days.
|
||||
|
||||
7.10.4
|
||||
|
||||
* DataForm email template - default_email
|
||||
|
|
|
|||
BIN
docs/upgrades/packages-7.10.10/job_listing.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.10/job_listing.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.10.12/image.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.12/image.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.10.12/root_import_dashboard.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.12/root_import_dashboard.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.10.13/default_search2.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.13/default_search2.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.10.13/greenportal.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.13/greenportal.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.10.13/style-underground.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.13/style-underground.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.10.15/home_map_map-templates.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.15/home_map_map-templates.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.10.7/data_list.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.7/data_list.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.10.9/style-underground.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.9/style-underground.wgpkg
Normal file
Binary file not shown.
123
docs/upgrades/upgrade_7.10.10-7.10.11.pl
Normal file
123
docs/upgrades/upgrade_7.10.10-7.10.11.pl
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.10.11';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
189
docs/upgrades/upgrade_7.10.11-7.10.12.pl
Normal file
189
docs/upgrades/upgrade_7.10.11-7.10.12.pl
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.10.12';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
installNewDashboardTables($session);
|
||||
addStockDataCacheColumn($session);
|
||||
addWeatherDataCacheColumn($session);
|
||||
addLastModifiedByMacro($session);
|
||||
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub addLastModifiedByMacro {
|
||||
my $session = shift;
|
||||
print "\tAdd LastModifiedBy macro to the config file... " unless $quiet;
|
||||
# and here's our code
|
||||
$session->config->addToHash('macros', 'LastModifiedBy', 'LastModifiedBy');
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub installNewDashboardTables {
|
||||
my $session = shift;
|
||||
print "\tInstall new Dashboard tables... " unless $quiet;
|
||||
$session->db->write(<<EOSQL);
|
||||
CREATE TABLE IF NOT EXISTS Dashboard_dashlets (
|
||||
dashboardAssetId CHAR(22) BINARY,
|
||||
dashletAssetId CHAR(22) BINARY,
|
||||
isStatic BOOLEAN,
|
||||
isRequired BOOLEAN,
|
||||
PRIMARY KEY (dashboardAssetId, dashletAssetId)
|
||||
) TYPE=MyISAM CHARSET=utf8;
|
||||
EOSQL
|
||||
$session->db->write(<<EOSQL);
|
||||
CREATE TABLE IF NOT EXISTS Dashboard_userPrefs (
|
||||
dashboardAssetId CHAR(22) BINARY,
|
||||
dashletAssetId CHAR(22) BINARY,
|
||||
userId CHAR(22) BINARY,
|
||||
isMinimized BOOLEAN,
|
||||
properties LONGTEXT,
|
||||
PRIMARY KEY (dashboardAssetId, dashletAssetId, userId)
|
||||
) TYPE=MyISAM CHARSET=utf8;
|
||||
EOSQL
|
||||
# and here's our code
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub addStockDataCacheColumn {
|
||||
my $session = shift;
|
||||
print "\tAdd cache column for the StockData asset... " unless $quiet;
|
||||
$session->db->write(<<EOSQL);
|
||||
ALTER TABLE StockData ADD COLUMN cacheTimeout BIGINT
|
||||
EOSQL
|
||||
# and here's our code
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub addWeatherDataCacheColumn {
|
||||
my $session = shift;
|
||||
print "\tAdd cache column for the WeatherData asset... " unless $quiet;
|
||||
$session->db->write(<<EOSQL);
|
||||
ALTER TABLE WeatherData ADD COLUMN cacheTimeout BIGINT
|
||||
EOSQL
|
||||
# and here's our code
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
165
docs/upgrades/upgrade_7.10.12-7.10.13.pl
Normal file
165
docs/upgrades/upgrade_7.10.12-7.10.13.pl
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.10.13';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
addAutoPlayToCarousel( $session );
|
||||
addProcessorDropdownToSnippet( $session );
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add AutoPlay fields to the Carousel
|
||||
sub addAutoPlayToCarousel {
|
||||
my $session = shift;
|
||||
print "\tAdding Auto Play to Carousel... " unless $quiet;
|
||||
$session->db->write(
|
||||
"ALTER TABLE Carousel ADD COLUMN autoPlay INT, ADD COLUMN autoPlayInterval INT"
|
||||
);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub addProcessorDropdownToSnippet {
|
||||
my $session = shift;
|
||||
my $db = $session->db;
|
||||
print "\tUpdating the Snippet table to add templateProcessor option..."
|
||||
unless $quiet;
|
||||
|
||||
my $rows = $db->buildArrayRefOfHashRefs(q{
|
||||
select assetId, revisionDate from snippet where processAsTemplate = 1
|
||||
});
|
||||
|
||||
$db->write(q{
|
||||
alter table snippet
|
||||
drop column processAsTemplate,
|
||||
add column templateParser char(255)
|
||||
});
|
||||
|
||||
my $default = $session->config->get('defaultTemplateParser');
|
||||
|
||||
for my $row (@$rows) {
|
||||
$db->write(q{
|
||||
update snippet
|
||||
set templateParser = ?
|
||||
where assetId = ? and revisionDate = ?
|
||||
}, [ $default, $row->{assetId}, $row->{revisionDate} ]);
|
||||
}
|
||||
|
||||
print "Done!\n";
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
191
docs/upgrades/upgrade_7.10.13-7.10.14.pl
Normal file
191
docs/upgrades/upgrade_7.10.13-7.10.14.pl
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
use WebGUI::Asset::Wobject::Calendar;
|
||||
|
||||
|
||||
my $toVersion = '7.10.14';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
addOrganizationsToTransaction($session);
|
||||
removeDuplicateUndergroundStyleTemplates($session);
|
||||
addRichEditToCarousel($session);
|
||||
fixBadCalendarFeedStatus($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub fixBadCalendarFeedStatus {
|
||||
my $session = shift;
|
||||
print "\tFix the name of the iCal status field in all Calendar assets... " unless $quiet;
|
||||
# and here's our code
|
||||
my $fetch_calendar = WebGUI::Asset::Wobject::Calendar->getIsa($session);
|
||||
my $sth = $session->db->read('select assetId, revisionDate from Calendar');
|
||||
CALENDAR: while (my ($assetId, $revisionDate) = $sth->array) {
|
||||
my $calendar = eval {WebGUI::Asset->new($session, $assetId, 'WebGUI::Asset::Wobject::Calendar', $revisionDate)};
|
||||
next CALENDAR if !$calendar;
|
||||
FEED: foreach my $feed ( @{ $calendar->getFeeds } ) {
|
||||
my $status = delete $feed->{status};
|
||||
if (!exists $feed->{lastResult}) {
|
||||
$feed->{lastResult} = $status;
|
||||
}
|
||||
if (!exists $feed->{lastUpdated}) {
|
||||
$feed->{lastUpdated} = 'never';
|
||||
}
|
||||
$calendar->setFeed($feed->{feedId}, $feed);
|
||||
}
|
||||
}
|
||||
$sth->finish;
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub addOrganizationsToTransaction {
|
||||
my $session = shift;
|
||||
print "\tAdd organization fields to the addresses stored in the Transaction and TransactionItem... " unless $quiet;
|
||||
# and here's our code
|
||||
$session->db->write('ALTER TABLE transaction ADD COLUMN shippingOrganization CHAR(35)');
|
||||
$session->db->write('ALTER TABLE transaction ADD COLUMN paymentOrganization CHAR(35)');
|
||||
$session->db->write('ALTER TABLE transactionItem ADD COLUMN shippingOrganization CHAR(35)');
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub removeDuplicateUndergroundStyleTemplates {
|
||||
my $session = shift;
|
||||
print "\tRemove duplicate Underground Style templatess that were mistakenly added during the 7.10.13 upgrade... " unless $quiet;
|
||||
# and here's our code
|
||||
ASSETID: foreach my $assetId(qw/IeFioyemW2Ov-hFGFwD75A niYg8Da1sULTQnevZ8wYpw/) {
|
||||
my $asset = WebGUI::Asset->newByDynamicClass($session, $assetId);
|
||||
next ASSETID unless $asset;
|
||||
$asset->purge; ##Kill it, crush it, grind its bits into dust.
|
||||
}
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub addRichEditToCarousel {
|
||||
my $session = shift;
|
||||
print "\tAdd RichEdit option to the Carousel... " unless $quiet;
|
||||
# and here's our code
|
||||
$session->db->write('ALTER TABLE Carousel ADD COLUMN richEditor CHAR(22) BINARY');
|
||||
$session->db->write(q!update Carousel set richEditor='PBrichedit000000000001'!);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
160
docs/upgrades/upgrade_7.10.14-7.10.15.pl
Normal file
160
docs/upgrades/upgrade_7.10.14-7.10.15.pl
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
use WebGUI::AssetAspect::Installable;
|
||||
use WebGUI::Asset::MapPoint;
|
||||
use WebGUI::Asset::Wobject::Thingy;
|
||||
|
||||
my $toVersion = '7.10.15';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
alterAssetIndexTable($session);
|
||||
reindexAllThingys($session);
|
||||
WebGUI::AssetAspect::Installable::upgrade("WebGUI::Asset::MapPoint",$session);
|
||||
addRenderThingDataMacro($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
sub addRenderThingDataMacro {
|
||||
my $session = shift;
|
||||
print "\tAdd the new RenderThingData macro to the site config... " unless $quiet;
|
||||
$session->config->addToHash('macros', 'RenderThingData', 'RenderThingData');
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub alterAssetIndexTable {
|
||||
my $session = shift;
|
||||
print "\tExtend the assetIndex table so we can search things other than assets... " unless $quiet;
|
||||
$session->db->write(<<EOSQL);
|
||||
alter table assetIndex
|
||||
drop primary key,
|
||||
add column subId char(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||
add primary key (assetId, url)
|
||||
EOSQL
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub reindexAllThingys {
|
||||
my $session = shift;
|
||||
print "\tReindex all Thingys... " unless $quiet;
|
||||
my $get_thingy = WebGUI::Asset::Wobject::Thingy->getIsa($session);
|
||||
THINGY: while (1) {
|
||||
my $thingy = eval { $get_thingy->() };
|
||||
next THINGY if Exception::Class->caught();
|
||||
last THINGY unless $thingy;
|
||||
$thingy->indexContent;
|
||||
}
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
144
docs/upgrades/upgrade_7.10.5-7.10.6.pl
Normal file
144
docs/upgrades/upgrade_7.10.5-7.10.6.pl
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
use WebGUI::Workflow;
|
||||
|
||||
my $toVersion = '7.10.6';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
addCollaborationSubscriptionWorkflow($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub addCollaborationSubscriptionWorkflow {
|
||||
my $session = shift;
|
||||
print "\tAdd Collaboration System subscriber validation workflow... " unless $quiet;
|
||||
# and here's our code
|
||||
$session->config->addToArray('workflowActivities/WebGUI::Asset', qw/WebGUI::Workflow::Activity::UpdateAssetSubscribers/);
|
||||
my $workflow = WebGUI::Workflow->create($session,
|
||||
{
|
||||
mode => 'parallel',
|
||||
enabled => 1,
|
||||
title => 'Update CS Subscription members',
|
||||
description => "This workflow will be run whenever the viewing permissions are changed on an Asset. It will update the members of the subscription group, and remove members who can no longer view the Asset.",
|
||||
type => 'WebGUI::Asset',
|
||||
},
|
||||
'xR-_GRRbjBojgLsFx3dEMA'
|
||||
);
|
||||
$workflow->addActivity('WebGUI::Workflow::Activity::UpdateAssetSubscribers');
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
163
docs/upgrades/upgrade_7.10.6-7.10.7.pl
Normal file
163
docs/upgrades/upgrade_7.10.6-7.10.7.pl
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.10.7';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
addEmailIndexToProfile( $session );
|
||||
addIndecesToUserLoginLog($session);
|
||||
addSSOOptionToConfigs($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add an index to the userProfileData table for email lookups
|
||||
sub addSSOOptionToConfigs {
|
||||
my $session = shift;
|
||||
print "\tAdding SSO flag to config file to enable the feature... " unless $quiet;
|
||||
$session->config->set('enableSimpleSSO', 0);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add an index to the userProfileData table for email lookups
|
||||
sub addEmailIndexToProfile {
|
||||
my $session = shift;
|
||||
print "\tAdding index to email column on userProfileData table... " unless $quiet;
|
||||
# and here's our code
|
||||
$session->db->write( "ALTER TABLE userProfileData ADD INDEX email ( email )" );
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub addIndecesToUserLoginLog {
|
||||
my $session = shift;
|
||||
print "\tAdd indeces to userLoginLog to speed cleanup... " unless $quiet;
|
||||
# and here's our code
|
||||
my $sth = $session->db->read('SHOW CREATE TABLE userLoginLog');
|
||||
my ($field,$stmt) = $sth->array;
|
||||
$sth->finish;
|
||||
unless ($stmt =~ m/KEY `userId`/i) {
|
||||
$session->db->write("ALTER TABLE userLoginLog ADD INDEX userId (userId)");
|
||||
}
|
||||
unless ($stmt =~ m/KEY `timeStamp`/i) {
|
||||
$session->db->write("ALTER TABLE userLoginLog ADD INDEX timeStamp (timeStamp)");
|
||||
}
|
||||
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
123
docs/upgrades/upgrade_7.10.7-7.10.8.pl
Normal file
123
docs/upgrades/upgrade_7.10.7-7.10.8.pl
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.10.8';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
123
docs/upgrades/upgrade_7.10.8-7.10.9.pl
Normal file
123
docs/upgrades/upgrade_7.10.8-7.10.9.pl
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.10.9';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
170
docs/upgrades/upgrade_7.10.9-7.10.10.pl
Normal file
170
docs/upgrades/upgrade_7.10.9-7.10.10.pl
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.10.10';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
convertCsMailInterval($session);
|
||||
addVersioningToMetadata($session);
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub convertCsMailInterval {
|
||||
my $session = shift;
|
||||
print "\tConvert the getMailInterval from seconds to enumeration... " unless $quiet;
|
||||
# and here's our code
|
||||
$session->db->write('alter table Collaboration modify column getMailInterval char(64)');
|
||||
my $get_row = $session->db->read('select assetId, revisionDate, getMailInterval from Collaboration');
|
||||
my $change_row = $session->db->prepare('update Collaboration set getMailInterval=? where assetId=? and revisionDate=?');
|
||||
while (my ($assetId, $revisionDate, $seconds ) = $get_row->array) {
|
||||
my $interval;
|
||||
if ($seconds <= 60) { $interval = 'every minute'; }
|
||||
elsif ($seconds <= 120) { $interval = 'every other minute'; }
|
||||
elsif ($seconds <= 300) { $interval = 'every 5 minutes'; }
|
||||
elsif ($seconds <= 600) { $interval = 'every 10 minutes'; }
|
||||
elsif ($seconds <= 900) { $interval = 'every 15 minutes'; }
|
||||
elsif ($seconds <= 1200) { $interval = 'every 20 minutes'; }
|
||||
elsif ($seconds <= 1800) { $interval = 'every 30 minutes'; }
|
||||
elsif ($seconds <= 3600) { $interval = 'every hour'; }
|
||||
elsif ($seconds <= 7200) { $interval = 'every other hour'; }
|
||||
else { $interval = 'once per day'; }
|
||||
$change_row->execute([$interval, $assetId, $revisionDate]);
|
||||
}
|
||||
$get_row->finish;
|
||||
$change_row->finish;
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub addVersioningToMetadata {
|
||||
my $session = shift;
|
||||
print "\tAltering metadata tables for versioning..." unless $quiet;
|
||||
my $db = $session->db;
|
||||
$db->write(q{
|
||||
alter table metaData_values
|
||||
add column revisionDate bigint,
|
||||
drop primary key,
|
||||
add primary key (fieldId, assetId, revisionDate);
|
||||
});
|
||||
$db->write(q{
|
||||
create table metaData_classes (
|
||||
className char(255),
|
||||
fieldId char(22)
|
||||
);
|
||||
});
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
print "\tUpgrading package $file\n" unless $quiet;
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval {
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
$node->importPackage( $storage, {
|
||||
overwriteLatest => 1,
|
||||
clearPackageFlag => 1,
|
||||
setDefaultTemplate => 1,
|
||||
} );
|
||||
};
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
|
|
@ -172,6 +172,24 @@
|
|||
# "password" : "password"
|
||||
# },
|
||||
|
||||
# If you have a multi-master set up, you must define increment_step and increment_offset
|
||||
# to prevent merge conflicts between the different masters. increment_step should be set
|
||||
# to the number of masters, and offset should be unique to each master, starting at 0.
|
||||
#
|
||||
# So, a 2-master cluster would define:
|
||||
# Master 1:
|
||||
# increment_step: 2
|
||||
# increment_offset: 0
|
||||
# Master 2:
|
||||
# increment_step: 2
|
||||
# increment_offset: 1
|
||||
#
|
||||
# "db" : {
|
||||
# "increment_step" : 1,
|
||||
# "increment_offset" : 0
|
||||
# },
|
||||
|
||||
|
||||
# Set this value if you wish to override all outbound emails to a specific
|
||||
# user for testing purposes.
|
||||
|
||||
|
|
@ -840,6 +858,7 @@
|
|||
"If" : "If",
|
||||
"International" : "International",
|
||||
"LastModified" : "LastModified",
|
||||
"LastModifiedBy" : "LastModifiedBy",
|
||||
"L" : "L_loginBox",
|
||||
"LoginToggle" : "LoginToggle",
|
||||
"MiniCart" : "MiniCart",
|
||||
|
|
@ -849,6 +868,7 @@
|
|||
"PickLanguage" : "PickLanguage",
|
||||
"RandomAssetProxy" : "RandomAssetProxy",
|
||||
"RandomThread" : "RandomThread",
|
||||
"RenderThingData" : "RenderThingData",
|
||||
"RootTitle" : "RootTitle",
|
||||
"r" : "r_printable",
|
||||
"Spacer" : "Spacer",
|
||||
|
|
@ -918,6 +938,9 @@
|
|||
"WebGUI::Asset::Wobject::Thingy" : [
|
||||
"WebGUI::Workflow::Activity::NotifyAboutThing"
|
||||
],
|
||||
"WebGUI::Asset" : [
|
||||
"WebGUI::Workflow::Activity::UpdateAssetSubscribers"
|
||||
],
|
||||
"WebGUI::User" : [
|
||||
"WebGUI::Workflow::Activity::CreateCronJob",
|
||||
"WebGUI::Workflow::Activity::NotifyAboutUser",
|
||||
|
|
@ -1070,6 +1093,9 @@
|
|||
# An array of SPAM words. Used in the Post and WikiPage to block spam by sending the asset directly
|
||||
# to the trash.
|
||||
"spamStopWords" : [
|
||||
]
|
||||
],
|
||||
|
||||
# A flag to enable a very simple SSO mechanism using sessionIds.
|
||||
"enableSimpleSSO" : 0
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,6 +156,9 @@ sub handle {
|
|||
# );
|
||||
# return;
|
||||
|
||||
# Look for the template preview HTTP headers
|
||||
WebGUI::Asset::Template->processVariableHeaders($session);
|
||||
|
||||
# TODO: refactor the following loop, find all instances of "chunked" and "empty" in codebase, etc..
|
||||
for my $handler (@{$session->config->get("contentHandlers")}) {
|
||||
my $output = eval { WebGUI::Pluggable::run($handler, "handler", [ $session ] )};
|
||||
|
|
@ -177,12 +180,12 @@ sub handle {
|
|||
if ( defined $output && blessed $output && $output->isa( 'WebGUI::Asset::Template' ) ) {
|
||||
$session->http->sendHeader;
|
||||
$session->output->print( $output->process );
|
||||
return;
|
||||
last;
|
||||
}
|
||||
# "chunked" or "empty" means it took care of its own output needs
|
||||
elsif (defined $output && ( $output eq "chunked" || $output eq "empty" )) {
|
||||
#warn "chunked and empty no longer stream, use session->response->stream() instead";
|
||||
return;
|
||||
last;
|
||||
}
|
||||
# other non-empty output should be used as the response body
|
||||
elsif (defined $output && $output ne "") {
|
||||
|
|
@ -191,15 +194,21 @@ sub handle {
|
|||
|
||||
# Use contentHandler's return value as the output
|
||||
$session->output->print($output);
|
||||
return;
|
||||
last;
|
||||
}
|
||||
# Keep processing for success codes
|
||||
elsif ($session->response->status < 200 || $session->response->status > 299) {
|
||||
$session->http->sendHeader;
|
||||
return;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Print out the template preview variables
|
||||
$session->output->print(
|
||||
WebGUI::Asset::Template->getVariableJson($session), 1
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ sub www_editFriends {
|
|||
my @manageableUsers = ();
|
||||
if ($groupName) { # Only adding users from a single group
|
||||
my $group = WebGUI::Group->find($session, $groupName);
|
||||
push @manageableUsers, @{ $group->getUsersNotIn($user->{_user}->{'friendsGroup'}, 'withoutExpired') };
|
||||
push @manageableUsers, @{ $group->getUsersNotIn($user->friends->getId, 'withoutExpired') };
|
||||
}
|
||||
else { # Defaults to groups selected in settings
|
||||
my $groupIds = $session->setting->get('groupsToManageFriends');
|
||||
|
|
@ -196,7 +196,7 @@ sub www_editFriends {
|
|||
foreach my $groupId (@groupIds) {
|
||||
my $group = WebGUI::Group->new($session, $groupId);
|
||||
next GROUP unless $group->getId || $group->getId eq 'new';
|
||||
push @manageableUsers, @{ $group->getUsersNotIn($user->{_user}->{'friendsGroup'}, 'withoutExpired') };
|
||||
push @manageableUsers, @{ $group->getUsersNotIn($user->friends->getId, 'withoutExpired') };
|
||||
}
|
||||
@manageableUsers = uniq @manageableUsers;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ property extraHeadTags => (
|
|||
around extraHeadTags => sub {
|
||||
my $orig = shift;
|
||||
my $self = shift;
|
||||
if (@_ > 1) {
|
||||
if (@_ > 0) {
|
||||
my $unpacked = $_[0];
|
||||
my $packed = $unpacked; ##Undo magic aliasing since a reference is passed below
|
||||
HTML::Packer::minify( \$packed, {
|
||||
|
|
@ -1709,6 +1709,19 @@ sub getViewCacheKey {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getContentLastModifiedBy ( )
|
||||
|
||||
Returns the userId that modified the content last.
|
||||
|
||||
=cut
|
||||
|
||||
sub getContentLastModifiedBy {
|
||||
my $self = shift;
|
||||
return $self->get("revisedBy");
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getWwwCacheKey ( )
|
||||
|
||||
Returns a cache object specific to this asset, and whether or not the request is in SSL mode.
|
||||
|
|
@ -2387,7 +2400,7 @@ sub publish {
|
|||
|
||||
$self->session->db->write("update asset set state='published', stateChangedBy=".$self->session->db->quote($self->session->user->userId).", stateChanged=".time()." where assetId in (".$idList.")");
|
||||
foreach my $id (@{$assetIds}) {
|
||||
my $asset = WebGUI::Asset->newById($self->session, $id);
|
||||
my $asset = WebGUI::Asset->newPending($self->session, $id);
|
||||
if (defined $asset) {
|
||||
$asset->purgeCache;
|
||||
}
|
||||
|
|
@ -2425,6 +2438,21 @@ sub purgeCache {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 refused ( )
|
||||
|
||||
Returns an error message to the user, wrapped in the user's style. This is most useful for
|
||||
handling UI errors. Privilege errors should be still be sent to $session->privilege.
|
||||
|
||||
=cut
|
||||
|
||||
sub refused {
|
||||
my ($self) = @_;
|
||||
return $self->{_session};
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 session ( )
|
||||
|
|
@ -2683,10 +2711,10 @@ sub www_addSave {
|
|||
my ( $form ) = $session->quick(qw{ form });
|
||||
|
||||
return $session->privilege->insufficient() unless $self->canEdit;
|
||||
if ($self->session->config("maximumAssets")) {
|
||||
if ($self->session->config->get("maximumAssets")) {
|
||||
my ($count) = $self->session->db->quickArray("select count(*) from asset");
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset");
|
||||
return $self->session->style->userStyle($i18n->get("over max assets")) if ($self->session->config("maximumAssets") <= $count);
|
||||
return $self->session->style->userStyle($i18n->get("over max assets")) if ($self->session->config->get("maximumAssets") <= $count);
|
||||
}
|
||||
|
||||
# Determine what version tag we should use
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use WebGUI::Storage;
|
|||
use Test::Deep::NoTest qw(eq_deeply);
|
||||
use DateTime::Event::ICal;
|
||||
use DateTime::Set;
|
||||
use Data::ICal::Entry::Event;
|
||||
|
||||
use Moose;
|
||||
use WebGUI::Definition::Asset;
|
||||
|
|
@ -212,6 +213,54 @@ override addRevision => sub {
|
|||
return $newRev;
|
||||
};
|
||||
|
||||
####################################################################
|
||||
|
||||
=head2 add_to_calendar ($iCal)
|
||||
|
||||
Build a Data::ICal::Entry::Event object that contains the information for this
|
||||
event and add it to the Data::ICal calendar
|
||||
|
||||
=head3 $iCal
|
||||
|
||||
A Data::ICal object, representing the top-level calendar instance.
|
||||
|
||||
=cut
|
||||
|
||||
sub add_to_calendar {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $calendar = shift;
|
||||
my $event = Data::ICal::Entry::Event->new();
|
||||
$event->add_properties(
|
||||
'last-modified' => WebGUI::DateTime->new($session, $event->get("revisionDate"))->toIcal,
|
||||
created => WebGUI::DateTime->new($session, $event->get("creationDate"))->toIcal,
|
||||
sequence => $self->get('iCalSequenceNumber'),
|
||||
summary => $self->get('title'),
|
||||
description => $self->get('description'),
|
||||
location => $self->get('location'),
|
||||
uid => $self->get('feedUid')
|
||||
? $self->get('feedUid')
|
||||
: $self->get('assetId') . '@'. $session->config->get("sitename")->[0],
|
||||
);
|
||||
##WebGUI Specific fields
|
||||
foreach my $prop (qw/groupIdView groupIdEdit url menuTitle timeZone/) {
|
||||
$event->add_property( 'x-webgui-'.lc($prop) => $self->get($prop));
|
||||
}
|
||||
my $eventStart = $self->getIcalStart;
|
||||
my $start_parameters = {};
|
||||
if (! $eventStart =~ /T/) {
|
||||
$start_parameters->{VALUE} = 'DATE';
|
||||
}
|
||||
$event->add_property(dtstart => [ $eventStart, $start_parameters ]);
|
||||
my $eventEnd = $self->getIcalEnd;
|
||||
my $end_parameters = {};
|
||||
if (! $eventEnd =~ /T/) {
|
||||
$end_parameters->{VALUE} = 'DATE';
|
||||
}
|
||||
$event->add_property(dtend => [ $eventEnd, $end_parameters ]);
|
||||
$calendar->add_entry($event);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
my %dayNamesToICal = (
|
||||
|
|
@ -411,6 +460,14 @@ sub duplicate {
|
|||
my $newAsset = $self->SUPER::duplicate(@_);
|
||||
my $newStorage = $self->getStorageLocation->copy;
|
||||
$newAsset->update({storageId=>$newStorage->getId});
|
||||
my $links = $self->getRelatedLinks();
|
||||
my $id = $self->session->id;
|
||||
foreach my $link (@{ $links }) {
|
||||
$link->{new_event} = 1;
|
||||
$link->{eventlinkId} = $id->generate;
|
||||
$link->{linkurl} = $link->{linkURL};
|
||||
}
|
||||
$newAsset->setRelatedLinks($links);
|
||||
return $newAsset;
|
||||
}
|
||||
|
||||
|
|
@ -434,13 +491,12 @@ sub generateRecurrence {
|
|||
WHERE recurId = ? AND startDate = ?
|
||||
};
|
||||
my $db = $self->session->db;
|
||||
unless ($db->quickScalar($sql, [$self->recurId, $sdb])) {
|
||||
my $child = $self->get;
|
||||
$child->{startDate} = $sdb;
|
||||
$child->{endDate} = $edb;
|
||||
$self->getParent->addChild(
|
||||
$child, undef, undef, { skipAutoCommitWorkflows => 1 }
|
||||
);
|
||||
unless ($db->quickScalar($sql, [$self->get('recurId'), $sdb])) {
|
||||
my $child = $self->duplicate({skipAutoCommitWorkflows => 1});
|
||||
$child->update({
|
||||
startDate => $sdb,
|
||||
endDate => $edb,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1374,9 +1430,18 @@ override processEditForm => sub {
|
|||
|
||||
### Verify the form was filled out correctly...
|
||||
my @errors;
|
||||
# If the start date is after the end date
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Event');
|
||||
if ($self->startDate gt $self->endDate) {
|
||||
|
||||
# Verify we got valid dates
|
||||
if ( !eval{ $self->getDateTimeStart; 1 } ) {
|
||||
push @errors, $i18n->get('invalid start date');
|
||||
}
|
||||
if ( !eval{ $self->getDateTimeEnd; 1 } ) {
|
||||
push @errors, $i18n->get('invalid end date');
|
||||
}
|
||||
|
||||
# If the start date is after the end date
|
||||
if ($self->get("startDate") gt $self->get("endDate")) {
|
||||
push @errors, $i18n->get("The event end date must be after the event start date.");
|
||||
}
|
||||
|
||||
|
|
@ -1605,13 +1670,17 @@ Extent the method from the super class to delete all storage locations.
|
|||
|
||||
override purge => sub {
|
||||
my $self = shift;
|
||||
my $sth = $self->session->db->read("select storageId from Event where assetId=?",[$self->getId]);
|
||||
while (my ($storageId) = $sth->array) {
|
||||
my $storage = WebGUI::Storage->get($self->session,$storageId);
|
||||
my $id = $self->getId;
|
||||
my $session = $self->session;
|
||||
my @storageIds = $session->db->buildArray("select storageId from Event where assetId=?",[$id]);
|
||||
my $success = $self->SUPER::purge;
|
||||
return 0 unless $success;
|
||||
foreach my $storageId (@storageIds) {
|
||||
my $storage = WebGUI::Storage->get($session, $storageId);
|
||||
$storage->delete if defined $storage;
|
||||
}
|
||||
$sth->finish;
|
||||
return super();
|
||||
$session->db->write('delete from Event_relatedlink where assetId=?',[$id]);
|
||||
return 1;
|
||||
};
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -2235,20 +2304,24 @@ sub www_edit {
|
|||
# End
|
||||
$var->{"formRecurEnd"}
|
||||
= q|
|
||||
<div><input type="radio" name="recurEndType" id="recurEndType_none" value="none" |.(!$recur->{endDate} && !$recur->{endAfter} ? 'checked="checked"' : '').q|/>
|
||||
<label for="recurEndType_none">|. $i18n->get('No end'). q|</label><br />
|
||||
<div><input type="radio" name="recurEndType" id="recurEndType_none" value="none" |.(!$recur->{endDate} && !$recur->{endAfter} ? 'checked="checked"' : '').q| onclick="toggleRecurEnd()"/>
|
||||
<label for="recurEndType_none">|. $i18n->get('No end'). q|</label>
|
||||
|
||||
<input type="radio" name="recurEndType" id="recurEndType_date" value="date" |.($recur->{endDate} ? 'checked="checked"' : '' ).q| />
|
||||
<label for="recurEndType_date">|. $i18n->get('By date'). q| </label>|
|
||||
<input type="radio" name="recurEndType" id="recurEndType_date" value="date" |.($recur->{endDate} ? 'checked="checked"' : '' ).q| onclick="toggleRecurEnd()"/>
|
||||
<label for="recurEndType_date">|. $i18n->get('By date'). q| </label>
|
||||
<div id="recurEndPattern_date"> |
|
||||
. WebGUI::Form::date($session,{ name => "recurEndDate", value => $recur->{endDate}, defaultValue => $recur->{endDate} })
|
||||
. q|
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<input type="radio" name="recurEndType" id="recurEndType_after" value="after" |.($recur->{endAfter} ? 'checked="checked"' : '' ).q| />
|
||||
<input type="radio" name="recurEndType" id="recurEndType_after" value="after" |.($recur->{endAfter} ? 'checked="checked"' : '' ).q| onclick="toggleRecurEnd()"/>
|
||||
<label for="recurEndType_after">|. $i18n->get('After'). q| </label>
|
||||
<div id="recurEndPattern_after">
|
||||
<input type="text" size="3" name="recurEndAfter" value="|.$recur->{endAfter}.q|" />
|
||||
|. $i18n->get('occurences'). q|.
|
||||
</div>
|
||||
</div>
|
||||
|;
|
||||
|
||||
# Include
|
||||
|
|
@ -2310,7 +2383,19 @@ sub www_edit {
|
|||
document.getElementById("recurPattern_yearly").style.display = "block";
|
||||
}
|
||||
}
|
||||
YAHOO.util.Event.onAvailable("recurPattern",function(e) { toggleRecur(); });
|
||||
|
||||
function toggleRecurEnd() {
|
||||
document.getElementById("recurEndPattern_date").style.display = "none";
|
||||
document.getElementById("recurEndPattern_after").style.display = "none";
|
||||
|
||||
if (document.getElementById("recurEndType_date").checked) {
|
||||
document.getElementById("recurEndPattern_date").style.display = "block";
|
||||
}
|
||||
else if (document.getElementById("recurEndType_after").checked) {
|
||||
document.getElementById("recurEndPattern_after").style.display = "block";
|
||||
}
|
||||
}
|
||||
YAHOO.util.Event.onAvailable("recurPattern",function(e) { toggleRecur(); toggleRecurEnd(); });
|
||||
</script>
|
||||
ENDJS
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,24 @@ sub setPrivileges {
|
|||
);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 commit ( )
|
||||
|
||||
Override commit to remove all privileges for previous revisions' storage
|
||||
locations
|
||||
|
||||
=cut
|
||||
|
||||
sub commit {
|
||||
my ( $self, @args ) = @_;
|
||||
|
||||
for my $rev ( grep { $_->get("revisionDate") < $self->get("revisionDate") } @{$self->getRevisions} ) {
|
||||
$rev->getStorageLocation->trash;
|
||||
}
|
||||
|
||||
return $self->SUPER::commit( @args );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -401,7 +419,6 @@ override processEditForm => sub {
|
|||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 purge
|
||||
|
|
@ -450,6 +467,20 @@ override purgeRevision => sub {
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 restore ( )
|
||||
|
||||
Override trash restore to restore storage location
|
||||
|
||||
=cut
|
||||
|
||||
sub restore {
|
||||
my ( $self, @args ) = @_;
|
||||
$self->setPrivileges;
|
||||
return $self->SUPER::restore( @args );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 setFile ( [pathtofile] )
|
||||
|
||||
Tells the asset to do all the postprocessing on the file (setting privs, thubnails, or whatever).
|
||||
|
|
@ -535,6 +566,23 @@ sub setStorageLocation {
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 trash ( )
|
||||
|
||||
Override to put the attached file in the trash too
|
||||
|
||||
=cut
|
||||
|
||||
sub trash {
|
||||
my ( $self, @args ) = @_;
|
||||
my $return = $self->SUPER::trash( @args );
|
||||
|
||||
$self->getStorageLocation->trash;
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 updatePropertiesFromStorage ( )
|
||||
|
||||
Updates the asset properties from the file tracked by this asset. Should be
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ package WebGUI::Asset::MapPoint;
|
|||
use strict;
|
||||
use Moose;
|
||||
use WebGUI::Definition::Asset;
|
||||
use Geo::Coder::Googlev3;
|
||||
|
||||
extends 'WebGUI::Asset';
|
||||
define assetName => ['assetName', 'Asset_MapPoint'];
|
||||
define icon => 'mappoint.png';
|
||||
|
|
@ -121,6 +123,12 @@ property userDefined5 => (
|
|||
fieldType => "hidden",
|
||||
noFormPost => 1,
|
||||
);
|
||||
property isGeocoded => (
|
||||
fieldType => "yesNo",
|
||||
tab => "properties",
|
||||
label => ["isGeocoded label",'Asset_MapPoint'],
|
||||
hoverHelp => ["isGeocoded description",'Asset_MapPoint'],
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -184,6 +192,7 @@ AT LEAST the following keys:
|
|||
title - The title of the point
|
||||
content - HTML content to show details about the point
|
||||
url - The URL of the point
|
||||
userDefined1-5 - The userDefined fields
|
||||
|
||||
The following keys are optional
|
||||
|
||||
|
|
@ -199,7 +208,7 @@ sub getMapInfo {
|
|||
# Get asset properties
|
||||
$var->{ url } = $self->getUrl;
|
||||
$var->{ assetId } = $self->getId;
|
||||
my @keys = qw( latitude longitude title );
|
||||
my @keys = qw( latitude longitude title userDefined1 userDefined2 userDefined3 userDefined4 userDefined5 isGeocoded );
|
||||
for my $key ( @keys ) {
|
||||
$var->{ $key } = $self->$key;
|
||||
}
|
||||
|
|
@ -246,6 +255,15 @@ sub getTemplateVarsEditForm {
|
|||
my $session = $self->session;
|
||||
my $var = $self->getTemplateVars;
|
||||
|
||||
my $parent = $self->getParent;
|
||||
#If it's a new point, we have to get the parent from the url
|
||||
unless ($parent) {
|
||||
my $url = $session->url->page;
|
||||
$parent = WebGUI::Asset->newByUrl($session,$url);
|
||||
}
|
||||
|
||||
$var->{'can_edit_map'} = $parent->canEdit;
|
||||
|
||||
$var->{ form_header }
|
||||
= WebGUI::Form::formHeader( $session )
|
||||
. WebGUI::Form::hidden( $session, {
|
||||
|
|
@ -293,8 +311,25 @@ sub getTemplateVarsEditForm {
|
|||
name => "synopsis",
|
||||
value => $self->synopsis,
|
||||
resizable => 0,
|
||||
} );
|
||||
} );
|
||||
|
||||
#Only allow people who can edit the parent to change isHidden
|
||||
if($var->{'can_edit_map'}) {
|
||||
my $isHidden = (defined $self->get("isHidden")) ? $self->get("isHidden") : 1;
|
||||
$var->{ "form_isHidden" }
|
||||
= WebGUI::Form::yesNo( $session, {
|
||||
name => "isHidden",
|
||||
value => $isHidden,
|
||||
} );
|
||||
}
|
||||
|
||||
my $isGeocoded = ( $self->getId ) ? $self->get("isGeocoded") : 1;
|
||||
$var->{"form_isGeocoded"}
|
||||
= WebGUI::Form::checkbox( $session, {
|
||||
name => "isGeocoded",
|
||||
value => 1,
|
||||
checked => $isGeocoded
|
||||
} );
|
||||
# Fix storageIdPhoto because scripts do not get executed in ajax requests
|
||||
$var->{ "form_storageIdPhoto" }
|
||||
= '<input type="file" name="storageIdPhoto" />';
|
||||
|
|
@ -309,6 +344,35 @@ sub getTemplateVarsEditForm {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexContent ( )
|
||||
|
||||
Indexing the content of attachments and user defined fields. See WebGUI::Asset::indexContent() for additonal details.
|
||||
|
||||
=cut
|
||||
|
||||
sub indexContent {
|
||||
my $self = shift;
|
||||
my $indexer = $self->SUPER::indexContent;
|
||||
$indexer->addKeywords($self->get("website"));
|
||||
$indexer->addKeywords($self->get("address1"));
|
||||
$indexer->addKeywords($self->get("address2"));
|
||||
$indexer->addKeywords($self->get("city"));
|
||||
$indexer->addKeywords($self->get("region"));
|
||||
$indexer->addKeywords($self->get("zipCode"));
|
||||
$indexer->addKeywords($self->get("country"));
|
||||
$indexer->addKeywords($self->get("phone"));
|
||||
$indexer->addKeywords($self->get("fax"));
|
||||
$indexer->addKeywords($self->get("email"));
|
||||
$indexer->addKeywords($self->get("userDefined1"));
|
||||
$indexer->addKeywords($self->get("userDefined2"));
|
||||
$indexer->addKeywords($self->get("userDefined3"));
|
||||
$indexer->addKeywords($self->get("userDefined4"));
|
||||
$indexer->addKeywords($self->get("userDefined5"));
|
||||
return $indexer;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 processAjaxEditForm ( )
|
||||
|
||||
Process the Ajax Edit Form from the Map. If any errors occur, return
|
||||
|
|
@ -336,6 +400,29 @@ sub processAjaxEditForm {
|
|||
$prop->{ synopsis } = $form->get('synopsis');
|
||||
$prop->{ url } = $session->url->urlize( $self->getParent->getUrl . '/' . $prop->{title} );
|
||||
$prop->{ ownerUserId } = $form->get('ownerUserId') || $session->user->userId;
|
||||
#Only users who can edit the map can set this property
|
||||
if($self->getParent->canEdit) {
|
||||
$prop->{ isHidden } = $form->get('isHidden');
|
||||
}
|
||||
$prop->{isGeocoded } = $form->get('isGeocoded') || 0;
|
||||
if($prop->{isGeocoded} &&
|
||||
(
|
||||
( $form->get("address1") ne $self->get("address1") )
|
||||
|| ( $form->get("address2") ne $self->get("address2") )
|
||||
|| ( $form->get("city") ne $self->get("city") )
|
||||
|| ( $form->get("region") ne $self->get("region") )
|
||||
|| ( $form->get("zipCode") ne $self->get("zipCode") )
|
||||
|| ( $form->get("country") ne $self->get("country") )
|
||||
)
|
||||
) {
|
||||
my $geocoder = Geo::Coder::Googlev3->new;
|
||||
my $address_str = $form->get("address1");
|
||||
$address_str .= " ".$form->get("address2") if($form->get("address2"));
|
||||
$address_str .= ", ".$form->get("city").", ".$form->get("region").", ".$form->get("zipCode").", ".$form->get("country");
|
||||
my $location = $geocoder->geocode( location => $address_str );
|
||||
$prop->{latitude } = $location->{geometry}->{location}->{lat};
|
||||
$prop->{longitude} = $location->{geometry}->{location}->{lng};
|
||||
}
|
||||
|
||||
$self->update( $prop );
|
||||
|
||||
|
|
|
|||
|
|
@ -235,12 +235,16 @@ Returns a boolean indicating whether the user can view the current post.
|
|||
|
||||
sub canView {
|
||||
my $self = shift;
|
||||
if (($self->status eq "approved" || $self->status eq "archived") && $self->getThread->getParent->canView) {
|
||||
my $userId = shift || $self->session->user->userId;
|
||||
$self->session->log->info( "$userId " . $self->status );
|
||||
if (($self->status eq "approved" || $self->status eq "archived") && $self->getThread->getParent->canView( $userId )) {
|
||||
$self->session->log->info( "CAN VIEW" );
|
||||
return 1;
|
||||
} elsif ($self->canEdit) {
|
||||
} elsif ($self->canEdit( $userId )) {
|
||||
$self->session->log->info( "CAN EDIT" );
|
||||
return 1;
|
||||
} else {
|
||||
$self->getThread->getParent->canEdit;
|
||||
return $self->getThread->getParent->canEdit( $userId );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -362,6 +366,26 @@ sub disqualifyAsLastPost {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 duplicate ( )
|
||||
|
||||
Extend the base method to handle duplicate storage locations and groups.
|
||||
|
||||
=cut
|
||||
|
||||
sub duplicate {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $copy = $self->SUPER::duplicate(@_);
|
||||
if ($self->get('storageId')) {
|
||||
my $storage = $self->getStorageLocation;
|
||||
my $copied_storage = $storage->copy;
|
||||
$copy->update({storageId => $copied_storage->getId});
|
||||
}
|
||||
return $copy;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 DESTROY
|
||||
|
||||
Extend the base method to delete the locally cached thread object.
|
||||
|
|
|
|||
|
|
@ -247,6 +247,27 @@ sub DEMOLISH {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 duplicate
|
||||
|
||||
Extends the base method to handle creating a new subscription group.
|
||||
|
||||
=cut
|
||||
|
||||
sub duplicate {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $copy = $self->SUPER::duplicate(@_);
|
||||
if ($self->get('subscriptionGroupId')) {
|
||||
my $group = WebGUI::Group->new($session, $self->get('subscriptionGroupId'));
|
||||
my $copied_group = WebGUI::Group->new($session, 'new');
|
||||
$copied_group->addUsers($group->getUsers('withoutExpired'));
|
||||
$copy->update({subscriptionGroupId => $copied_group->getId});
|
||||
}
|
||||
return $copy;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getAdjacentThread ( )
|
||||
|
||||
Given a field and an order, returns the nearest thread when sorting by those.
|
||||
|
|
|
|||
|
|
@ -326,7 +326,140 @@ override getEditForm => sub {
|
|||
return $f;
|
||||
};
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getAllButtons ( )
|
||||
|
||||
Get a list of all the buttons in this MCE
|
||||
|
||||
=cut
|
||||
|
||||
sub getAllButtons {
|
||||
my ( $self ) = @_;
|
||||
my @toolbarRows = map{[split "\n", $self->get("toolbarRow$_")]} (1..3);
|
||||
my @toolbarButtons = map{ @{$_} } @toolbarRows;
|
||||
return @toolbarButtons;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getConfig ( )
|
||||
|
||||
Get a hashref of configuration to create this MCE. You must run the code
|
||||
from getLoadPlugins before you can successfully initialize an MCE. You
|
||||
must also specify the "elements" key so TinyMCE knows what textarea to
|
||||
replace.
|
||||
|
||||
=cut
|
||||
|
||||
sub getConfig {
|
||||
my ($self) = @_;
|
||||
my $i18n = WebGUI::International->new($self->session, 'Asset_RichEdit');
|
||||
my @plugins;
|
||||
push @plugins, "safari";
|
||||
push @plugins, "paste";
|
||||
push @plugins, "contextmenu"
|
||||
if $self->enableContextMenu;
|
||||
push @plugins, "inlinepopups"
|
||||
if $self->inlinePopups;
|
||||
push @plugins, "media"
|
||||
if $self->allowMedia;
|
||||
|
||||
my @toolbarRows = map{[split "\n", $self->get("toolbarRow$_")]} (1..3);
|
||||
my @toolbarButtons = map{ @{$_} } @toolbarRows;
|
||||
my %config = (
|
||||
mode => 'exact',
|
||||
theme => "advanced",
|
||||
relative_urls => JSON::false(),
|
||||
remove_script_host => JSON::true(),
|
||||
auto_reset_designmode => JSON::true(),
|
||||
cleanup_callback => "tinyMCE_WebGUI_Cleanup",
|
||||
urlconverter_callback => "tinyMCE_WebGUI_URLConvertor",
|
||||
theme_advanced_resizing => JSON::true(),
|
||||
( map { "theme_advanced_buttons" . ( $_ + 1 ) => ( join ',', @{ $toolbarRows[$_] } ) } ( 0 .. $#toolbarRows ) ),
|
||||
|
||||
ask => JSON::false(),
|
||||
preformatted => $self->preformatted ? JSON::true() : JSON::false(),
|
||||
force_br_newlines => $self->useBr ? JSON::true() : JSON::false(),
|
||||
force_p_newlines => $self->useBr ? JSON::false() : JSON::true(),
|
||||
$self->useBr ? ( forced_root_block => JSON::false() ) : (),
|
||||
remove_linebreaks => $self->removeLineBreaks ? JSON::true() : JSON::false(),
|
||||
nowrap => $self->nowrap ? JSON::true() : JSON::false(),
|
||||
directionality => $self->directionality,
|
||||
theme_advanced_toolbar_location => $self->toolbarLocation,
|
||||
theme_advanced_statusbar_location => "bottom",
|
||||
valid_elements => $self->validElements,
|
||||
wg_userIsVisitor => $self->session->user->isVisitor ? JSON::true() : JSON::false(),
|
||||
paste_postprocess => 'tinyMCE_WebGUI_paste_postprocess',
|
||||
);
|
||||
foreach my $button (@toolbarButtons) {
|
||||
if ( $button eq "spellchecker" && $self->session->config->get('availableDictionaries') ) {
|
||||
push( @plugins, "-wgspellchecker" );
|
||||
$config{spellchecker_rpc_url} = $self->session->url->gateway( '', "op=spellCheck" );
|
||||
$config{spellchecker_languages} = join( ',',
|
||||
map { ( $_->{default} ? '+' : '' ) . $_->{name} . '=' . $_->{id} }
|
||||
@{ $self->session->config->get('availableDictionaries') } );
|
||||
}
|
||||
push( @plugins, "table" ) if ( $button eq "tablecontrols" );
|
||||
push( @plugins, "save" ) if ( $button eq "save" );
|
||||
push( @plugins, "advhr" ) if ( $button eq "advhr" );
|
||||
push( @plugins, "fullscreen" ) if ( $button eq "fullscreen" );
|
||||
if ( $button eq "advimage" ) {
|
||||
push( @plugins, "advimage" );
|
||||
$config{external_link_list_url} = "";
|
||||
}
|
||||
if ( $button eq "advlink" ) {
|
||||
$config{external_image_list_url} = "";
|
||||
$config{file_browser_callback} = "mcFileManager.filebrowserCallBack";
|
||||
push( @plugins, "advlink" );
|
||||
}
|
||||
push( @plugins, "emotions" ) if ( $button eq "emotions" );
|
||||
push( @plugins, "iespell" ) if ( $button eq "iespell" );
|
||||
$config{gecko_spellcheck} = 'true' if ( $button eq "iespell" );
|
||||
if ( $button eq "paste" || $button eq "pastetext" || $button eq "pasteword" ) {
|
||||
push( @plugins, "paste" );
|
||||
}
|
||||
if ( $button eq "insertdate" || $button eq "inserttime" || $button eq "insertdatetime" ) {
|
||||
$config{plugin_insertdate_dateFormat} = "%Y-%m-%d";
|
||||
$config{plugin_insertdate_timeFormat} = "%H:%M:%S";
|
||||
push( @plugins, "insertdatetime" );
|
||||
}
|
||||
push( @plugins, "preview" ) if ( $button eq "preview" );
|
||||
if ( $button eq "media" ) {
|
||||
push( @plugins, "media" );
|
||||
}
|
||||
push( @plugins, "searchreplace" )
|
||||
if ( $button eq "search" || $button eq "replace" || $button eq "searchreplace" );
|
||||
push( @plugins, "print" ) if ( $button eq "print" );
|
||||
if ( $button eq "wginsertimage" ) {
|
||||
push @plugins, "-wginsertimage";
|
||||
}
|
||||
if ( $button eq "wgpagetree" ) {
|
||||
push @plugins, "-wgpagetree";
|
||||
}
|
||||
if ( $button eq "wgmacro" ) {
|
||||
push @plugins, "-wgmacro";
|
||||
}
|
||||
if ( $button eq "code" ) {
|
||||
$config{theme_advanced_source_editor_width} = $self->sourceEditorWidth
|
||||
if ( $self->sourceEditorWidth > 0 );
|
||||
$config{theme_advanced_source_editor_height} = $self->sourceEditorHeight
|
||||
if ( $self->sourceEditorHeight > 0 );
|
||||
}
|
||||
} ## end foreach my $button (@toolbarButtons)
|
||||
my $language = $i18n->getLanguage( '', "languageAbbreviation" );
|
||||
unless ($language) {
|
||||
$language = $i18n->getLanguage( "English", "languageAbbreviation" );
|
||||
}
|
||||
$config{language} = $language;
|
||||
$config{content_css} = $self->cssFile
|
||||
|| $self->session->url->extras('tinymce-webgui/defaultcontent.css');
|
||||
$config{width} = $self->editorWidth if ( $self->editorWidth > 0 );
|
||||
$config{height} = $self->editorHeight if ( $self->editorHeight > 0 );
|
||||
$config{plugins} = join( ",", @plugins );
|
||||
|
||||
return \%config;
|
||||
} ## end sub getConfig
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -354,6 +487,40 @@ my $sql = "select asset.assetId, assetData.revisionDate from RichEdit left join
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getLoadPlugins ( )
|
||||
|
||||
Get the JS code to load the plugins for this MCE. Needs to be called once
|
||||
on the page this MCE will be on
|
||||
|
||||
=cut
|
||||
|
||||
sub getLoadPlugins {
|
||||
my ( $self ) = @_;
|
||||
my %loadPlugins;
|
||||
for my $button ( $self->getAllButtons ) {
|
||||
if ( $button eq 'spellchecker' ) {
|
||||
$loadPlugins{wgspellchecker} = $self->session->url->extras("tinymce-webgui/plugins/wgspellchecker/editor_plugin.js");
|
||||
}
|
||||
if ( $button eq 'wginsertimage' ) {
|
||||
$loadPlugins{wginsertimage} = $self->session->url->extras("tinymce-webgui/plugins/wginsertimage/editor_plugin.js");
|
||||
}
|
||||
if ( $button eq 'wgpagetree' ) {
|
||||
$loadPlugins{wgpagetree} = $self->session->url->extras("tinymce-webgui/plugins/wgpagetree/editor_plugin.js");
|
||||
}
|
||||
if ( $button eq 'wgmacro' ) {
|
||||
$loadPlugins{wgmacro} = $self->session->url->extras("tinymce-webgui/plugins/wgmacro/editor_plugin.js");
|
||||
}
|
||||
}
|
||||
|
||||
my $out = '';
|
||||
while (my ($plugin, $path) = each %loadPlugins) {
|
||||
$out .= "tinymce.PluginManager.load('$plugin', '$path');\n";
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getRichEditor ( $nameId )
|
||||
|
||||
Return the javascript needed to make the Rich Editor.
|
||||
|
|
@ -369,119 +536,16 @@ sub getRichEditor {
|
|||
my $self = shift;
|
||||
return '' if ($self->disableRichEditor);
|
||||
my $nameId = shift;
|
||||
my @plugins;
|
||||
my %loadPlugins;
|
||||
push @plugins, "safari";
|
||||
push @plugins, "contextmenu"
|
||||
if $self->enableContextMenu;
|
||||
push @plugins, "inlinepopups"
|
||||
if $self->inlinePopups;
|
||||
push @plugins, "media"
|
||||
if $self->allowMedia;
|
||||
|
||||
my @toolbarRows = map{[split "\n", $self->get("toolbarRow$_")]} (1..3);
|
||||
my @toolbarButtons = map{ @{$_} } @toolbarRows;
|
||||
my $i18n = WebGUI::International->new($self->session, 'Asset_RichEdit');
|
||||
my $ask = $self->askAboutRichEdit;
|
||||
my %config = (
|
||||
mode => $ask ? "none" : "exact",
|
||||
elements => $nameId,
|
||||
theme => "advanced",
|
||||
relative_urls => JSON::false(),
|
||||
remove_script_host => JSON::true(),
|
||||
auto_reset_designmode => JSON::true(),
|
||||
cleanup_callback => "tinyMCE_WebGUI_Cleanup",
|
||||
urlconverter_callback => "tinyMCE_WebGUI_URLConvertor",
|
||||
theme_advanced_resizing => JSON::true(),
|
||||
(map { "theme_advanced_buttons".($_+1) => (join ',', @{$toolbarRows[$_]}) }
|
||||
(0..$#toolbarRows)),
|
||||
#ask => $self->getValue("askAboutRichEdit") ? JSON::true() : JSON::false(),
|
||||
ask => JSON::false(),
|
||||
preformatted => $self->preformatted ? JSON::true() : JSON::false(),
|
||||
force_br_newlines => $self->useBr ? JSON::true() : JSON::false(),
|
||||
force_p_newlines => $self->useBr ? JSON::false() : JSON::true(),
|
||||
$self->useBr ? ( forced_root_block => JSON::false() ) : (),
|
||||
remove_linebreaks => $self->removeLineBreaks ? JSON::true() : JSON::false(),
|
||||
nowrap => $self->nowrap ? JSON::true() : JSON::false(),
|
||||
directionality => $self->directionality,
|
||||
theme_advanced_toolbar_location => $self->toolbarLocation,
|
||||
theme_advanced_statusbar_location => "bottom",
|
||||
valid_elements => $self->validElements,
|
||||
wg_userIsVisitor => $self->session->user->isVisitor ? JSON::true() : JSON::false(),
|
||||
);
|
||||
# if ($ask) {
|
||||
# $config{oninit} = 'turnOffTinyMCE_'.$nameId;
|
||||
# }
|
||||
foreach my $button (@toolbarButtons) {
|
||||
if ($button eq "spellchecker" && $self->session->config->get('availableDictionaries')) {
|
||||
push(@plugins,"-wgspellchecker");
|
||||
$loadPlugins{wgspellchecker} = $self->session->url->extras("tinymce-webgui/plugins/wgspellchecker/editor_plugin.js");
|
||||
$config{spellchecker_rpc_url} = $self->session->url->gateway('', "op=spellCheck");
|
||||
$config{spellchecker_languages} =
|
||||
join(',', map { ($_->{default} ? '+' : '').$_->{name}.'='.$_->{id} } @{$self->session->config->get('availableDictionaries')});
|
||||
}
|
||||
push(@plugins,"table") if ($button eq "tablecontrols");
|
||||
push(@plugins,"save") if ($button eq "save");
|
||||
push(@plugins,"advhr") if ($button eq "advhr");
|
||||
push(@plugins,"fullscreen") if ($button eq "fullscreen");
|
||||
if ($button eq "advimage") {
|
||||
push(@plugins,"advimage");
|
||||
$config{external_link_list_url} = "";
|
||||
}
|
||||
if ($button eq "advlink") {
|
||||
$config{external_image_list_url} = "";
|
||||
$config{file_browser_callback} = "mcFileManager.filebrowserCallBack";
|
||||
push(@plugins,"advlink");
|
||||
}
|
||||
push(@plugins,"emotions") if ($button eq "emotions");
|
||||
push(@plugins,"iespell") if ($button eq "iespell");
|
||||
$config{gecko_spellcheck} = 'true' if ($button eq "iespell");
|
||||
if ($button eq "paste" || $button eq "pastetext" || $button eq "pasteword") {
|
||||
push(@plugins,"paste");
|
||||
}
|
||||
if ($button eq "insertdate" || $button eq "inserttime" || $button eq "insertdatetime") {
|
||||
$config{plugin_insertdate_dateFormat} = "%Y-%m-%d";
|
||||
$config{plugin_insertdate_timeFormat} = "%H:%M:%S";
|
||||
push(@plugins,"insertdatetime");
|
||||
}
|
||||
push(@plugins,"preview") if ($button eq "preview");
|
||||
if ($button eq "media") {
|
||||
push(@plugins,"media");
|
||||
}
|
||||
push(@plugins,"searchreplace") if ($button eq "search" || $button eq "replace" || $button eq "searchreplace");
|
||||
push(@plugins,"print") if ($button eq "print");
|
||||
if ($button eq "wginsertimage") {
|
||||
push @plugins, "-wginsertimage";
|
||||
$loadPlugins{wginsertimage} = $self->session->url->extras("tinymce-webgui/plugins/wginsertimage/editor_plugin.js");
|
||||
}
|
||||
if ($button eq "wgpagetree") {
|
||||
push @plugins, "-wgpagetree";
|
||||
$loadPlugins{wgpagetree} = $self->session->url->extras("tinymce-webgui/plugins/wgpagetree/editor_plugin.js");
|
||||
}
|
||||
if ($button eq "wgmacro") {
|
||||
push @plugins, "-wgmacro";
|
||||
$loadPlugins{wgmacro} = $self->session->url->extras("tinymce-webgui/plugins/wgmacro/editor_plugin.js");
|
||||
}
|
||||
if ($button eq "code") {
|
||||
$config{theme_advanced_source_editor_width} = $self->sourceEditorWidth if ($self->sourceEditorWidth > 0);
|
||||
$config{theme_advanced_source_editor_height} = $self->sourceEditorHeight if ($self->sourceEditorHeight > 0);
|
||||
}
|
||||
}
|
||||
my $language = $i18n->getLanguage('' ,"languageAbbreviation");
|
||||
unless ($language) {
|
||||
$language = $i18n->getLanguage("English","languageAbbreviation");
|
||||
}
|
||||
$config{language} = $language;
|
||||
$config{content_css} = $self->cssFile || $self->session->url->extras('tinymce-webgui/defaultcontent.css');
|
||||
$config{width} = $self->editorWidth || "100%";
|
||||
$config{height} = $self->editorHeight || "100%";
|
||||
$config{plugins} = join(",",@plugins);
|
||||
|
||||
$self->richedit_headTags;
|
||||
my $out = '';
|
||||
if ($ask) {
|
||||
$out = q|<a style="display: block;" href="javascript:toggleEditor('|.$nameId.q|')">|.$i18n->get('Toggle editor').q|</a>|;
|
||||
}
|
||||
$self->richedit_headTags;
|
||||
$out .= qq|<script type="text/javascript">\n|;
|
||||
if ($ask) {
|
||||
$out .= <<"EOHTML1";
|
||||
|
|
@ -498,11 +562,16 @@ EOHTML1
|
|||
# }
|
||||
#}
|
||||
#YAHOO.util.Event.onDOMReady(turnOffTinyMCE_$nameId);
|
||||
}
|
||||
|
||||
my $config = $self->getConfig;
|
||||
$config->{ elements } = $nameId;
|
||||
if ( $ask ) {
|
||||
$config->{mode} = "none";
|
||||
}
|
||||
while (my ($plugin, $path) = each %loadPlugins) {
|
||||
$out .= "tinymce.PluginManager.load('$plugin', '$path');\n";
|
||||
}
|
||||
$out .= "\ttinyMCE.init(" . JSON->new->pretty->encode(\%config) . " );\n";
|
||||
|
||||
$out .= $self->getLoadPlugins;
|
||||
$out .= "\ttinyMCE.init(" . JSON->new->pretty->encode( $config ) . " );\n";
|
||||
$out .= "</script>";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -637,7 +637,8 @@ sub getShortcutByCriteria {
|
|||
|
||||
my $replacement = $expression; # We don't want to modify $expression.
|
||||
# We need it later.
|
||||
push(@joins," left join metaData_values ".$counter."_v on a.assetId=".$counter."_v.assetId ");
|
||||
my $alias = $counter . '_v';
|
||||
push(@joins," left join metaData_values $alias on a.assetId=$alias.assetId and d.revisionDate = $alias.revisionDate ");
|
||||
# Get the field (State) and the value (Wisconsin) from the $expression.
|
||||
$expression =~ /($attribute)\s*($operator)\s*($attribute)/gi;
|
||||
my $field = $1;
|
||||
|
|
@ -670,7 +671,12 @@ sub getShortcutByCriteria {
|
|||
}
|
||||
|
||||
my $sql = "select a.assetId from asset a
|
||||
".join("\n", @joins)."
|
||||
left join assetData d on a.assetId = d.assetId
|
||||
and d.revisionDate=(
|
||||
select max(revisionDate)
|
||||
from assetData d2
|
||||
where d2.assetId = a.assetId
|
||||
) ".join("\n", @joins)."
|
||||
where a.className = ".$db->quote($self->getShortcutDefault->get("className"));
|
||||
# Add constraint only if it has been modified.
|
||||
$sql .= " and ".$constraint if (($constraint ne $criteria) && $constraint ne "");
|
||||
|
|
|
|||
|
|
@ -528,7 +528,9 @@ The WebGUI::Shop::TransactionItem being refunded.
|
|||
|
||||
sub onRefund {
|
||||
my ($self, $item) = @_;
|
||||
$self->onCancelRecurring($item);
|
||||
if ($self->isRecurring) {
|
||||
$self->onCancelRecurring($item);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1792,34 +1792,42 @@ sub view {
|
|||
$var{'addaccessory_url'} = $self->getUrl('func=addAccessory');
|
||||
$var{'addaccessory_label'} = $i18n->get(36);
|
||||
##Need an id for collateral operations, and an assetId for asset instantiation.
|
||||
foreach my $collateral ( @{ $self->getAllCollateral('accessoryJSON') } ) {
|
||||
ACCESSORY: foreach my $collateral ( @{ $self->getAllCollateral('accessoryJSON') } ) {
|
||||
my $id = $collateral->{accessoryAssetId};
|
||||
$segment = $self->session->icon->delete('func=deleteAccessoryConfirm&aid='.$id,$self->get('url'),$i18n->get(2))
|
||||
. $self->session->icon->moveUp('func=moveAccessoryUp&aid='.$id,$self->get('url'))
|
||||
. $self->session->icon->moveDown('func=moveAccessoryDown&aid='.$id,$self->get('url'));
|
||||
my $accessory_vars = {
|
||||
accessory_title => $i18n->get('Lost'),
|
||||
accessory_controls => $segment,
|
||||
};
|
||||
my $accessory = WebGUI::Asset->newById($session, $collateral->{accessoryAssetId});
|
||||
push(@accessoryloop,{
|
||||
'accessory_URL' => $accessory->getUrl,
|
||||
'accessory_title' => $accessory->getTitle,
|
||||
'accessory_controls' => $segment,
|
||||
});
|
||||
if ( $accessory ) {
|
||||
$accessory_vars->{ accessory_URL } = $accessory->getUrl;
|
||||
$accessory_vars->{ accessory_title } = $accessory->getTitle;
|
||||
}
|
||||
push(@accessoryloop, $accessory_vars);
|
||||
}
|
||||
$var{accessory_loop} = \@accessoryloop;
|
||||
|
||||
#---related
|
||||
$var{'addrelatedproduct_url'} = $self->getUrl('func=addRelated');
|
||||
$var{'addrelatedproduct_label'} = $i18n->get(37);
|
||||
foreach my $collateral ( @{ $self->getAllCollateral('relatedJSON')} ) {
|
||||
RELATED: foreach my $collateral ( @{ $self->getAllCollateral('relatedJSON')} ) {
|
||||
my $id = $collateral->{relatedAssetId};
|
||||
$segment = $self->session->icon->delete('func=deleteRelatedConfirm&rid='.$id, $self->get('url'),$i18n->get(4))
|
||||
. $self->session->icon->moveUp('func=moveRelatedUp&rid='.$id, $self->get('url'))
|
||||
. $self->session->icon->moveDown('func=moveRelatedDown&rid='.$id, $self->get('url'));
|
||||
my $related_vars = {
|
||||
relatedproduct_title => $i18n->get('Lost'),
|
||||
relatedproduct_controls => $segment,
|
||||
};
|
||||
my $related = WebGUI::Asset->newById($session, $collateral->{relatedAssetId});
|
||||
push(@relatedloop,{
|
||||
'relatedproduct_URL' => $related->getUrl,
|
||||
'relatedproduct_title' => $related->getTitle,
|
||||
'relatedproduct_controls' => $segment,
|
||||
});
|
||||
if ($related) {
|
||||
$related_vars->{ relatedproduct_URL } = $related->getUrl;
|
||||
$related_vars->{ relatedproduct_title } = $related->getTitle;
|
||||
}
|
||||
push(@relatedloop, $related_vars);
|
||||
}
|
||||
$var{relatedproduct_loop} = \@relatedloop;
|
||||
|
||||
|
|
|
|||
|
|
@ -91,13 +91,6 @@ property cacheTimeout => (
|
|||
label => ["cache timeout",'Asset_Snippet'],
|
||||
hoverHelp => ["cache timeout help",'Asset_Snippet'],
|
||||
);
|
||||
property processAsTemplate => (
|
||||
fieldType => 'yesNo',
|
||||
label => ['process as template','Asset_Snippet'],
|
||||
hoverHelp => ['process as template description','Asset_Snippet'],
|
||||
tab => "properties",
|
||||
default => 0,
|
||||
);
|
||||
property mimeType => (
|
||||
tab => "properties",
|
||||
hoverHelp => ['mimeType description','Asset_Snippet'],
|
||||
|
|
@ -105,6 +98,15 @@ property mimeType => (
|
|||
fieldType => 'mimeType',
|
||||
default => 'text/html',
|
||||
);
|
||||
property templateParser => (
|
||||
fieldType => 'templateParser',
|
||||
allowNone => 1,
|
||||
label => ['parser','Asset_Template'],
|
||||
hoverHelp => ['parser description','Asset_Template'],
|
||||
tab => 'properties',
|
||||
defaultValue => '',
|
||||
);
|
||||
|
||||
has '+uiLevel' => (
|
||||
default => 5,
|
||||
);
|
||||
|
|
@ -247,13 +249,15 @@ sub view {
|
|||
my $out = $session->cache->get( $cacheKey );
|
||||
return $out if $out;
|
||||
}
|
||||
my $output = $self->usePacked
|
||||
? $self->snippetPacked
|
||||
: $self->snippet
|
||||
;
|
||||
my $output = $self->get('usePacked')
|
||||
? $self->get("snippetPacked")
|
||||
: $self->get('snippet')
|
||||
;
|
||||
$output = $self->getToolbar.$output if ($session->isAdminOn && !$calledAsWebMethod);
|
||||
if ($self->processAsTemplate) {
|
||||
$output = WebGUI::Asset::Template->processRaw($session, $output, $self->get);
|
||||
if (my $parser = $self->templateParser) {
|
||||
$output = WebGUI::Asset::Template->processRaw(
|
||||
$session, $output, $self->get, $parser
|
||||
);
|
||||
}
|
||||
WebGUI::Macro::process($session,\$output);
|
||||
unless ($noCache) {
|
||||
|
|
|
|||
|
|
@ -207,6 +207,26 @@ sub exportAssetData {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 exportGetRelatedAssetIds
|
||||
|
||||
Overriden to include any topics in which this story would appear.
|
||||
|
||||
=cut
|
||||
|
||||
sub exportGetRelatedAssetIds {
|
||||
my $self = shift;
|
||||
my $rel = $self->SUPER::exportGetRelatedAssetIds(@_);
|
||||
push @$rel, @{
|
||||
WebGUI::Keyword->new($self->session)->getMatchingAssets({
|
||||
keywords => WebGUI::Keyword::string2list($self->get('keywords')),
|
||||
isa => 'WebGUI::Asset::Wobject::StoryTopic',
|
||||
})
|
||||
};
|
||||
return $rel;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 formatDuration ( $lastUpdated )
|
||||
|
||||
Format the time since this story was last updated. If it is longer than 1 week, then
|
||||
|
|
@ -396,6 +416,9 @@ sub getEditForm {
|
|||
value => $i18n->get('save and add another photo'),
|
||||
}),
|
||||
};
|
||||
if ($session->setting->get('metaDataEnabled')) {
|
||||
$var->{metadata} = $self->getMetaDataAsFormFields;
|
||||
}
|
||||
$var->{ photo_form_loop } = [];
|
||||
##Provide forms for the existing photos, if any
|
||||
##Existing photos get a delete Yes/No.
|
||||
|
|
@ -405,12 +428,16 @@ sub getEditForm {
|
|||
foreach my $photoIndex (1..$numberOfPhotos) {
|
||||
my $photo = $photoData->[$photoIndex-1];
|
||||
my $storage = WebGUI::Storage->get($session, $photo->{storageId});
|
||||
my $filename = $storage->getFiles->[0];
|
||||
my $filename = $storage && $storage->getFiles->[0];
|
||||
push @{ $var->{ photo_form_loop } }, {
|
||||
hasPhoto => $filename ? 1 : 0,
|
||||
imgThumb => $filename ? $storage->getThumbnailUrl($filename) : '',
|
||||
imgUrl => $filename ? $storage->getUrl($filename) : '',
|
||||
imgFilename => $filename ? $filename : '',
|
||||
imgRemoteUrlForm => WebGUI::Form::text($session, {
|
||||
name => 'imgRemoteUrl'.$photoIndex,
|
||||
value => $photo->{remoteUrl},
|
||||
}),
|
||||
newUploadForm => WebGUI::Form::file($session, {
|
||||
name => 'newPhoto' . $photoIndex,
|
||||
maxAttachments => 1,
|
||||
|
|
@ -442,6 +469,9 @@ sub getEditForm {
|
|||
};
|
||||
}
|
||||
push @{ $var->{ photo_form_loop } }, {
|
||||
imgRemoteUrlForm => WebGUI::Form::text($session, {
|
||||
name => 'imgRemoteUrl',
|
||||
}),
|
||||
newUploadForm => WebGUI::Form::image($session, {
|
||||
name => 'newPhoto',
|
||||
maxAttachments => 1,
|
||||
|
|
@ -580,16 +610,20 @@ sub processEditForm {
|
|||
PHOTO: foreach my $photoIndex (1..$numberOfPhotos) {
|
||||
##TODO: Deletion check and storage cleanup
|
||||
my $storageId = $photoData->[$photoIndex-1]->{storageId};
|
||||
my $storage = $storageId && WebGUI::Storage->get($session, $storageId);
|
||||
my $remote = $form->process("imgRemoteUrl$photoIndex");
|
||||
if ($form->process('deletePhoto'.$photoIndex, 'yesNo')) {
|
||||
my $storage = WebGUI::Storage->get($session, $storageId);
|
||||
$storage->delete if $storage;
|
||||
splice @{ $photoData }, $photoIndex-1, 1;
|
||||
next PHOTO;
|
||||
}
|
||||
##Process photos with urls that replace existing photos
|
||||
if ($remote) {
|
||||
$storage->delete() if $storage;
|
||||
}
|
||||
##Process uploads that replace existing photos
|
||||
if (my $uploadId = $form->process('newPhoto'.$photoIndex,'File')) {
|
||||
elsif (my $uploadId = $form->process('newPhoto'.$photoIndex,'File')) {
|
||||
my $upload = WebGUI::Storage->get($session, $uploadId);
|
||||
my $storage = WebGUI::Storage->get($session, $storageId);
|
||||
$storage->clear;
|
||||
my $filename = $upload->getFiles->[0];
|
||||
$storage->addFileFromFilesystem($upload->getPath($filename));
|
||||
|
|
@ -600,31 +634,43 @@ sub processEditForm {
|
|||
$upload->delete;
|
||||
}
|
||||
my $newPhoto = {
|
||||
storageId => $storageId,
|
||||
caption => $form->process('imgCaption'.$photoIndex, 'text'),
|
||||
alt => $form->process('imgAlt' .$photoIndex, 'text'),
|
||||
title => $form->process('imgTitle' .$photoIndex, 'text'),
|
||||
byLine => $form->process('imgByline' .$photoIndex, 'text'),
|
||||
url => $form->process('imgUrl' .$photoIndex, 'url' ),
|
||||
};
|
||||
if ($remote) {
|
||||
$newPhoto->{remoteUrl} = $remote;
|
||||
}
|
||||
else {
|
||||
$newPhoto->{storageId} = $storageId;
|
||||
}
|
||||
splice @{ $photoData }, $photoIndex-1, 1, $newPhoto;
|
||||
}
|
||||
my $newStorageId = $form->process('newPhoto', 'image');
|
||||
if ($newStorageId) {
|
||||
my $newStorage = WebGUI::Storage->get($session, $newStorageId);
|
||||
my $photoName = $newStorage->getFiles->[0];
|
||||
my ($width, $height) = $newStorage->getSizeInPixels($photoName);
|
||||
if ($width > $self->getArchive->photoWidth) {
|
||||
$newStorage->resize($photoName, $self->getArchive->photoWidth);
|
||||
}
|
||||
push @{ $photoData }, {
|
||||
my $newRemote = $form->process('imgRemoteUrl');
|
||||
if ($newStorageId || $newRemote) {
|
||||
my $newPhoto = {
|
||||
caption => $form->process('newImgCaption', 'text'),
|
||||
alt => $form->process('newImgAlt', 'text'),
|
||||
title => $form->process('newImgTitle', 'text'),
|
||||
byLine => $form->process('newImgByline', 'text'),
|
||||
url => $form->process('newImgUrl', 'url'),
|
||||
storageId => $newStorageId,
|
||||
};
|
||||
if ($newRemote) {
|
||||
$newPhoto->{remoteUrl} = $newRemote;
|
||||
}
|
||||
else {
|
||||
my $newStorage = WebGUI::Storage->get($session, $newStorageId);
|
||||
my $photoName = $newStorage->getFiles->[0];
|
||||
my ($width, $height) = $newStorage->getSizeInPixels($photoName);
|
||||
if ($width > $self->getArchive->get('photoWidth')) {
|
||||
$newStorage->resize($photoName, $self->getArchive->get('photoWidth'));
|
||||
}
|
||||
$newPhoto->{storageId} = $newStorageId;
|
||||
}
|
||||
push @{ $photoData }, $newPhoto;
|
||||
}
|
||||
$self->setPhotoData($photoData);
|
||||
$self->{_parent} = $archive; ##Restore archive, for URL and other calculations
|
||||
|
|
@ -666,8 +712,9 @@ Remove the storage locations for this revision of the Asset.
|
|||
override purgeRevision => sub {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
foreach my $photo ( @{ $self->getPhotoData} ) {
|
||||
my $storage = WebGUI::Storage->get($session, $self-$photo->{storageId});
|
||||
PHOTO: foreach my $photo ( @{ $self->getPhotoData} ) {
|
||||
my $id = $photo->{storageId} or next PHOTO;
|
||||
my $storage = WebGUI::Storage->get($session, $id);
|
||||
$storage->delete if $storage;
|
||||
}
|
||||
return super();
|
||||
|
|
@ -832,13 +879,23 @@ sub viewTemplateVariables {
|
|||
}
|
||||
}
|
||||
|
||||
my $key = WebGUI::Keyword->new($session);
|
||||
my $keywords = $key->getKeywordsForAsset( { asArrayRef => 1, asset => $self });
|
||||
my $isExporting = $session->scratch->get('isExporting');
|
||||
my $key = WebGUI::Keyword->new($session);
|
||||
my $keywords = $key->getKeywordsForAsset( { asArrayRef => 1, asset => $self });
|
||||
$var->{keyword_loop} = [];
|
||||
my $parent = $self->getParent;
|
||||
my $upwards = $parent->isa('WebGUI::Asset::Wobject::StoryArchive')
|
||||
? '' #In parallel with the Keywords files
|
||||
: '../' #Keywords files are one level up
|
||||
;
|
||||
foreach my $keyword (@{ $keywords }) {
|
||||
my $keyword_url = $isExporting
|
||||
? $upwards . $archive->getKeywordFilename($keyword)
|
||||
: $archive->getUrl("func=view;keyword=".$session->url->escape($keyword))
|
||||
;
|
||||
push @{ $var->{keyword_loop} }, {
|
||||
keyword => $keyword,
|
||||
url => $archive->getUrl("func=view;keyword=".$session->url->escape($keyword)),
|
||||
url => $keyword_url,
|
||||
};
|
||||
}
|
||||
$var->{updatedTime} = $self->formatDuration();
|
||||
|
|
@ -849,11 +906,19 @@ sub viewTemplateVariables {
|
|||
$var->{photo_loop} = [];
|
||||
my $photoCounter = 0;
|
||||
PHOTO: foreach my $photo (@{ $photoData }) {
|
||||
next PHOTO unless $photo->{storageId};
|
||||
my $storage = WebGUI::Storage->get($session, $photo->{storageId});
|
||||
my $file = $storage->getFiles->[0];
|
||||
next PHOTO unless $file;
|
||||
my $imageUrl = $storage->getUrl($file);
|
||||
my $imageUrl;
|
||||
if (my $remote = $photo->{remoteUrl}) {
|
||||
$imageUrl = $remote;
|
||||
}
|
||||
elsif (my $id = $photo->{storageId}) {
|
||||
my $storage = WebGUI::Storage->get($session, $photo->{storageId});
|
||||
my $file = $storage->getFiles->[0];
|
||||
next PHOTO unless $file;
|
||||
$imageUrl = $storage->getUrl($file);
|
||||
}
|
||||
else {
|
||||
next PHOTO;
|
||||
}
|
||||
push @{ $var->{photo_loop} }, {
|
||||
imageUrl => $imageUrl,
|
||||
imageCaption => $photo->{caption},
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ use List::MoreUtils qw{ any };
|
|||
use Tie::IxHash;
|
||||
use Clone qw/clone/;
|
||||
use HTML::Packer;
|
||||
use JSON qw{ to_json };
|
||||
use JSON qw{ to_json from_json };
|
||||
use Try::Tiny;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -227,6 +228,8 @@ around cut => sub {
|
|||
return $returnValue;
|
||||
};
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 addRevision ( )
|
||||
|
||||
Override the master addRevision to copy attachments
|
||||
|
|
@ -324,19 +327,22 @@ Returns the WebGUI::FormBuilder object that will be used in generating the edit
|
|||
override getEditForm => sub {
|
||||
my $self = shift;
|
||||
my $tabform = super();
|
||||
my $i18n = WebGUI::International->new($self->session, 'Asset_Template');
|
||||
my $session = $self->session;
|
||||
my ( $url, $style ) = $session->quick(qw( url style ));
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Template');
|
||||
my $returnUrl = $session->form->get("returnUrl");
|
||||
$tabform->addField( "hidden",
|
||||
name=>"returnUrl",
|
||||
value=>$self->session->form->get("returnUrl")
|
||||
value=>$returnUrl,
|
||||
);
|
||||
if ($self->namespace eq "") {
|
||||
my $namespaces = $self->session->dbSlave->buildHashRef("select distinct(namespace) from template order by namespace");
|
||||
my $namespaces = $session->dbSlave->buildHashRef("select distinct(namespace) from template order by namespace");
|
||||
$tabform->getTab("properties")->addField( "combo",
|
||||
name=>"namespace",
|
||||
options=>$namespaces,
|
||||
label=>$i18n->get('namespace'),
|
||||
hoverHelp=>$i18n->get('namespace description'),
|
||||
value=>[$self->session->form->get("namespace")]
|
||||
value=>[$session->form->get("namespace")]
|
||||
);
|
||||
} else {
|
||||
$tabform->getTab("meta")->addField( "ReadOnly",
|
||||
|
|
@ -346,14 +352,68 @@ override getEditForm => sub {
|
|||
value=>$self->namespace
|
||||
);
|
||||
}
|
||||
if($self->session->config->get("templateParsers")){
|
||||
my @temparray = @{$self->session->config->get("templateParsers")};
|
||||
|
||||
my $previewButtons
|
||||
= $tabform->getTab('properties')->addField( "ButtonGroup",
|
||||
name => 'previewButtons',
|
||||
label => $i18n->get('Preview'),
|
||||
);
|
||||
$previewButtons->addButton( 'Button' => { id => 'preview', value => $i18n->get('Preview') } );
|
||||
$previewButtons->addButton( 'Button' => { id => 'previewConfig', value => $i18n->get('Configure') } );
|
||||
my $cform = WebGUI::HTMLForm->new($session);
|
||||
$cform->yesNo(
|
||||
id => 'previewRaw',
|
||||
name => 'previewRaw',
|
||||
label => $i18n->get('Plain Text?'),
|
||||
hoverHelp => $i18n->get('Plain Text hoverHelp'),
|
||||
);
|
||||
$cform->text(
|
||||
id => 'previewFetchUrl',
|
||||
label => $i18n->get('URL'),
|
||||
hoverHelp => $i18n->get('URL hoverHelp'),
|
||||
defaultValue => $returnUrl,
|
||||
);
|
||||
$cform->button(
|
||||
id => 'previewFetch',
|
||||
label => $i18n->get('Fetch Variables'),
|
||||
hoverHelp => $i18n->get('Fetch Variables hoverHelp'),
|
||||
value => $i18n->get('Fetch'),
|
||||
);
|
||||
$cform->codearea(
|
||||
id => 'previewVars',
|
||||
label => $i18n->get('Variables'),
|
||||
hoverHelp => $i18n->get('Variables hoverHelp'),
|
||||
);
|
||||
|
||||
$cform->hidden(id => 'previewId', value => $self->getId);
|
||||
$cform->hidden(id => 'previewGateway', value => $url->gateway);
|
||||
$tabform->getTab('properties')->addField("ReadOnly",
|
||||
name => 'previewDialog',
|
||||
value => qq(
|
||||
<div id='previewConfigForm'>
|
||||
<div class='hd'>${\ $i18n->get('Configure Preview') }</div>
|
||||
<table class='bd'>${\ $cform->printRowsOnly }</table>
|
||||
<div class='ft' style='margin:0 auto; text-align: center'>
|
||||
<button id='previewConfigClose'>Close</button>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
);
|
||||
|
||||
$style->setScript($url->extras($_)) for qw(
|
||||
yui/build/json/json-min.js
|
||||
yui/build/container/container-min.js
|
||||
templatePreview.js
|
||||
);
|
||||
|
||||
if($session->config->get("templateParsers")){
|
||||
my @temparray = @{$session->config->get("templateParsers")};
|
||||
tie my %parsers, 'Tie::IxHash';
|
||||
while(my $a = shift @temparray){
|
||||
$parsers{$a} = $self->getParser($self->session, $a)->getName();
|
||||
$parsers{$a} = $self->getParser($session, $a)->getName();
|
||||
}
|
||||
my $value = [$self->parser];
|
||||
$value = \[$self->session->config->get("defaultTemplateParser")] if(!$self->parser);
|
||||
$value = \[$session->config->get("defaultTemplateParser")] if(!$self->parser);
|
||||
$tabform->getTab("properties")->addField( "SelectBox",
|
||||
name=>"parser",
|
||||
options=>\%parsers,
|
||||
|
|
@ -501,6 +561,22 @@ sub getParser {
|
|||
return $parser->new($session);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
#
|
||||
# See the warning about using this on processVariableHeaders(). If no
|
||||
# variables were captured, we'll return the empty string.
|
||||
|
||||
sub getVariableJson {
|
||||
my ($class, $session) = @_;
|
||||
my ($show, $vars, $json);
|
||||
|
||||
return ($show = $session->stow->get('showTemplateVars'))
|
||||
&& ($vars = $show->{vars})
|
||||
&& ($json = eval { JSON::encode_json($vars) })
|
||||
&& ($show->{startDelimiter} . $json . $show->{endDelimiter})
|
||||
or '';
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 importAssetCollateralData ( data )
|
||||
|
|
@ -631,6 +707,15 @@ sub process {
|
|||
return to_json( $self->param );
|
||||
}
|
||||
|
||||
my $stow = $session->stow;
|
||||
my $show = $stow->get('showTemplateVars');
|
||||
if ( $show && $show->{assetId} eq $self->getId && $self->canEdit ) {
|
||||
# This will never be true again, cause we're getting rid of assetId
|
||||
delete $show->{assetId};
|
||||
$show->{vars} = $vars;
|
||||
$stow->set( showTemplateVars => $show );
|
||||
}
|
||||
|
||||
$self->prepare unless ($self->{_prepared});
|
||||
my $parser = $self->getParser($session, $self->parser);
|
||||
my $template = $self->usePacked
|
||||
|
|
@ -653,6 +738,59 @@ sub process {
|
|||
return $output;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
# Used for debugging and the template test renderer.
|
||||
|
||||
# WARNING: Please do not rely on this behavior. It's a bit of a hack, and
|
||||
# should not be considered part of the core API. Eventually, we will have
|
||||
# introspectable template objects so that you can more easily (and
|
||||
# efficiently) get this kind of information.
|
||||
|
||||
# If the first value for the 'X-Webgui-Template-Variables' header is our
|
||||
# assetId, then in addition to processing the template, append add a json
|
||||
# representation of our template variables to the response. The headers
|
||||
# "X-Webgui-Template-Variables-Start" and "X-Webgui-Template-Variables-End"
|
||||
# will contain the delimiters for the start and end of this content so that
|
||||
# the user agent (who had to have stuck the header in in the first place) can
|
||||
# parse it out. The delimiters will make the whole thing look like an xml
|
||||
# comment (<!-- ... -->) just in case.
|
||||
|
||||
# We would just send the vars in the header, but different webservers have
|
||||
# different limits on header field size and it's impossible to say whether our
|
||||
# data will fit inside them or not.
|
||||
|
||||
# This is intended to be called earlier in the request cycle (in the Content
|
||||
# URL handler) so that the headers get sent before any chunked content starts
|
||||
# being set up. We set the stow here and check it during process() to see
|
||||
# whether we need to include the delimited json. Later on, Content will call
|
||||
# call getVariableJson to get the results.
|
||||
|
||||
{
|
||||
my $head = 'X-Webgui-Template-Variables';
|
||||
my @chr = ('0'..'9', 'a'..'z', 'A'..'Z');
|
||||
|
||||
sub processVariableHeaders {
|
||||
my ($class, $session) = @_;
|
||||
my $r = $session->request;
|
||||
if (my $id = $r->headers->header($head)) {
|
||||
my $rnd = join('', map { $chr[int(rand($#chr))] } (1..32));
|
||||
my $out = {};
|
||||
my $st = "<!-- $rnd ";
|
||||
my $end = " $rnd -->";
|
||||
$out->{"$head-Start"} = $st;
|
||||
$out->{"$head-End"} = $end;
|
||||
$session->response->headers( $out );
|
||||
$session->stow->set(
|
||||
showTemplateVars => {
|
||||
assetId => $id,
|
||||
startDelimiter => $st,
|
||||
endDelimiter => $end,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -921,6 +1059,42 @@ sub www_manage {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_preview
|
||||
|
||||
Rendes this template with the given variables (posted as JSON)
|
||||
|
||||
=cut
|
||||
|
||||
sub www_preview {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient unless $self->canEdit;
|
||||
|
||||
my $form = $session->form;
|
||||
my $http = $session->http;
|
||||
|
||||
try {
|
||||
my $output = $self->processRaw(
|
||||
$session,
|
||||
$form->get('template'),
|
||||
from_json($form->get('variables')),
|
||||
$form->get('parser'),
|
||||
);
|
||||
if ($form->get('plainText')) {
|
||||
$http->setMimeType('text/plain');
|
||||
}
|
||||
elsif ($output !~ /<html>/) {
|
||||
$output = $session->style->userStyle($output);
|
||||
}
|
||||
return $output;
|
||||
} catch {
|
||||
$http->setMimeType('text/plain');
|
||||
$_[0];
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_view
|
||||
|
||||
Override the default behavior. When a template is viewed, it redirects you
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package WebGUI::Asset::Template::TemplateToolkit;
|
|||
use strict;
|
||||
use base 'WebGUI::Asset::Template::Parser';
|
||||
use Template;
|
||||
use WebGUI::Template::Provider;
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub _rewriteVars { # replace dots with underscrores in keys (except in keys that aren't usable as variables (URLs etc.))
|
||||
|
|
@ -81,12 +82,30 @@ sub process {
|
|||
my $vars = $self->addSessionVars(shift);
|
||||
my ($t,$output);
|
||||
eval {
|
||||
$t = Template->new({
|
||||
INTERPOLATE => 1, # expand "$var" in plain text
|
||||
POST_CHOMP => 1, # cleanup whitespace
|
||||
EVAL_PERL => 0, # evaluate Perl code blocks
|
||||
});
|
||||
$t->process( \$template, _rewriteVars($vars),\$output) || $self->session->log->error($t->error());
|
||||
my $config = $self->session->config->get( 'template' ) || {};
|
||||
$config->{INTERPOLATE} //= 1; # expand "$var" in plain text
|
||||
$config->{POST_CHOMP} //= 1; # cleanup whitespace
|
||||
$config->{EVAL_PERL} //= 0; # evaluate Perl code blocks
|
||||
# Add WebGUI::Template::Plugin to PLUGIN_BASE
|
||||
if ( defined $config->{PLUGIN_BASE} && !ref $config->{PLUGIN_BASE} ) {
|
||||
$config->{PLUGIN_BASE} = [ $config->{PLUGIN_BASE} ];
|
||||
}
|
||||
elsif ( !defined $config->{PLUGIN_BASE} ) {
|
||||
$config->{PLUGIN_BASE} = [];
|
||||
}
|
||||
push @{$config->{PLUGIN_BASE}}, 'WebGUI::Template::Plugin';
|
||||
|
||||
# Allow WebGUI assets to be included in templates
|
||||
$config->{LOAD_TEMPLATES} = [ WebGUI::Template::Provider->new( $self->session, $config ) ];
|
||||
|
||||
$t = Template->new( $config );
|
||||
$vars = _rewriteVars($vars);
|
||||
$vars->{_session} = $self->session;
|
||||
unless ($t->process( \$template, $vars, \$output)) {
|
||||
my $e = $t->error;
|
||||
$self->session->log->error($e);
|
||||
die $e;
|
||||
}
|
||||
};
|
||||
if ($@) {
|
||||
WebGUI::Error::Template->throw( error => $@ );
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use Moose;
|
|||
use Tie::IxHash;
|
||||
use WebGUI::Definition::Asset;
|
||||
extends 'WebGUI::Asset::Wobject';
|
||||
with 'WebGUI::Role::Asset::JSONCollateral';
|
||||
|
||||
define assetName => ['assetName', 'Asset_Calendar'];
|
||||
define icon => 'calendar.gif';
|
||||
|
|
@ -260,7 +261,7 @@ property icalFeeds => (
|
|||
label => ['Feed URL','Asset_Calendar'],
|
||||
},
|
||||
{
|
||||
name => 'status',
|
||||
name => 'lastResult',
|
||||
type => 'readonly',
|
||||
label => ['434','WebGUI'],
|
||||
},
|
||||
|
|
@ -303,6 +304,7 @@ use WebGUI::Search;
|
|||
use WebGUI::Form;
|
||||
use WebGUI::HTML;
|
||||
use WebGUI::DateTime;
|
||||
use WebGUI::ICal;
|
||||
|
||||
use DateTime;
|
||||
use JSON;
|
||||
|
|
@ -348,10 +350,6 @@ The date this feed was added, or edited last.
|
|||
|
||||
The results of what happened the last time this feed was accessed to pull iCal.
|
||||
|
||||
=head4 feedType
|
||||
|
||||
What kind of feed this is.
|
||||
|
||||
=cut
|
||||
|
||||
sub addFeed {
|
||||
|
|
@ -860,6 +858,17 @@ override processEditForm => sub {
|
|||
$self->createSubscriptionGroup();
|
||||
}
|
||||
|
||||
my @feeds = @{ $self->getFeeds };
|
||||
foreach my $feed (@feeds) {
|
||||
if ($feed->{lastUpdated} eq 'new') {
|
||||
$feed->{lastUpdated} = 'never';
|
||||
}
|
||||
if ($feed->{lastResult} eq 'new') {
|
||||
$feed->{lastResult} = '';
|
||||
}
|
||||
$self->setFeed($feed->{feedId}, $feed);
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
@ -1706,97 +1715,20 @@ sub www_ical {
|
|||
$dt_end = $dt_start->clone->add( seconds => $self->icalInterval );
|
||||
}
|
||||
|
||||
my $ical = WebGUI::ICal->new();
|
||||
|
||||
# Get all the events we're going to display
|
||||
my @events = $self->getEventsIn($dt_start->toMysql,$dt_end->toMysql);
|
||||
|
||||
|
||||
my $ical = qq{BEGIN:VCALENDAR\r\n}
|
||||
. qq{PRODID:WebGUI }.$WebGUI::VERSION."-".$WebGUI::STATUS.qq{\r\n}
|
||||
. qq{VERSION:2.0\r\n};
|
||||
|
||||
# VEVENT:
|
||||
EVENT: for my $event (@events) {
|
||||
next EVENT unless $event->canView();
|
||||
$ical .= qq{BEGIN:VEVENT\r\n};
|
||||
|
||||
### UID
|
||||
# Use feed's UID to prevent over-propagation
|
||||
if ($event->feedUid) {
|
||||
$ical .= qq{UID:}.$event->feedUid."\r\n";
|
||||
}
|
||||
# Create a UID for feeds native to this calendar
|
||||
else {
|
||||
my $domain = $session->config->get("sitename")->[0];
|
||||
$ical .= qq{UID:}.$event->assetId.'@'.$domain."\r\n";
|
||||
}
|
||||
|
||||
# LAST-MODIFIED (revisionDate)
|
||||
$ical .= qq{LAST-MODIFIED:}
|
||||
. WebGUI::DateTime->new($self->session, $event->revisionDate)->toIcal
|
||||
. "\r\n";
|
||||
|
||||
# CREATED (creationDate)
|
||||
$ical .= qq{CREATED:}
|
||||
. WebGUI::DateTime->new($self->session, $event->creationDate)->toIcal
|
||||
. "\r\n";
|
||||
|
||||
# SEQUENCE
|
||||
my $sequenceNumber = $event->iCalSequenceNumber;
|
||||
if (defined $sequenceNumber) {
|
||||
$ical .= qq{SEQUENCE:}
|
||||
. $event->iCalSequenceNumber
|
||||
. "\r\n";
|
||||
}
|
||||
|
||||
# DTSTART
|
||||
my $eventStart = $event->getIcalStart;
|
||||
$ical .= 'DTSTART';
|
||||
if ($eventStart !~ /T/) {
|
||||
$ical .= ';VALUE=DATE';
|
||||
}
|
||||
$ical .= ":$eventStart\r\n";
|
||||
|
||||
# DTEND
|
||||
my $eventEnd = $event->getIcalEnd;
|
||||
$ical .= 'DTEND';
|
||||
if ($eventEnd !~ /T/) {
|
||||
$ical .= ';VALUE=DATE';
|
||||
}
|
||||
$ical .= ":$eventEnd\r\n";
|
||||
|
||||
# Summary (the title)
|
||||
# Wrapped at 75 columns
|
||||
$ical .= $self->wrapIcal("SUMMARY:".$event->title)."\r\n";
|
||||
|
||||
# Description (the text)
|
||||
# Wrapped at 75 columns
|
||||
$ical .= $self->wrapIcal("DESCRIPTION:".$event->description)."\r\n";
|
||||
|
||||
# Location (the text)
|
||||
# Wrapped at 75 columns
|
||||
$ical .= $self->wrapIcal("LOCATION:".$event->location)."\r\n";
|
||||
|
||||
# X-WEBGUI lines
|
||||
if ($event->groupIdView) {
|
||||
$ical .= "X-WEBGUI-GROUPIDVIEW:".$event->groupIdView."\r\n";
|
||||
}
|
||||
if ($event->get("groupIdEdit")) {
|
||||
$ical .= "X-WEBGUI-GROUPIDEDIT:".$event->groupIdEdit."\r\n";
|
||||
}
|
||||
$ical .= "X-WEBGUI-URL:".$event->get("url")."\r\n";
|
||||
$ical .= "X-WEBGUI-MENUTITLE:".$event->menuTitle."\r\n";
|
||||
|
||||
$ical .= qq{END:VEVENT\r\n};
|
||||
$event->add_to_calendar($ical);
|
||||
}
|
||||
# ENDVEVENT
|
||||
|
||||
$ical .= qq{END:VCALENDAR\r\n};
|
||||
|
||||
|
||||
# Set mime of text/icalendar
|
||||
$self->session->response->header( 'Content-Disposition' => qq{attachment; filename="feed.ics"});
|
||||
$self->session->response->content_type("text/calendar");
|
||||
return $ical;
|
||||
#$self->session->http->setMimeType("text/plain");
|
||||
$self->session->http->setFilename("feed.ics","text/calendar");
|
||||
return $ical->as_string;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -48,6 +48,20 @@ property items => (
|
|||
noFormPost => 1,
|
||||
fieldType => 'text',
|
||||
);
|
||||
property autoPlay => (
|
||||
fieldType => 'yesNo',
|
||||
defaultValue => 0,
|
||||
tab => "properties",
|
||||
hoverHelp => ['carousel autoPlay description', 'Asset_Carousel' ],
|
||||
label => ['carousel autoPlay label', 'Asset_Carousel' ],
|
||||
);
|
||||
property autoPlayInterval => (
|
||||
fieldType => 'Integer',
|
||||
defaultValue => 4,
|
||||
tab => 'properties',
|
||||
hoverHelp => ['carousel autoPlayInterval description', 'Asset_Carousel'],
|
||||
label => ['carousel autoPlayInterval label', 'Asset_Carousel'],
|
||||
);
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -63,16 +77,30 @@ override getEditForm => sub {
|
|||
my $tabform = super();
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Carousel");
|
||||
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/editor/editor-min.js'));
|
||||
$self->session->style->setCss($self->session->url->extras('yui/build/editor/assets/skins/sam/editor.css'));
|
||||
$self->session->style->setScript($self->session->url->extras('wobject/Carousel/carousel.js'));
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'), {type =>
|
||||
'text/javascript'});
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/element/element-min.js'), {type =>
|
||||
'text/javascript'});
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/tabview/tabview-min.js'), {type =>
|
||||
'text/javascript'});
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/editor/editor-min.js'), {type =>
|
||||
'text/javascript'});
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/json/json-min.js'), {type =>
|
||||
'text/javascript'});
|
||||
$self->session->style->setLink($self->session->url->extras('yui/build/editor/assets/skins/sam/editor.css'), {type
|
||||
=>'text/css', rel=>'stylesheet'});
|
||||
$self->session->style->setLink($self->session->url->extras('yui/build/tabview/assets/skins/sam/tabview.css'), {type
|
||||
=>'text/css', rel=>'stylesheet'});
|
||||
$self->session->style->setScript($self->session->url->extras('wobject/Carousel/carousel.js'), {type =>
|
||||
'text/javascript'});
|
||||
|
||||
my $tableRowStart =
|
||||
'<tr id="items_row">'
|
||||
.' <td class="formDescription" valign="top" style="width: 180px;"><label for="item1">'
|
||||
.$i18n->get("items label").'</label><div class="wg-hoverhelp">'.$i18n->get("items description").'</div></td>'
|
||||
.' <td id="items_td" valign="top" class="tableData">'
|
||||
.' <input type="button" value="Add item" onClick="javascript:addItem()"></input><br />'
|
||||
.' <input type="hidden" id="items_formId" name="items" />'
|
||||
.' <input type="button" value="Add item" onclick="window.carouselEditor.addTab()"></input><br />'
|
||||
." <br />\n";
|
||||
|
||||
$tabform->getTab("properties")->addField('ReadOnly', value => $tableRowStart);
|
||||
|
|
@ -122,6 +150,27 @@ onClick='javascript:deleteItem(this.id)'></input>\n"
|
|||
."</script>\n";
|
||||
$tabform->getTab("properties")->addField('ReadOnly', value => $itemHTML);
|
||||
}
|
||||
|
||||
|
||||
$self->session->log->warn('richedit:' .$self->get('richEditor'));
|
||||
my $richEditId = $self->get('richEditor') || "PBrichedit000000000001";
|
||||
my $richedit = WebGUI::Asset->newById( $self->session, $richEditId );
|
||||
my $config = JSON->new->encode( $richedit->getConfig );
|
||||
my $loadMcePlugins = $richedit->getLoadPlugins;
|
||||
my $items = $self->get('items') ? JSON->new->decode($self->get('items'))->{items} : [];
|
||||
$items = JSON->new->encode( $items );
|
||||
my $i18nJson = JSON->new->encode( { "delete" => $i18n->get("delete") } );
|
||||
|
||||
$tabform->getTab('properties')->raw(<<"ENDHTML");
|
||||
<div id="carouselEditor"></div>
|
||||
<script type="text/javascript">
|
||||
$loadMcePlugins
|
||||
YAHOO.util.Event.onDOMReady( function() {
|
||||
window.carouselEditor = new WebGUI.Carousel.Editor( "carouselEditor", $config, $items, $i18nJson );
|
||||
} );
|
||||
</script>
|
||||
ENDHTML
|
||||
|
||||
my $tableRowEnd = qq|
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -165,32 +214,9 @@ Used to process properties from the form posted.
|
|||
override processEditForm => sub {
|
||||
my $self = shift;
|
||||
my $form = $self->session->form;
|
||||
my (@items,$items);
|
||||
super();
|
||||
|
||||
foreach my $param ($form->param) {
|
||||
if ($param =~ m/^item_/){
|
||||
my $sequenceNumber = $param;
|
||||
$sequenceNumber =~ s/^item_//;
|
||||
if($form->process('itemId_'.$sequenceNumber)){
|
||||
push(@items,{
|
||||
sequenceNumber => $sequenceNumber,
|
||||
text => $form->process($param),
|
||||
itemId => $form->process('itemId_'.$sequenceNumber),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my @sortedItems = sort { $a->{sequenceNumber} cmp $b->{sequenceNumber} } @items;
|
||||
@items = ();
|
||||
for (my $i=0; $i<scalar @sortedItems; $i++) {
|
||||
$sortedItems[$i]->{sequenceNumber} = $i + 1;
|
||||
push(@items,$sortedItems[$i]);
|
||||
}
|
||||
|
||||
$items = JSON->new->encode({items => \@items});
|
||||
$self->update({items => $items});
|
||||
my $items = JSON->new->decode( $form->get("items") );
|
||||
$self->update({ items => JSON->new->encode({ items => $items }) });
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -879,19 +879,19 @@ override commit => sub {
|
|||
unless (defined $cron) {
|
||||
$cron = WebGUI::Workflow::Cron->create($self->session, {
|
||||
title=>$self->getTitle." ".$i18n->get("mail"),
|
||||
minuteOfHour=>"*/".($self->getMailInterval/60),
|
||||
className=>(ref $self),
|
||||
methodName=>"new",
|
||||
parameters=>$self->getId,
|
||||
workflowId=>"csworkflow000000000001"
|
||||
workflowId=>"csworkflow000000000001",
|
||||
$self->getCronIntervals,
|
||||
});
|
||||
$self->update({getMailCronId=>$cron->getId});
|
||||
}
|
||||
if ($self->getMail) {
|
||||
$cron->set({enabled=>1,title=>$self->getTitle." ".$i18n->get("mail"), minuteOfHour=>"*/".($self->getMailInterval/60)});
|
||||
} else {
|
||||
$cron->set({enabled=>0,title=>$self->getTitle." ".$i18n->get("mail"), minuteOfHour=>"*/".($self->getMailInterval/60)});
|
||||
}
|
||||
$cron->set({
|
||||
enabled => $self->get('getMail') ? 1 : 0,
|
||||
title => $self->getTitle." ".$i18n->get("mail"),
|
||||
$self->getCronIntervals(),
|
||||
});
|
||||
};
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -931,11 +931,11 @@ sub duplicate {
|
|||
my $i18n = WebGUI::International->new($self->session, "Asset_Collaboration");
|
||||
my $newCron = WebGUI::Workflow::Cron->create($self->session, {
|
||||
title=>$self->getTitle." ".$i18n->get("mail"),
|
||||
minuteOfHour=>"*/".($self->get("getMailInterval")/60),
|
||||
className=>(ref $self),
|
||||
methodName=>"new",
|
||||
parameters=>$self->getId,
|
||||
workflowId=>"csworkflow000000000001"
|
||||
workflowId=>"csworkflow000000000001",
|
||||
$self->getCronIntervals(),
|
||||
});
|
||||
$newAsset->update({getMailCronId=>$newCron->getId});
|
||||
$newAsset->incrementReplies('','');
|
||||
|
|
@ -959,6 +959,87 @@ sub duplicateBranch {
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getCronIntervals
|
||||
|
||||
Translate the settings for getCsMailInterval into options for Spectre's Cron,
|
||||
minuteOfHour, hourOfDay and so on.
|
||||
|
||||
Returns a hash of those options that can be folded into a hash of property settings for the
|
||||
Cron job.
|
||||
|
||||
=cut
|
||||
|
||||
sub getCronIntervals {
|
||||
my $self = shift;
|
||||
my $interval = $self->get('getMailInterval');
|
||||
##My kingdom for a switch statement!
|
||||
if ($interval eq 'every minute') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '*/1',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every other minute') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '*/2',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every 5 minutes') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '*/5',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every 10 minutes') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '*/10',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every 15 minutes') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '*/15',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every 20 minutes') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '*/20',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every 30 minutes') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '*/30',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every hour') {
|
||||
return(
|
||||
hourOfDay => '*',
|
||||
minuteOfHour => '0',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'every other hour') {
|
||||
return(
|
||||
hourOfDay => '*/2',
|
||||
minuteOfHour => '0',
|
||||
);
|
||||
}
|
||||
elsif ($interval eq 'once per day') {
|
||||
return(
|
||||
hourOfDay => '7',
|
||||
minuteOfHour => '0',
|
||||
);
|
||||
}
|
||||
return(
|
||||
minuteOfHour => '*/10',
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getHelpers ( )
|
||||
|
||||
Add the collaboration-specific asset helpers
|
||||
|
|
@ -1282,6 +1363,35 @@ sub getViewTemplateVars {
|
|||
return \%var;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
=head2 groupIdView ( [newvalue] )
|
||||
|
||||
Override the existing accessor to update the subscription group if the value
|
||||
changes.
|
||||
|
||||
=cut
|
||||
|
||||
around groupIdView => sub {
|
||||
my $orig = shift;
|
||||
my $self = shift;
|
||||
my ( $newValue ) = @_;
|
||||
my $oldValue = $self->$orig;
|
||||
my $return = $self->$orig(@_);
|
||||
# Update the subscription group so if they can't see the collab, they don't get e-mailed
|
||||
if ( $newValue && $newValue != $oldValue ) {
|
||||
my $instance_data = {
|
||||
workflowId => 'xR-_GRRbjBojgLsFx3dEMA',
|
||||
className => 'WebGUI::Asset',
|
||||
methodName => 'newById',
|
||||
parameters => $self->getId,
|
||||
};
|
||||
my $instance = WebGUI::Workflow::Instance->create($self->session, $instance_data);
|
||||
$instance->start('skipRealtime');
|
||||
}
|
||||
return $return;
|
||||
};
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 incrementReplies ( lastPostDate, lastPostId )
|
||||
|
|
@ -1586,7 +1696,6 @@ sub unsubscribe {
|
|||
$group->deleteUsers([$user->userId]);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 view
|
||||
|
|
|
|||
|
|
@ -320,13 +320,17 @@ override purge => sub {
|
|||
|
||||
=head2 view
|
||||
|
||||
Render the dashboard.
|
||||
Render the dashboard. Of all the positions for content, position1 is reserved for hidden content
|
||||
or content to be placed. Deleting content causes it to go into position1.
|
||||
|
||||
=cut
|
||||
|
||||
sub view {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my %vars = %{$self->get()};
|
||||
$vars{canEdit} = $self->canEdit;
|
||||
$vars{fullUrl} = $self->getUrl;
|
||||
|
||||
$self->session->style->setScript( $self->session->url->extras('yui/build/utilities/utilities.js'));
|
||||
|
||||
|
|
@ -356,60 +360,85 @@ sub view {
|
|||
|
||||
my @found;
|
||||
my $newStuff;
|
||||
my $showPerformance = $self->session->log->performanceLogger();
|
||||
my $user = $self->session->user;
|
||||
foreach my $position (@positions) {
|
||||
my @assets = split(",",$position);
|
||||
foreach my $asset (@assets) {
|
||||
foreach my $child (@{$children}) {
|
||||
CHILD: foreach my $child (@{$children}) {
|
||||
if ($asset eq $child->getId) {
|
||||
unless ($asset ~~ @hidden || !$child->canView) {
|
||||
$self->session->style->setRawHeadTags($child->getExtraHeadTags);
|
||||
$child->{_properties}{title} = $child->getTitle;
|
||||
$child->{_properties}{title} = $child->getShortcut->getTitle if (ref $child eq 'WebGUI::Asset::Shortcut');
|
||||
if ($i == 1 || $i > $numPositions) {
|
||||
push(@{$vars{"position1_loop"}},{
|
||||
id=>$child->getId,
|
||||
content=>'', #so things in the New Content bar don't display.
|
||||
dashletTitle=>$child->{_properties}{title},
|
||||
shortcutUrl=>$child->getUrl,
|
||||
canPersonalize=>$self->canPersonalize,
|
||||
showReloadIcon=>$child->{_properties}{showReloadIcon},
|
||||
canEditUserPrefs=>(($self->session->user->isRegistered) && (ref $child eq 'WebGUI::Asset::Shortcut') && (scalar($child->getPrefFieldsToShow) > 0))
|
||||
});
|
||||
$newStuff .= 'available_dashlets["'.$child->getId.'"]=\''.$child->getUrl.'\';';
|
||||
|
||||
} else {
|
||||
$child->prepareView;
|
||||
push(@{$vars{"position".$i."_loop"}},{
|
||||
id=>$child->getId,
|
||||
content=>$child->view,
|
||||
dashletTitle=>$child->{_properties}{title},
|
||||
shortcutUrl=>$child->getUrl,
|
||||
canPersonalize=>$self->canPersonalize,
|
||||
showReloadIcon=>$child->{_properties}{showReloadIcon},
|
||||
canEditUserPrefs=>(($self->session->user->isRegistered) && (ref $child eq 'WebGUI::Asset::Shortcut') && (scalar($child->getPrefFieldsToShow) > 0))
|
||||
});
|
||||
$newStuff .= 'available_dashlets["'.$child->getId.'"]=\''.$child->getUrl.'\';';
|
||||
}
|
||||
}
|
||||
push(@found, $child->getId);
|
||||
}
|
||||
##Filter based on visibility
|
||||
next CHILD unless $child->canView;
|
||||
next CHILD if isIn($asset, @hidden);
|
||||
##Detect child types
|
||||
my $is_shortcut = $child->isa('WebGUI::Asset::Shortcut');
|
||||
my $is_dashlet = $child->can('getOverrideFormDefinition');
|
||||
$self->session->style->setRawHeadTags($child->getExtraHeadTags);
|
||||
##Override the title for shortcuts
|
||||
if ($is_shortcut) {
|
||||
$child->{_properties}{title} = $child->getShortcut->getTitle;
|
||||
}
|
||||
##Fetch dashlet options from the database
|
||||
my $options = $session->db->quickHashRef('select * from Dashboard_dashlets where dashboardAssetId=? and dashletAssetId=?', [$self->getId, $child->getId]);
|
||||
if (!($i == 1 || $i > $numPositions)) {
|
||||
$child->prepareView;
|
||||
}
|
||||
my $spot = $i > $numPositions ? 1 : $i;
|
||||
my $canMove = $self->canPersonalize && !$options->{isStatic};
|
||||
my $editFormUrl = ($is_shortcut && $child->getPrefsFieldToShow) ? $child->getUrl('func=getUserPrefsForm')
|
||||
: ($is_dashlet && $child->getOverrideFormDefinition) ? $self->getUrl('func=customizeDashlet;dashletAssetId='.$child->getId)
|
||||
: ''
|
||||
;
|
||||
my $canEditUserPrefs = $user->isRegistered && $editFormUrl;
|
||||
|
||||
push(@{$vars{"position".$spot."_loop"}},{
|
||||
id => $child->getId,
|
||||
content => $child->view,
|
||||
dashletTitle => $child->get('title'),
|
||||
shortcutUrl => ($is_shortcut ? $child->getUrl : ''),
|
||||
editFormUrl => $editFormUrl,
|
||||
dashletUrl => ($is_dashlet ? $child->getUrl : ''),
|
||||
canDelete => $self->canPersonalize && !$options->{isRequired},
|
||||
canMove => $canMove,
|
||||
canPersonalize => $self->canPersonalize,
|
||||
showReloadIcon => $is_shortcut && $child->get('showReloadIcon'),
|
||||
canEditUserPrefs => $canEditUserPrefs,
|
||||
});
|
||||
if ($canMove) {
|
||||
$newStuff .= 'available_dashlets["'.$child->getId.'"]=\''.$child->getUrl.'\';';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
# deal with unplaced children
|
||||
# deal with unplaced children, they go into position 1
|
||||
foreach my $child (@{$children}) {
|
||||
unless ($child->getId ~~ @found || $child->getId ~~ @hidden) {
|
||||
if ($child->canView) {
|
||||
$child->{_properties}{title} = $child->getShortcut->title if (ref $child eq 'WebGUI::Asset::Shortcut');
|
||||
my $is_shortcut = $child->isa('WebGUI::Asset::Shortcut');
|
||||
my $is_dashlet = $child->can('getOverrideFormDefinition');
|
||||
my $title = $child->{_properties}{title} = $is_shortcut ? $child->getShortcut->getTitle : $child->getTitle;
|
||||
my $options = $session->db->quickHashRef('select * from Dashboard_dashlets where dashboardAssetId=? and dashletAssetId=?', [$self->getId, $child->getId]);
|
||||
my $canMove = $self->canPersonalize && !$options->{isStatic};
|
||||
my $editFormUrl = ($is_shortcut && $child->getPrefFieldsToShow) ? $child->getUrl('func=getUserPrefsForm')
|
||||
: ($is_dashlet && $child->getOverrideFormDefinition) ? $self->getUrl('func=customizeDashlet;dashletAssetId='.$child->getId)
|
||||
: ''
|
||||
;
|
||||
my $canEditUserPrefs = $user->isRegistered && $editFormUrl;
|
||||
push(@{$vars{"position1_loop"}},{
|
||||
id=>$child->getId,
|
||||
content=>'',
|
||||
dashletTitle=>$child->getTitle,
|
||||
shortcutUrl=>$child->getUrl,
|
||||
showReloadIcon=>$child->{_properties}{showReloadIcon},
|
||||
canPersonalize=>$self->canPersonalize,
|
||||
canEditUserPrefs=>(($self->session->user->isRegistered) && (ref $child eq 'WebGUI::Asset::Shortcut') && (scalar($child->getPrefFieldsToShow) > 0))
|
||||
id => $child->getId,
|
||||
content => '',
|
||||
dashletTitle => $title,
|
||||
shortcutUrl => ($is_shortcut ? $child->getUrl : ''),
|
||||
editFormUrl => $editFormUrl,
|
||||
dashletUrl => ($is_dashlet ? $child->getUrl : ''),
|
||||
canDelete => $self->canPersonalize && !$options->{isRequired},
|
||||
canMove => $canMove,
|
||||
canPersonalize => $self->canPersonalize,
|
||||
showReloadIcon => $is_shortcut && $child->{_properties}{showReloadIcon},
|
||||
canEditUserPrefs => $canEditUserPrefs,
|
||||
});
|
||||
$newStuff .= 'available_dashlets["'.$child->getId.'"]=\''.$child->getUrl.'\';';
|
||||
}
|
||||
|
|
@ -418,9 +447,9 @@ sub view {
|
|||
$vars{showAdmin} = ($self->session->isAdminOn && $self->canEdit);
|
||||
$vars{"dragger.init"} = '
|
||||
<script type="text/javascript">
|
||||
dragable_init("'.$self->getUrl.'");
|
||||
var available_dashlets= new Array();
|
||||
'.$newStuff.'
|
||||
dragable_init("'.$self->getUrl.'");
|
||||
</script>
|
||||
';
|
||||
return $self->processTemplate(\%vars, $templateId);
|
||||
|
|
@ -428,6 +457,128 @@ sub view {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_customizeDashlet
|
||||
|
||||
Web facing method for saving per dashlet configuration, such as being required, or movable.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_customizeDashlet {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient() unless ($session->user->isRegistered);
|
||||
my $dashletAssetId = $session->form->get('dashletAssetId');
|
||||
my $dashlet = WebGUI::Asset->newById($session, $dashletAssetId);
|
||||
return $session->privilege->insufficient() unless ($dashlet && $dashlet->canView && $dashlet->can('getOverrideFormDefinition'));
|
||||
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Dashboard');
|
||||
|
||||
my $form = $session->form;
|
||||
my $html_form = WebGUI::HTMLForm->new($session, action => $self->getUrl, method => 'POST', );
|
||||
$html_form->hidden(name => 'func', value => 'customizeDashletSave', );
|
||||
$html_form->hidden(name => 'dashletAssetId', value => $dashletAssetId, );
|
||||
$html_form->readOnly(name => $i18n->get(), value => $dashlet->getTitle, );
|
||||
|
||||
my $overrides = $dashlet->fetchUserOverrides($self->getId);
|
||||
my @dashlet_properties = $dashlet->getOverrideFormDefinition;
|
||||
foreach my $property (@dashlet_properties) {
|
||||
my %properties = %{ $property };
|
||||
$properties{value} = $overrides->{$property->{name}} || $dashlet->get($property->{name});
|
||||
$html_form->dynamicField(%properties);
|
||||
}
|
||||
|
||||
$html_form->submit();
|
||||
return $html_form->print;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_customizeDashletSave
|
||||
|
||||
Web facing method for saving per dashlet configuration, such as being required, or movable.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_customizeDashletSave {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient() unless ($session->user->isRegistered);
|
||||
my $dashletAssetId = $session->form->get('dashletAssetId');
|
||||
my $dashlet = WebGUI::Asset->newById($session, $dashletAssetId);
|
||||
return $session->privilege->insufficient() unless ($dashlet && $dashlet->canView && $dashlet->can('getOverrideFormDefinition'));
|
||||
my $overrides = {};
|
||||
my @dashlet_properties = $dashlet->getOverrideFormDefinition;
|
||||
my $form = $session->form;
|
||||
foreach my $property (@dashlet_properties) {
|
||||
my $value = $form->process($property->{name}, $property->{fieldType}, $property->{value});
|
||||
$overrides->{$property->{name}} = $value;
|
||||
}
|
||||
$dashlet->storeUserOverrides($self->getId, $overrides);
|
||||
return $self->www_view;
|
||||
}
|
||||
|
||||
##-------------------------------------------------------------------
|
||||
|
||||
=head2 www_editDashlet
|
||||
|
||||
Web facing method for saving per dashlet configuration, such as being required, or movable.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_editDashlet {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient() unless ($self->canEdit);
|
||||
my $dashletAssetId = $session->form->get('dashletAssetId');
|
||||
my $dashlet = WebGUI::Asset->newById($session, $dashletAssetId);
|
||||
return $session->privilege->insufficient() unless ($dashletAssetId);
|
||||
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Dashboard');
|
||||
|
||||
my $form = $session->form;
|
||||
my $html_form = WebGUI::HTMLForm->new($session, action => $self->getUrl, method => 'POST', );
|
||||
$html_form->hidden(name => 'func', value => 'editDashletSave', );
|
||||
$html_form->hidden(name => 'dashletAssetId', value => $dashletAssetId, );
|
||||
$html_form->readOnly(name => $i18n->get(), value => $dashlet->getTitle, );
|
||||
my $options = $session->db->quickHashRef('select * from Dashboard_dashlets where dashboardAssetId=? and dashletAssetId=?', [$self->getId, $dashletAssetId]);
|
||||
$html_form->yesNo(
|
||||
name => 'isStatic',
|
||||
label => $i18n->get('Is static'),
|
||||
hoverHelp => $i18n->get('Is static help'),
|
||||
value => $form->get('isStatic') || $options->{isStatic},
|
||||
);
|
||||
$html_form->yesNo(
|
||||
name => 'isRequired',
|
||||
label => $i18n->get('Is required'),
|
||||
hoverHelp => $i18n->get('Is required help'),
|
||||
value => $form->get('isRequired') || $options->{isRequired},
|
||||
);
|
||||
$html_form->submit();
|
||||
return $html_form->print;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_editDashletSave
|
||||
|
||||
Web facing method for saving per dashlet configuration, such as being required, or movable.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_editDashletSave {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient() unless ($self->canEdit);
|
||||
my $dashletAssetId = $session->form->get('dashletAssetId');
|
||||
my $isStatic = $session->form->get('isStatic', 'yesNo');
|
||||
my $isRequired = $session->form->get('isRequired', 'yesNo');
|
||||
$session->db->write('DELETE FROM Dashboard_dashlets where dashboardAssetId=? and dashletAssetId=?',[$self->getId, $dashletAssetId, ]);
|
||||
$session->db->write('INSERT INTO Dashboard_dashlets (dashboardAssetId, dashletAssetId, isStatic, isRequired) VALUES (?,?,?,?)', [$self->getId, $dashletAssetId, $isStatic, $isRequired, ]);
|
||||
return $self->www_view;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_setContentPositions
|
||||
|
||||
Web method for saving the positions of dashlets in the dashboard.
|
||||
|
|
|
|||
|
|
@ -320,12 +320,13 @@ sub _fieldAdminIcons {
|
|||
my $self = shift;
|
||||
my $fieldName = shift;
|
||||
my $i18n = WebGUI::International->new($self->session,"Asset_DataForm");
|
||||
my $mode = ";mode=" . $self->currentView;
|
||||
my $output;
|
||||
$output = $self->session->icon->delete('func=deleteFieldConfirm;fieldName='.$fieldName,$self->url,$i18n->get(19))
|
||||
$output = $self->session->icon->delete('func=deleteFieldConfirm;fieldName='.$fieldName.$mode,$self->get("url"),$i18n->get(19))
|
||||
unless $self->getFieldConfig($fieldName)->{isMailField};
|
||||
$output .= $self->session->icon->edit('func=editField;fieldName='.$fieldName,$self->url)
|
||||
. $self->session->icon->moveUp('func=moveFieldUp;fieldName='.$fieldName,$self->url)
|
||||
. $self->session->icon->moveDown('func=moveFieldDown;fieldName='.$fieldName,$self->url);
|
||||
$output .= $self->session->icon->edit('func=editField;fieldName='.$fieldName.$mode,$self->get("url"))
|
||||
. $self->session->icon->moveUp('func=moveFieldUp;fieldName='.$fieldName.$mode,$self->get("url"))
|
||||
. $self->session->icon->moveDown('func=moveFieldDown;fieldName='.$fieldName.$mode,$self->get("url"));
|
||||
return $output;
|
||||
}
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -784,6 +785,7 @@ sub getListTemplateVars {
|
|||
'field.label' => $fieldConfig->{$_}{label},
|
||||
'field.isMailField' => $fieldConfig->{$_}{isMailField},
|
||||
'field.type' => $fieldConfig->{$_}{type},
|
||||
"field.controls" => $self->_fieldAdminIcons($fieldConfig->{$_}{name}),
|
||||
}
|
||||
} @{ $self->getFieldOrder };
|
||||
$var->{field_loop} = \@fieldLoop;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ Overridden to check the revision dates of children as well
|
|||
|
||||
sub getContentLastModified {
|
||||
my $self = shift;
|
||||
my $mtime = $self->revisionDate;
|
||||
my $mtime = $self->get("lastModified");
|
||||
my $childIter = $self->getLineageIterator(["children"]);
|
||||
while ( 1 ) {
|
||||
my $child;
|
||||
|
|
@ -119,6 +119,60 @@ sub getContentLastModified {
|
|||
return $mtime;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getContentLastModifiedBy
|
||||
|
||||
Overridden to check the updated dates of children as well
|
||||
|
||||
=cut
|
||||
|
||||
sub getContentLastModifiedBy {
|
||||
my $self = shift;
|
||||
my $mtime = $self->SUPER::getContentLastModified;
|
||||
my $userId = $self->get('revisedBy');
|
||||
my $childIter = $self->getLineageIterator(["children"]);
|
||||
while ( 1 ) {
|
||||
my $child;
|
||||
eval { $child = $childIter->() };
|
||||
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
|
||||
$self->session->log->error($x->full_message);
|
||||
next;
|
||||
}
|
||||
last unless $child;
|
||||
my $child_mtime = $child->getContentLastModified;
|
||||
if ($child_mtime > $mtime) {
|
||||
$mtime = $child_mtime;
|
||||
$userId = $child->get("revisedBy");
|
||||
}
|
||||
}
|
||||
return $userId;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=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();
|
||||
my $i18n = WebGUI::International->new($self->session,"Asset_Folder");
|
||||
if ($self->get("assetId") eq "new") {
|
||||
$tabform->getTab("properties")->whatNext(
|
||||
-options=>{
|
||||
view=>$i18n->get(823),
|
||||
"viewParent"=>$i18n->get(847)
|
||||
},
|
||||
-value=>"view"
|
||||
);
|
||||
}
|
||||
return $tabform;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getTemplateVars ( )
|
||||
|
|
|
|||
|
|
@ -363,6 +363,36 @@ override getContentLastModified => sub {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getContentLastModifiedBy
|
||||
|
||||
Extend the base class to include the userid of the person that made last modification.
|
||||
|
||||
=cut
|
||||
|
||||
sub getContentLastModifiedBy {
|
||||
my $self = shift;
|
||||
my $mtime = $self->SUPER::getContentLastModified;
|
||||
my $userId = $self->get('revisedBy');
|
||||
my $childIter = $self->getLineageIterator(["children"],{excludeClasses=>['WebGUI::Asset::Wobject::Layout']});
|
||||
while ( 1 ) {
|
||||
my $child;
|
||||
eval { $child = $childIter->() };
|
||||
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
|
||||
$self->session->log->error($x->full_message);
|
||||
next;
|
||||
}
|
||||
last unless $child;
|
||||
my $child_mtime = $child->getContentLastModified;
|
||||
if ($child_mtime > $mtime) {
|
||||
$mtime = $child_mtime;
|
||||
$userId = $child->get("revisedBy");
|
||||
}
|
||||
}
|
||||
return $userId;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_view
|
||||
|
||||
Extend the base method to handle caching and ad rotation.
|
||||
|
|
|
|||
|
|
@ -371,7 +371,9 @@ sub view {
|
|||
google.setOnLoadCallback( function() {
|
||||
var mapId = "%s";
|
||||
var mapUrl = "%s";
|
||||
var map = new GMap2( document.getElementById("map_" + mapId) );
|
||||
var element = document.getElementById("map_" + mapId);
|
||||
var map = new GMap2( element );
|
||||
element.mapObject = map;
|
||||
map.url = mapUrl;
|
||||
map.assetId = mapId;
|
||||
map.setCenter(new GLatLng(%s, %s), %s);
|
||||
|
|
@ -379,6 +381,10 @@ sub view {
|
|||
map.extrasUrl = "%s";
|
||||
|
||||
var markermanager = new MarkerManager(map, {trackMarkers: true});
|
||||
map.markermanager = markermanager;
|
||||
map.fancyClickHandler = null;
|
||||
map.panOnClick = true;
|
||||
map.clickToEdit = false;
|
||||
ENDHTML
|
||||
|
||||
|
||||
|
|
@ -392,9 +398,9 @@ ENDHTML
|
|||
for my $pointId ( @{$pointIds} ) {
|
||||
my $point = WebGUI::Asset->newById( $session, $pointId );
|
||||
next unless $point;
|
||||
$mapHtml .= sprintf ' points.push(%s);'."\n",
|
||||
JSON->new->encode($point->getMapInfo),
|
||||
;
|
||||
my $buffer = JSON->new->encode( $point->getMapInfo );
|
||||
|
||||
$mapHtml .= sprintf ' points.push(%s);'."\n", $buffer;
|
||||
|
||||
push @{$var->{ mapPoints }}, $point->getTemplateVars;
|
||||
}
|
||||
|
|
@ -416,11 +422,11 @@ ENDHTML
|
|||
}
|
||||
|
||||
# Script to control addPoint and setPoint buttons
|
||||
$mapHtml .= <<'ENDHTML';
|
||||
$mapHtml .= sprintf <<'ENDHTML', $self->getUrl;
|
||||
if ( document.getElementById( "setCenter_" + mapId ) ) {
|
||||
var button = document.getElementById( "setCenter_" + mapId );
|
||||
GEvent.addDomListener( button, "click", function () {
|
||||
WebGUI.Map.setCenter( map );
|
||||
WebGUI.Map.setCenter( map, '%s' );
|
||||
} );
|
||||
}
|
||||
if ( document.getElementById( "addPoint_" + mapId ) ) {
|
||||
|
|
|
|||
|
|
@ -175,30 +175,31 @@ sub view {
|
|||
);
|
||||
|
||||
my @results = ();
|
||||
foreach my $data (@{$p->getPageData}) {
|
||||
next unless (
|
||||
ENTRY: foreach my $data (@{$p->getPageData}) {
|
||||
next ENTRY unless (
|
||||
$user->userId eq $data->{ownerUserId}
|
||||
|| $user->isInGroup($data->{groupIdView})
|
||||
|| $user->isInGroup($data->{groupIdEdit})
|
||||
);
|
||||
|
||||
my $asset = WebGUI::Asset->newById($session, $data->{assetId});
|
||||
if (defined $asset) {
|
||||
my $properties = $asset->get;
|
||||
if ($self->useContainers) {
|
||||
$properties->{url} = $asset->isa('WebGUI::Asset::Post::Thread') ? $asset->getCSLinkUrl()
|
||||
: $asset->getContainer->url;
|
||||
}
|
||||
#Add highlighting
|
||||
$properties->{'title' } = $hl->highlight($properties->{title} || '');
|
||||
$properties->{'title_nohighlight' } = $properties->{title};
|
||||
my $synopsis = $data->{'synopsis'} || '';
|
||||
WebGUI::Macro::process($self->session, \$synopsis);
|
||||
$properties->{'synopsis' } = $hl->highlight($synopsis);
|
||||
$properties->{'synopsis_nohighlight'} = $synopsis;
|
||||
push(@results, $properties);
|
||||
$var{results_found} = 1;
|
||||
}
|
||||
next ENTRY unless defined $asset;
|
||||
my $properties = $asset->get;
|
||||
##Overlay the asset properties with the original data to handle sub-entries for assets
|
||||
$properties = { %{ $properties }, %{ $data} };
|
||||
if ( $self->get("useContainers") && $asset->getContainer->canView ) {
|
||||
$properties->{url} = $asset->isa('WebGUI::Asset::Post::Thread') ? $asset->getCSLinkUrl()
|
||||
: $asset->getContainer->get("url");
|
||||
}
|
||||
#Add highlighting
|
||||
$properties->{'title' } = $hl->highlight($properties->{title} || '');
|
||||
$properties->{'title_nohighlight' } = $properties->{title};
|
||||
my $synopsis = $properties->{'synopsis'} || '';
|
||||
WebGUI::Macro::process($self->session, \$synopsis);
|
||||
$properties->{'synopsis' } = $hl->highlight($synopsis);
|
||||
$properties->{'synopsis_nohighlight'} = $synopsis;
|
||||
push(@results, $properties);
|
||||
$var{results_found} = 1;
|
||||
}
|
||||
|
||||
$var{result_set} = \@results;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use Number::Format ();
|
|||
use Moose;
|
||||
use WebGUI::Definition::Asset;
|
||||
extends 'WebGUI::Asset::Wobject';
|
||||
with 'WebGUI::Role::Asset::Dashlet';
|
||||
define tableName => 'StockData';
|
||||
define icon => 'stockData.gif';
|
||||
define assetName => ["assetName", 'Asset_StockData'];
|
||||
|
|
@ -45,6 +46,7 @@ property defaultStocks => (
|
|||
tab => 'properties',
|
||||
label => ["default_stock_label", 'Asset_StockData'],
|
||||
hoverHelp => ["default_stock_label_description", 'Asset_StockData'],
|
||||
dashletOverridable => 1,
|
||||
);
|
||||
property source => (
|
||||
fieldType => "selectList",
|
||||
|
|
@ -208,9 +210,12 @@ sub _convertToEpoch {
|
|||
if($time =~ m/pm/i) {
|
||||
$hour += 12;
|
||||
}
|
||||
$hour ||= 0;
|
||||
$hour = $self->_appendZero($hour);
|
||||
$minute ||= 0;
|
||||
$minute = $self->_appendZero($minute);
|
||||
return $self->session->datetime->humanToEpoch("$year-$month-$day $hour:$minute:00");
|
||||
my $epoch = eval {$self->session->datetime->humanToEpoch("$year-$month-$day $hour:$minute:00")};
|
||||
return $epoch;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -226,21 +231,45 @@ List of stock symbols to find passed in as an array reference. Stock symbols sh
|
|||
=cut
|
||||
|
||||
sub _getStocks {
|
||||
my $self = shift;
|
||||
my $stocks = $_[0];
|
||||
my $self = shift;
|
||||
my $stocks = $_[0];
|
||||
my $session = $self->session;
|
||||
|
||||
# Create a new Finance::Quote object
|
||||
my $q = Finance::Quote->new;
|
||||
# Disable failover if specified
|
||||
unless ($self->failover) {
|
||||
$q->failover(0);
|
||||
}
|
||||
# Create a new Finance::Quote object
|
||||
my $q = Finance::Quote->new;
|
||||
# Disable failover if specified
|
||||
unless ($self->failover) {
|
||||
$q->failover(0);
|
||||
}
|
||||
# Hardcoded timeout for now.
|
||||
$q->timeout(15);
|
||||
|
||||
# Hardcoded timeout for now.
|
||||
$q->timeout(15);
|
||||
my $source = $self->source;
|
||||
my %stocks = ();
|
||||
my @stocks_to_fetch = ();
|
||||
STOCK: foreach my $stock (@{$stocks}) {
|
||||
$stock = uc $stock;
|
||||
my $value = $session->cache->get( join "", $self->getId, $source, $stock );
|
||||
if ($value) {
|
||||
%stocks = (%stocks, %{ $value });
|
||||
}
|
||||
else {
|
||||
push @stocks_to_fetch, $stock;
|
||||
}
|
||||
}
|
||||
|
||||
# Fetch the stock information and return the results
|
||||
return $q->fetch($self->source,@{$stocks});
|
||||
# Fetch the information for uncached stocks, cache them individually, and build the composite data.
|
||||
my %new_stocks = $q->fetch($source, @stocks_to_fetch);
|
||||
foreach my $stock (@stocks_to_fetch) {
|
||||
$stock = uc $stock;
|
||||
my @stock_keys = grep { /$stock\b/ } keys %new_stocks;
|
||||
my %slice;
|
||||
@slice{ @stock_keys } = @new_stocks{ @stock_keys };
|
||||
$slice{$stock,'last_fetch'} = time();
|
||||
$session->cache->set( join( "", $self->getId, $source, $stock ), \%slice, $self->get('cacheTimeout') );
|
||||
%stocks = (%stocks, %slice);
|
||||
}
|
||||
return \%stocks;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -330,7 +359,8 @@ sub view {
|
|||
$var->{'stock.display.url'} = $self->getUrl("func=displayStock;symbol=");
|
||||
|
||||
#Build list of stocks as an array
|
||||
my $defaults = $self->defaultStocks;
|
||||
my $overrides = $self->fetchUserOverrides($self->getParent->getId);
|
||||
my $defaults = $overrides->{defaultStocks} || $self->defaultStocks;
|
||||
#replace any windows newlines
|
||||
$defaults =~ s/\r//;
|
||||
my @array = split("\n",$defaults);
|
||||
|
|
|
|||
|
|
@ -171,38 +171,48 @@ sub viewTemplateVariables {
|
|||
rowsPerPage => $numberOfStories,
|
||||
});
|
||||
my $storyIds = $p->getPageData();
|
||||
$var->{story_loop} = [];
|
||||
|
||||
my $icon = $session->icon;
|
||||
my $userUiLevel = $session->user->get("uiLevel");
|
||||
my $uiLevels = $session->config->get('assetToolbarUiLevel');
|
||||
my $i18n = WebGUI::International->new($session);
|
||||
my $url = $session->url;
|
||||
|
||||
##Only build objects for the assets that we need
|
||||
STORY: foreach my $storyId (@{ $storyIds }) {
|
||||
my $story = WebGUI::Asset->newById($session, $storyId->{assetId}, $storyId->{revisionDate});
|
||||
next STORY unless $story;
|
||||
my $storyVars = {
|
||||
url => ( $exporting
|
||||
? $story->getUrl
|
||||
: $session->url->append($self->getUrl, 'func=viewStory;assetId='.$storyId->{assetId}) ),
|
||||
title => $story->getTitle,
|
||||
creationDate => $story->creationDate,
|
||||
};
|
||||
if ($story->canEdit && $userUiLevel >= $uiLevels->{delete} && !$exporting) {
|
||||
$storyVars->{deleteIcon} = $icon->delete('func=delete', $story->url, $i18n->get(43));
|
||||
$var->{story_loop} = [
|
||||
map {
|
||||
my $v = $_->viewTemplateVariables;
|
||||
if ($exporting) {
|
||||
$v->{url} = $_->getUrl;
|
||||
}
|
||||
else {
|
||||
my $params = "func=viewStory;assetId=$v->{assetId}";
|
||||
my $rawUrl = $v->{url};
|
||||
$v->{url} = $url->append($self->getUrl, $params);
|
||||
if ($v->{canEdit}) {
|
||||
if ($userUiLevel >= $uiLevels->{delete}) {
|
||||
$v->{deleteIcon} = $icon->delete('func=delete', $rawUrl, $i18n->get(43));
|
||||
}
|
||||
if ($userUiLevel >= $uiLevels->{edit}) {
|
||||
$v->{editIcon} = $icon->edit('func=edit', $rawUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
$v;
|
||||
}
|
||||
if ($story->canEdit && $userUiLevel >= $uiLevels->{edit} && !$exporting) {
|
||||
$storyVars->{editIcon} = $icon->edit('func=edit', $story->url);
|
||||
grep { $_ }
|
||||
map {
|
||||
WebGUI::Asset->newById( $session, $_->{assetId} )
|
||||
}
|
||||
push @{$var->{story_loop}}, $storyVars;
|
||||
}
|
||||
@{ $storyIds }
|
||||
];
|
||||
|
||||
if (@{ $storyIds }) {
|
||||
my $topStoryData = $storyIds->[0];
|
||||
my $topStoryVars = shift @{ $var->{story_loop} };
|
||||
##Note, this could have saved from the loop above, but this looks more clean and encapsulated to me.
|
||||
my $topStory = WebGUI::Asset->newById($session, $topStoryData->{assetId}, $topStoryData->{revisionDate});
|
||||
$var->{topStory} = $topStoryVars;
|
||||
$var->{topStoryTitle} = $topStory->getTitle;
|
||||
$var->{topStorySubtitle} = $topStory->subtitle;
|
||||
$var->{topStoryUrl} = $session->url->append($self->getUrl, 'func=viewStory;assetId='.$topStoryData->{assetId}),
|
||||
|
|
|
|||
|
|
@ -2336,12 +2336,12 @@ sub www_viewStatisticalOverview {
|
|||
}
|
||||
}
|
||||
else{
|
||||
my $responses = $db->read('select value,answerComment from Survey_tempReport'
|
||||
my $responses = $db->read('select answerValue,answerComment from Survey_tempReport'
|
||||
. ' where sectionNumber=? and questionNumber=?',
|
||||
[$sectionIndex,$questionIndex]);
|
||||
while (my $response = $responses->hashRef) {
|
||||
push @answerloop,{
|
||||
'answer_value' =>$response->{value},
|
||||
'answer_value' =>$response->{answerValue},
|
||||
'answer_comment' =>$response->{answerComment}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ has '+uiLevel' => (
|
|||
with 'WebGUI::Role::Asset::RssFeed';
|
||||
use WebGUI::Macro;
|
||||
use XML::FeedPP;
|
||||
use XML::FeedPP::MediaRSS;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -252,6 +253,7 @@ A reference to an XML::FeedPP object.
|
|||
|
||||
sub getTemplateVariables {
|
||||
my ($self, $feed) = @_;
|
||||
my $media = XML::FeedPP::MediaRSS->new($feed);
|
||||
my @items = $feed->get_item;
|
||||
my %var;
|
||||
$var{channel_title} = WebGUI::HTML::filter(scalar $feed->title, 'javascript');
|
||||
|
|
@ -268,6 +270,7 @@ sub getTemplateVariables {
|
|||
$var{channel_image_height} = WebGUI::HTML::filter($image[5], 'javascript');
|
||||
foreach my $object (@items) {
|
||||
my %item;
|
||||
$item{media} = [ map { { %$_ } } $media->for_item($object) ];
|
||||
$item{title} = WebGUI::HTML::filter(scalar $object->title, 'javascript');
|
||||
$item{date} = WebGUI::HTML::filter(scalar $object->get_pubDate_epoch, 'javascript');
|
||||
$item{category} = WebGUI::HTML::filter(scalar $object->category, 'javascript');
|
||||
|
|
|
|||
|
|
@ -260,6 +260,24 @@ sub badOtherThing {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteThingIndex ( $thingId )
|
||||
|
||||
Remove the entry about this Thing from the database, and for any rows for it that are indexed as well.
|
||||
|
||||
=head3 $thingId
|
||||
|
||||
The GUID of the Thing, used to pick out this record in the database.
|
||||
|
||||
=cut
|
||||
|
||||
sub deleteThingIndex {
|
||||
my $self = shift;
|
||||
my $thingId = shift;
|
||||
$self->session->db->write(q|delete from assetIndex where assetId=? and subId like CONCAT(?,'%')|,[$self->getId, $thingId]);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 duplicate ( )
|
||||
|
||||
Duplicates a Thingy, including the definitions of the Things in this Thingy and their fields.
|
||||
|
|
@ -346,6 +364,8 @@ sub duplicateThing {
|
|||
$self->addField($field,0);
|
||||
}
|
||||
|
||||
$thingProperties->{thingId} = $newThingId;
|
||||
$self->indexThing($thingProperties);
|
||||
return $newThingId;
|
||||
|
||||
}
|
||||
|
|
@ -397,6 +417,7 @@ sub deleteField {
|
|||
$db->write("ALTER TABLE ".$db->quote_identifier("Thingy_".$thingId)." DROP "
|
||||
.$db->quote_identifier("field_".$fieldId));
|
||||
}
|
||||
$self->reindexThings;
|
||||
$log->info("Deleted field: $fieldId in thing: $thingId.");
|
||||
return undef;
|
||||
}
|
||||
|
|
@ -433,7 +454,7 @@ sub copyThingData {
|
|||
my @storage_field_ids = ();
|
||||
##Check to see if any of them are File or Image
|
||||
foreach my $field (@{ $fields }) {
|
||||
if ($field->{fieldType} eq 'File' or $field->{fieldType} eq 'Image') {
|
||||
if ($self->field_isa($field->{fieldType}, 'WebGUI::Form::File')) {
|
||||
push @storage_field_ids, $field->{fieldId};
|
||||
}
|
||||
}
|
||||
|
|
@ -447,6 +468,7 @@ sub copyThingData {
|
|||
}
|
||||
##Update the copy
|
||||
$self->setCollateral("Thingy_".$thingId, "thingDataId", $origCollateral, 0, 0);
|
||||
$self->indexThingData($thingId, $origCollateral);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
|
@ -491,7 +513,7 @@ sub deleteThingData {
|
|||
my @storage_field_ids = ();
|
||||
##Check to see if any of them are File or Image
|
||||
foreach my $field (@{ $fields }) {
|
||||
if ($field->{fieldType} eq 'File' or $field->{fieldType} eq 'Image') {
|
||||
if ($self->field_isa($field->{fieldType}, 'WebGUI::Form::File')) {
|
||||
push @storage_field_ids, $field->{fieldId};
|
||||
}
|
||||
}
|
||||
|
|
@ -501,11 +523,30 @@ sub deleteThingData {
|
|||
$storage->delete;
|
||||
}
|
||||
|
||||
$self->deleteThingDataIndex($thingDataId);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteThingDataIndex ( $thingDataId )
|
||||
|
||||
Remove the entry about this Thing from the database, and for any rows for it that are indexed as well.
|
||||
|
||||
=head3 $thingDataId
|
||||
|
||||
The GUID of the thingData to remove, used to pick out this record in the database.
|
||||
|
||||
=cut
|
||||
|
||||
sub deleteThingDataIndex {
|
||||
my $self = shift;
|
||||
my $thingDataId = shift;
|
||||
$self->session->db->write(q|delete from assetIndex where assetId=? and subId like CONCAT('%-',?)|,[$self->getId, $thingDataId]);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteThing ( thingId )
|
||||
|
||||
Deletes a Thing and its fields from Collateral and drops the things table.
|
||||
|
|
@ -528,6 +569,7 @@ sub deleteThing {
|
|||
$session->db->write("drop table if exists ".$session->db->quote_identifier("Thingy_".$thingId));
|
||||
|
||||
$log->info("Deleted thing: $thingId.");
|
||||
$self->deleteThingIndex($thingId);
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
|
@ -535,7 +577,9 @@ sub deleteThing {
|
|||
|
||||
=head2 editThingDataSave ( )
|
||||
|
||||
Saves a row of thing data and triggers the appropriate workflow triggers.
|
||||
Saves a row of thing data and triggers the appropriate workflow triggers. Returns the id of the row created in
|
||||
the database, and an array reference of errors from required fields and other sources. In there are errors, no data
|
||||
is saved in the database, and the id returned in the empty string.
|
||||
|
||||
=head3 thingId
|
||||
|
||||
|
|
@ -579,8 +623,7 @@ sub editThingDataSave {
|
|||
lastUpDated=>time(),
|
||||
);
|
||||
|
||||
$fields = $session->db->read('select * from Thingy_fields where assetId = ? and thingId = ? order by sequenceNumber',
|
||||
[$self->getId,$thingId]);
|
||||
$fields = $self->getFields($thingId);
|
||||
while (my $field = $fields->hashRef) {
|
||||
my $fieldName = 'field_'.$field->{fieldId};
|
||||
my $fieldValue;
|
||||
|
|
@ -589,7 +632,7 @@ sub editThingDataSave {
|
|||
$fieldType = "" if ($fieldType =~ m/^otherThing/x);
|
||||
# Modify the defaultValue for certain field types. For most types we want to use
|
||||
# the default in the database, for these we want the last known value for this thingData
|
||||
if ( $fieldType eq "File" || $fieldType eq "Image" ) {
|
||||
if ($self->field_isa($fieldType, 'WebGUI::Form::File')) {
|
||||
$field->{ defaultValue } = $thingData{ "field_" . $field->{ fieldId } };
|
||||
}
|
||||
$fieldValue = $thingData->{$fieldName} || $session->form->process($fieldName,$fieldType,$field->{defaultValue},$field);
|
||||
|
|
@ -598,7 +641,6 @@ sub editThingDataSave {
|
|||
push (@errors,{
|
||||
"error_message"=>$field->{label}." ".$i18n->get('is required error').".",
|
||||
});
|
||||
#$hadErrors = 1;
|
||||
}
|
||||
if ($field->{status} eq "hidden") {
|
||||
$fieldValue = $field->{defaultValue};
|
||||
|
|
@ -611,7 +653,11 @@ sub editThingDataSave {
|
|||
$thingData{$fieldName} = $fieldValue;
|
||||
}
|
||||
|
||||
if (@errors) {
|
||||
return ('', \@errors);
|
||||
}
|
||||
$newThingDataId = $self->setCollateral("Thingy_".$thingId,"thingDataId",\%thingData,0,0);
|
||||
$self->indexThingData($thingId, \%thingData);
|
||||
|
||||
# trigger workflow
|
||||
if($thingDataId eq "new"){
|
||||
|
|
@ -653,6 +699,33 @@ override exportAssetData => sub {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 field_isa ( $fieldType, $isa )
|
||||
|
||||
Builds a form field and does an isa check on it.
|
||||
|
||||
=head2 $fieldType
|
||||
|
||||
This is the type of a field to build. It will have 'WebGUI::Form' prepended to it to form
|
||||
a complete classname.
|
||||
|
||||
=head2 $isa
|
||||
|
||||
This is the class name to check against.
|
||||
|
||||
=cut
|
||||
|
||||
sub field_isa {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $fieldType = shift;
|
||||
my $isa = shift;
|
||||
$fieldType = ucfirst $fieldType;
|
||||
my $control = eval { WebGUI::Pluggable::instanciate("WebGUI::Form::".$fieldType, "new", [ $session, () ]) };
|
||||
return ($control && $control->isa($isa));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _getDbDataType ( fieldType )
|
||||
|
||||
returns the database data type for a field based on the fieldType.
|
||||
|
|
@ -905,6 +978,23 @@ sub getEditFieldForm {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getFields ( $thingId )
|
||||
|
||||
Returns a result set with all the fields in a thing in this Thingy.
|
||||
|
||||
=head3 $thingId
|
||||
|
||||
The GUID for a thing
|
||||
|
||||
=cut
|
||||
|
||||
sub getFields {
|
||||
my ($self, $thingId) = @_;
|
||||
return $self->session->db->read("select * from Thingy_fields where assetId=? and thingId=? order by sequenceNumber",[$self->getId, $thingId]);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getFieldValue ( value, field )
|
||||
|
||||
Processes the field value for date(Time) fields and Other Thing fields.
|
||||
|
|
@ -1153,6 +1243,29 @@ sub getThing {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getThingUrl ( thingData )
|
||||
|
||||
Returns a the URL to view a Thing in this Thingy
|
||||
|
||||
=head3 thingData
|
||||
|
||||
A hashref of properties for the Thing, as returned by getThing. This is needed to extract the defaultView,
|
||||
to get the right func, and the thingId.
|
||||
|
||||
=cut
|
||||
|
||||
sub getThingUrl {
|
||||
my ($self, $thing) = @_;
|
||||
if ($thing->{defaultView} eq "addThing") {
|
||||
return 'func=editThingData;thingId='.$thing->{thingId}.';thingDataId=new';
|
||||
}
|
||||
else{
|
||||
return 'func=search;thingId='.$thing->{thingId};
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getViewThingVars ( )
|
||||
|
||||
Returns the field values of a thing instance and the title for its view screen in a tmpl var hashref.
|
||||
|
|
@ -1171,8 +1284,7 @@ sub getViewThingVars {
|
|||
." where thingDataId = ?",[$thingDataId]);
|
||||
|
||||
if (%thingData) {
|
||||
my $fields = $db->read('select * from Thingy_fields where assetId = ? and thingId = ? order by sequenceNumber',
|
||||
[$self->getId,$thingId]);
|
||||
my $fields = $self->getFields($thingId);
|
||||
while (my %field = $fields->hash) {
|
||||
next unless ($field{display} eq '1');
|
||||
my $hidden = ($field{status} eq "hidden" && !$self->session->isAdminOn);
|
||||
|
|
@ -1207,6 +1319,7 @@ sub getViewThingVars {
|
|||
);
|
||||
push(@viewScreenTitleFields,$value) if ($field{viewScreenTitle});
|
||||
push(@field_loop, { map {("field_".$_ => $fieldProperties{$_})} keys(%fieldProperties) });
|
||||
$var->{ $field{label} } = $value;
|
||||
}
|
||||
$var->{viewScreenTitle} = join(" ",@viewScreenTitleFields);
|
||||
$var->{field_loop} = \@field_loop;
|
||||
|
|
@ -1314,7 +1427,7 @@ sub importAssetCollateralData {
|
|||
push(@importThings,$thing->{thingId});
|
||||
my ($thingIdExists) = $session->db->quickArray("select thingId from Thingy_things where thingId = ?",
|
||||
[$thing->{thingId}]);
|
||||
if ($assetExists && $thingIdExists){
|
||||
if ($thingIdExists){
|
||||
# update existing thing
|
||||
$log->info("Updating Thing, label: ".$thing->{label}.", id: ".$thing->{thingId});
|
||||
$self->setCollateral("Thingy_things","thingId",$thing,0,0);
|
||||
|
|
@ -1323,6 +1436,7 @@ sub importAssetCollateralData {
|
|||
# add new thing
|
||||
$self->addThing($thing,1);
|
||||
}
|
||||
$self->indexThing($thing);
|
||||
}
|
||||
# delete deleted things
|
||||
my $thingsInDatabase = $self->getThings;
|
||||
|
|
@ -1338,7 +1452,7 @@ sub importAssetCollateralData {
|
|||
push(@importFields,$field->{fieldId});
|
||||
my $dbDataType = $self->_getDbDataType($field->{fieldType});
|
||||
my ($fieldIdExists) = $session->db->quickArray("select fieldId from Thingy_fields where fieldId = ? and thingId = ? ",[$field->{fieldId},$field->{thingId}]);
|
||||
if ($assetExists && $fieldIdExists){
|
||||
if ($fieldIdExists){
|
||||
# update existing field
|
||||
$log->info("Updating Field, label: ".$field->{label}.", id: ".$field->{fieldId}.",seq :"
|
||||
.$field->{sequenceNumber});
|
||||
|
|
@ -1364,6 +1478,126 @@ sub importAssetCollateralData {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexContent ( )
|
||||
|
||||
Extend the base class to handle reindexing every Thing, and every row in every Thing. We have
|
||||
to do a complete rework because the URL may have changed, and that affects everything that has
|
||||
been inserted into the AssetIndex.
|
||||
|
||||
=cut
|
||||
|
||||
sub indexContent {
|
||||
my ($self) = @_;
|
||||
my $session = $self->session;
|
||||
$self->SUPER::indexContent();
|
||||
$self->reindexThings;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexThing ( $thing )
|
||||
|
||||
Add an entry about this Thing into the AssetIndex so it can be found for searches.
|
||||
|
||||
=head3 $thing
|
||||
|
||||
A hashref of Thing properties, as returned by getThing
|
||||
|
||||
=cut
|
||||
|
||||
sub indexThing {
|
||||
my ($self, $thing) = @_;
|
||||
return unless $thing;
|
||||
my $index = WebGUI::Search::Index->new($self);
|
||||
$index->addRecord(
|
||||
url => $self->getUrl($self->getThingUrl($thing)),
|
||||
groupIdView => $thing->{groupIdView},
|
||||
title => $thing->{label},
|
||||
subId => $thing->{thingId},
|
||||
keywords => join(' ', @{$thing}{qw/label editScreenTitle editInstructions searchScreenTitle searchDescription/}),
|
||||
);
|
||||
##Easy update of all thingData fields for this thing. This is in lieu of deleting all records
|
||||
##And rebuilding them all.
|
||||
$self->session->db->write(q|update assetIndex set title=?, groupIdView=? where assetId=? and subId like CONCAT(?, '%')|, [$thing->{label}, $thing->{groupIdView}, $self->getId, $thing->{thingId}]);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 indexThingData ( $thingId, $thingData )
|
||||
|
||||
Add an entry about a row from this Thing into the AssetIndex so it can be found for searches.
|
||||
|
||||
=head3 $thingId
|
||||
|
||||
The GUID for a Thing.
|
||||
|
||||
=head3 $thingData
|
||||
|
||||
A hashref of ThingData properties
|
||||
|
||||
=cut
|
||||
|
||||
sub indexThingData {
|
||||
my ($self, $thingId, $thingData) = @_;
|
||||
my $session = $self->session;
|
||||
return unless $thingId;
|
||||
my $thing = $self->getThing($thingId);
|
||||
my $index = WebGUI::Search::Index->new($self);
|
||||
my $keywords;
|
||||
##Get the Thingy's fields
|
||||
my $fields = $session->db->read('select * from Thingy_fields where assetId = ? and thingId = ?',
|
||||
[$self->getId, $thingId]);
|
||||
##Walk the fields
|
||||
my @viewScreenTitleFields = ();
|
||||
FIELD: while (my %field = $fields->hash) {
|
||||
my $fieldName = 'field_'.$field{fieldId};
|
||||
$field{value} = $thingData->{$fieldName} || $field{defaultValue};
|
||||
my $subkeywords = '';
|
||||
my $value = '';
|
||||
if ($self->field_isa($field{fieldType}, 'WebGUI::Form::File')) {
|
||||
my $storage = WebGUI::Storage->get($session, $field{value});
|
||||
if ($storage) {
|
||||
foreach my $file (@{$storage->getFiles()}) {
|
||||
$subkeywords = $index->getKeywordsForFile($storage->getPath($file));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$value = $self->getFieldValue($field{value}, \%field);
|
||||
##If it's a file type, then get keywords from the file.
|
||||
##Accumulate keywords
|
||||
$subkeywords = $value;
|
||||
}
|
||||
if ($value && $field{viewScreenTitle}) {
|
||||
push @viewScreenTitleFields, $value;
|
||||
}
|
||||
##We don't index date fields, since they're unix epochs and they'd be different for everyone based on timezone.
|
||||
next FIELD if $field{fieldType} eq 'date'
|
||||
|| $field{fieldType} eq 'datetime'
|
||||
|| $field{fieldType} eq 'time';
|
||||
##Don't show what shouldn't be shown
|
||||
next FIELD unless $field{displayInSearch};
|
||||
$keywords = join ' ', $keywords, $subkeywords;
|
||||
}
|
||||
return unless $keywords; ##No sense indexing nothing;
|
||||
my $title = join('', @viewScreenTitleFields)
|
||||
|| $thing->{label}
|
||||
|| $self->getTitle;
|
||||
$index->addRecord(
|
||||
assetId => $self->getId,
|
||||
url => $self->getUrl('func=viewThingData;thingId='. $thing->{thingId} . ';thingDataId='. $thingData->{thingDataId}),
|
||||
groupIdView => $thing->{groupIdView},
|
||||
title => $title,
|
||||
subId => $thing->{thingId} . '-' . $thingData->{thingDataId},
|
||||
keywords => $keywords,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 prepareView ( )
|
||||
|
|
@ -1412,6 +1646,30 @@ override purge => sub {
|
|||
return super();
|
||||
};
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 reindexThings ( )
|
||||
|
||||
Reindex every Thing, and every row in every Thing.
|
||||
|
||||
=cut
|
||||
|
||||
sub reindexThings {
|
||||
my ($self) = @_;
|
||||
my $session = $self->session;
|
||||
my $things = $self->getThings;
|
||||
THING: while (my $thing = $things->hashRef) {
|
||||
$self->deleteThingIndex($thing->{thingId});
|
||||
$self->indexThing($thing);
|
||||
my $sth = $session->db->read('select * from '. $session->db->dbh->quote_identifier('Thingy_'.$thing->{thingId}));
|
||||
while (my $thingData = $sth->hashRef) {
|
||||
$self->indexThingData($thing->{thingId}, $thingData);
|
||||
}
|
||||
$sth->finish;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 triggerWorkflow ( workflowId, thingId, thingDataId )
|
||||
|
|
@ -1734,7 +1992,7 @@ sub www_editThing {
|
|||
exportMetaData=>undef,
|
||||
maxEntriesPerUser=>undef,
|
||||
);
|
||||
$thingId = $self->addThing(\%properties,0);
|
||||
$thingId = "new";
|
||||
}
|
||||
else{
|
||||
%properties = %{$self->getThing($thingId)};
|
||||
|
|
@ -1834,15 +2092,15 @@ sub www_editThing {
|
|||
." <td class='formDescription'>".$i18n->get('sort by label')."</td>\n"
|
||||
."</tr>\n";
|
||||
|
||||
$fields = $self->session->db->read('select * from Thingy_fields where assetId = '.$self->session->db->quote($self->getId).' and thingId = '.$self->session->db->quote($thingId).' order by sequenceNumber');
|
||||
$fields = $self->getFields($thingId);
|
||||
while (my $field = $fields->hashRef) {
|
||||
my $formElement;
|
||||
if ($field->{fieldType} eq "File"){
|
||||
$formElement = "<input type='file' name='file'>";
|
||||
}
|
||||
if ($field->{fieldType} eq "Image"){
|
||||
if ($self->field_isa($field->{fieldType}, 'WebGUI::Form::Image')) {
|
||||
$formElement = "<input type='file' name='image'>";
|
||||
}
|
||||
elsif ($self->field_isa($field->{fieldType}, 'WebGUI::Form::File')) {
|
||||
$formElement = "<input type='file' name='file'>";
|
||||
}
|
||||
else{
|
||||
$formElement = $self->getFormElement($field);
|
||||
}
|
||||
|
|
@ -1857,11 +2115,12 @@ sub www_editThing {
|
|||
."\n<table>\n<tr>\n"
|
||||
." <td style='width:100px;' valign='top' class='formDescription'>".$field->{label}."</td>\n"
|
||||
." <td style='width:370px;'>".$formElement."</td>\n"
|
||||
." <td style='width:120px;' valign='top'> <input onClick=\"editListItem('".$self->session->url->page()
|
||||
."?func=editField;fieldId=".$field->{fieldId}.";thingId=".$thingId."','".$field->{fieldId}."')\" value='Edit' type='button'>"
|
||||
." <input onClick=\"editListItem('".$self->session->url->page()
|
||||
."?func=editField;copy=1;fieldId=".$field->{fieldId}.";thingId=".$thingId."','".$field->{fieldId}
|
||||
."','copy')\" value='Copy' type='button'>"
|
||||
." <td style='width:120px;' valign='top'> <input onClick=\"editListItem('"
|
||||
.$self->getUrl('func=editField;fieldId='.$field->{fieldId}.';thingId='.$thingId)
|
||||
."','".$field->{fieldId}."')\" value='".$i18n->get('Edit','Icon')."' type='button'>"
|
||||
." <input onClick=\"editListItem('"
|
||||
.$self->getUrl('func=editField;copy=1;fieldId='.$field->{fieldId}.';thingId='.$thingId)
|
||||
."','".$field->{fieldId}."','copy')\" value='".$i18n->get('Copy','Icon')."' type='button'>"
|
||||
."<input onClick=\"deleteListItem('".$self->session->url->page()."','".$field->{fieldId}."','".$thingId."')\" "
|
||||
."value='".$i18n->get('Delete','Icon')."' type='button'></td>\n</tr>\n</table>\n</li>\n";
|
||||
|
||||
|
|
@ -2138,50 +2397,47 @@ database immediately.
|
|||
=cut
|
||||
|
||||
sub www_editThingSave {
|
||||
|
||||
my $self = shift;
|
||||
return $self->session->privilege->insufficient() unless $self->canEdit;
|
||||
my $form = $self->session->form;
|
||||
my ($thingId, $fields);
|
||||
$thingId = $self->session->form->process("thingId");
|
||||
my $form = $self->session->form;
|
||||
my $thingId = $self->session->form->process("thingId");
|
||||
my $fields = $self->getFields($thingId);
|
||||
|
||||
$fields = $self->session->db->read('select * from Thingy_fields where assetId = '.$self->session->db->quote($self->getId).' and thingId = '.$self->session->db->quote($thingId).' order by sequenceNumber');
|
||||
|
||||
|
||||
$self->setCollateral("Thingy_things","thingId",{
|
||||
thingId=>$thingId,
|
||||
label=>$form->process("label"),
|
||||
editScreenTitle=>$form->process("editScreenTitle"),
|
||||
editInstructions=>$form->process("editInstructions"),
|
||||
groupIdAdd=>$form->process("groupIdAdd"),
|
||||
groupIdEdit=>$form->process("groupIdEdit"),
|
||||
saveButtonLabel=>$form->process("saveButtonLabel"),
|
||||
afterSave=>$form->process("afterSave"),
|
||||
editTemplateId=>$form->process("editTemplateId") || 1,
|
||||
onAddWorkflowId=>$form->process("onAddWorkflowId"),
|
||||
onEditWorkflowId=>$form->process("onEditWorkflowId"),
|
||||
onDeleteWorkflowId=>$form->process("onDeleteWorkflowId"),
|
||||
groupIdView=>$form->process("groupIdView"),
|
||||
viewTemplateId=>$form->process("viewTemplateId") || 1,
|
||||
defaultView=>$form->process("defaultView"),
|
||||
searchScreenTitle=>$form->process("searchScreenTitle"),
|
||||
searchDescription=>$form->process("searchDescription"),
|
||||
groupIdSearch=>$form->process("groupIdSearch"),
|
||||
groupIdImport=>$form->process("groupIdImport"),
|
||||
groupIdExport=>$form->process("groupIdExport"),
|
||||
searchTemplateId=>$form->process("searchTemplateId") || 1,
|
||||
thingsPerPage=>$form->process("thingsPerPage") || 25,
|
||||
sortBy=>$form->process("sortBy") || '',
|
||||
exportMetaData=>$form->process("exportMetaData") || '',
|
||||
maxEntriesPerUser=>$form->process("maxEntriesPerUser") || '',
|
||||
},0,1);
|
||||
my $thing = {
|
||||
thingId => $thingId,
|
||||
label => $form->process("label"),
|
||||
editScreenTitle => $form->process("editScreenTitle"),
|
||||
editInstructions => $form->process("editInstructions"),
|
||||
groupIdAdd => $form->process("groupIdAdd"),
|
||||
groupIdEdit => $form->process("groupIdEdit"),
|
||||
saveButtonLabel => $form->process("saveButtonLabel"),
|
||||
afterSave => $form->process("afterSave"),
|
||||
editTemplateId => $form->process("editTemplateId") || 1,
|
||||
onAddWorkflowId => $form->process("onAddWorkflowId"),
|
||||
onEditWorkflowId => $form->process("onEditWorkflowId"),
|
||||
onDeleteWorkflowId => $form->process("onDeleteWorkflowId"),
|
||||
groupIdView => $form->process("groupIdView"),
|
||||
viewTemplateId => $form->process("viewTemplateId") || 1,
|
||||
defaultView => $form->process("defaultView"),
|
||||
searchScreenTitle => $form->process("searchScreenTitle"),
|
||||
searchDescription => $form->process("searchDescription"),
|
||||
groupIdSearch => $form->process("groupIdSearch"),
|
||||
groupIdImport => $form->process("groupIdImport"),
|
||||
groupIdExport => $form->process("groupIdExport"),
|
||||
searchTemplateId => $form->process("searchTemplateId") || 1,
|
||||
thingsPerPage => $form->process("thingsPerPage") || 25,
|
||||
sortBy => $form->process("sortBy") || '',
|
||||
exportMetaData => $form->process("exportMetaData") || '',
|
||||
maxEntriesPerUser => $form->process("maxEntriesPerUser") || '',
|
||||
};
|
||||
$self->setCollateral("Thingy_things", "thingId", $thing, 0, 1);
|
||||
|
||||
if($fields->rows < 1){
|
||||
$self->session->log->warn("Thing failed to create because it had no fields");
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
|
||||
return $self->www_editThing($i18n->get("thing must have fields"));
|
||||
}
|
||||
|
||||
|
||||
while (my $field = $fields->hashRef) {
|
||||
my $display = $self->session->form->process("display_".$field->{fieldId}) || 0;
|
||||
my $viewScreenTitle = $self->session->form->process("viewScreenTitle_".$field->{fieldId}) || 0;
|
||||
|
|
@ -2190,6 +2446,7 @@ sub www_editThingSave {
|
|||
|
||||
$self->session->db->write("update Thingy_fields set display = ?, viewScreenTitle = ?, displayinSearch = ?, searchIn = ? where fieldId = ? and thingId = ?",[$display, $viewScreenTitle, $displayInSearch, $searchIn, $field->{fieldId}, $thingId]);
|
||||
}
|
||||
$self->indexThing($thing);
|
||||
return $self->www_manage;
|
||||
}
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -2208,6 +2465,7 @@ sub www_editField {
|
|||
return $session->privilege->insufficient() unless $self->canEdit;
|
||||
$fieldId = $session->form->process("fieldId");
|
||||
$thingId = $session->form->process("thingId");
|
||||
|
||||
%properties = $session->db->quickHash("select * from Thingy_fields where thingId=? and fieldId=? and assetId=?",
|
||||
[$thingId,$fieldId,$self->getId]);
|
||||
if($session->form->process("copy")){
|
||||
|
|
@ -2248,6 +2506,8 @@ sub www_editFieldSave {
|
|||
if ($fieldType =~ m/^otherThing/){
|
||||
$defaultValue = $session->form->process("defaultFieldInThing");
|
||||
}
|
||||
|
||||
$thingId = $self->addThing({ thingId => 'new' },0) if $thingId eq 'new';
|
||||
|
||||
$fieldId = $session->form->process("fieldId");
|
||||
%properties = (
|
||||
|
|
@ -2285,12 +2545,12 @@ sub www_editFieldSave {
|
|||
$newFieldId = $self->setCollateral("Thingy_fields","fieldId",\%properties,1,1,"thingId",$thingId);
|
||||
}
|
||||
|
||||
if ($properties{fieldType} eq "File"){
|
||||
$formElement = "<input type='file' name='file'>";
|
||||
}
|
||||
elsif ($properties{fieldType} eq "Image"){
|
||||
if ($self->field_isa($properties{fieldType}, 'WebGUI::Form::Image')) {
|
||||
$formElement = "<input type='file' name='image'>";
|
||||
}
|
||||
elsif ($self->field_isa($properties{fieldType}, 'WebGUI::Form::File')) {
|
||||
$formElement = "<input type='file' name='file'>";
|
||||
}
|
||||
else{
|
||||
$formElement = $self->getFormElement(\%properties);
|
||||
}
|
||||
|
|
@ -2303,15 +2563,16 @@ sub www_editFieldSave {
|
|||
|
||||
$listItemHTML = "<table>\n<tr>\n<td style='width:100px;' valign='top' class='formDescription'>".$label."</td>\n"
|
||||
."<td style='width:370px;'>".$formElement."</td>\n"
|
||||
."<td style='width:120px;' valign='top'> <input onClick=\"editListItem('".$session->url->page()
|
||||
."?func=editField;fieldId=".$newFieldId.";thingId=".$properties{thingId}."','".$newFieldId."')\" value='".$i18n->get('Edit','Icon')."' type='button'>"
|
||||
."<td style='width:120px;' valign='top'> <input onClick=\"editListItem('"
|
||||
.$self->getUrl('func=editField;fieldId='.$newFieldId.';thingId='.$properties{thingId})
|
||||
."','".$newFieldId."')\" value='".$i18n->get('Edit','Icon')."' type='button'>"
|
||||
."<input onClick=\"deleteListItem('".$session->url->page()."','".$newFieldId
|
||||
."','".$properties{thingId}."')\" value='".$i18n->get('Delete','Icon')."' type='button'></td>\n</tr>\n</table>";
|
||||
|
||||
# Make sure we send debug information along with the field.
|
||||
$log->preventDebugOutput;
|
||||
|
||||
$session->output->print($newFieldId.$listItemHTML);
|
||||
$session->output->print($thingId.$newFieldId.$listItemHTML);
|
||||
return "chunked";
|
||||
}
|
||||
|
||||
|
|
@ -2493,8 +2754,7 @@ sub editThingData {
|
|||
." where thingDataId = ?",[$thingDataId]);
|
||||
}
|
||||
|
||||
$fields = $session->db->read('select * from Thingy_fields where assetId = ? and thingId = ? order by sequenceNumber'
|
||||
,[$self->getId,$thingId]);
|
||||
$fields = $self->getFields($thingId);
|
||||
while (my %field = $fields->hash) {
|
||||
my $fieldName = 'field_'.$field{fieldId};
|
||||
$fieldValue = undef;
|
||||
|
|
@ -2656,13 +2916,13 @@ sub www_editThingDataSaveViaAjax {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_export ( )
|
||||
=head2 www_exportThing ( )
|
||||
|
||||
Exports search results as csv.
|
||||
Exports one entire Thing as CSV.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_export {
|
||||
sub www_exportThing {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my ($query,$sth,$out,$fields,@fields,$fileName,@fieldLabels);
|
||||
|
|
@ -2676,30 +2936,29 @@ sub www_export {
|
|||
$pb->start($i18n->get('export label').' '.$thingProperties->{label}, $session->url->extras('assets/thingy.gif'));
|
||||
$pb->update($i18n->get('Creating column headers'));
|
||||
my $tempStorage = WebGUI::Storage->createTemp($session);
|
||||
$fields = $session->db->read('select * from Thingy_fields where assetId =? and thingId = ? order by sequenceNumber',
|
||||
[$self->getId,$thingId]);
|
||||
$fields = $self->getFields($thingId);
|
||||
while (my $field = $fields->hashRef) {
|
||||
if ($field->{displayInSearch}){
|
||||
push(@fields, {
|
||||
fieldId => $field->{fieldId},
|
||||
properties => $field,
|
||||
});
|
||||
push(@fieldLabels,$field->{label});
|
||||
}
|
||||
push(@fields, {
|
||||
fieldId => $field->{fieldId},
|
||||
properties => $field,
|
||||
});
|
||||
push(@fieldLabels,$field->{label});
|
||||
}
|
||||
|
||||
my @metaDataFields = ('thingDataId','dateCreated','createdById','updatedById','updatedByName','lastUpdated','ipAddress');
|
||||
if ($thingProperties->{exportMetaData}){
|
||||
push(@fieldLabels,@metaDataFields)
|
||||
}
|
||||
|
||||
$query = $session->cache->get("query_".$thingId);
|
||||
$query = 'select * from '.$session->db->dbh->quote_identifier("Thingy_".$thingId);
|
||||
$sth = $session->db->read($query);
|
||||
|
||||
### Loop through the returned structure and put it through Text::CSV
|
||||
# Column heads
|
||||
$self->session->log->warn("field labels: ". join ' ', @fieldLabels);
|
||||
my $csv_filename = 'export_'.$thingProperties->{label}.'.csv';
|
||||
$tempStorage->addFileFromScalar($csv_filename, WebGUI::Text::joinCSV(@fieldLabels));
|
||||
open my $CSV, '>', $tempStorage->getPath($csv_filename);
|
||||
print $CSV WebGUI::Text::joinCSV( @fieldLabels );
|
||||
|
||||
# Data lines
|
||||
$pb->update($i18n->get('Writing data'));
|
||||
|
|
@ -2712,11 +2971,11 @@ sub www_export {
|
|||
my $value = $self->getFieldValue($data->{"field_".$fieldId},$field->{properties},"%y-%m-%d","%y-%m-%d %j:%n:%s");
|
||||
push(@fieldValues, $value);
|
||||
}
|
||||
if ($thingProperties->{exportMetaData}) {
|
||||
foreach my $metaDataField (@metaDataFields){
|
||||
push(@fieldValues,$data->{$metaDataField});
|
||||
}
|
||||
}
|
||||
|
||||
if ($thingProperties->{exportMetaData}) {
|
||||
push(@fieldValues, @{$data}{@metaDataFields});
|
||||
}
|
||||
|
||||
print $CSV "\n".WebGUI::Text::joinCSV( @fieldValues );
|
||||
#if (! ++$rowCounter % 25) {
|
||||
$pb->update($i18n->get('Writing data'));
|
||||
|
|
@ -2724,7 +2983,7 @@ sub www_export {
|
|||
}
|
||||
close $CSV;
|
||||
|
||||
$pb->update(sprintf q|<a href="%s">%s</a>|, $self->getUrl, sprintf($i18n->get('Return to %s'), $thingProperties->{label}));
|
||||
$pb->update(sprintf q|<a href="%s">%s</a>|, $self->getUrl($self->getThingUrl($thingProperties)), sprintf($i18n->get('Return to %s'), $thingProperties->{label}));
|
||||
return $pb->finish($tempStorage->getUrl($csv_filename));
|
||||
}
|
||||
|
||||
|
|
@ -2758,8 +3017,7 @@ sub www_getThingViaAjax {
|
|||
$thingProperties->{groupIdView});
|
||||
|
||||
my @field_loop;
|
||||
my $fields = $session->db->read('select * from Thingy_fields where assetId=? and thingId=? order by sequenceNumber'
|
||||
,[$self->getId,$thingId]);
|
||||
my $fields = $self->getFields($thingId);
|
||||
while (my $field = $fields->hashRef) {
|
||||
$field->{formElement} = $self->getFormElement($field);
|
||||
push(@field_loop,$field);
|
||||
|
|
@ -2992,8 +3250,7 @@ sub www_importForm {
|
|||
." <td>".$i18n->get("check duplicates label")."</td>"
|
||||
."</tr>";
|
||||
|
||||
$fields = $db->read('select label, fieldId from Thingy_fields where assetId =? and thingId = ? order by sequenceNumber',
|
||||
[$self->getId,$thingId]);
|
||||
$fields = $self->getFields($thingId);
|
||||
while (my $field = $fields->hashRef) {
|
||||
$fieldOptions .= "<tr><td>".$field->{label}."</td><td>";
|
||||
$fieldOptions .= WebGUI::Form::Checkbox->new($self->session, {
|
||||
|
|
@ -3059,13 +3316,7 @@ sub www_manage {
|
|||
'thing_searchUrl' => $session->url->append($url, 'func=search;thingId='.$thing->{thingId}),
|
||||
);
|
||||
# set the url for the view icon to the things default view
|
||||
my $viewParams;
|
||||
if ($thing->{defaultView} eq "addThing") {
|
||||
$viewParams = 'func=editThingData;thingId='.$thing->{thingId}.';thingDataId=new';
|
||||
}
|
||||
else{
|
||||
$viewParams = 'func=search;thingId='.$thing->{thingId};
|
||||
}
|
||||
my $viewParams = $self->getThingUrl($thing);
|
||||
$templateVars{'thing_viewIcon'} = $session->icon->view($viewParams);
|
||||
push (@things_loop, \%templateVars);
|
||||
}
|
||||
|
|
@ -3240,13 +3491,12 @@ sub getSearchTemplateVars {
|
|||
my $session = $self->session;
|
||||
my $dbh = $session->db->dbh;
|
||||
my $i18n = WebGUI::International->new($self->session,"Asset_Thingy");
|
||||
my ($var,$url,$orderBy);
|
||||
my ($fields,@searchFields_loop,@displayInSearchFields_loop,$query,@constraints);
|
||||
my (@searchResult_loop,$searchResults,@searchResults,@displayInSearchFields,$paginatePage,$currentUrl,$p);
|
||||
my (@searchResult_loop,$searchResults,@searchResults,@displayInSearchFields,$paginatePage,$p);
|
||||
|
||||
$orderBy = $session->form->process("orderBy") || $thingProperties->{sortBy};
|
||||
$var = $self->get;
|
||||
$url = $self->getUrl;
|
||||
my $orderBy = $session->form->process("orderBy") || $thingProperties->{sortBy};
|
||||
my $var = $self->get;
|
||||
my $url = $self->getUrl;
|
||||
|
||||
$var->{canEditThings} = $self->canEdit;
|
||||
$var->{"addThing_url"} = $session->url->append($url, 'func=editThing;thingId=new');
|
||||
|
|
@ -3254,7 +3504,7 @@ sub getSearchTemplateVars {
|
|||
$var->{"thing_label"} = $thingProperties->{label};
|
||||
|
||||
if ($self->hasPrivileges($thingProperties->{groupIdExport})){
|
||||
$var->{"export_url"} = $session->url->append($url, 'func=export;thingId='.$thingId);
|
||||
$var->{"export_url"} = $session->url->append($url, 'func=exportThing;thingId='.$thingId);
|
||||
}
|
||||
if ($self->hasPrivileges($thingProperties->{groupIdImport})){
|
||||
$var->{"import_url"} = $session->url->append($url, 'func=importForm;thingId='.$thingId);
|
||||
|
|
@ -3265,21 +3515,17 @@ sub getSearchTemplateVars {
|
|||
$var->{searchScreenTitle} = $thingProperties->{searchScreenTitle};
|
||||
$var->{searchDescription} = $thingProperties->{searchDescription};
|
||||
|
||||
$currentUrl = $self->getUrl();
|
||||
foreach ($self->session->form->param) {
|
||||
# if we just saved data from an edit, we do not want to keep any of the params
|
||||
last if $_ eq 'func' and $self->session->form->process($_) eq 'editThingDataSave';
|
||||
|
||||
unless ($_ eq "pn" || $_ eq "op" || $_ =~ /identifier/xi || $_ =~ /password/xi || $_ eq "orderBy" ||
|
||||
$self->session->form->process($_) eq "") {
|
||||
$currentUrl = $self->session->url->append($currentUrl,$self->session->url->escape($_)
|
||||
.'='.$self->session->url->escape($self->session->form->process($_)));
|
||||
}
|
||||
my $currentUrl;
|
||||
my $func = $session->form->process('func');
|
||||
$func = 'search' if $func eq 'editThingDataSave';
|
||||
$currentUrl = $self->getUrl('func='.$func.';thingId='.$thingId);
|
||||
##Instead of blacklisting query params, they are whitelisted. List is currently empty.
|
||||
FORM: foreach my $form (qw//) {
|
||||
my $param = $session->form->process($form);
|
||||
next FORM unless defined $param;
|
||||
$currentUrl = $session->url->append($currentUrl, $form.'='.$param);
|
||||
}
|
||||
|
||||
$fields = $session->db->read('select * from Thingy_fields where assetId =
|
||||
'.$session->db->quote($self->getId).' and thingId = '.$session->db->quote($thingId).' order by
|
||||
sequenceNumber');
|
||||
$fields = $self->getFields($thingId);
|
||||
while (my $field = $fields->hashRef) {
|
||||
if ($field->{searchIn}){
|
||||
my $searchForm = $self->getFormPlugin($field, 1);
|
||||
|
|
@ -3332,7 +3578,8 @@ sequenceNumber');
|
|||
}
|
||||
$query .= join(", ",map {$dbh->quote_identifier('field_'.$_->{fieldId})} @displayInSearchFields);
|
||||
$query .= " from ".$dbh->quote_identifier("Thingy_".$thingId);
|
||||
if($session->form->process('func') eq 'search'){
|
||||
my $func = $session->form->process('func');
|
||||
if( $func eq 'search' || $func eq 'searchViaAjax' ){
|
||||
# Don't add constraints when the search screen is displayed as an 'after save' option.
|
||||
$query .= " where ".join(" and ",@constraints) if (scalar(@constraints) > 0);
|
||||
}
|
||||
|
|
@ -3345,9 +3592,6 @@ sequenceNumber');
|
|||
$noFields = 1;
|
||||
}
|
||||
|
||||
# store query in cache for thirty minutes
|
||||
$self->session->cache->set("query_".$thingId, $query, 30*60);
|
||||
|
||||
$paginatePage = $self->session->form->param('pn') || 1;
|
||||
$currentUrl = $self->session->url->append($currentUrl, "orderBy=".$orderBy) if $orderBy;
|
||||
|
||||
|
|
@ -3355,7 +3599,7 @@ sequenceNumber');
|
|||
|
||||
my @visibleResults;
|
||||
if (! $noFields) {
|
||||
my $sth = $self->session->db->read($query) if ! $noFields;
|
||||
my $sth = $self->session->db->read($query);
|
||||
while (my $result = $sth->hashRef){
|
||||
if ($self->canViewThingData($thingId,$result->{thingDataId})){
|
||||
push(@visibleResults,$result);
|
||||
|
|
@ -3532,6 +3776,11 @@ The unique id of a thing.
|
|||
|
||||
The unique id of a row of thing data.
|
||||
|
||||
=head3 templateId
|
||||
|
||||
Optional. The unique id or url of the template to be used. When specified, the style template is not used.
|
||||
If omitted, the thing data view template and style will be used.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_viewThingData {
|
||||
|
|
@ -3540,7 +3789,7 @@ sub www_viewThingData {
|
|||
my $session = $self->session;
|
||||
my $thingId = shift || $session->form->process('thingId');
|
||||
my $thingDataId = shift || $session->form->process('thingDataId');
|
||||
|
||||
my $templateId = shift || $session->form->process('templateId');
|
||||
my $var = $self->get;
|
||||
my $url = $self->getUrl;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
|
||||
|
|
@ -3570,9 +3819,19 @@ sub www_viewThingData {
|
|||
|
||||
$self->getViewThingVars($thingId,$thingDataId,$var);
|
||||
$self->appendThingsVars($var, $thingId);
|
||||
|
||||
my $template;
|
||||
if( $templateId )
|
||||
{
|
||||
$template = WebGUI::Asset::Template->newByUrl( $session, $templateId ) ||
|
||||
WebGUI::Asset::Template->newById( $session, $templateId );
|
||||
}
|
||||
|
||||
return $self->processStyle(
|
||||
$self->processTemplate($var,$thingProperties->{viewTemplateId})
|
||||
);
|
||||
$self->processTemplate($var,$thingProperties->{viewTemplateId})
|
||||
) if !$template;
|
||||
|
||||
return $self->processTemplate($var,$template->getId,$template);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use WebGUI::International;
|
|||
use Moose;
|
||||
use WebGUI::Definition::Asset;
|
||||
extends 'WebGUI::Asset::Wobject';
|
||||
with 'WebGUI::Role::Asset::Dashlet';
|
||||
define tableName => 'WeatherData';
|
||||
define assetName => ["assetName", 'Asset_WeatherData'];
|
||||
define icon => 'weatherData.gif';
|
||||
|
|
@ -57,6 +58,7 @@ property locations => (
|
|||
tab => "properties",
|
||||
hoverHelp => ["Your list of default weather locations", 'Asset_WeatherData'],
|
||||
label => ["Default Locations", 'Asset_WeatherData'],
|
||||
dashletOverridable => 1,
|
||||
);
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -93,49 +95,70 @@ to be displayed within the page style
|
|||
|
||||
sub view {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my %var;
|
||||
my $url = $self->session->url;
|
||||
|
||||
if ($self->partnerId ne "" && $self->licenseKey ne "") {
|
||||
foreach my $location (split("\n", $self->locations)) {
|
||||
my $weather = Weather::Com::Finder->new({
|
||||
'partner_id' => $self->partnerId,
|
||||
'license' => $self->licenseKey,
|
||||
'cache' => '/tmp',
|
||||
});
|
||||
next unless defined $weather;
|
||||
my $overrides = $self->fetchUserOverrides($self->getParent->getId);
|
||||
my $locations = $overrides->{locations} || $self->locations;
|
||||
foreach my $location (split("\n", $locations)) {
|
||||
my $loop_data;
|
||||
my $link_data = [];
|
||||
my $cached_data = $session->cache->get( join "", $self->getId, $location );
|
||||
if ($cached_data) {
|
||||
$loop_data = $cached_data->{locations};
|
||||
$link_data = $cached_data->{links} || [];
|
||||
}
|
||||
else {
|
||||
my $weather = Weather::Com::Finder->new({
|
||||
'partner_id' => $self->partnerId,
|
||||
'license' => $self->licenseKey,
|
||||
'cache' => '/tmp',
|
||||
});
|
||||
next unless defined $weather;
|
||||
|
||||
foreach my $foundLocation(@{$weather->find($location)}) {
|
||||
my $current_conditions = $foundLocation->current_conditions;
|
||||
my $conditions = $current_conditions->description;
|
||||
$conditions =~ s/\b(\w)/uc($1)/eg;
|
||||
my $tempC = $current_conditions->temperature;
|
||||
my $tempF;
|
||||
$tempF = sprintf("%.0f",(((9/5)*$tempC) + 32)) if($tempC);
|
||||
my $icon = $current_conditions->icon || "na";
|
||||
foreach my $foundLocation(@{$weather->find($location)}) {
|
||||
my $current_conditions = $foundLocation->current_conditions;
|
||||
my $conditions = $current_conditions->description;
|
||||
$conditions =~ s/\b(\w)/uc($1)/eg;
|
||||
my $tempC = $current_conditions->temperature;
|
||||
my $tempF;
|
||||
$tempF = sprintf("%.0f",(((9/5)*$tempC) + 32)) if($tempC);
|
||||
my $icon = $current_conditions->icon || "na";
|
||||
|
||||
push(@{$var{'ourLocations.loop'}}, {
|
||||
query => $location,
|
||||
cityState => $foundLocation->name || $location,
|
||||
sky => $conditions || 'N/A',
|
||||
tempF => (defined $tempF)?$tempF:'N/A',
|
||||
tempC => (defined $tempC)?$tempC:'N/A',
|
||||
smallIcon => $url->extras("wobject/WeatherData/small_icons/".$icon.".png"),
|
||||
mediumIcon => $url->extras("wobject/WeatherData/medium_icons/".$icon.".png"),
|
||||
largeIcon => $url->extras("wobject/WeatherData/large_icons/".$icon.".png"),
|
||||
iconUrl => $url->extras("wobject/WeatherData/medium_icons/".$icon.".png"),
|
||||
iconAlt => $conditions,
|
||||
});
|
||||
if (!$var{links_loop}) {
|
||||
$var{links_loop} = [];
|
||||
push @{$loop_data}, {
|
||||
query => $location,
|
||||
cityState => $foundLocation->name || $location,
|
||||
sky => $conditions || 'N/A',
|
||||
tempF => (defined $tempF)?$tempF:'N/A',
|
||||
tempC => (defined $tempC)?$tempC:'N/A',
|
||||
smallIcon => $url->extras("wobject/WeatherData/small_icons/".$icon.".png"),
|
||||
mediumIcon => $url->extras("wobject/WeatherData/medium_icons/".$icon.".png"),
|
||||
largeIcon => $url->extras("wobject/WeatherData/large_icons/".$icon.".png"),
|
||||
iconUrl => $url->extras("wobject/WeatherData/medium_icons/".$icon.".png"),
|
||||
iconAlt => $conditions,
|
||||
last_fetch => time(),
|
||||
};
|
||||
for my $lnk (@{$foundLocation->current_conditions->{WEATHER}{lnks}{link}} ) {
|
||||
push @{$var{links_loop}}, {
|
||||
link_url => $lnk->{l},
|
||||
link_title => $lnk->{t},
|
||||
};
|
||||
if (! $link_data) {
|
||||
push @{ $link_data }, {
|
||||
link_url => $lnk->{l},
|
||||
link_title => $lnk->{t},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
my $cached_data = {
|
||||
locations => $loop_data,
|
||||
links => $link_data,
|
||||
};
|
||||
$session->cache->set( join( "", $self->getId, $location ), $cached_data, $self->get('cacheTimeout'));
|
||||
}
|
||||
push @{$var{'ourLocations.loop'}}, @{ $loop_data };
|
||||
if (!$var{links_loop}) {
|
||||
$var{links_loop} = $link_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $self->processTemplate(\%var, undef, $self->{_viewTemplate});
|
||||
|
|
|
|||
|
|
@ -869,6 +869,8 @@ Return search results that match the keyword from the form variable C<keyword>.
|
|||
|
||||
sub www_byKeyword {
|
||||
my $self = shift;
|
||||
my $check = $self->checkView;
|
||||
return $self->session->privilege->noAccess() unless $self->canView;
|
||||
my $session = $self->session;
|
||||
my $keyword = $session->form->process("keyword");
|
||||
|
||||
|
|
@ -980,6 +982,8 @@ Render a search form and process the contents, returning the results.
|
|||
|
||||
sub www_search {
|
||||
my $self = shift;
|
||||
my $check = $self->checkView;
|
||||
return $self->session->privilege->noAccess() unless $self->canView;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_WikiMaster");
|
||||
my $queryString = $self->session->form->process('query', 'text');
|
||||
my $var = {
|
||||
|
|
|
|||
129
lib/WebGUI/AssetAspect/Dashlet.pm
Normal file
129
lib/WebGUI/AssetAspect/Dashlet.pm
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
package WebGUI::AssetAspect::Dashlet;
|
||||
|
||||
use strict;
|
||||
use Class::C3;
|
||||
use JSON qw/to_json from_json/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
WebGUI::AssetAspect::Dashlet - Implement features to turn Assets into Dashlets
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
This Aspect provides methods that allow a Dashboard to determine, store and retrieve
|
||||
customization options for Assets.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 fetchUserOverrides ($dashboardAssetId, [$userId])
|
||||
|
||||
Retrieve user preferences for a particular dashboard and user for this Asset from the database.
|
||||
|
||||
=head3 $dashboardId
|
||||
|
||||
The assetId of the dashboard to reference.
|
||||
|
||||
=head3 $userId
|
||||
|
||||
The userId to whose preferences should be returned. Uses the current session user if omitted.
|
||||
|
||||
=cut
|
||||
|
||||
sub fetchUserOverrides {
|
||||
my $self = shift;
|
||||
my $dashboardAssetId = shift;
|
||||
my $userId = shift || $self->session->user->userId;
|
||||
my $properties_json = $self->session->db->quickScalar('select properties from Dashboard_userPrefs where dashboardAssetId=? and userId=? and dashletAssetId=?',[$dashboardAssetId, $userId, $self->getId,]);
|
||||
$properties_json ||= '{}';
|
||||
my $properties = from_json($properties_json);
|
||||
return $properties;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getOverrideFormDefinition
|
||||
|
||||
Return an array ref of form properties. The form properties are those that the
|
||||
Asset has marked as being able to be overridden by a Dashboard asset by giving
|
||||
the property the dashletOverridable flag.
|
||||
|
||||
Assets that want to allow additional properties outside of their definition should
|
||||
override and extend this method.
|
||||
|
||||
=cut
|
||||
|
||||
sub getOverrideFormDefinition {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my @definitions = reverse @{ $self->definition($session) };
|
||||
my @properties = ();
|
||||
foreach my $definition (@definitions) {
|
||||
foreach my $property_name (keys %{ $definition->{properties} }) {
|
||||
my $property = $definition->{properties}->{$property_name};
|
||||
next unless $property->{dashletOverridable};
|
||||
$property->{name} = $property_name;
|
||||
push @properties, $property;
|
||||
}
|
||||
}
|
||||
return @properties;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getUserOverrides
|
||||
|
||||
Store user preferences for this Asset. This is direct reference from inside the object, so
|
||||
if you plan to modify the data, Clone it first.
|
||||
|
||||
=cut
|
||||
|
||||
sub getUserOverrides {
|
||||
return shift->{_userOverrides};
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 setUserOverrides
|
||||
|
||||
Store user preferences for this Asset.
|
||||
|
||||
=cut
|
||||
|
||||
sub setUserOverrides {
|
||||
shift->{_userOverrides} = shift;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 storeUserOverrides ($dashboardAssetId, $properties, [$userId])
|
||||
|
||||
Store user preferences for a particular dashboard and user for this Asset to the database.
|
||||
|
||||
=head3 $dashboardId
|
||||
|
||||
The assetId of the dashboard to reference.
|
||||
|
||||
=head3 $userId
|
||||
|
||||
The userId to whose preferences should be returned. Uses the current session user if omitted.
|
||||
|
||||
=cut
|
||||
|
||||
sub storeUserOverrides {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $dashboardAssetId = shift;
|
||||
my $properties = shift;
|
||||
my $userId = shift || $session->user->userId;
|
||||
my $properties_json = to_json($properties);
|
||||
$session->db->write('DELETE FROM Dashboard_userPrefs where dashboardAssetId=? and userId=? and dashletAssetId=?',[$dashboardAssetId, $userId, $self->getId]);
|
||||
$session->db->write('INSERT INTO Dashboard_userPrefs (dashboardAssetId, userId, dashletAssetId, properties) VALUES (?,?,?,?)', [$dashboardAssetId, $userId, $self->getId, $properties_json]);
|
||||
}
|
||||
|
||||
|
||||
1; # You can't handle the truth
|
||||
|
|
@ -99,6 +99,10 @@ A hash reference of options that can modify how this method works.
|
|||
|
||||
Assets that normally autocommit their workflows (like CS Posts, and Wiki Pages) won't if this is true.
|
||||
|
||||
=head4 skipNotification
|
||||
|
||||
Disable sending a notification that a new revision was added, for those assets that support it.
|
||||
|
||||
=head4 state
|
||||
|
||||
A state for the duplicated asset (defaults to 'published')
|
||||
|
|
@ -110,8 +114,15 @@ sub duplicate {
|
|||
my $session = $self->session;
|
||||
my $options = shift;
|
||||
my $parent = $self->getParent;
|
||||
##Remove state and pass all other options along to addChild
|
||||
my $asset_state = delete $options->{state};
|
||||
my $newAsset
|
||||
= $parent->addChild( $self->get, undef, $self->get("revisionDate"), { skipAutoCommitWorkflows => $options->{skipAutoCommitWorkflows} } );
|
||||
= $parent->addChild(
|
||||
$self->get,
|
||||
undef,
|
||||
$self->get("revisionDate"),
|
||||
$options,
|
||||
);
|
||||
|
||||
if (! $newAsset) {
|
||||
$self->session->log->error(
|
||||
|
|
@ -120,12 +131,13 @@ sub duplicate {
|
|||
return undef;
|
||||
}
|
||||
# Duplicate metadata fields
|
||||
my $sth = $session->db->read(
|
||||
"select * from metaData_values where assetId = ?",
|
||||
[$self->getId]
|
||||
my $sth = $self->session->db->read(
|
||||
"select * from metaData_values where assetId = ? and revisionDate = ?",
|
||||
[$self->getId, $self->get('revisionDate')]
|
||||
);
|
||||
while (my $h = $sth->hashRef) {
|
||||
$session->db->write("insert into metaData_values (fieldId, assetId, value) values (?, ?, ?)", [$h->{fieldId}, $newAsset->getId, $h->{value}]);
|
||||
$self->session->db->write("insert into metaData_values (fieldId,
|
||||
assetId, revisionDate, value) values (?, ?, ?, ?)", [$h->{fieldId}, $newAsset->getId, $newAsset->get('revisionDate'), $h->{value}]);
|
||||
}
|
||||
|
||||
# Duplicate keywords
|
||||
|
|
@ -139,8 +151,8 @@ sub duplicate {
|
|||
keywords => $keywords,
|
||||
} );
|
||||
|
||||
if (my $state = $options->{state}) {
|
||||
$newAsset->setState($state);
|
||||
if ($asset_state) {
|
||||
$newAsset->setState($asset_state);
|
||||
}
|
||||
|
||||
return $newAsset;
|
||||
|
|
@ -263,11 +275,12 @@ WebGUI::Fork method called by www_pasteList
|
|||
sub pasteInFork {
|
||||
my ( $process, $args ) = @_;
|
||||
my $session = $process->session;
|
||||
$session->log->info( "Trying " . $args->{assetId} );
|
||||
my $self = WebGUI::Asset->newById( $session, $args->{assetId} );
|
||||
$session->asset($self);
|
||||
|
||||
my @roots = grep { $_ && $_->canEdit }
|
||||
map { WebGUI::Asset->newPending( $session, $_ ) } @{ $args->{list} };
|
||||
map { $session->log->info( " Trying " . $_ ); WebGUI::Asset->newPending( $session, $_ ) } @{ $args->{list} };
|
||||
|
||||
my @ids = map {
|
||||
my $list
|
||||
|
|
|
|||
|
|
@ -39,10 +39,6 @@ use WebGUI::Exception;
|
|||
use WebGUI::DateTime;
|
||||
use WebGUI::Asset::Wobject::DataForm;
|
||||
|
||||
#readonly session => my %session;
|
||||
#readonly assetId => my %assetId;
|
||||
#readonly asset => my %asset;
|
||||
|
||||
has session => (
|
||||
is => 'ro',
|
||||
required => 1,
|
||||
|
|
@ -101,13 +97,6 @@ has entryId => (
|
|||
writer => '_set_entryId',
|
||||
);
|
||||
|
||||
#private entryData => my %entryData;
|
||||
#private entryId => my %entryId;
|
||||
#private userId => my %userId;
|
||||
#readonly username => my %username;
|
||||
#public ipAddress => my %ipAddress;
|
||||
#public submissionDate => my %submissionDate;
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 delete
|
||||
|
|
|
|||
|
|
@ -379,8 +379,8 @@ sub exportBranch {
|
|||
|
||||
# try to write the file
|
||||
eval { $asset->exportWriteFile };
|
||||
if( $@ ) {
|
||||
WebGUI::Error->throw(error => "could not export asset with URL " . $asset->getUrl . ": $@");
|
||||
if( my $e = WebGUI::Error->caught() || $@ ) {
|
||||
WebGUI::Error->throw(error => "could not export asset with URL " . $asset->getUrl . ": $e");
|
||||
}
|
||||
|
||||
# next, tell the asset that we're exporting, so that it can export any
|
||||
|
|
@ -419,7 +419,7 @@ sub exportBranch {
|
|||
$asset->$report('done');
|
||||
};
|
||||
|
||||
my $assetIds = $self->exportGetDescendants(undef, $depth);
|
||||
my $assetIds = $self->exportGetAssetIds($options);
|
||||
foreach my $assetId ( @{$assetIds} ) {
|
||||
$exportAsset->( $assetId );
|
||||
}
|
||||
|
|
@ -507,6 +507,33 @@ sub exportCheckExportable {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 exportGetAssetIds ( options )
|
||||
|
||||
Gets the ids of all the assets to be exported in this run as an arrayref.
|
||||
Takes the same options spec as exportBranch.
|
||||
|
||||
=cut
|
||||
|
||||
sub exportGetAssetIds {
|
||||
my ($self, $options) = @_;
|
||||
my $session = $self->session;
|
||||
my $ids = $self->exportGetDescendants( undef, $options->{depth} );
|
||||
return $ids unless $options->{exportRelated};
|
||||
# We want the ids in a descendant order, but we don't want to repeat
|
||||
# assetIds, so we're using Tie::IxHash to get an ordered set.
|
||||
tie my %set, 'Tie::IxHash';
|
||||
while (my $id = shift @$ids) {
|
||||
my $asset = WebGUI::Asset->newById($session, $id);
|
||||
undef $set{$id};
|
||||
for my $id (@{ $asset->exportGetRelatedAssetIds }) {
|
||||
push(@$ids, $id) unless exists $set{$id};
|
||||
}
|
||||
}
|
||||
return [ keys %set ];
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 exportGetDescendants ( user, depth )
|
||||
|
||||
Gets the descendants of this asset for exporting, walking the lineage as the
|
||||
|
|
@ -587,6 +614,27 @@ sub exportGetDescendants {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 exportGetRelatedAssetIds
|
||||
|
||||
Normally all an asset's shorcuts, but override if exporting your asset would
|
||||
invalidate other exported assets. If exportRelated is checked, this will be
|
||||
called and any assetIds it returns will be exported when your asset is
|
||||
exported.
|
||||
|
||||
Note: You should NOT include parents as related assets simply because they're
|
||||
your parents. If the user wants to export your parent, he can do that. This is
|
||||
for assets that aren't necessarily in your ancestry. If parents were always
|
||||
related, exporting anything would export everything.
|
||||
|
||||
=cut
|
||||
|
||||
sub exportGetRelatedAssetIds {
|
||||
my $self = shift;
|
||||
WebGUI::Asset::Shortcut->getShortcutsForAssetId($self->session, $self->getId);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 exportGetUrlAsPath ( index )
|
||||
|
||||
Translates an asset's URL into an appropriate path and filename for exporting. For
|
||||
|
|
@ -663,7 +711,7 @@ sub exportInFork {
|
|||
my $session = $process->session;
|
||||
my $self = WebGUI::Asset->newById( $session, delete $args->{assetId} );
|
||||
$args->{indexFileName} = delete $args->{index};
|
||||
my $assetIds = $self->exportGetDescendants( undef, $args->{depth} );
|
||||
my $assetIds = $self->exportGetAssetIds($args);
|
||||
my $tree = WebGUI::ProgressTree->new( $session, $assetIds );
|
||||
$process->update( sub { $tree->json } );
|
||||
my %reports = (
|
||||
|
|
|
|||
|
|
@ -88,6 +88,12 @@ ENDHTML
|
|||
name => "depth",
|
||||
value => 99,
|
||||
);
|
||||
$f->addField( "YesNo",
|
||||
label => $i18n->get('Export Related Assets'),
|
||||
hoverHelp => $i18n->get('Export Related Assets description'),
|
||||
name => "exportRelated",
|
||||
value => '',
|
||||
);
|
||||
$f->addField( "selectBox",
|
||||
label => $i18n->get('Export as user'),
|
||||
hoverHelp => $i18n->get('Export as user description'),
|
||||
|
|
@ -157,7 +163,7 @@ sub www_exportStatus {
|
|||
unless $session->user->isInGroup(13);
|
||||
my $form = $session->form;
|
||||
my @vars = qw(
|
||||
index depth userId extrasUploadsAction rootUrlAction exportUrl
|
||||
index depth userId extrasUploadsAction rootUrlAction exportUrl exportRelated
|
||||
);
|
||||
$asset->forkWithStatusPage({
|
||||
plugin => 'ProgressTree',
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ sub importProducts {
|
|||
my %productRow;
|
||||
##Order the data according to the headers, in whatever order they exist.
|
||||
@productRow{ @headers } = @{ $productRow };
|
||||
$productRow{price} =~ tr/0-9.//cd;
|
||||
##Isolate just the collateral from the other product information
|
||||
my %productCollateral;
|
||||
@productCollateral{ @collateralFields } = @productRow{ @collateralFields };
|
||||
|
|
|
|||
|
|
@ -783,19 +783,25 @@ Returns a 6 digit number with leading zeros of the next rank a child will get.
|
|||
=cut
|
||||
|
||||
sub getNextChildRank {
|
||||
my $self = shift;
|
||||
my ($lineage) = $self->session->db->quickArray("select max(lineage) from asset where parentId=?",[$self->getId]);
|
||||
my $rank;
|
||||
if (defined $lineage) {
|
||||
$rank = $self->getRank($lineage);
|
||||
$self->session->log->fatal("Asset ".$self->getId." has too many children.") if ($rank >= 999998);
|
||||
$rank++;
|
||||
} else {
|
||||
$rank = 1;
|
||||
}
|
||||
return $self->formatRank($rank);
|
||||
}
|
||||
my $self = shift;
|
||||
|
||||
# Increment by steps for servers in multi-master DB setups
|
||||
my $inc_step = $self->session->config->get('db/increment_step') || 1;
|
||||
my $inc_offset = $self->session->config->get('db/increment_offset') || 0;
|
||||
|
||||
my ($lineage) = $self->session->db->quickArray("select max(lineage) from asset where parentId=?",[$self->getId]);
|
||||
my $rank;
|
||||
if (defined $lineage) {
|
||||
$rank = $self->getRank($lineage);
|
||||
# Increase rank to next step then add offset
|
||||
$rank += ( $inc_step - $rank % $inc_step ) + $inc_offset;
|
||||
$self->session->log->fatal("Asset ".$self->getId." has too many children.") if ($rank >= 999999); # Each lineage area is only 6 digits
|
||||
}
|
||||
else {
|
||||
$rank = 1;
|
||||
}
|
||||
return $self->formatRank($rank);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ These methods are available from this class:
|
|||
|
||||
=head2 addMetaDataField ( )
|
||||
|
||||
Adds a new field to the metadata system, or edit an existing one.
|
||||
Adds a new field to the metadata system, or edit an existing one. The id of
|
||||
the field is returned.
|
||||
|
||||
=head3 fieldId
|
||||
|
||||
|
|
@ -68,6 +69,10 @@ The form field type for metaData: selectBox, text, integer, or checkList, yesNo,
|
|||
For fields that provide options, the list of options. This is a string with
|
||||
newline separated values.
|
||||
|
||||
=head3 classes
|
||||
|
||||
An arrayref of classnames that this metadata field applies to
|
||||
|
||||
=cut
|
||||
|
||||
sub addMetaDataField {
|
||||
|
|
@ -79,18 +84,31 @@ sub addMetaDataField {
|
|||
my $description = shift || '';
|
||||
my $fieldType = shift;
|
||||
my $possibleValues = shift;
|
||||
my $classes = shift;
|
||||
my $db = $self->session->db;
|
||||
|
||||
if($fieldId eq 'new') {
|
||||
$fieldId = $self->session->id->generate();
|
||||
$self->session->db->write("insert into metaData_properties (fieldId, fieldName, defaultValue, description, fieldType, possibleValues) values (?,?,?,?,?,?)",
|
||||
$db->write("insert into metaData_properties (fieldId, fieldName, defaultValue, description, fieldType, possibleValues) values (?,?,?,?,?,?)",
|
||||
[ $fieldId, $fieldName, $defaultValue, $description, $fieldType, $possibleValues, ]
|
||||
);
|
||||
}
|
||||
else {
|
||||
$self->session->db->write("update metaData_properties set fieldName = ?, defaultValue = ?, description = ?, fieldType = ?, possibleValues = ? where fieldId = ?",
|
||||
$db->write("update metaData_properties set fieldName = ?, defaultValue = ?, description = ?, fieldType = ?, possibleValues = ? where fieldId = ?",
|
||||
[ $fieldName, $defaultValue, $description, $fieldType, $possibleValues, $fieldId, ]
|
||||
);
|
||||
$db->write('delete from metaData_classes where fieldId=?', [$fieldId]);
|
||||
}
|
||||
|
||||
if ($classes && @$classes) {
|
||||
my $qfid = $db->quote($fieldId);
|
||||
$db->write('insert into metaData_classes (fieldId, className) values '
|
||||
.join(', ',
|
||||
map { my $q = $db->quote($_); "($qfid, $q)" } @$classes
|
||||
));
|
||||
}
|
||||
|
||||
return $fieldId;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -109,12 +127,57 @@ The fieldId to be deleted.
|
|||
sub deleteMetaDataField {
|
||||
my $self = shift;
|
||||
my $fieldId = shift;
|
||||
$self->session->db->beginTransaction;
|
||||
$self->session->db->write("delete from metaData_properties where fieldId = ?",[$fieldId]);
|
||||
$self->session->db->write("delete from metaData_values where fieldId = ?",[$fieldId]);
|
||||
$self->session->db->commit;
|
||||
my $db = $self->session->db;
|
||||
$db->beginTransaction;
|
||||
for my $table (map { "metaData_$_" } qw(properties values classes)) {
|
||||
$db->write("delete from $table where fieldId = ?", [ $fieldId ]);
|
||||
}
|
||||
$db->commit;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getMetaDataAsFormFields
|
||||
|
||||
Returns a hashref of metadata field names WebGUI::Form objects appropriate
|
||||
for use on edit forms.
|
||||
|
||||
=cut
|
||||
|
||||
sub getMetaDataAsFormFields {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'Asset');
|
||||
my $fields = $self->getMetaDataFields;
|
||||
my %hash;
|
||||
for my $fid (keys %$fields) {
|
||||
my $info = $fields->{$fid};
|
||||
my $type = lcfirst ($info->{fieldType} || 'text');
|
||||
my $name = $info->{fieldName};
|
||||
my $options = $info->{possibleValues};
|
||||
if($type eq 'selectBox') {
|
||||
my $label = $i18n->get('Select');
|
||||
$options = "|$label\n$options";
|
||||
}
|
||||
my $formClass = ucfirst $type;
|
||||
$hash{$name} = WebGUI::Pluggable::instanciate(
|
||||
"WebGUI::Form::$formClass",
|
||||
'new',
|
||||
[
|
||||
$session, {
|
||||
name => "metadata_$fid",
|
||||
label => $name,
|
||||
value => $info->{value},
|
||||
extras => qq'title="$info->{description}"',
|
||||
defaultValue => $info->{defaultValue},
|
||||
fieldType => $type,
|
||||
options => $options,
|
||||
}
|
||||
]
|
||||
)->toHtml;
|
||||
};
|
||||
\%hash;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -140,21 +203,11 @@ sub getMetaDataAsTemplateVariables {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getMetaDataFields ( [fieldId] )
|
||||
|
||||
Returns a hash reference containing all metadata field properties for this Asset.
|
||||
You can limit the output to a certain field by specifying a fieldId.
|
||||
|
||||
=head3 fieldId
|
||||
|
||||
If specified, the hashRef will contain only this field.
|
||||
|
||||
=cut
|
||||
|
||||
sub getMetaDataFields {
|
||||
sub _getMetaDataFieldsHelper {
|
||||
my $self = shift;
|
||||
my $fieldId = shift;
|
||||
my $session = $self->session;
|
||||
my $listAll = shift || $fieldId;
|
||||
my $db = $self->session->db;
|
||||
my $sql = "select
|
||||
f.fieldId,
|
||||
f.fieldName,
|
||||
|
|
@ -164,19 +217,76 @@ sub getMetaDataFields {
|
|||
f.possibleValues,
|
||||
d.value
|
||||
from metaData_properties f
|
||||
left join metaData_values d on f.fieldId=d.fieldId and d.assetId=".$session->db->quote($self->getId);
|
||||
$sql .= " where f.fieldId = ".$session->db->quote($fieldId) if ($fieldId);
|
||||
$sql .= " order by f.fieldName";
|
||||
if ($fieldId) {
|
||||
return $session->db->quickHashRef($sql);
|
||||
}
|
||||
else {
|
||||
tie my %hash, 'Tie::IxHash';
|
||||
%hash = %{ $session->db->buildHashRefOfHashRefs($sql, [], 'fieldId') };
|
||||
return \%hash;
|
||||
}
|
||||
left join metaData_values d
|
||||
on f.fieldId=d.fieldId
|
||||
and d.assetId=?
|
||||
and d.revisionDate = ?
|
||||
";
|
||||
|
||||
my @where;
|
||||
my @place = ($self->getId, $self->get('revisionDate'));
|
||||
unless ($listAll) {
|
||||
# Either there's no class info stored for this field or this class is
|
||||
# one of them.
|
||||
push @where, q{
|
||||
not exists (
|
||||
select * from metaData_classes where fieldId = f.fieldId
|
||||
)
|
||||
or exists (
|
||||
select *
|
||||
from metaData_classes
|
||||
where className = ?
|
||||
and fieldId = f.fieldId
|
||||
)
|
||||
};
|
||||
push @place, ref $self;
|
||||
}
|
||||
|
||||
if ($fieldId) {
|
||||
push @where, 'f.fieldId = ?';
|
||||
push @place, $fieldId;
|
||||
}
|
||||
|
||||
if (@where) {
|
||||
$sql .= 'where ' . join(' AND ', map { "($_)" } @where);
|
||||
}
|
||||
|
||||
my $hash = $db->buildHashRefOfHashRefs( $sql, \@place, 'fieldId' );
|
||||
|
||||
return $fieldId ? $hash->{$fieldId} : $hash;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getAllMetaDataFields
|
||||
|
||||
getMetaDataFields without bothering about whether they apply to this class.
|
||||
|
||||
=cut
|
||||
|
||||
sub getAllMetaDataFields {
|
||||
my $self = shift;
|
||||
return $self->_getMetaDataFieldsHelper(undef, 1);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getMetaDataFields ( [fieldId] )
|
||||
|
||||
Returns a hash reference containing all metadata field properties for this Asset.
|
||||
You can limit the output to a certain field by specifying a fieldId.
|
||||
|
||||
=head3 fieldId
|
||||
|
||||
If specified, the hashRef will contain only this field. In this case, you will
|
||||
get that metadata field if it exists whether it applies to this asset or not.
|
||||
|
||||
=cut
|
||||
|
||||
sub getMetaDataFields {
|
||||
my ($self, $fieldId) = @_;
|
||||
return $self->_getMetaDataFieldsHelper($fieldId);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -198,17 +308,10 @@ sub updateMetaData {
|
|||
my $self = shift;
|
||||
my $fieldId = shift;
|
||||
my $value = shift;
|
||||
my $db = $self->session->db;
|
||||
my ($exists) = $db->quickArray("select count(*) from metaData_values where assetId = ? and fieldId = ?",[$self->getId, $fieldId]);
|
||||
if (!$exists && $value ne "") {
|
||||
$db->write("insert into metaData_values (fieldId, assetId) values (?,?)",[$fieldId, $self->getId]);
|
||||
}
|
||||
if ($value eq "") { # Keep it clean
|
||||
$db->write("delete from metaData_values where assetId = ? and fieldId = ?",[$self->getId, $fieldId]);
|
||||
}
|
||||
else {
|
||||
$db->write("update metaData_values set value = ? where assetId = ? and fieldId=?", [$value, $self->getId, $fieldId]);
|
||||
}
|
||||
$self->session->db->write(
|
||||
'replace into metaData_values (fieldId, assetId, revisionDate, value) values (?, ?, ?, ?)',
|
||||
[$fieldId, $self->getId, $self->get('revisionDate'), $value]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -279,7 +382,49 @@ sub www_editMetaDataField {
|
|||
value=>$fieldInfo->{fieldType} || "text",
|
||||
types=> [ qw /text integer yesNo selectBox radioList checkList/ ]
|
||||
);
|
||||
$f->addField( "textarea",
|
||||
|
||||
my $default = ref WebGUI::Asset->assetName eq 'ARRAY'
|
||||
? WebGUI::International->new( $self->session )->get( @{WebGUI::Asset->assetName} )
|
||||
: WebGUI::Asset->assetName;
|
||||
my %classOptions;
|
||||
# usedNames maps a name to a class. If a name exists there, it has been
|
||||
# used. If it maps to a classname, that classname needs to be renamed.
|
||||
my %usedNames;
|
||||
for my $class (WebGUI::Pluggable::findAndLoad('WebGUI::Asset')) {
|
||||
next unless $class->isa('WebGUI::Asset');
|
||||
my $name = ref $class->assetName eq 'ARRAY'
|
||||
? WebGUI::International->new( $self->session )->get( @{$class->assetName} )
|
||||
: $class->assetName;
|
||||
next unless $name; # abstract classes (e.g. wobject) don't have names
|
||||
|
||||
# We don't want things named "Asset".
|
||||
if ($name eq $default) {
|
||||
$name = $class;
|
||||
}
|
||||
elsif (exists $usedNames{$name}) {
|
||||
if (my $rename = $usedNames{$name}) {
|
||||
$classOptions{$rename} = "$name ($rename)";
|
||||
undef $usedNames{$name};
|
||||
}
|
||||
$name = "$name ($class)";
|
||||
}
|
||||
$usedNames{$name} = $class;
|
||||
$classOptions{$class} = $name;
|
||||
}
|
||||
|
||||
$f->addField( "selectList",
|
||||
name => 'classes',
|
||||
label => $i18n->get('Allowed Classes'),
|
||||
hoverHelp => $i18n->get('Allowed Classes hoverHelp'),
|
||||
options => \%classOptions,
|
||||
defaultValue => $fid ne 'new' && $self->session->db->buildArrayRef(
|
||||
'select className from metaData_classes where fieldId = ?',
|
||||
[ $fid ]
|
||||
),
|
||||
sortByValue => 1,
|
||||
);
|
||||
|
||||
$f->addField( "textarea",
|
||||
name=>"possibleValues",
|
||||
label=>$i18n->get(487),
|
||||
hoverHelp=>$i18n->get('Possible Values description'),
|
||||
|
|
@ -332,6 +477,7 @@ sub www_editMetaDataFieldSave {
|
|||
$self->session->form->process("description") || '',
|
||||
$self->session->form->process("fieldType"),
|
||||
$self->session->form->process("possibleValues"),
|
||||
[ $self->session->form->process("classes") ],
|
||||
);
|
||||
|
||||
return $self->www_manageMetaData;
|
||||
|
|
@ -353,7 +499,7 @@ sub www_manageMetaData {
|
|||
my $i18n = WebGUI::International->new($self->session,"Asset");
|
||||
$ac->addSubmenuItem($self->getUrl('func=editMetaDataField'), $i18n->get("Add new field"));
|
||||
my $output;
|
||||
my $fields = $self->getMetaDataFields();
|
||||
my $fields = $self->getAllMetaDataFields;
|
||||
foreach my $fieldId (keys %{$fields}) {
|
||||
$output .= $self->session->icon->delete("func=deleteMetaDataField;fid=".$fieldId,$self->get("url"),$i18n->get('deleteConfirm'));
|
||||
$output .= $self->session->icon->edit("func=editMetaDataField;fid=".$fieldId,$self->get("url"));
|
||||
|
|
|
|||
|
|
@ -363,6 +363,8 @@ sub trash {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
require WebGUI::Workflow::Activity::DeleteExportedFiles;
|
||||
sub _invokeWorkflowOnExportedFiles {
|
||||
my $self = shift;
|
||||
|
|
|
|||
|
|
@ -89,13 +89,33 @@ sub addRevision {
|
|||
foreach my $table ($self->meta->get_tables) {
|
||||
$session->db->write( "insert into ".$table." (assetId,revisionDate) values (?,?)", [$self->getId, $now]);
|
||||
}
|
||||
|
||||
# Copy metadata values
|
||||
my $db = $self->session->db;
|
||||
my $id = $self->getId;
|
||||
my $then = $self->get('revisionDate');
|
||||
my $mdget = q{
|
||||
select fieldId, value from metaData_values
|
||||
where assetId = ? and revisionDate = ?
|
||||
};
|
||||
my $mdset = q{
|
||||
insert into metaData_values (fieldId, value, assetId, revisionDate)
|
||||
values (?, ?, ?, ?)
|
||||
};
|
||||
for my $row (@{ $db->buildArrayRefOfHashRefs($mdget, [ $id, $then ]) }) {
|
||||
$db->write($mdset, [ $row->{fieldId}, $row->{value}, $id, $now ]);
|
||||
}
|
||||
|
||||
$session->db->commit;
|
||||
|
||||
# current values, and the user set properties
|
||||
my %mergedProperties = (%{$self->get}, %{$properties}, );
|
||||
|
||||
# Set some defaults
|
||||
$mergedProperties{ revisedBy } ||= $session->user->userId;
|
||||
$mergedProperties{ revisedBy } = $properties->{ revisedBy } || $session->user->userId;
|
||||
|
||||
# Force the packed head block to be regenerated
|
||||
delete $mergedProperties{extraHeadTagsPacked};
|
||||
|
||||
#Instantiate new revision and fill with real data
|
||||
my $newVersion = WebGUI::Asset->newById($session, $self->getId, $now);
|
||||
|
|
@ -330,6 +350,10 @@ sub purgeRevision {
|
|||
if ($count < 1) {
|
||||
$db->write("update asset set isLockedBy=null where assetId=?",[$self->getId]);
|
||||
}
|
||||
$db->write(
|
||||
'delete from metaData_values where assetId=? and revisionDate=?',
|
||||
[ $self->getId, $self->get('revisionDate') ]
|
||||
);
|
||||
$db->commit;
|
||||
$self->purgeCache;
|
||||
$self->updateHistory("purged revision ".$self->get("revisionDate"));
|
||||
|
|
|
|||
|
|
@ -900,7 +900,7 @@ sub www_createAccountSave {
|
|||
my $username = $_[0];
|
||||
my $properties = $_[1];
|
||||
my $password = $_[2];
|
||||
my $profile = $_[3];
|
||||
my $profile = $_[3] || {};
|
||||
|
||||
my $i18n = WebGUI::International->new($self->session);
|
||||
|
||||
|
|
@ -910,6 +910,13 @@ sub www_createAccountSave {
|
|||
my $userId = $u->userId;
|
||||
$u->username($username);
|
||||
$u->authMethod($self->authMethod);
|
||||
$self->session->log->info( " override: " . $self->session->scratch->getLanguageOverride );
|
||||
use Data::Dumper;
|
||||
$self->session->log->info( Dumper $profile );
|
||||
|
||||
if (!$profile->{'language'} && $self->session->scratch->getLanguageOverride) {
|
||||
$profile->{'language'} = $self->session->scratch->getLanguageOverride;
|
||||
}
|
||||
$u->karma($self->session->setting->get("karmaPerLogin"),"Login","Just for logging in.") if ($self->session->setting->get("useKarma"));
|
||||
$u->updateProfileFields($profile) if ($profile);
|
||||
$self->update($properties);
|
||||
|
|
|
|||
|
|
@ -1127,7 +1127,13 @@ sub www_emailRecoverPasswordFinish {
|
|||
my $mail = WebGUI::Mail::Send->create($session, { to=>$email, subject=>$i18n->get('WebGUI password recovery')});
|
||||
my $vars = { };
|
||||
$vars->{recoverPasswordUrl} = $session->url->append($session->url->getSiteURL,'op=auth;method=emailResetPassword;token='.$recoveryGuid);
|
||||
my $template = WebGUI::Asset->newByDynamicClass($session, $session->setting->get('webguiPasswordRecoveryEmailTemplate'));
|
||||
my $templateId = $session->setting->get('webguiPasswordRecoveryEmailTemplate');
|
||||
my $template = WebGUI::Asset->newById($session, $templateId);
|
||||
if (!$template) {
|
||||
$session->errorHandler->error("Can't instantiate template $templateId for template email recovery");
|
||||
my $i18n = WebGUI::International->new($self->session, 'Asset');
|
||||
return $i18n->get('Error: Cannot instantiate template').' '.$templateId;
|
||||
}
|
||||
my $emailText = $template->process($vars);
|
||||
WebGUI::Macro::process($session, \$emailText);
|
||||
$mail->addText($emailText);
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ sub handler {
|
|||
return undef unless ($form->get("op") eq "account");
|
||||
|
||||
#Visitor cannot access the acccount system
|
||||
return $session->privilege->insufficient if($session->user->isVisitor);
|
||||
return $session->privilege->noAccess if($session->user->isVisitor);
|
||||
|
||||
my $module = $form->get("module");
|
||||
my $method = $form->get("do");
|
||||
|
|
|
|||
|
|
@ -452,7 +452,7 @@ sub init {
|
|||
$class->daemonize( $request, sub { $class->runCmd } );
|
||||
};
|
||||
}
|
||||
exit 0;
|
||||
CORE::exit(0);
|
||||
} ## end sub init
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ sub renderBar {
|
|||
my ( $process, $template, $extras ) = @_;
|
||||
my $session = $process->session;
|
||||
my $url = $session->url;
|
||||
my $style = $session->style;
|
||||
my $f = $session->form->paramsHashRef;
|
||||
my $tt = Template->new;
|
||||
my $dialog = delete $f->{dialog};
|
||||
|
|
@ -211,13 +212,18 @@ sub renderBar {
|
|||
return $styled;
|
||||
}
|
||||
else {
|
||||
my $console = WebGUI::AdminConsole->new( $session, $f->{icon} );
|
||||
my $style = $session->style;
|
||||
$link->query_form($f);
|
||||
$console->addSubmenuItem( $link->as_string, $label );
|
||||
$style->setLink($_, { rel => 'stylesheet' }) for @sheets;
|
||||
$style->setScript($_) for @scripts;
|
||||
return $console->render( $content, $title );
|
||||
if ( $session->var->isAdminOn ) {
|
||||
my $console = WebGUI::AdminConsole->new( $session, $f->{icon} );
|
||||
my $style = $session->style;
|
||||
$link->query_form($f);
|
||||
$console->addSubmenuItem( $link->as_string, $label );
|
||||
return $console->render( $content, $title );
|
||||
}
|
||||
else {
|
||||
return $session->style->userStyle( $content );
|
||||
}
|
||||
}
|
||||
} ## end sub renderBar
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ my $template = <<'TEMPLATE';
|
|||
}
|
||||
tree = document.getElementById('tree');
|
||||
tree.innerHTML = '';
|
||||
_.each(JSON.parse(data.status), function (root) {
|
||||
_.each(YAHOO.lang.JSON.parse(data.status), function (root) {
|
||||
recurse(root, tree);
|
||||
});
|
||||
bar.update(finished, total);
|
||||
|
|
|
|||
|
|
@ -100,4 +100,37 @@ sub getName {
|
|||
return WebGUI::International->new($session, 'WebGUI')->get('codearea');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 headTags
|
||||
|
||||
Includes script files for the code area
|
||||
|
||||
=cut
|
||||
|
||||
sub headTags {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
$self->SUPER::headTags(@_);
|
||||
$session->style->setScript(
|
||||
$session->url->extras('yui-webgui/build/codeArea/codeArea-min.js')
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 toHtml
|
||||
|
||||
Add some javascript to fix hitting the tab key.
|
||||
|
||||
=cut
|
||||
|
||||
sub toHtml {
|
||||
my $self = shift;
|
||||
$self->headTags;
|
||||
my $id = $self->get('id');
|
||||
return $self->SUPER::toHtml(@_)
|
||||
. qq{<script>new YAHOO.WebGUI.CodeArea('$id').render()</script>};
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -245,7 +245,10 @@ sub toHtml {
|
|||
my $originalValue = $self->getOriginalValue;
|
||||
my $dt = eval { WebGUI::DateTime->new($session, $originalValue); };
|
||||
$dt = WebGUI::DateTime->new($session,0) if ! (blessed $dt && $dt->isa('DateTime')); ##Parsing error
|
||||
$dt->set_time_zone($session->datetime->getTimeZone);
|
||||
if ($originalValue =~ $isaEpoch) {
|
||||
##Epoch date, correct for time zone;
|
||||
$dt->set_time_zone($session->datetime->getTimeZone);
|
||||
}
|
||||
$value = $dt->toMysqlDate;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,6 +141,37 @@ sub getValueAsHtml {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 headTags ( )
|
||||
|
||||
Set the head tags for this form plugin
|
||||
|
||||
=cut
|
||||
|
||||
sub headTags {
|
||||
my $self = shift;
|
||||
my $style = $self->session->style;
|
||||
my $url = $self->session->url;
|
||||
$style->setScript($url->extras('yui/build/yahoo/yahoo-min.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/dom/dom-min.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/event/event-min.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras("yui/build/datasource/datasource-min.js"), {type=>"text/javascript"});
|
||||
$style->setScript($url->extras('yui/build/connection/connection-min.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/element/element-min.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/button/button-min.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/container/container-min.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras("yui/build/autocomplete/autocomplete-min.js"), {type=>"text/javascript"});
|
||||
$style->setScript($url->extras('yui-webgui/build/form/form.js'), { type=>'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/json/json-min.js'), {type => 'text/javascript'});
|
||||
$style->setScript($url->extras('yui-webgui/build/i18n/i18n.js'), {type => 'text/javascript'} );
|
||||
$style->setScript($url->extras('yui-webgui/build/form/groupManager.js'), { type=>'text/javascript' });
|
||||
$style->setLink($url->extras('yui/build/autocomplete/assets/skins/sam/autocomplete.css'), { rel => 'stylesheet', type => 'text/css' });
|
||||
$style->setLink($url->extras('yui/build/container/assets/skins/sam/container.css'), { rel => 'stylesheet', type => 'text/css' });
|
||||
$style->setLink($url->extras('yui/build/button/assets/skins/sam/button.css'), { rel => 'stylesheet', type => 'text/css' });
|
||||
$style->setLink($url->extras('yui-webgui/build/form/groupManager.css'), { rel => 'stylesheet', type => 'text/css' });
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 isDynamicCompatible ( )
|
||||
|
|
@ -180,9 +211,9 @@ Creates a series of hidden fields representing the data in the list.
|
|||
=cut
|
||||
|
||||
sub toHtmlAsHidden {
|
||||
my $self = shift;
|
||||
$self->set("options", $self->session->db->buildHashRef("select groupId,groupName from groups"));
|
||||
return $self->SUPER::toHtmlAsHidden();
|
||||
my $self = shift;
|
||||
$self->set("options", $self->session->db->buildHashRef("select groupId,groupName from groups"));
|
||||
return $self->SUPER::toHtmlAsHidden();
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -194,14 +225,187 @@ Renders the form field to HTML as a table row complete with labels, subtext, hov
|
|||
=cut
|
||||
|
||||
sub toHtmlWithWrapper {
|
||||
my $self = shift;
|
||||
if ($self->session->user->isAdmin) {
|
||||
my $subtext = $self->session->icon->manage("op=listGroups");
|
||||
$self->set("subtext",$subtext . $self->get("subtext"));
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $user = $session->user;
|
||||
if ($user->isAdmin) {
|
||||
my $subtext = $session->icon->manage("op=listGroups");
|
||||
$self->set("subtext", $subtext . $self->get("subtext"));
|
||||
}
|
||||
my $dialog = $self->get('name') . '_groupDialog';
|
||||
my $group_manager = $user->isInGroup($session->setting->get('groupIdAdminGroup'));
|
||||
my $form;
|
||||
if ($group_manager) {
|
||||
my $i18n = WebGUI::International->new($self->session,'Icon');
|
||||
my $name = $self->get('name');
|
||||
my $groupId = $self->getOriginalValue;
|
||||
my $extra_subtext = qq!<span class="toolbarIcon" style="vertical-align:middle;"><a href="#" onClick="WebGUI.Form.GroupManager.show_dialog('$name'); return false;"><img src="!. $session->icon->getBaseURL().qq!edit.gif" alt="!. $i18n->get('Edit') .qq!"style="vertical-align:middle;border: 0px;" /></a></span>!;
|
||||
$extra_subtext .= qq!<span class="toolbarIcon" style="vertical-align:middle;"><a href="#" onClick="WebGUI.Form.GroupManager.show_dialog('$name', 'new'); return false;"><img src="!. $session->icon->getBaseURL().qq!add.gif" alt="!. $i18n->get('Add') .qq!" style="vertical-align:middle;border: 0px;" /></a></span>!;
|
||||
$self->set("subtext", $self->get('subtext').$extra_subtext);
|
||||
}
|
||||
$self->headTags;
|
||||
$form .= $self->SUPER::toHtmlWithWrapper;
|
||||
return $form;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_groupMembers ($session)
|
||||
|
||||
Returns a list of users that are in the sub-group specified by the form variable
|
||||
variable C<groupId>. Data returned is in JSON format.
|
||||
|
||||
This is a class method.
|
||||
|
||||
=head3 $session
|
||||
|
||||
A WebGUI::Session object.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_groupMembers {
|
||||
my $session = shift;
|
||||
return '{}' unless $session->user->isInGroup($session->setting->get('groupIdAdminGroup'));
|
||||
my $groupId = $session->form->param('groupId');
|
||||
return '{}' unless $groupId;
|
||||
|
||||
my $group = WebGUI::Group->new($session, $groupId);
|
||||
return '{}' unless $group;
|
||||
|
||||
my $results = {
|
||||
groupName => $group->name,
|
||||
users => [],
|
||||
groups => [],
|
||||
};
|
||||
my $userIds = $group->getUsers('withoutExpired');
|
||||
USER: foreach my $userId (@{ $userIds }) {
|
||||
my $user = WebGUI::User->new($session, $userId);
|
||||
next USER unless $user;
|
||||
push @{$results->{users}},
|
||||
{
|
||||
username => $user->username,
|
||||
userId => $userId,
|
||||
};
|
||||
}
|
||||
my $groupIds = $group->getGroupsIn(0); ##Without recursion
|
||||
GROUP: foreach my $groupId (@{ $groupIds }) {
|
||||
my $group = WebGUI::Group->new($session, $groupId);
|
||||
next GROUP unless $group;
|
||||
push @{$results->{groups}},
|
||||
{
|
||||
groupName => $group->name,
|
||||
groupId => $groupId,
|
||||
};
|
||||
}
|
||||
|
||||
return JSON::to_json($results);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_saveGroup ($session)
|
||||
|
||||
Save new information about the membership of a group, which users have
|
||||
been added and deleted, and which groups have been added and deleted.
|
||||
|
||||
This is a subroutine, not a class method, not an object method.
|
||||
|
||||
=head3 $session
|
||||
|
||||
A WebGUI::Session object.
|
||||
|
||||
=head3 Expected form variables
|
||||
|
||||
=head4 groupId
|
||||
|
||||
The GUID for the group to modify.
|
||||
|
||||
=head4 groupName
|
||||
|
||||
The name of the group. This is always set, so it should always be included.
|
||||
|
||||
=head4 usersAdded
|
||||
|
||||
A list of userId's for users who were added.
|
||||
|
||||
=head4 usersDeleted
|
||||
|
||||
A list of userId's for users who were deleted. Deleting happens after adding.
|
||||
|
||||
=head4 groupsAdded
|
||||
|
||||
A list of groupId's for groups who were added.
|
||||
|
||||
=head4 groupsDeleted
|
||||
|
||||
A list of groupId's for groups who were deleted. Deleting happens after adding.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_saveGroup {
|
||||
my $session = shift;
|
||||
$session->log->warn("hit the group plugin");
|
||||
return '{}' unless $session->user->isInGroup($session->setting->get('groupIdAdminGroup'));
|
||||
my $form = $session->form;
|
||||
my $groupId = $form->get('groupId');
|
||||
my $group = WebGUI::Group->new($session, $groupId);
|
||||
$session->log->warn("got groupId: $groupId");
|
||||
return '{}' unless $group;
|
||||
|
||||
$session->log->warn("updating group data, name = ".$form->get('groupName'));
|
||||
$group->name($form->get('groupName'));
|
||||
my @usersAdded = $form->get('usersAdded');
|
||||
use Data::Dumper;
|
||||
$session->log->warn("users added ".Dumper(\@usersAdded));
|
||||
$group->addUsers(\@usersAdded);
|
||||
my @usersDeleted = $form->get('usersDeleted');
|
||||
$group->deleteUsers(\@usersDeleted);
|
||||
my @groupsAdded = $form->get('groupsAdded');
|
||||
$session->log->warn("groups added ".Dumper(\@groupsAdded));
|
||||
$group->addGroups(\@groupsAdded);
|
||||
my @groupsDeleted = $form->get('groupsDeleted');
|
||||
$group->deleteGroups(\@groupsDeleted);
|
||||
|
||||
return JSON::to_json({ groupId => $group->getId, groupName => $group->name, originalGroupId => $groupId });
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_searchGroups ($session)
|
||||
|
||||
Returns groups that match the supplied group name. Group name is specified via the form
|
||||
variable C<search>. A list of groups will be returned of up to 15 names and groupIds.
|
||||
|
||||
This is a subroutine, not a class method, not an object method.
|
||||
|
||||
=head3 $session
|
||||
|
||||
A WebGUI::Session object.
|
||||
|
||||
=head3 Sample JSON
|
||||
|
||||
{
|
||||
'results' : [
|
||||
{
|
||||
'groupId': 'someGroupId',
|
||||
'groupName' : 'Great Group'
|
||||
}
|
||||
return $self->SUPER::toHtmlWithWrapper;
|
||||
//Other hashes may be in the list, or it could be completely empty
|
||||
]
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub www_searchGroups {
|
||||
my $session = shift;
|
||||
return '{"results":[]}' unless $session->user->isInGroup($session->setting->get('groupIdAdminGroup'));
|
||||
my $search = $session->form->param('query');
|
||||
|
||||
my $results = $session->db->buildArrayRefOfHashRefs(q|select groupId, groupName from groups where groupName like CONCAT(?, '%') and showInForms=1 LIMIT 15|, [ $search ]);
|
||||
|
||||
return JSON::to_json({ results => $results });
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
|||
|
|
@ -139,6 +139,8 @@ sub headTags {
|
|||
my ( $url, $style ) = $self->session->quick(qw( url style ));
|
||||
$style->setScript( $url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'));
|
||||
$style->setScript( $url->extras('yui/build/json/json-min.js'));
|
||||
$style->setScript( $url->extras('yui/build/connect/connect-min.js') );
|
||||
$style->setScript( $url->extras('yui-webgui/build/i18n/i18n.js') );
|
||||
$style->setScript( $url->extras('yui-webgui/build/form/jsontable.js'));
|
||||
}
|
||||
|
||||
|
|
@ -153,6 +155,7 @@ Renders an input tag of type text.
|
|||
sub toHtml {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'WebGUI');
|
||||
my ( $url, $style ) = $session->quick(qw( url style ));
|
||||
my $value = $self->fixMacros($self->fixQuotes($self->fixSpecialCharacters($self->getOriginalValue)));
|
||||
my $output = '';
|
||||
|
|
@ -167,7 +170,7 @@ sub toHtml {
|
|||
# Buttons to add rows in the table footer
|
||||
my $cols = scalar @{ $self->get('fields') } + 1; # Extra column for buttons
|
||||
$output .= '</thead><tfoot><tr><td colspan="' . $cols . '">'
|
||||
. '<button id="' . $self->get('id') . '_add">' . "Add" . '</button>'
|
||||
. '<button id="' . $self->get('id') . '_add">' . $i18n->get('Add') . '</button>'
|
||||
. '</td></tr></tfoot>'
|
||||
;
|
||||
|
||||
|
|
@ -194,7 +197,10 @@ sub toHtml {
|
|||
elsif ( $field->{type} eq "id" ) {
|
||||
$fieldHtml .= '<input type="hidden" class="jsontable_id" name="' . $fieldName . '" value="new" />';
|
||||
}
|
||||
else { # Readonly or unknown
|
||||
elsif ( $field->{type} eq "hidden" || $field->{type} eq "readonly" ) {
|
||||
$fieldHtml .= '<input type="hidden" name="' . $fieldName . '" value="new" />';
|
||||
}
|
||||
else { # Unknown
|
||||
$fieldHtml = ' ';
|
||||
}
|
||||
|
||||
|
|
|
|||
122
lib/WebGUI/Form/TemplateParser.pm
Normal file
122
lib/WebGUI/Form/TemplateParser.pm
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
package WebGUI::Form::TemplateParser;
|
||||
|
||||
=head1 LEGAL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
WebGUI is Copyright 2001-2009 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 base 'WebGUI::Form::SelectBox';
|
||||
use WebGUI::International;
|
||||
use Tie::IxHash;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Form::TemplateParser
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A dropdown list for selecting a template parser.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
This is a subclass of WebGUI::Form::SelectBox.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
The following methods are specifically available from this class. Check the superclass for additional methods.
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 areOptionsSettable
|
||||
|
||||
No, they aren't.
|
||||
|
||||
=cut
|
||||
|
||||
sub areOptionsSettable { 0 }
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 definition ( [ additionalTerms ] )
|
||||
|
||||
See the super class for additional details.
|
||||
|
||||
=head3 additionalTerms
|
||||
|
||||
The following additional parameters have been added via this sub class.
|
||||
|
||||
=head3 allowNone
|
||||
|
||||
Set to true if "None" is an acceptable option for this dropdown. Defaults to
|
||||
false.
|
||||
|
||||
=head4 defaultValue
|
||||
|
||||
Defaults to the default parser selected in the config file
|
||||
|
||||
=cut
|
||||
|
||||
sub definition {
|
||||
my ($class, $session, $definition) = @_;
|
||||
push @{$definition ||= []}, {
|
||||
allowNone => {
|
||||
defaultValue => 0,
|
||||
},
|
||||
defaultValue => {
|
||||
defaultValue => $session->config->get('defaultTemplateParser')
|
||||
}
|
||||
};
|
||||
return $class->SUPER::definition($session, $definition);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getName ( session )
|
||||
|
||||
Returns the human readable name of this control.
|
||||
|
||||
=cut
|
||||
|
||||
sub getName {
|
||||
my ($self, $session) = @_;
|
||||
return WebGUI::International->new($session, 'WebGUI')->get('Template Parser');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getOptions
|
||||
|
||||
Called by the superclass to determine which options are presented.
|
||||
|
||||
=cut
|
||||
|
||||
sub getOptions {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
tie my %o, 'Tie::IxHash';
|
||||
if ($self->get('allowNone')) {
|
||||
$o{''} = WebGUI::International->new($session, 'WebGUI')->get('881');
|
||||
}
|
||||
return \%o unless my $parsers = $session->config->get('templateParsers');
|
||||
|
||||
for my $class (@$parsers) {
|
||||
my $parser = WebGUI::Asset::Template->getParser($session, $class);
|
||||
$o{$class} = $parser->getName;
|
||||
}
|
||||
|
||||
return \%o;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -157,6 +157,32 @@ sub getValue {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getValueAsHtml ( )
|
||||
|
||||
Return the Form's value as a formatted time.
|
||||
|
||||
=cut
|
||||
|
||||
sub getValueAsHtml {
|
||||
my $self = shift;
|
||||
my $value = $self->getOriginalValue();
|
||||
my $mysqlTime = ($value =~ $mysqlFormattedDate);
|
||||
my $digits = ($value =~ /^\d+$/);
|
||||
##Format is fine
|
||||
if ( $mysqlTime ) {
|
||||
return $value;
|
||||
}
|
||||
##Convert to mysql format
|
||||
elsif ($digits) {
|
||||
return $self->session->datetime->secondsToTime($value);
|
||||
}
|
||||
else { ##Bad stuff, maynard
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 headTags ( )
|
||||
|
||||
Set the head tags for this form plugin
|
||||
|
|
@ -164,8 +190,15 @@ Set the head tags for this form plugin
|
|||
=cut
|
||||
|
||||
sub headTags {
|
||||
my $self = shift;
|
||||
$self->session->style->setScript($self->session->url->extras('inputCheck.js'));
|
||||
my $self = shift;
|
||||
my $style = $self->session->style;
|
||||
my $url = $self->session->url;
|
||||
$style->setScript($url->extras('inputCheck.js'), { type => 'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/connection/connection-min.js'), { type => 'text/javascript'});
|
||||
$style->setScript($url->extras('yui/build/event/event-min.js'), { type => 'text/javascript' });
|
||||
$style->setScript($url->extras('yui/build/json/json-min.js'), { type => 'text/javascript' });
|
||||
$style->setScript($url->extras('yui-webgui/build/i18n/i18n.js' ), { type => 'text/javascript' });
|
||||
$style->setScript($url->extras('form/timefield.js'), { type => 'text/javascript' });
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -190,15 +223,11 @@ Renders a time field.
|
|||
|
||||
sub toHtml {
|
||||
my $self = shift;
|
||||
my $value = $self->getOriginalValue;
|
||||
my $i18n = WebGUI::International->new($self->session);
|
||||
$self->set("extras", $self->get('extras') . ' onkeyup="doInputCheck(document.getElementById(\''.$self->get("id").'\'),\'0123456789:\')"');
|
||||
return $self->SUPER::toHtml
|
||||
.WebGUI::Form::Button->new($self->session,
|
||||
id=>$self->get('id'),
|
||||
extras=>'style="font-size: 8pt;" onclick="window.timeField = this.form.'.$self->get("name").';clockSet = window.open(\''.$self->session->url->extras('timeChooser.html').'\',\'timeChooser\',\'WIDTH=230,HEIGHT=100\');return false"',
|
||||
value=>$i18n->get(970)
|
||||
)->toHtml;
|
||||
##JS expects formatted time
|
||||
$self->set('value', $self->getValueAsHtml);
|
||||
#my $i18n = WebGUI::International->new($self->session);
|
||||
$self->set("extras", $self->get('extras') . ' onblur="WebGUI.TimeField.munge(document.getElementById(\''.$self->get("id").'\'))" onkeyup="WebGUI.TimeField.check(document.getElementById(\''.$self->get("id").'\'));"');
|
||||
return $self->SUPER::toHtml;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -170,5 +170,25 @@ sub toHtml {
|
|||
)->toHtml).$manage;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_searchUsers
|
||||
|
||||
Returns users that match the supplied username. Username is specified via the form
|
||||
variable C<search>. A list of usernames will be returned of up to 15 names and userIds.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_searchUsers {
|
||||
my $session = shift;
|
||||
return '{"results":[]}' unless $session->user->isInGroup($session->setting->get('groupIdAdminUser'));
|
||||
my $search = $session->form->param('query');
|
||||
|
||||
my $results = $session->db->buildArrayRefOfHashRefs(q|select userId, username from users where username like CONCAT(?, '%') LIMIT 15|, [ $search ]);
|
||||
|
||||
return JSON::to_json({ results => $results });
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
|||
|
|
@ -92,9 +92,8 @@ An optional value to use instead of POST input.
|
|||
|
||||
sub getValue {
|
||||
my $self = shift;
|
||||
my $value = $self->SUPER::getValue(@_);
|
||||
my $value = uc $self->SUPER::getValue(@_);
|
||||
$value =~ tr/\r\n//d;
|
||||
$value =~ tr/a-z/A-Z/;
|
||||
if ($value =~ /^[A-Z\d\s\-]+$/) {
|
||||
return $value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ sub addGroups {
|
|||
my $group = WebGUI::Group->new($self->session, $gid);
|
||||
my $recursive = $self->getId ~~ $group->getGroupsIn(1);
|
||||
next GROUP if $recursive;
|
||||
$self->session->db->write("insert into groupGroupings (groupId,inGroup) values (?,?)",[$gid, $self->getId]);
|
||||
$self->session->db->write("REPLACE into groupGroupings (groupId,inGroup) values (?,?)",[$gid, $self->getId]);
|
||||
}
|
||||
$self->clearCaches();
|
||||
return 1;
|
||||
|
|
@ -212,7 +212,7 @@ sub addUsers {
|
|||
foreach my $uid (@{$users}) {
|
||||
my ($isIn) = $self->session->db->quickArray("select count(*) from groupings where groupId=? and userId=?", [$self->getId, $uid]);
|
||||
unless ($isIn) {
|
||||
$self->session->db->write("insert into groupings (groupId,userId,expireDate) values (?,?,?)", [$self->getId, $uid, (time()+$expireOffset)]);
|
||||
$self->session->db->write("REPLACE into groupings (groupId,userId,expireDate) values (?,?,?)", [$self->getId, $uid, (time()+$expireOffset)]);
|
||||
$self->session->stow->delete("gotGroupsForUser");
|
||||
} else {
|
||||
$self->userGroupExpireDate($uid,(time()+$expireOffset));
|
||||
|
|
@ -1007,24 +1007,33 @@ sub getUsersNotIn {
|
|||
if($groupId eq "") {
|
||||
return $self->getUsers($withoutExpired);
|
||||
}
|
||||
my $selfWhere;
|
||||
if ( $self->getId ne '2' ) {
|
||||
$selfWhere = "and groupId=" . $self->session->db->dbh->quote( $self->getId );
|
||||
}
|
||||
else {
|
||||
$selfWhere = 'and userId != ' . $self->session->db->dbh->quote( "1" );
|
||||
}
|
||||
|
||||
my $expireTime = 0;
|
||||
if ($withoutExpired) {
|
||||
$expireTime = time();
|
||||
}
|
||||
|
||||
my $sql = q{
|
||||
my $sql = qq{
|
||||
select
|
||||
userId
|
||||
from
|
||||
groupings
|
||||
users
|
||||
left join
|
||||
groupings using (userId)
|
||||
where
|
||||
expireDate > ?
|
||||
and groupId=?
|
||||
$selfWhere
|
||||
and userId not in (select userId from groupings where expireDate > ? and groupId=?)
|
||||
};
|
||||
|
||||
my @users = $self->session->db->buildArray($sql, [$expireTime,$self->getId,$expireTime,$groupId]);
|
||||
my @users = $self->session->db->buildArray($sql, [$expireTime,$expireTime,$groupId]);
|
||||
return \@users;
|
||||
|
||||
}
|
||||
|
|
|
|||
60
lib/WebGUI/Help/Asset_Dashboard.pm
Normal file
60
lib/WebGUI/Help/Asset_Dashboard.pm
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
package WebGUI::Help::Asset_Dashboard;
|
||||
use strict;
|
||||
|
||||
our $HELP = {
|
||||
|
||||
'dashboard template' => {
|
||||
title => 'Dashboard Template Variables',
|
||||
isa => [
|
||||
{ namespace => "Asset_Dashboard",
|
||||
tag => "dashboard asset template variables"
|
||||
},
|
||||
{ namespace => "Asset",
|
||||
tag => "asset template"
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
{ name => 'dragger.init' },
|
||||
{ name => 'fullUrl' },
|
||||
{ name => 'canEdit' },
|
||||
{ name => 'positionN_loop',
|
||||
variables => [
|
||||
{ 'name' => 'id' },
|
||||
{ 'name' => 'content' },
|
||||
{ 'name' => 'dashletTitle' },
|
||||
{ 'name' => 'shortcutUrl' },
|
||||
{ 'name' => 'dashletUrl' },
|
||||
{ 'name' => 'canDelete' },
|
||||
{ 'name' => 'canMove' },
|
||||
{ 'name' => 'canPersonalize' },
|
||||
{ 'name' => 'showReloadIcon' },
|
||||
{ 'name' => 'canEditUserPrefs' },
|
||||
{ 'name' => 'editFormUrl' },
|
||||
]
|
||||
},
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
||||
'dashboard asset template variables' => {
|
||||
private => 1,
|
||||
title => 'dashboard asset template variables title',
|
||||
isa => [
|
||||
{ namespace => "Asset_Wobject",
|
||||
tag => "wobject template variables"
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
{ name => 'templateId' },
|
||||
{ name => 'adminsGroupId' },
|
||||
{ name => 'usersGroupId' },
|
||||
{ name => 'isInitialized' },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
59
lib/WebGUI/Help/Asset_Map.pm
Normal file
59
lib/WebGUI/Help/Asset_Map.pm
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package WebGUI::Help::Asset_Map;
|
||||
use strict;
|
||||
|
||||
our $HELP = {
|
||||
|
||||
'view template' => {
|
||||
title => 'view template',
|
||||
body => '',
|
||||
isa => [
|
||||
{ namespace => 'Asset_Template',
|
||||
tag => 'template variables'
|
||||
},
|
||||
{ namespace => 'Asset_Map',
|
||||
tag => 'map asset template variables'
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
{ name => 'canAddPoint', },
|
||||
{ name => 'canEdit', },
|
||||
{ name => 'mapPoints', required => 1, },
|
||||
{ name => 'button_addPoint', required => 1, },
|
||||
{ name => 'button_setCenter', required => 1, },
|
||||
{ name => 'button_setCenter', selectPoint => 1, },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
||||
'map asset template variables' => {
|
||||
private => 1,
|
||||
title => 'map asset template variables',
|
||||
body => '',
|
||||
isa => [
|
||||
{ namespace => 'Asset',
|
||||
tag => 'asset template asset variables'
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
{ name => 'groupIdAddPoint', },
|
||||
{ name => 'mapApiKey', },
|
||||
{ name => 'mapHeight', },
|
||||
{ name => 'mapWidth', },
|
||||
{ name => 'startLatitude', },
|
||||
{ name => 'startLongitude', },
|
||||
{ name => 'startZoom', },
|
||||
{ name => 'templateIdEditPoint', },
|
||||
{ name => 'templateIdView', },
|
||||
{ name => 'templateIdViewPoint', },
|
||||
{ name => 'workflowIdPoint', },
|
||||
{ name => 'canAddPoint', },
|
||||
{ name => 'canEdit', },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
@ -10,6 +10,9 @@ our $HELP = {
|
|||
{ namespace => 'Asset_Template',
|
||||
tag => 'template variables'
|
||||
},
|
||||
{ namespace => 'Asset_MapPoint',
|
||||
tag => 'map point asset template variables'
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
variables => [
|
||||
|
|
@ -31,6 +34,9 @@ our $HELP = {
|
|||
{ name => 'form_phone', },
|
||||
{ name => 'form_fax', },
|
||||
{ name => 'form_email', },
|
||||
{ name => 'user defined variables', },
|
||||
{ name => 'form_isHidden', },
|
||||
{ name => 'form_isGeocoded', },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
|
@ -60,6 +66,11 @@ our $HELP = {
|
|||
{ name => 'phone', },
|
||||
{ name => 'fax', },
|
||||
{ name => 'email', },
|
||||
{ name => 'userDefined1', },
|
||||
{ name => 'userDefined2', },
|
||||
{ name => 'userDefined3', },
|
||||
{ name => 'userDefined4', },
|
||||
{ name => 'userDefined5', },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue