Merge branch 'WebGUI8' of github.com:plainblack/webgui into WebGUI8

This commit is contained in:
JT Smith 2010-08-27 13:41:36 -05:00
commit 1753ce64b3
156 changed files with 1044 additions and 940 deletions

View file

@ -1,4 +1,18 @@
7.10.0
7.9.13
- fixed #11783: Instances deleted during realtime run
- fixed #11781: Thingy wrong retorn value from Ajax method
- fixed #11780: fixFilenames regex needs an anchor in ZipArchive asset
- fixed #11782: Attachments all showing duplicated first thumbnail
- fixed #11777: Thingy search on yes no field fails
- fixed #11787: Gallery resolutions wrongly ordered
- fixed #11785: Article title / URL with äÄöÖüÜ (reopen #11683)
- fixed #11799: 7.8.24->7.9.11 upgrade breaks on custom Paydrivers
- fixed #11798: Gallery request non existent image
- fixed #11800: Group to view for new events defaults to 'Everyone'
- fixed #11796: Gallery Drag & Drop broken in IE 7
- fixed #11795: Wrong display UTF8 chars in Syndicated content (#12621)
7.9.12
- webgui.org homepage gives 404 (#11778)

View file

@ -64,6 +64,13 @@ save you many hours of grief.
* The Cart will now work without javascript. Javascript is used to make parts of the cart easier,
and to automatically update the user's cart so they don't have to manually update it.
* All custom Payment drivers have to be rewritten. Please read the POD for
WebGUI::Shop::PayDriver for information about the update. The upgrade script for 7.9.4
is designed to die if a non-core payment driver is detected, so after updating your custom
driver you will need to change the upgrade script.
* Custom cart templates will need to be updated to accomodate the new cart design.
7.9.3
--------------------------------------------------------------------
* Test:Deep, which had been an optional dependency for testing, has been used

View file

@ -1,529 +0,0 @@
#!/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::WikiPage;
use WebGUI::Shop::AddressBook;
use WebGUI::Shop::Pay;
use WebGUI::Workflow;
use WebGUI::Utility;
my $toVersion = "7.9.11"; # make this match what version you're going to
my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
##7.9.1-.2
addSortItemsSCColumn($session);
addExtensionWorkflow($session);
##7.9.2-.3
reindexSiteForDefaultSynopsis( $session );
addTopLevelWikiKeywords( $session );
##7.9.3-.4
addWikiSubKeywords($session);
addSynopsistoEachWikiPage($session);
dropVisitorAddressBooks($session);
alterCartTable($session);
alterAddressBookTable($session);
addWizardHandler( $session );
addTemplateExampleImage( $session );
addPayDriverTemplates( $session );
##7.9.4-.5
modifySortItems( $session );
addRejectNoticeSetting($session);
installNewCSUnsubscribeTemplate($session);
##7.9.5-.6
addIndexForInbox($session);
##7.9.7-.8
addTwitterAuth( $session );
##7.9.8-.9
migrateAttachmentsToJson( $session );
##7.9.9-.10
alterStoryArchiveTable($session);
##7.9.10-.11
alterStoryTopicTable($session);
addAssetReport($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 addExtensionWorkflow {
print "\tAdding calendar event extension to weekly maintenence..."
unless $quiet;
my $workflow = WebGUI::Workflow->new($session, 'pbworkflow000000000002');
my $activity = $workflow->addActivity('WebGUI::Workflow::Activity::ExtendCalendarRecurrences');
$activity->set(title => 'Extend Calendar Recurrences');
$activity->set(description => 'Create events for live recurrences up to two years from the current date');
print "Done\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addSortItemsSCColumn {
my $session = shift;
print "\tAdding sort items switch to Syndicated Content... " unless $quiet;
my $sth = $session->db->read('DESCRIBE `SyndicatedContent`');
while (my ($col) = $sth->array) {
if ($col eq 'sortItems') {
print "Skipped.\n" unless $quiet;
return;
}
}
$session->db->write('ALTER TABLE SyndicatedContent ADD COLUMN sortItems BOOL DEFAULT 1');
print "Done.\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addTopLevelWikiKeywords {
my $session = shift;
print "\tAdding top level keywords page to WikiMaster... " unless $quiet;
my $sth = $session->db->read('DESCRIBE `WikiMaster`');
while (my ($col) = $sth->array) {
if ($col eq 'topLevelKeywords') {
print "Skipped.\n" unless $quiet;
return;
}
}
$session->db->write('ALTER TABLE WikiMaster ADD COLUMN topLevelKeywords LONGTEXT');
print "Done.\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Reindex the site to clear out default synopsis
sub reindexSiteForDefaultSynopsis {
my $session = shift;
print "\tRe-indexing site to clear out default synopses... " unless $quiet;
my $rs = $session->db->read("select assetId, className from asset where state='published'");
my @searchableAssetIds;
while (my ($id, $class) = $rs->array) {
my $asset = WebGUI::Asset->new($session,$id,$class);
if (defined $asset && $asset->get("state") eq "published" && ($asset->get("status") eq "approved" || $asset->get("status") eq "archived")) {
$asset->indexContent;
push (@searchableAssetIds, $id);
}
}
# delete indexes of assets that are no longer searchable
my $list = $session->db->quoteAndJoin(\@searchableAssetIds) if scalar(@searchableAssetIds);
$session->db->write("delete from assetIndex where assetId not in (".$list.")") if $list;
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Add example images to templates
sub addTemplateExampleImage {
my $session = shift;
print "\tAdding example image field to template... " unless $quiet;
$session->db->write( q{
ALTER TABLE template ADD storageIdExample CHAR(22)
} );
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addWizardHandler {
my ( $sesssion ) = @_;
print "\tAdding WebGUI::Wizard... " unless $quiet;
if ( !grep { $_ eq 'WebGUI::Content::Wizard' } @{$session->config->get('contentHandlers')} ) {
# Find the place of Operation and add before
my @handlers = ();
for my $handler ( @{$session->config->get('contentHandlers')} ) {
if ( $handler eq 'WebGUI::Content::Operation' ) {
push @handlers, 'WebGUI::Content::Wizard';
}
push @handlers, $handler;
}
$session->config->set('contentHandlers',\@handlers);
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addWikiSubKeywords {
my $session = shift;
print "\tAdd the WikiMaster sub-keywords table... " unless $quiet;
# and here's our code
$session->db->write(<<EOSQL);
CREATE TABLE IF NOT EXISTS WikiMasterKeywords (
assetId CHAR(22) binary not null,
keyword CHAR(64) not null,
subKeyword CHAR(64),
PRIMARY KEY (`assetId`,`keyword`, `subKeyword`),
KEY `assetId` (`assetId`),
KEY `keyword` (`keyword`),
KEY `subKeyword` (`subKeyword`)
)
EOSQL
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addSynopsistoEachWikiPage {
my $session = shift;
print "\tAdd a synopsis to each wiki page this may take a while... " unless $quiet;
my $pager = WebGUI::Asset::WikiPage->getIsa($session);
PAGE: while (1) {
my $page = eval {$pager->()};
next PAGE if Exception::Class->caught();
last PAGE unless $page;
my ($synopsis) = $page->getSynopsisAndContent(undef, $page->get('content'));
$page->update({synopsis => $synopsis});
}
# and here's our code
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub dropVisitorAddressBooks {
my $session = shift;
print "\tDrop AddressBooks owned by Visitor... " unless $quiet;
my $sth = $session->db->read(q|SELECT addressBookId FROM addressBook where userId='1'|);
BOOK: while (my ($addressBookId) = $sth->array) {
my $book = eval { WebGUI::Shop::AddressBook->new($session, $addressBookId); };
next BOOK if Exception::Class->caught();
$book->delete;
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub alterAddressBookTable {
my $session = shift;
print "\tDrop sessionId from the Address Book database table... " unless $quiet;
# and here's our code
$session->db->write("ALTER TABLE addressBook DROP COLUMN sessionId");
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub alterCartTable {
my $session = shift;
print "\tAdd billing address column to the Cart table... " unless $quiet;
# and here's our code
$session->db->write("ALTER TABLE cart ADD COLUMN billingAddressId CHAR(22)");
$session->db->write("ALTER TABLE cart ADD COLUMN gatewayId CHAR(22)");
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addPayDriverTemplates {
my $session = shift;
print "\tAdd templates to the Payment Drivers that need them... " unless $quiet;
# and here's our code
my $pay = WebGUI::Shop::Pay->new($session);
my @gateways = @{ $pay->getPaymentGateways };
GATEWAY: foreach my $gateway (@gateways) {
next GATEWAY unless $gateway;
my $properties = $gateway->get;
if ($gateway->isa('WebGUI::Shop::PayDriver::Cash')) {
$properties->{summaryTemplateId} = '30h5rHxzE_Q0CyI3Gg7EJw';
}
elsif ($gateway->isa('WebGUI::Shop::PayDriver::ITransact')) {
##Nothing to do. This template was only changed, not added.
}
elsif ($gateway->isa('WebGUI::Shop::PayDriver::Ogone')) {
$properties->{summaryTemplateId} = 'jysVZeUR0Bx2NfrKs5sulg';
}
elsif ($gateway->isa('WebGUI::Shop::PayDriver::PayPal::PayPalStd')) {
$properties->{summaryTemplateId} = '300AozDaeveAjB_KN0ljlQ';
}
elsif ($gateway->isa('WebGUI::Shop::PayDriver::PayPal::ExpressCheckout')) {
$properties->{summaryTemplateId} = 'GqnZPB0gLoZmqQzYFaq7bg';
}
else {
die "Unknown payment driver type found. Unable to automatically upgrade.\n";
}
$gateway->update($properties);
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Changes sortItems to a SelectBox
sub modifySortItems {
my $session = shift;
print "\tUpdating SyndicatedContent...\n" unless $quiet;
require WebGUI::Form::SelectBox;
print "\t\tModifying table...\n" unless $quiet;
my $type = WebGUI::Form::SelectBox->getDatabaseFieldType;
$session->db->write("ALTER TABLE SyndicatedContent MODIFY sortItems $type");
print "\t\tConverting old values..." unless $quiet;
$session->db->write(q{
UPDATE SyndicatedContent
SET sortItems = 'none'
WHERE sortItems <> '1'
});
$session->db->write(q{
UPDATE SyndicatedContent
SET sortItems = 'pubDate_des'
WHERE sortItems = '1'
});
# and here's our code
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Adds setting which allows users to set whether or not to send reject notices
sub addRejectNoticeSetting {
my $session = shift;
print "\tAdding reject notice setting... " unless $quiet;
$session->setting->add('sendRejectNotice',1);
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub installNewCSUnsubscribeTemplate {
my $session = shift;
print "\tAdding new unsubscribe template to the CS... " unless $quiet;
$session->db->write(q|ALTER TABLE Collaboration ADD COLUMN unsubscribeTemplateId CHAR(22) NOT NULL|);
$session->db->write(q|UPDATE Collaboration set unsubscribeTemplateId='default_CS_unsubscribe'|);
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Add keys and indicies to groupGroupings to help speed up group queries
sub addIndexForInbox {
my $session = shift;
print "\tAdding index to inbox_messageState... " unless $quiet;
my $sth = $session->db->read('show create table inbox_messageState');
my ($field,$stmt) = $sth->array;
$sth->finish;
unless ($stmt =~ m/KEY `userId_deleted_isRead`/i) {
$session->db->write("alter table inbox_messageState add index userId_deleted_isRead (userId,deleted,isRead)");
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Add twitter auth and macro
sub addTwitterAuth {
my $session = shift;
print "\tAdding twitter auth method... " unless $quiet;
$session->config->addToArray( 'authMethods', 'Twitter' );
$session->config->addToHash( 'macros', "TwitterLogin" => "TwitterLogin" );
$session->setting->set( 'twitterEnabled', 0 );
$session->setting->set( 'twitterTemplateIdChooseUsername', 'mfHGkp6t9gdclmzN33OEnw' );
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Move Template attachments to JSON collateral
sub migrateAttachmentsToJson {
my $session = shift;
print "\tMoving template attachments to JSON... " unless $quiet;
# and here's our code
$session->db->write(
"ALTER TABLE template ADD attachmentsJson LONGTEXT"
);
my $attach; # hashref (template) of hashrefs (revisionDate)
# of arrayrefs (attachments) of hashrefs (attachment)
my $sth = $session->db->read( "SELECT * FROM template_attachments" );
while ( my $row = $sth->hashRef ) {
push @{ $attach->{ $row->{templateId} }{ $row->{revisionDate} } }, {
url => $row->{url},
type => $row->{type},
};
}
for my $templateId ( keys %{ $attach } ) {
for my $revisionDate ( keys %{ $attach->{$templateId} } ) {
my $data = $attach->{$templateId}{$revisionDate};
my $asset = WebGUI::Asset->newByDynamicClass( $session, $templateId, $revisionDate );
$asset->update({ attachmentsJson => JSON->new->encode( $data ) });
}
}
$session->db->write(
"DROP TABLE template_attachments"
);
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub alterStoryArchiveTable {
my $session = shift;
print "\tAdd story sort order column to the StoryAcrhive table... " unless $quiet;
my $sth = $session->db->read('DESCRIBE `StoryArchive`');
while (my ($col) = $sth->array) {
if ($col eq 'storySortOrder') {
print "Skipped.\n" unless $quiet;
return;
}
}
$session->db->write("ALTER TABLE StoryArchive ADD COLUMN storySortOrder CHAR(22)");
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub alterStoryTopicTable {
my $session = shift;
print "\tAdd story sort order column to the StoryTopic table... " unless $quiet;
my $sth = $session->db->read('DESCRIBE `StoryTopic`');
while (my ($col) = $sth->array) {
if ($col eq 'storySortOrder') {
print "Skipped.\n" unless $quiet;
return;
}
}
$session->db->write("ALTER TABLE StoryTopic ADD COLUMN storySortOrder CHAR(22)");
$session->db->write("UPDATE StoryTopic SET storySortOrder = 'Chronologically' WHERE storySortOrder IS NULL");
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub addAssetReport {
my $session = shift;
print "\tAdding Asset Report Asset ... " unless $quiet;
#Add the database table
$session->db->write(q{
CREATE TABLE `AssetReport` (
`assetId` char(22) character set utf8 collate utf8_bin NOT NULL,
`revisionDate` bigint(20) NOT NULL,
`settings` mediumtext,
`templateId` char(22) character set utf8 collate utf8_bin default NULL,
`paginateAfter` bigint(20) default NULL,
PRIMARY KEY (`assetId`,`revisionDate`)
)
});
#Add the asset to the config file
$session->config->addToHash( "assets", "WebGUI::Asset::Wobject::AssetReport", { category => "utilities" } );
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;
# 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;
print "\tUpdating packages.\n" unless ($quiet);
addPackage( $session, 'packages-7.8.24-7.9.11/merged.wgpkg' );
}
#vim:ft=perl

View file

@ -261,6 +261,44 @@ sub getTreePaginator {
}
#----------------------------------------------------------------------
=head2 www_findUser ( )
Find a user based on a partial name, username, alias, or e-mail address
=cut
sub www_findUser {
my ( $self ) = @_;
my $session = $self->session;
my ( $form, $db, $url ) = $session->quick(qw( form db url ));
my $query = '%' . $form->get('query') . '%';
my @places; # Places to look
for my $col ( 'username', 'alias', 'firstName', 'lastName', 'CONCAT(firstName," ",lastName)' ) {
push @places, $col . " LIKE ?";
}
my $sql = 'SELECT userId, CONCAT(firstName,lastName) AS name, username, alias, avatar
FROM users JOIN userProfileData USING (userId) WHERE ' . join( ' || ', @places );
my $params = [ ( $query ) x scalar @places ];
$session->log->warn( 'SQL: ' . $sql );
$session->log->warn( 'PARAM: ' . join ", ", @$params );
my $sth = $db->read( $sql, $params );
my @results;
while ( my $result = $sth->hashRef ) {
$result->{avatar} ||= $url->extras('icon/user.png');
push @results, $result;
}
my $output = JSON->new->encode( { results => \@results } );
$session->log->warn( $output );
return $output;
}
#----------------------------------------------------------------------
=head2 www_getClipboard ( )
@ -485,6 +523,7 @@ sub www_view {
$style->setLink( $url->extras('yui/build/paginator/assets/skins/sam/paginator.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink( $url->extras('yui/build/datatable/assets/skins/sam/datatable.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/autocomplete/assets/skins/sam/autocomplete.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink( $url->extras('yui/build/menu/assets/skins/sam/menu.css'), {rel=>'stylesheet', type=>'text/css'});
#$style->setLink( $url->extras('yui-webgui/build/assetManager/assetManager.css' ), { rel => "stylesheet", type => 'text/css' } );
$style->setLink( $url->extras('admin/admin.css'), { type=>'text/css', rel=>'stylesheet'} );
@ -501,6 +540,7 @@ sub www_view {
$style->setScript($url->extras('yui/build/tabview/tabview-min.js'));
$style->setScript($url->extras('yui/build/menu/menu-min.js'));
$style->setScript($url->extras('yui/build/button/button-min.js'));
$style->setScript($url->extras('yui/build/autocomplete/autocomplete-min.js'));
$style->setScript( $url->extras( 'yui/build/json/json-min.js' ) );
$style->setScript( $url->extras( 'yui-webgui/build/i18n/i18n.js' ) );
$style->setScript($url->extras('admin/admin.js'));
@ -602,7 +642,7 @@ __DATA__
<input type="button" id="backButton" value="&lt;" /><input type="button" id="forwardButton" value="&gt;" />
</span>
<div id="location">
<input type="text" id="locationUrl" value="" />
<input type="text" id="locationInput" value="" />
<span id="locationTitle"></span>
</div>
<span id="right">

View file

@ -957,7 +957,7 @@ sub getEditForm {
name => 'approved',
id => 'approveCheckbox',
value => 'approved',
label => 'Approved',
label => $i18n->get('560', 'WebGUI'),
checked => ( $session->setting->get( 'versionTagMode' ) eq 'autoCommit' ? 1 : 0 ),
} );
@ -2590,7 +2590,7 @@ sub www_add {
isHidden => $self->get("isHidden"),
className=>$class,
assetId=>"new",
url=>$self->session->form->param("url")
url=>scalar($self->session->form->param("url")),
);
$properties{isHidden} = 1 unless $self->session->config->get("assets/".$class."/isContainer");
my $newAsset = WebGUI::Asset->newByPropertyHashRef($self->session,\%properties);

View file

@ -1352,10 +1352,14 @@ override processEditForm => sub {
WebGUI::VersionTag->new($session, $self->tagId)->setWorking;
}
### Form is verified
# Events are always hidden from navigation
### Form is verified, fix properties
if (!$session->form->hasParam('groupIdView')) {
$self->update({
groupIdView => $self->getParent->get('groupIdView'),
});
}
if (!$self->get("groupIdEdit")) {
if (!$session->form->hasParam('groupIdEdit')) {
my $groupIdEdit = $self->getParent->groupIdEventEdit
|| $self->getParent->groupIdEdit
;

View file

@ -278,8 +278,14 @@ sub getResolutions {
my $self = shift;
my $storage = $self->getStorageLocation;
##Filter out the web view image and thumbnail files.
my @resolutions = grep { $_ ne $self->get("filename") } @{ $storage->getFiles };
# Return a list not including the web view image.
return [ sort { $a cmp $b } grep { $_ ne $self->filename } @{ $storage->getFiles } ];
@resolutions = map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map { my $number = $_; $number =~ s/\.\w+$//; [ $number, $_ ] } @resolutions;
return \@resolutions;
}
#----------------------------------------------------------------------------

View file

@ -135,7 +135,8 @@ sub fixFilenames {
my $extension = $storage->getFileExtension($file);
next FILE unless isIn($extension, qw/pl perl pm cgi php asp sh/);
my $newFile = $file;
$newFile =~ s/\.$extension/_$extension.txt/;
#$newFile =~ s/\.$extension$/_$extension.txt/;
$newFile =~ s/\.$extension$/_$extension.txt/;
$storage->renameFile($file, $newFile);
}
}

View file

@ -750,11 +750,11 @@ sub getTemplateVars {
$gotAttachment = 1;
}
push(@{$var{"attachment_loop"}}, {
url =>$fileUrl,
icon =>$var{"attachment.icon"},
filename =>$filename,
thumbnail =>$var{"image.thumbnail"},
isImage =>$isImage
url => $fileUrl,
icon => $storage->getFileIconUrl($filename),
filename => $filename,
thumbnail => $isImage ? $storage->getThumbnailUrl($filename) : '',
isImage => $isImage,
});
}
}

View file

@ -686,9 +686,7 @@ Return the asset that this Shortcut points to.
sub getShortcutDefault {
my $self = shift;
use Carp; $self->get('shortcutToAssetId') or Carp::confess('no ShortcutToAssetId; our getId says: ' . $self->getId);
warn "getShortcutDefault has a shortcutToAssetId of: " . $self->get('shortcutToAssetId');
return WebGUI::Asset->newById($self->session, $self->get("shortcutToAssetId")); # XXX "newById must get an assetId"
return WebGUI::Asset->newById($self->session, $self->get("shortcutToAssetId"));
}
#-------------------------------------------------------------------

View file

@ -22,6 +22,7 @@ use WebGUI::Asset::Wobject;
use WebGUI::Image::Graph;
use WebGUI::Storage;
use JSON;
use Try::Tiny;
use Moose;
use WebGUI::Definition::Asset;
@ -376,8 +377,15 @@ override processEditForm => sub {
}
if (WebGUI::Image::Graph->getPluginList($self->session)) {
my $graph = WebGUI::Image::Graph->processConfigurationForm($self->session);
$self->setGraphConfig( $graph->getConfiguration );
my $graph;
try {
$graph = WebGUI::Image::Graph->processConfigurationForm($self->session);
} catch {
$self->session->log->error( "Graph plugin not available or not functional: Error: ``$_''" );
};
if( $graph ) {
$self->setGraphConfig( $graph->getConfiguration );
}
}
$self->update($property);

View file

@ -162,12 +162,8 @@ sub generateFeed {
}
}, $self->cacheTimeout );
# if the content can be downgraded, it is either valid latin1 or didn't have
# an HTTP Content-Encoding header. In the second case, XML::FeedPP will take
# care of any encoding specified in the XML prolog
utf8::downgrade($value, 1);
eval {
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1, -type => 'string', %opt);
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1, -type => 'string', xml_deref => 1, %opt);
$feed->merge_channel($singleFeed);
$feed->merge_item($singleFeed);
};
@ -176,7 +172,6 @@ sub generateFeed {
}
}
# build a new feed that matches the term the user is interested in
if ($self->hasTerms ne '') {
my @terms = split /,\s*/, $self->hasTerms; # get the list of terms

View file

@ -2587,9 +2587,10 @@ sub www_editThingDataSaveViaAjax {
}
my $thingProperties = $self->getThing($thingId);
use Data::Dumper;
warn $thingId;
warn Dumper $thingProperties;
if ($thingProperties->{thingId}){
my ($privilegedGroup,$workflowId);
return $session->privilege->insufficient() unless $self->canEditThingData($thingId, $thingDataId
,$thingProperties);
@ -2600,12 +2601,15 @@ sub www_editThingDataSaveViaAjax {
my ($newThingDataId,$errors) = $self->editThingDataSave($thingId,$thingDataId);
if ($errors){
if (@{ $errors }) {
$session->http->setStatus(400);
return JSON->new->encode($errors);
}
$session->http->setStatus("200");
return '{}';
}
else {
warn "thingId not found in thingProperties\n";
$session->http->setStatus(404);
return JSON->new->encode({message => "The thingId you requested can not be found."});
}

View file

@ -19,7 +19,6 @@ use LWP::MediaTypes qw(guess_media_type);
use Time::HiRes;
use WebGUI::Asset;
use WebGUI::PassiveAnalytics::Logging;
use URI;
=head1 NAME
@ -143,9 +142,7 @@ sub getUrlPermutations {
push @permutations, $url;
$url =~ s/\.\w+$//;
}
my $uri = URI->new($url);
my @fragments = $uri->path_segments();
use Data::Dumper;
my @fragments = split /\//, $url;
FRAG: while (@fragments) {
last FRAG if $fragments[-1] eq '';
push @permutations, join "/", @fragments;

View file

@ -53,7 +53,7 @@ sub alignmentSeparator {
return "<br />\n";
}
else {
return " &nbsp; &nbsp;\n";
return "&nbsp;&nbsp;";
}
}

View file

@ -141,13 +141,14 @@ sub toHtml {
$checked = 1;
}
$output .= WebGUI::Form::Radio->new($self->session, {
name=>$self->get('name'),
value=>$key,
extras=>$self->get('extras'),
checked=>$checked,
id=>$self->get('name').$i
name => $self->get('name'),
value => $key,
extras => $self->get('extras'),
checked => $checked,
id => $self->get('name').$i,
label => $options->{$key},
})->toHtml;
$output .= '<label for="'.$self->get('name').$i.'">'.$options->{$key}."</label>" . $alignment;
$output .= $alignment;
}
$output .= "</fieldset>";
return $output;

View file

@ -15,8 +15,7 @@ package WebGUI::Form::YesNo;
=cut
use strict;
use base 'WebGUI::Form::Control';
use WebGUI::Form::Radio;
use base 'WebGUI::Form::RadioList';
use WebGUI::International;
=head1 NAME
@ -39,6 +38,18 @@ The following methods are specifically available from this class. Check the supe
#-------------------------------------------------------------------
=head2 areOptionsSettable ( )
Options are predefined for a Yes/No.
=cut
sub areOptionsSettable {
return 0;
}
#-------------------------------------------------------------------
=head2 definition ( [ additionalTerms ] )
See the super class for additional details.
@ -92,6 +103,24 @@ sub getName {
#-------------------------------------------------------------------
=head2 getOptions
Return the options, set to defaults for the Yes/No. These options are not overridable.
=cut
sub getOptions {
my $self = shift;
my $i18n = WebGUI::International->new($self->session);
$self->set('options',{
1 => $i18n->get(138),
0 => $i18n->get(139),
});
return $self->SUPER::getOptions;
}
#-------------------------------------------------------------------
=head2 getValue ( [ value ] )
If value is present, we will process it, otherwise the superclass will handle the request.
@ -137,44 +166,5 @@ sub isDynamicCompatible {
return 1;
}
#-------------------------------------------------------------------
=head2 toHtml ( )
Renders a yes/no question field.
=cut
sub toHtml {
my $self = shift;
my $i18n = WebGUI::International->new($self->session);
my ($checkYes, $checkNo);
if ($self->getOriginalValue) {
$checkYes = 1;
} else {
$checkNo = 1;
}
my $output = '<fieldset style="border:none;margin:0;padding:0">'
. WebGUI::Form::Radio->new($self->session,
checked => $checkYes,
name => $self->get("name"),
value => 1,
extras => $self->get("extras"),
label => $i18n->get(138),
)->toHtml
. '&nbsp;&nbsp;&nbsp;'
. WebGUI::Form::Radio->new($self->session,
checked => $checkNo,
name => $self->get("name"),
value => 0,
extras => $self->get("extras"),
label => $i18n->get(139),
)->toHtml
. '</fieldset>'
;
return $output;
}
1;

View file

@ -1,5 +1,20 @@
package WebGUI::FormBuilder::Role::HasObjects;
=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 Moose::Role;
has 'objects' => (
@ -10,6 +25,34 @@ has 'objects' => (
# Objects combines "fields", "fieldsets", and "tabsets"
=head1 NAME
Package WebGUI::FormBuilder::Role::HasObjects
=head1 DESCRIPTION
Role that provides an attribute for holding a set of objects.
=head1 SYNOPSIS
This method is used by several FormBuilder packages that need to nest objects. For example, a FormBuilder object
can have multiple tabs, each of which can contain multiple form fields. The role provides an objects attribute,
and an addObject method for pushing an object onto the list of objects.
with 'WebGUI::FormBuilder::Role::HasObjects';
=head1 METHODS
=head2 addObject ($object)
Adds $object to the list of objects for the consumer.
=head3 $object
Some variable, or data. It really can be anything.
=cut
sub addObject {
my ( $self, $object ) = @_;
push @{$self->objects}, $object;

View file

@ -257,6 +257,16 @@ sub _transformMacro {
});
}
=head2 quote ($text)
Escape backslashes and single quotes, and then return the text wrapped in single quotes.
=head3 $text
Text to quote.
=cut
sub quote {
my $text = shift;
$text =~ s/([\\'])/\\$1/g;

View file

@ -18,6 +18,17 @@ use Try::Tiny;
use Scalar::Util 'blessed';
use HTTP::Status ();
=head2 transform_error ($env)
Transforms exceptions of the class WebGUI::Error::Fatal into HTTP 500 error messages, displaying
the contents of the exception to the user.
=head3 $env
A Plack environment hash
=cut
sub transform_error {
my $self = shift;
my ($e, $env) = @_;
@ -33,4 +44,4 @@ sub transform_error {
}
}
1;
1;

View file

@ -38,9 +38,15 @@ These subroutines are available from this package:
#-------------------------------------------------------------------
=head2 handler ( session )
=head2 call ( $env )
The content handler for this package.
Interface method for this middleware. It checks the settings for the special entry, upgradeState.
If this is set, then it returns an HTTP 503. It will also clear the maintenance state when the
upgrade is complete.
=head3 $env
A Plack environment hash. This is used to access the WebGUI Session object.
=cut

View file

@ -24,6 +24,14 @@ and not worry about closing it.
It also sets C<webgui.debug> as appropriate.
=head2 call ($env)
Interface method for this Middleware class.
=head3 $env
A plack environment hash
=cut
sub call {
@ -77,6 +85,17 @@ sub call {
);
}
=head2 canShowDebug ($env)
Checks to see whether or not the owner of this session can see debug output. It checks
WebGUI settings showDebug and ipDebug for this.
=head3 $env
A Plack environment hash.
=cut
sub canShowDebug {
my $self = shift;
my $env = shift;

View file

@ -16,6 +16,14 @@ L<WebGUI::URL::Snoop> described itself as "A URL handler that should never be ca
You might find this middleware useful as a template for creating other simple classes.
=head2 call ($env)
Interface method for Plack to call, for this class.
=head3 $env
A Plack environment hash
=cut
sub call {
@ -31,4 +39,4 @@ sub call {
}
}
1;
1;

View file

@ -17,6 +17,14 @@ awareness.
This middleware should really only be used in development, for production you want
to be serving static files with something a lot faster.
=head2 call ($env)
Interface subroutine to implement the privilege checks inside the WGaccess files.
=head3 $env
A Plack environment hash
=cut
sub call {

View file

@ -18,12 +18,20 @@ is created.
=cut
=head2 stream
=cut
sub stream {
my $self = shift;
$self->streamer(shift);
$self->streaming(1);
}
=head2 stream_write
=cut
sub stream_write {
my $self = shift;
if (!$self->streaming) {
@ -33,4 +41,4 @@ sub stream_write {
$self->writer->write(@_);
}
1;
1;

View file

@ -541,7 +541,7 @@ sub new {
Accessor for the driver properties. This returns a hashref
any driver specific properties. To set the properties, use
the C<set> method.
the C<update> method.
=cut
@ -783,5 +783,20 @@ sub www_editSave {
return undef;
}
=head2 CHANGES ( )
=head3 7.9.4
In 7.9.4, the base PayDriver class was changed to accomodate the new Cart. The Cart is now in
charge of gathering billing information. The PayDriver's job is to summarize all the payment
information for the user to review (www_getCredentials) and provide the user a button to complete
the checkout process (getButton), and then to complete the checkout. PayDrivers can
do additional things beyond those steps, like the PayPal driver.
PayDrivers also now have a defult template for displaying that screen, the summaryTemplate.
While each core driver has its own template, custom drivers can use any existing one that
meets its needs.
=cut
1;

View file

@ -36,9 +36,53 @@ These subroutines are available from this package:
use strict;
use Class::InsideOut qw{ :std };
use Moose;
use WebGUI::Definition;
use Scalar::Util qw/blessed/;
has session => (
is => 'ro',
required => 1,
);
has messages => (
is => 'rw',
default => sub { [] },
);
use JSON qw{ from_json to_json };
#-------------------------------------------------------------------
=head2 new ( $session )
Constructor
=head3 session
Instanciated WebGUI::Session object.
=cut
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
my $session = shift;
if (! (blessed $session && $session->isa('WebGUI::Session'))) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session.");
}
my $optionsJSON = $session->db->quickScalar( 'select options from taxDriver where className=?', [
$class,
] );
my $options = $optionsJSON ? from_json( $optionsJSON ) : {};
$options->{session} = $session;
return $class->$orig($options);
};
=head1 NAME
Package WebGUI::Shop::TaxDriver
@ -59,11 +103,6 @@ These subroutines are available from this package:
=cut
readonly session => my %session;
readonly messages => my %messages;
private options => my %options;
=head2 appendCartItemVars ( var, cartItem )
Adds tax driver specific template variables for the given cart item to the supplied hashref.
@ -121,47 +160,20 @@ sub canManage {
=head2 className {
Returns the class name of your plugin. You must overload this method in you own plugin.
Returns the class name of your plugin.
=cut
sub className {
my $self = shift;
$self->session->log->fatal( "Tax plugin (".$self->className.") is required to overload the className method" );
my $className = ref $self;
$self->session->log->fatal( "Tax plugin (".$self->className.") is required to overload the className method" )
if $className eq 'WebGUI::Shop::TaxDriver';
return 'WebGUI::Shop::TaxDriver';
return $className;
}
#-----------------------------------------------------------
=head2 get ( [ property ] )
Returns the value of the requested configuration property. Returns a hash ref of all property/value pairs when no
specific property is passed.
=head3 property
The property whose value should be returned.
=cut
sub get {
my $self = shift;
my $key = shift;
my $options = $options{ id $self };
# Return safe copy of options hash if no key is passed.
return { %{ $options } } unless $key;
# Return option if key is passed.
return $options->{ $key } if exists $options->{ $key };
# Key does not exist.
$self->session->log->warn( "Non-existant option [$key] was queried by tax plugin $self" );
return undef;
}
#-----------------------------------------------------------
@ -252,42 +264,6 @@ sub skuFormDefinition {
#-------------------------------------------------------------------
=head2 new ( $session )
Constructor
=head3 session
Instanciated WebGUI::Session object.
=cut
sub new {
my $class = shift;
my $session = shift;
WebGUI::Error::InvalidObject->throw( expected => "WebGUI::Session", got => (ref $session), error => "Need a session." )
unless $session && $session->isa( 'WebGUI::Session' );
my $self = {};
bless $self, $class;
register $self;
my $id = id $self;
$session{ $id } = $session;
$messages{ $id } = [];
# Load plugin configuration
my $optionsJSON = $session->db->quickScalar( 'select options from taxDriver where className=?', [
$self->className,
] );
$options{ $id } = $optionsJSON ? from_json( $optionsJSON ) : {};
return $self;
}
#-------------------------------------------------------------------
=head2 processSkuFormPost ( )
Processes the form parameters defined in the skuFormDefinition method and returns a hash ref containing the result.
@ -312,28 +288,21 @@ sub processSkuFormPost {
#-----------------------------------------------------------
=head2 update ( properties )
=head2 write ( )
Updates the properties of the tax driver according to those passed.
=head3 properties
Hash ref containing the properties to set.
Store the properties of this object to the database, as a JSON blob.
=cut
sub update {
sub write {
my $self = shift;
my $update = shift;
my $db = $self->session->db;
# update local options hash
$options{ id $self } = { %{ $options{ id $self } }, %{ $update } };
my $options = $self->get();
# Persist to db
$db->write( 'replace into taxDriver (className, options) values (?,?)', [
$self->session->db->write( 'replace into taxDriver (className, options) values (?,?)', [
$self->className,
to_json( $options{ id $self } ),
to_json( $options ),
] );
}

View file

@ -26,6 +26,45 @@ use JSON qw{ to_json };
use Tie::IxHash;
use base qw{ WebGUI::Shop::TaxDriver };
use Moose;
use WebGUI::Definition;
extends 'WebGUI::Shop::TaxDriver';
property taxGroups => (
fieldType => 'text',
noFormPost => 1,
default => sub { [] },
);
property shopCountry => (
fieldType => 'text',
noFormPost => 1,
default => '',
);
property userTemplateId => (
fieldType => 'text',
noFormPost => 1,
default => '',
);
property automaticViesApproval => (
fieldType => 'text',
noFormPost => 1,
default => '',
);
property acceptOnViesUnavailable => (
fieldType => 'text',
noFormPost => 1,
default => '',
);
property defaultGroup => (
fieldType => 'text',
noFormPost => 1,
default => '',
);
=head1 NAME
@ -200,18 +239,6 @@ sub appendCartItemVars {
#-------------------------------------------------------------------
=head2 className
Returns the name of this class.
=cut
sub className {
return 'WebGUI::Shop::TaxDriver::EU';
}
#-------------------------------------------------------------------
=head2 deleteGroup ( groupId )
Deletes a tax group.

View file

@ -8,7 +8,9 @@ use WebGUI::Exception::Shop;
use List::Util qw{ sum };
use Tie::IxHash;
use base qw{ WebGUI::Shop::TaxDriver };
use Moose;
use WebGUI::Definition;
extends 'WebGUI::Shop::TaxDriver';
=head1 NAME
@ -142,18 +144,6 @@ sub getTaxRate {
#-------------------------------------------------------------------
=head2 className
Returns the name of this class.
=cut
sub className {
return 'WebGUI::Shop::TaxDriver::Generic';
}
#-------------------------------------------------------------------
=head2 delete ( [$params] )
Deletes data from the tax table by taxId.
@ -469,7 +459,8 @@ sub www_getTaxesAsJson {
my ($db, $form) = $session->quick(qw(db form));
my $startIndex = $form->get('startIndex') || 0;
my $numberOfResults = $form->get('results') || 25;
my %goodKeys = qw/country 1 state 1 city 1 code 1 'tax rate' 1/;
my %goodKeys = qw/country 1 state 1 city 1 code 1/;
$goodKeys{'tax rate'} = 1;
my $sortKey = $form->get('sortKey');
$sortKey = $goodKeys{$sortKey} == 1 ? $sortKey : 'country';
my $sortDir = $form->get('sortDir');

View file

@ -106,6 +106,10 @@ sub delete {
$self->session->db->write("delete from WorkflowInstanceScratch where instanceId=?",[$self->getId]);
$self->session->db->deleteRow("WorkflowInstance","instanceId",$self->getId);
WebGUI::Workflow::Spectre->new($self->session)->notify("workflow/deleteInstance",$self->getId) unless ($skipNotify);
# We will need to remember that we were deleted if we get realtime-run
# during start().
$self->{deleted} = 1;
}
#-------------------------------------------------------------------
@ -643,7 +647,8 @@ sub start {
my $start = time();
my $status = "complete";
$log->info('Trying to execute workflow instance '.$self->getId.' in realtime.');
while ($status eq "complete" && ($start > time() -10)) { # how much can we run in 10 seconds
# If we got deleted in the middle, we need to stop. This is a hack.
while (!$self->{deleted} && $status eq "complete" && ($start > time() -10)) { # how much can we run in 10 seconds
$status = $self->run;
$log->info('Completed activity for workflow instance '.$self->getId.' in realtime with return status of '.$status.'.');
}

View file

@ -44,11 +44,7 @@ ASSET: while (1) {
next ASSET;
}
last ASSET unless $file;
$file->getStorageLocation->setPrivileges(
$file->get('ownerUserId'),
$file->get('groupIdView'),
$file->get('groupIdEdit'),
);
$file->setPrivileges;
}
finish($session);

File diff suppressed because one or more lines are too long

View file

@ -118,6 +118,7 @@ $properties = {
%{ $properties },
ownerUserId => $user->userId,
createdBy => $user->userId,
groupIdEdit => '2',
};
cmp_deeply( $event->get, superhashof( $properties ), 'Event properties saved correctly' );
@ -164,6 +165,7 @@ $properties = {
%{ $properties },
ownerUserId => $user->userId,
createdBy => $user->userId,
groupIdEdit => '2',
};
cmp_deeply( $event->get, superhashof( $properties ), 'Events properties saved correctly' );

View file

@ -39,7 +39,7 @@ addToCleanup($versionTag);
my $gallery
= $node->addChild({
className => "WebGUI::Asset::Wobject::Gallery",
imageResolutions => "1024x768",
imageResolutions => "1024",
},
undef,
undef,

View file

@ -35,7 +35,7 @@ my ($gallery, $album, $photo);
$gallery
= $node->addChild({
className => "WebGUI::Asset::Wobject::Gallery",
imageResolutions => "1600x1200\n1024x768\n800x600\n640x480",
imageResolutions => "1600\n1024\n800\n640",
});
$album
= $gallery->addChild({
@ -49,7 +49,7 @@ $album
#----------------------------------------------------------------------------
# Tests
plan tests => 13;
plan tests => 14;
#----------------------------------------------------------------------------
# makeResolutions gets default resolutions from a parent Photo Gallery asset
@ -76,10 +76,16 @@ diag( $@ )
cmp_deeply(
$photo->getStorageLocation->getFiles,
bag( '1024x768.jpg', '1600x1200.jpg', '640x480.jpg', '800x600.jpg', 'page_title.jpg' ),
bag( '1024.jpg', '1600.jpg', '640.jpg', '800.jpg', 'page_title.jpg' ),
"makeResolutions makes all the required resolutions with the appropriate names.",
);
cmp_deeply(
$photo->getResolutions,
[qw/640.jpg 800.jpg 1024.jpg 1600.jpg/],
'getResolutions: sorts numerically'
);
TODO: {
local $TODO = 'Test to ensure the files are created with correct resolution and density';
}
@ -92,7 +98,7 @@ WebGUI::Test->addToCleanup($versionTags[-1]);
$gallery
= $node->addChild({
className => "WebGUI::Asset::Wobject::Gallery",
imageResolutions => "1600x1200\n1024x768\n800x600\n640x480",
imageResolutions => "1600\n1024\n800\n640",
});
$album
= $gallery->addChild({
@ -117,12 +123,12 @@ $photo->getStorageLocation->addFileFromFilesystem( WebGUI::Test->getTestCollater
$photo->update({ filename => 'page_title.jpg' });
ok(
!eval{ $photo->makeResolutions('100x100','200x200'); 1 },
!eval{ $photo->makeResolutions('100','200'); 1 },
"makeResolutions fails when first argument is not array reference",
);
ok(
eval{ $photo->makeResolutions(['100x100','200x200']); 1 },
eval{ $photo->makeResolutions(['100','200']); 1 },
"makeResolutions succeeds when first argument is array reference of resolutions to make",
);
diag( $@ )
@ -130,7 +136,7 @@ diag( $@ )
is_deeply(
[ sort({ $a cmp $b} @{ $photo->getStorageLocation->getFiles }) ],
['100x100.jpg', '200x200.jpg', 'page_title.jpg'],
['100.jpg', '200.jpg', 'page_title.jpg'],
"makeResolutions makes all the required resolutions with the appropriate names.",
);
@ -158,18 +164,18 @@ $photo->getStorageLocation->addFileFromFilesystem( WebGUI::Test->getTestCollater
$photo->update({ filename => 'page_title.jpg' });
ok(
!eval{ $photo->makeResolutions('100x100','200x200'); 1 },
!eval{ $photo->makeResolutions('100','200'); 1 },
"makeResolutions fails when first argument is not array reference",
);
ok(
eval{ $photo->makeResolutions(['100x100','200x200']); 1 },
eval{ $photo->makeResolutions(['100','200']); 1 },
"makeResolutions succeeds when first argument is array reference of resolutions to make",
);
is_deeply(
[ sort({ $a cmp $b} @{ $photo->getStorageLocation->getFiles }) ],
['100x100.jpg', '200x200.jpg', 'page_title.jpg'],
['100.jpg', '200.jpg', 'page_title.jpg'],
"makeResolutions makes all the required resolutions with the appropriate names.",
);

View file

@ -37,7 +37,7 @@ addToCleanup($versionTag);
my $gallery
= $node->addChild({
className => "WebGUI::Asset::Wobject::Gallery",
imageResolutions => "1024x768",
imageResolutions => "1024",
},
undef,
undef,

View file

@ -30,7 +30,7 @@ $versionTag->set({name=>"Photo Test"});
my $gallery
= $node->addChild({
className => "WebGUI::Asset::Wobject::Gallery",
imageResolutions => "1024x768",
imageResolutions => "1024",
});
my $album
= $gallery->addChild({
@ -62,7 +62,7 @@ $photo->setFile( WebGUI::Test->getTestCollateralPath('page_title.jpg') );
my $storage = $photo->getStorageLocation;
cmp_deeply(
$storage->getFiles, bag('page_title.jpg','1024x768.jpg'),
$storage->getFiles, bag('page_title.jpg','1024.jpg'),
"Storage location contains the resolution file",
);

View file

@ -19,7 +19,7 @@ use WebGUI::Asset::File::ZipArchive;
use WebGUI::Test;
use Test::More; # increment this value for each test you create
use Test::Deep;
plan tests => 2;
plan tests => 3;
my $session = WebGUI::Test->session;
@ -42,3 +42,12 @@ cmp_bag(
[ qw{ extensions.tar extension_pm.txt extension_perl.txt extension.html extensions extensions/extension.html }],
'files after fixFilenames, html files left alone'
);
$storage->addFileFromScalar('file.pm.pm','content');
$arch->fixFilenames();
cmp_bag(
$storage->getFiles,
[ qw{ extensions.tar extension_pm.txt extension_perl.txt extension.html extensions extensions/extension.html file_pm.pm.txt}],
'fixFilenames: anchors replacements to the end of the string'
);

View file

@ -19,7 +19,8 @@ use strict;
use lib "$FindBin::Bin/../lib";
use WebGUI::Test;
use WebGUI::Session;
use Test::More tests => 17; # increment this value for each test you create
use Test::More tests => 18; # increment this value for each test you create
use Test::Deep;
use WebGUI::Asset::Wobject::Collaboration;
use WebGUI::Asset::Post;
use WebGUI::Asset::Post::Thread;
@ -167,4 +168,40 @@ $variables = $post2->getTemplateVars();
is( $variables->{'ownerUserId'}, 1, 'first post owned by admin');
ok( $variables->{'hideProfileUrl'}, 'hide profile url, since poster is visitor');
##Check for attachments
my $storage = $post1->getStorageLocation();
$storage->addFileFromFilesystem(WebGUI::Test->getTestCollateralPath('gooey.jpg'));
$storage->addFileFromFilesystem(WebGUI::Test->getTestCollateralPath('lamp.jpg'));
$storage->addFileFromFilesystem(WebGUI::Test->getTestCollateralPath('littleTextFile'));
my $attachment_loop = $post1->getTemplateVars()->{attachment_loop};
cmp_bag(
$attachment_loop,
[
{
filename => 'gooey.jpg',
url => $storage->getUrl('gooey.jpg'),
icon => $session->url->extras('fileIcons/jpg.gif'),
thumbnail => $storage->getThumbnailUrl('gooey.jpg'),
isImage => bool(1),
},
{
filename => 'lamp.jpg',
url => $storage->getUrl('lamp.jpg'),
icon => $session->url->extras('fileIcons/jpg.gif'),
thumbnail => $storage->getThumbnailUrl('lamp.jpg'),
isImage => bool(1),
},
{
filename => 'littleTextFile',
url => $storage->getUrl('littleTextFile'),
icon => $session->url->extras('fileIcons/unknown.gif'),
thumbnail => '',
isImage => bool(0),
},
],
'checking attachment loop with multiple attachments for handling of image and non-image types'
);
# vim: syntax=perl filetype=perl

View file

@ -190,20 +190,6 @@ Rich Text editor in the first sentence of the description.",
#
####################################################################
sub withCachedFeed {
my ($url, $path, $block) = @_;
$syndicated_content->update({ rssUrl => $url });
open my $file, '<', WebGUI::Test->getTestCollateralPath($path)
or die "Unable to get RSS file: $path";
my $content = do { local $/; <$file> };
close $file;
$session->cache->set($url, $content, 60);
$block->();
$session->cache->remove($url);
}
sub titles_are {
my ($expected, $message) = @_;
my $feed = $syndicated_content->generateFeed;
@ -211,18 +197,23 @@ sub titles_are {
cmp_deeply \@got, $expected, $message;
}
$syndicated_content->update({ hasTerms => 'WebGUI' });
$syndicated_content->update({ hasTerms => 'WebGUI', });
my $testFeedUrl = 'http://www.example.com/feed.rss';
$syndicated_content->update({ rssUrl => $testFeedUrl, });
my $cache = WebGUI::Cache->new($session, $testFeedUrl, 'RSS');
$cache->set(slurp_rss('tbb.rss'), 60);
my $feed = $syndicated_content->generateFeed;
titles_are(
[
'Google Picasa Plugin for WebGUI Gallery',
'WebGUI Roadmap',
'WebGUI 8 Performance',
],
'generateFeed: filters items based on the terms being in title, or description'
);
withCachedFeed 'http://www.plainblack.com/tbb.rss', 'tbb.rss', sub {
titles_are(
[
'Google Picasa Plugin for WebGUI Gallery',
'WebGUI Roadmap',
'WebGUI 8 Performance',
],
'generateFeed: filters items based on the terms being in title, or description'
);
};
####################################################################
#
@ -235,13 +226,11 @@ $syndicated_content->update({
hasTerms => '',
maxHeadlines => 50,
});
$cache->set(slurp_rss('duplicate-link.rss'), 60);
withCachedFeed 'http://www.oncp.gob.ve/oncp.xml', 'oncp.xml', sub {
my $oddFeed1 = $syndicated_content->generateFeed();
my @oddItems = $oddFeed1->get_item();
is (@oddItems, 13, 'feed has items even without pubDates or links');
};
my $oddFeed1 = $syndicated_content->generateFeed();
my @oddItems = $oddFeed1->get_item();
is (@oddItems, 2, 'feed has items even without pubDates or links');
####################################################################
#
@ -249,27 +238,36 @@ withCachedFeed 'http://www.oncp.gob.ve/oncp.xml', 'oncp.xml', sub {
#
####################################################################
withCachedFeed 'http://www.plainblack.com/tbb.rss', 'tbb_odd.rss', sub {
my @ascending = (
'I have arrived in Lisboa!',
'WebGUI 8 Performance',
'WebGUI Roadmap',
'Google Picasa Plugin for WebGUI Gallery',
);
my @descending = reverse @ascending;
my @feed = (
'WebGUI Roadmap',
'Google Picasa Plugin for WebGUI Gallery',
'I have arrived in Lisboa!',
'WebGUI 8 Performance',
);
$cache->set(slurp_rss('tbb_odd.rss'), 60);
my @ascending = (
'I have arrived in Lisboa!',
'WebGUI 8 Performance',
'WebGUI Roadmap',
'Google Picasa Plugin for WebGUI Gallery',
);
my @descending = reverse @ascending;
my @feed = (
'WebGUI Roadmap',
'Google Picasa Plugin for WebGUI Gallery',
'I have arrived in Lisboa!',
'WebGUI 8 Performance',
);
$syndicated_content->update({ sortItems => 'pubDate_asc' });
titles_are \@ascending, 'ascending sort';
$syndicated_content->update({ sortItems => 'pubDate_asc' });
titles_are \@ascending, 'ascending sort';
$syndicated_content->update({ sortItems => 'pubDate_des' });
titles_are \@descending, 'descending sort';
$syndicated_content->update({ sortItems => 'pubDate_des' });
titles_are \@descending, 'descending sort';
$syndicated_content->update({ sortItems => 'feed' });
titles_are \@feed, 'feed order';
};
$syndicated_content->update({ sortItems => 'feed' });
titles_are \@feed, 'feed order';
sub slurp_rss {
my $file = shift;
my $filepath = WebGUI::Test->getTestCollateralPath('rss/' . $file);
open my $fh, '<', $filepath
or die "Unable to get RSS file $file: $!";
my $content = do { local $/; <$fh> };
close $fh;
return $content;
}

View file

@ -0,0 +1,119 @@
#-------------------------------------------------------------------
# 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
#-------------------------------------------------------------------
use FindBin;
use strict;
use File::Spec;
use lib "$FindBin::Bin/../../../lib";
# The goal of this test is to test the creation of
# and expose any bugs of SyndicatedContent Wobjects.
use WebGUI::Test;
use Test::More; # increment this value for each test you create
use WebGUI::Session;
plan tests => 13; # increment this value for each test you create
use Test::Deep;
use WebGUI::Asset::Wobject::SyndicatedContent;
use XML::FeedPP;
use WebGUI::Cache;
my $session = WebGUI::Test->session;
my %var;
##############################
## SETUP ##
##############################
# Do our work in the import node
my $node = WebGUI::Asset->getImportNode($session);
# Create a version tag to work in
my $versionTag = WebGUI::VersionTag->getWorking($session);
$versionTag->set({name=>"SyndicatedContent Test"});
addToCleanup($versionTag);
my $syndicated_content = $node->addChild({className=>'WebGUI::Asset::Wobject::SyndicatedContent'});
####################################################################
#
# Encoding tests
#
####################################################################
my $UTF8_BOM = "\xEF\xBB\xBF";
my $testFeedUrl = 'http://www.example.com/feed.rss';
$syndicated_content->update({
hasTerms => '',
rssUrl => $testFeedUrl,
});
my $cache = WebGUI::Cache->new($session, $testFeedUrl, 'RSS');
my $utf8_es = slurp_rss('utf8-es.rss');
my $utf8_ru = slurp_rss('utf8-ru.rss');
my $entity_es = slurp_rss('entity-es.rss');
my $entity_ru = slurp_rss('entity-ru.rss');
my $utf8_no_prolog = Encode::decode_utf8(slurp_rss('utf8-no-prolog-encoding.rss'));
my $iso_8859_1 = slurp_rss('iso-8859-1.rss');
my $iso_8859_5 = slurp_rss('iso-8859-5.rss');
my $es_title = "PM captur\x{00F3} a tres delincuentes que robaron agencia bancaria en San Mart\x{00ED}n";
my $ru_title = "\x{412}\x{438}\x{43a}\x{438}\x{43f}\x{435}\x{434}\x{438}\x{44f} - \x{421}\x{432}\x{435}\x{436}\x{438}\x{435} \x{43f}\x{440}\x{430}\x{432}\x{43a}\x{438} [ru]";
$cache->set($utf8_es, 60);
is $syndicated_content->generateFeed->title, $es_title, 'Latin-1 compatible, UTF-8 encoded';
$cache->set($utf8_ru, 60);
is $syndicated_content->generateFeed->title, $ru_title, 'Russian, UTF-8 encoded';
$cache->set($entity_es, 60);
is $syndicated_content->generateFeed->title, $es_title, 'Latin-1 compatible, Entity encoded, utf8 flag off';
$cache->set($entity_ru, 60);
is $syndicated_content->generateFeed->title, $ru_title, 'Russian, Entity encoded, utf8 flag off';
$cache->set($UTF8_BOM . $utf8_es, 60);
is $syndicated_content->generateFeed->title, $es_title, 'Latin-1 compatible, UTF-8 encoded, With BOM';
$cache->set(Encode::decode_utf8($utf8_es), 60);
is $syndicated_content->generateFeed->title, $es_title, 'Latin-1 compatible, Decoded';
$cache->set(Encode::decode_utf8($utf8_ru), 60);
is $syndicated_content->generateFeed->title, $ru_title, 'Russian, Decoded';
$cache->set(Encode::decode_utf8($entity_es), 60);
is $syndicated_content->generateFeed->title, $es_title, 'Latin-1, Entity encoded, utf8 flag on';
$cache->set(Encode::decode_utf8($entity_ru), 60);
is $syndicated_content->generateFeed->title, $ru_title, 'Russian, Entity encoded, utf8 flag on';
$cache->set($UTF8_BOM . Encode::decode_utf8($utf8_es), 60);
is $syndicated_content->generateFeed->title, $es_title, 'Latin-1 compatible, Decoded, With BOM';
$cache->set($utf8_no_prolog, 60);
is $syndicated_content->generateFeed->title, $es_title, 'No encoding in prolog, Decoded';
$cache->set($iso_8859_1, 60);
is $syndicated_content->generateFeed->title, $es_title, 'ISO-8859-1 encoded';
$cache->set($iso_8859_5, 60);
is $syndicated_content->generateFeed->title, $ru_title, 'ISO-8859-5 encoded';
$cache->delete;
sub slurp_rss {
my $file = shift;
my $filepath = WebGUI::Test->getTestCollateralPath('rss/' . $file);
open my $fh, '<', $filepath
or die "Unable to get RSS file $file: $!";
my $content = do { local $/; <$fh> };
close $fh;
return $content;
}

View file

@ -17,7 +17,7 @@ use lib "$FindBin::Bin/../../lib";
use WebGUI::Test;
use WebGUI::Test::MockAsset;
use WebGUI::Session;
use Test::More tests => 28; # increment this value for each test you create
use Test::More tests => 30; # increment this value for each test you create
use Test::Deep;
use JSON;
use WebGUI::Asset::Wobject::Thingy;
@ -404,6 +404,7 @@ is($table, undef, '... drops thing specific table');
# getFieldValue
#
#################################################################
{
my %newThingProperties = %thingProperties;
my $newThingId = $thingy->addThing(\%newThingProperties, 0);
@ -419,3 +420,22 @@ is($table, undef, '... drops thing specific table');
like($datetime, qr{^\d+/\d+/\d+\s+\d+:\d+}, "... DateTime field also returns data in user's format");
}
#################################################################
#
# www_editThingDataSaveViaAjax
#
#################################################################
$session->request->setup_body({
thingId => $thingId,
thingDataId => 'new',
});
$session->user({userId => '3'});
$session->http->setStatus(200);
my $json = $thingy->www_editThingDataSaveViaAjax();
diag "json: ".$json;
is $json, '{}', 'www_editThingDataSaveViaAjax: Empty JSON hash';
is $session->http->getStatus, 200, '... http status=200';
$session->request->setup_body({ });

View file

@ -18,9 +18,11 @@ use strict;
use lib "$FindBin::Bin/../lib";
use Test::More;
use Test::Deep;
use Data::Dumper;
use WebGUI::Test; # Must use this before any other WebGUI modules
use WebGUI::Session;
use WebGUI::Content::Asset;
use Encode;
my $output;
@ -76,7 +78,15 @@ my $td
url => 'testdispatch',
} );
diag $td->getId;
my $utf8_url = "Viel-spa\x{00DF}";
utf8::upgrade $utf8_url;
my $utf8
= WebGUI::Asset->getImportNode( $session )->addChild( {
title => "utf8",
className => 'WebGUI::Asset::TestDispatch',
url => $utf8_url,
} );
WebGUI::Test->addToCleanup( WebGUI::VersionTag->getWorking( $session ) );
#----------------------------------------------------------------------------
@ -122,7 +132,11 @@ cmp_deeply(
[ '/one/two/three.rss', '/one/two/three', '/one/two', '/one', ],
".ext is a seperate URL permutation",
);
cmp_deeply(
WebGUI::Content::Asset::getUrlPermutations( $utf8_url ),
[ $utf8_url ],
"UTF-8 handling for URLs",
);
#----------------------------------------------------------------------------
# test dispatch( session, url ) method
@ -132,6 +146,12 @@ is $output, "www_view one", "Regular www_view";
is $session->asset && $session->asset->getId, $td->getId, 'dispatch set the session asset';
my $_asset = WebGUI::Asset->newByUrl($session, $utf8_url);
isa_ok $_asset, 'WebGUI::Asset::TestDispatch';
$output = WebGUI::Content::Asset::dispatch( $session, $utf8_url );
is $output, "www_view utf8", "dispatch for utf8 urls";
$output = WebGUI::Content::Asset::dispatch( $session, "testdispatch/foo" );
is $output, "bar", "special /foo handler";

View file

@ -17,7 +17,7 @@ use Tie::IxHash;
use WebGUI::Test;
use WebGUI::Session;
use Test::More tests => 57; # increment this value for each test you create
use Test::More tests => 2; # increment this value for each test you create
use Test::Deep;
my $session = WebGUI::Test->session;
@ -36,12 +36,6 @@ ok(WebGUI::Utility::isIn("webgui", qw(cars trucks webgui trains)), 'isIn()');
is_deeply([keys %hash2], [qw/e c b d a/], 'sortHash');
}
TODO: {
local $TODO = 'Things to do';
ok(0, 'Move email validation tests out of Form/Email into here');
}
# Local variables:
# mode: cperl
# End:

View file

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1" ?>
<rss version="2.0"><channel>
<title><![CDATA[Oficina Nacional de Crédito Público]]></title>
<link>http://www.oncp.gob.ve</link>
<description>Información Financiera</description>
<language>es-ve</language>
<copyright>Oficina Nacional de Crédito Público - 2009</copyright>
<image>
<title>Oficina Nacional de Crédito Público</title>
<url>http://www.oncp.gob.ve/data/themes/digital//banner/oncp.png</url>
<link>http://www.oncp.gob.ve</link>
</image>
<item>
<title><![CDATA[Deuda Interna I Sem 09 / MM US$ 20.441]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[MM US$ 20.441]]></description>
<guid isPermaLink="true">http://www.oncp.gob.ve</guid>
</item>
<item>
<title><![CDATA[Deuda Externa I Sem 09 / MM US$ 29.894]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[MM US$ 29.894]]></description>
</item>
<item>
<title><![CDATA[Tasa Pasiva / 14,52%]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[14,52%]]></description>
</item>
<item>
<title><![CDATA[Tasa Activa / 19,56%]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[19,56%]]></description>
</item>
<item>
<title><![CDATA[Variación PIB II Trimestre / -2,4%]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[-2,4%]]></description>
</item>
<item>
<title><![CDATA[PIB II Trimestre 2009 / M BsF 13.979.77]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[M BsF 13.979.77]]></description>
</item>
<item>
<title><![CDATA[Unidad Tributaria / BsF. 55,00]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[BsF. 55,00]]></description>
</item>
<item>
<title><![CDATA[Cesta Venezolana / US$ 65,32]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[US$ 65,32]]></description>
</item>
<item>
<title><![CDATA[Cesta OPEP / US$ 67,92]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[US$ 67,92]]></description>
</item>
<item>
<title><![CDATA[Variación Acumuladaa / 15,6%]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[15,6%]]></description>
</item>
<item>
<title><![CDATA[IPC Variación Agosto 2009 / 2,2%]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[2,2%]]></description>
</item>
<item>
<title><![CDATA[Reservas Internacionales con BCV + FEM / MM US$ 33.213 (32.384 + 829)]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[MM US$ 33.213 (32.384 + 829)]]></description>
</item>
<item>
<title><![CDATA[Variación Acumulada / 15,6%]]></title>
<link>http://www.oncp.gob.ve</link>
<description><![CDATA[15,6%]]></description>
</item>
</channel>
</rss>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0"><channel>
<title>Duplicate Link Feed Title</title>
<link>http://www.example.com/</link>
<description>Duplicate Link Feed Description</description>
<item>
<title>Duplicate Link Feed Item 1</title>
<link>http://www.example.com/</link>
<description>Duplicate Link Feed Item 1</description>
<guid isPermaLink="true">http://www.example.com/</guid>
</item>
<item>
<title>Duplicate Link Feed Item 2</title>
<link>http://www.example.com/</link>
<description>Duplicate Link Feed Item 2</description>
<guid isPermaLink="true">http://www.example.com/</guid>
</item>
</channel>
</rss>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>PM captur&#xF3; a tres delincuentes que robaron agencia bancaria en San Mart&#xED;n</title>
<link>http://www.vtv.gob.ve/rss-noticias-nacionales</link>
<description>RSS Noticias Nacionales</description>
<language>es</language>
<item>
<title>PM captur&#xF3; a tres delincuentes que robaron agencia bancaria en San Mart&#xED;n</title>
<link>http://www.vtv.gob.ve/noticias-nacionales/25087</link>
<description>&lt;p&gt;Efectivos de la Polic&#xED;a Metropolitana (PM) de Caracas capturaron, este lunes en horas de la ma&#xF1;ana, a tres delincuentes implicados en el robo perpetrado en el Banco Industrial de Venezuela (BIV) ubicado dentro de la oficina del Instituto Postal Telegr&#xE1;fico de Venezuela, Ipostel, en la avenida Jos&#xE9; &#xC1;ngel Lamas, San Mart&#xED;n.&lt;/p&gt;</description>
<pubDate>Mon, 19 Oct 2009 15:42:17 -0400</pubDate>
</item>
</channel>
</rss>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
<channel>
<title>PM capturó a tres delincuentes que robaron agencia bancaria en San Martín</title>
<link>http://www.vtv.gob.ve/rss-noticias-nacionales</link>
<description>RSS Noticias Nacionales</description>
<language>es</language>
<item>
<title>PM capturó a tres delincuentes que robaron agencia bancaria en San Martín</title>
<link>http://www.vtv.gob.ve/noticias-nacionales/25087</link>
<description>&lt;p&gt;Efectivos de la Policía Metropolitana (PM) de Caracas capturaron, este lunes en horas de la mañana, a tres delincuentes implicados en el robo perpetrado en el Banco Industrial de Venezuela (BIV) ubicado dentro de la oficina del Instituto Postal Telegráfico de Venezuela, Ipostel, en la avenida José Ángel Lamas, San Martín.&lt;/p&gt;</description>
<pubDate>Mon, 19 Oct 2009 15:42:17 -0400</pubDate>
</item>
</channel>
</rss>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="iso-8859-5"?>
<rss version="2.0">
<channel>
<title>Википедия - Свежие правки [ru]</title>
<link>http://ru.wikipedia.org/wiki/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:RecentChanges</link>
<description>Отслеживать последние изменения в вики в этом потоке.</description>
<language>ru</language>
<item>
<title>Йиржи из Подебрад</title>
<link>http://ru.wikipedia.org/w/index.php?title=%D0%99%D0%B8%D1%80%D0%B6%D0%B8_%D0%B8%D0%B7_%D0%9F%D0%BE%D0%B4%D0%B5%D0%B1%D1%80%D0%B0%D0%B4&amp;diff=19271780&amp;oldid=prev</link>
<description>&lt;div&gt;Происходил из знатной и влиятельной чешской семьи, примкнувшей к гуситскому лагерю. Отец Йиржи, Виктор из [[Подебрады|Подебрад]], был одним из руководителей [[табориты|таборитов]];? радикального крыла гуситов, однако через некоторое время присоединился к умеренным утраквистам. Сам Йиржи из Подебрад, будучи четырнадцатилетним мальчиком, участвовал в [[битва под Липанами|битве под Липанами]] в [[1434]], в которой умеренные гуситы, объединившиеся с австрийцами, нанесли поражение радикальным. В общем, при [[Сигизмунд (император )|Сигизмунде Люксембургском]] семья Йиржи из Подебрад принадлежала к умеренной партии, но после избрания королем Чехии с подачи католической партии Альбрехта V Австрийского (немецкого императора [[Альбрехт II (император)|Альбрехта II]]), отец и сын примкнули к оппозиции, желавшей избрания [[Казимир III|Казимира Польского]].&lt;/div&gt;</description>
<pubDate>Tue, 20 Oct 2009 00:00:44 GMT</pubDate>
</item>
</channel>
</rss>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>PM capturó a tres delincuentes que robaron agencia bancaria en San Martín</title>
<link>http://www.vtv.gob.ve/rss-noticias-nacionales</link>
<description>RSS Noticias Nacionales</description>
<language>es</language>
<item>
<title>PM capturó a tres delincuentes que robaron agencia bancaria en San Martín</title>
<link>http://www.vtv.gob.ve/noticias-nacionales/25087</link>
<description>&lt;p&gt;Efectivos de la Policía Metropolitana (PM) de Caracas capturaron, este lunes en horas de la mañana, a tres delincuentes implicados en el robo perpetrado en el Banco Industrial de Venezuela (BIV) ubicado dentro de la oficina del Instituto Postal Telegráfico de Venezuela, Ipostel, en la avenida José Ángel Lamas, San Martín.&lt;/p&gt;</description>
<pubDate>Mon, 19 Oct 2009 15:42:17 -0400</pubDate>
</item>
</channel>
</rss>

View file

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>PM capturó a tres delincuentes que robaron agencia bancaria en San Martín</title>
<link>http://www.vtv.gob.ve/rss-noticias-nacionales</link>
<description>RSS Noticias Nacionales</description>
<language>es</language>
<item>
<title>PM capturó a tres delincuentes que robaron agencia bancaria en San Martín</title>
<link>http://www.vtv.gob.ve/noticias-nacionales/25087</link>
<description>&lt;p&gt;Efectivos de la Policía Metropolitana (PM) de Caracas capturaron, este lunes en horas de la mañana, a tres delincuentes implicados en el robo perpetrado en el Banco Industrial de Venezuela (BIV) ubicado dentro de la oficina del Instituto Postal Telegráfico de Venezuela, Ipostel, en la avenida José Ángel Lamas, San Martín.&lt;/p&gt;</description>
<pubDate>Mon, 19 Oct 2009 15:42:17 -0400</pubDate>
</item>
</channel>
</rss>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Википедия - Свежие правки [ru]</title>
<link>http://ru.wikipedia.org/wiki/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:RecentChanges</link>
<description>Отслеживать последние изменения в вики в этом потоке.</description>
<language>ru</language>
<item>
<title>Йиржи из Подебрад</title>
<link>http://ru.wikipedia.org/w/index.php?title=%D0%99%D0%B8%D1%80%D0%B6%D0%B8_%D0%B8%D0%B7_%D0%9F%D0%BE%D0%B4%D0%B5%D0%B1%D1%80%D0%B0%D0%B4&amp;diff=19271780&amp;oldid=prev</link>
<description>&lt;div&gt;Происходил из знатной и влиятельной чешской семьи, примкнувшей к гуситскому лагерю. Отец Йиржи, Виктор из [[Подебрады|Подебрад]], был одним из руководителей [[табориты|таборитов]];— радикального крыла гуситов, однако через некоторое время присоединился к умеренным утраквистам. Сам Йиржи из Подебрад, будучи четырнадцатилетним мальчиком, участвовал в [[битва под Липанами|битве под Липанами]] в [[1434]], в которой умеренные гуситы, объединившиеся с австрийцами, нанесли поражение радикальным. В общем, при [[Сигизмунд (император )|Сигизмунде Люксембургском]] семья Йиржи из Подебрад принадлежала к умеренной партии, но после избрания королем Чехии с подачи католической партии Альбрехта V Австрийского (немецкого императора [[Альбрехт II (император)|Альбрехта II]]), отец и сын примкнули к оппозиции, желавшей избрания [[Казимир III|Казимира Польского]].&lt;/div&gt;</description>
<pubDate>Tue, 20 Oct 2009 00:00:44 GMT</pubDate>
</item>
</channel>
</rss>

View file

@ -34,6 +34,13 @@ sub postProcessMergedProperties {
return;
}
sub dump_assets {
my $session = shift;
# my $assets = WebGUI::Asset->getRoot($session)->getLineage(['descendants'], { returnObjects => 1, } );
my $assets = WebGUI::Asset->getRoot($session)->getLineage(['descendants']);
warn "all assets: " . Dumper $assets;
}
sub debug {
# if the last eval { } caught something, give full diagnostics on that and stop the tests.
@ -42,17 +49,19 @@ sub debug {
my $e = Exception::Class->caught() or return;
my $line = (caller)[2];
if( Scalar::Util::blessed( $e ) ) {
note( $line . ': ' . $e->error . "\n" . $e->full_message . "\n" . $e->trace->as_string );
} else {
note( $line . ': ' . "\n(non-object error:) $e" );
}
# XXX redundant with $SIG{__DIE__} handlers
#if( Scalar::Util::blessed( $e ) ) {
# note( $line . ': ' . $e->error . "\n" . $e->full_message . "\n" . $e->trace->as_string );
#} else {
# note( $line . ': ' . "\n(non-object error:) $e" );
#}
return; # XXX enable/disable aborting tests on failure
# return; # XXX enable/disable aborting tests on failure
# system '/home/scott/bin/perl', '/home/scott/plainblack/dumplineage.pl'; # XXX
warn "going to exit in ... a whole bunch... of seconds";
sleep 10;
# system 'sleep 6000'; # sleep 10; # this way, we can control-c it!
# sleep 10;
system 'sleep 6000'; # sleep 10; # this way, we can control-c it!
exit;
}
@ -453,7 +462,6 @@ sub t_10_addRevision : Tests {
my $newRevision = $asset->addRevision(
{ title => "Newly Revised Title" },
$asset->revisionDate+2,
# {skipNotification => 1, skipAutoCommitWorkflows => 1,} # XXX don't commit these until first inspecting the default implementation of getAutoCommitWorkflowId to see if explicitly thawrting it really is called for ... yeah, what's going on is getAutoCommitWorkflowId returns undef in the default case but certain classes override it XXX commenting this out is making the MapPoint tests fail again... but we aren't doing the skip thing
);
isa_ok( $newRevision, Scalar::Util::blessed( $asset ), "addRevision returns new revision of asset object" );
is( $newRevision->title, "Newly Revised Title", "properties set correctly" );
@ -480,6 +488,7 @@ sub t_11_getEditForm : Tests {
my ( $tag, $asset, @parents ) = $test->getAnchoredAsset();
# local $SIG{__DIE__} = sub { use Carp; Carp::confess "@_"; };
# local $SIG{__DIE__} = sub { use wth; wth::wth "@_"; }; # wth.pm is in a gist of scrottie's on github
my $f = $asset->getEditForm;
@ -558,8 +567,7 @@ sub t_20_www_editSave : Tests {
$tag->setWorking;
# $tag = WebGUI::VersionTag->create($session, {}); $tag->setWorking; # XXXXXX
sleep 2; # also XXXX
sleep 2; # XXXX Todo -- investigate whether this is actually fixing duplicate commit problems
my %mergedProperties = (
formProperties($asset),
@ -568,13 +576,12 @@ sleep 2; # also XXXX
$test->postProcessMergedProperties(\%mergedProperties);
warn "XXX mergedProperties: " . Dumper \%mergedProperties;
# local $SIG{__DIE__} = sub { use Carp; Carp::confess "@_"; };
# local $SIG{__DIE__} = sub { use Carp; Carp::confess "@_"; };
# local $SIG{__DIE__} = sub { use wth; wth::wth "@_"; }; # see note above about wth
$session->request->setup_body( \%mergedProperties );
ok(eval { $asset->www_editSave; }, 'www_editSave returns true'); # "DBD::mysql::db do failed: Duplicate entry ... for key 'PRIMARY' [for Statement "insert into assetData (assetId,revisionDate) values (?,?)"]" ... getting ready to insert into tables... assetId is: dinQXqxuUyrO0DmooZe4bg at /data/WebGUI/lib/WebGUI/AssetVersioning.pm line 123. XXX does that sleep 2 actually fix this or did I imagine that?
ok(eval { $asset->www_editSave; }, 'www_editSave returns true');
debug($@);
undef $@;
@ -608,6 +615,27 @@ warn "XXX mergedProperties: " . Dumper \%mergedProperties;
undef $@;
}
#sub asserts : Test(shutdown) {
# # XXX Todo these should be moved into the appropriate Test::Class subclasses and be made more explicit, if they are to be kept
# # XXX debugging garbage to track down corruption of the asset tree
# my $test = shift;
# my $session = $test->session;
# my $assets = WebGUI::Asset->getRoot($session)->getLineage(['descendants'], {returnObjects=>1});
# # local $SIG{__DIE__} = sub { use wth; wth::wth "@_"; }; # see note above about wth
# for my $asset (@$assets) {
# #if(ref($asset) eq 'WebGUI::Asset::Wobject::Layout') {
# # note "running view on Wobject::Layout of Id: " . $asset->getId;
# # # make sure any WG::A::Story objects created check out before testing gets any further along
# # $asset->view;
# #}
# if(ref($asset) eq 'WebGUI::Asset::Story') {
# note "running canEdit on Asset::Story of Id: " . $asset->getId;
# # make sure any WG::A::Story objects created check out before testing gets any further along
# $asset->canEdit;
# }
# }
#}
1;
__END__

View file

@ -21,7 +21,7 @@ sub list_of_tables {
}
sub parent_list {
return ['WebGUI::Asset::Wobject::StoryArchive'];
return ['WebGUI::Asset::Wobject::StoryArchive', 'WebGUI::Asset::Wobject::Folder'];
}
sub t_11_getEditForm : Tests {

View file

@ -5,6 +5,18 @@
html,body { margin: 0; padding: 0; height: 100% }
input.disabled {
font-style: italic;
color: #555;
}
.with_avatar {
background-position: 0 0;
background-repeat: no-repeat;
padding-left: 50px;
min-height: 50px;
}
#wrapper {
position: relative;
margin-left: 165px; /* move out of the adminbar's way */
@ -103,11 +115,12 @@ html,body { margin: 0; padding: 0; height: 100% }
-webkit-border-radius: 3px;
}
#locationBar #locationUrl {
#locationBar #locationInput {
width: 99%;
height: 90%;
border: none;
font: 14px Verdana, sans-serif;
font-size: 14px;
font-family: Verdana, sans-serif;
}
#locationBar #locationTitle {
@ -153,6 +166,47 @@ html,body { margin: 0; padding: 0; height: 100% }
#searchFilters {
clear: both;
list-style-type: none;
margin: 0;
padding: 0;
}
#searchFilters .deleteIcon {
display: block;
}
#searchFilters li { height: 28px; } /* autocomplete is position: absolute, so pretend some height */
#searchFilters span.name {
display: block;
float: left;
width: 9%;
text-align: right;
padding-right: 1%;
line-height: 24px;
}
#searchFilterAdd {
clear: both;
}
.filter_title input, .filter_ownerUserId div.autocomplete {
display: block;
float: left;
width: 89%;
}
#searchFilters .yui-ac-bd li {
height: 50px;
}
.autocomplete_value {
font-size: larger;
font-weight: bold;
}
.autocomplete_subtext {
font-size: smaller;
}
#wrapper .yui-content {

View file

@ -746,6 +746,7 @@ WebGUI.Admin.LocationBar
this.currentAssetDef = null; // Object containing assetId, title, url, icon
this.backAssetDefs = [ ]; // Asset defs to go back to
this.forwardAssetDefs = [ ]; // Asset defs to go forward to
this.filters = [ ]; // search filters
// Private members
var self = this;
@ -787,21 +788,22 @@ WebGUI.Admin.LocationBar
menu : 'searchFilterSelect'
} );
var self = this;
YAHOO.util.Event.onDOMReady( 'searchFilterSelect', function () {
YAHOO.util.Event.on( window, "load", function () {
self.filterSelect.getMenu().subscribe( "click", self.addFilter, self, true );
} );
YAHOO.util.Event.on( 'searchKeywords', 'keyup', this.updateLocationBarQuery, this, true );
YAHOO.util.Event.on( 'searchKeywords', 'focus', this.focusKeywords, this, true );
YAHOO.util.Event.on( 'searchKeywords', 'blur', this.blurKeywords, this, true );
// Take control of the location input
this.klInput = new YAHOO.util.KeyListener( "locationUrl", { keys: 13 }, {
this.klInput = new YAHOO.util.KeyListener( "locationInput", { keys: 13 }, {
fn: this.doInputSearch,
scope: this,
correctScope: true
} );
YAHOO.util.Event.addListener( "locationUrl", "focus", this.inputFocus, this, true );
YAHOO.util.Event.addListener( "locationUrl", "blur", this.inputBlur, this, true );
YAHOO.util.Event.addListener( "locationInput", "focus", this.inputFocus, this, true );
YAHOO.util.Event.addListener( "locationInput", "blur", this.inputBlur, this, true );
};
@ -855,7 +857,7 @@ WebGUI.Admin.LocationBar.prototype.clickForwardMenuItem
*/
WebGUI.Admin.LocationBar.prototype.doInputSearch
= function ( ) {
var input = document.getElementById("locationUrl").value;
var input = document.getElementById("locationInput").value;
// If input starts with a / it's a URL
if ( input.match(/^\//) ) {
// If it doesn't have a ?, just go to the asset
@ -984,7 +986,7 @@ WebGUI.Admin.LocationBar.prototype.setTitle
*/
WebGUI.Admin.LocationBar.prototype.setUrl
= function ( url ) {
var input = document.getElementById( "locationUrl" );
var input = document.getElementById( "locationInput" );
input.value = url;
};
@ -1055,13 +1057,23 @@ WebGUI.Admin.LocationBar.prototype.goHome
*/
WebGUI.Admin.LocationBar.prototype.toggleSearchDialog
= function ( ) {
var input = document.getElementById( 'locationInput' );
if ( this.searchDialog == true ) {
this.hideSearchDialog();
this.searchDialog = false;
input.value = this.savedLocationInput;
this.savedLocationInput = "";
input.readonly = false;
YAHOO.util.Dom.removeClass( input, 'disabled' );
}
else {
this.showSearchDialog();
this.searchDialog = true;
this.savedLocationInput = input.value;
input.value = "";
this.updateLocationBarQuery();
input.readonly = true;
YAHOO.util.Dom.addClass( input, 'disabled' );
}
};
@ -1113,6 +1125,130 @@ WebGUI.Admin.LocationBar.prototype.hideSearchDialog
anim.animate();
};
/**
* addFilter ( eventType, args )
* Add the selected filter into the filter list
*/
WebGUI.Admin.LocationBar.prototype.addFilter
= function ( eventType, args ) {
var self = this;
var ev = args[0];
var menuitem = args[1];
var keys = {}; // Listen for all keys
// Keep track of our filters
var filter = { };
this.filters.push( filter );
var li = document.createElement( 'li' );
filter.li = li;
var type = menuitem.value;
filter.type = type;
li.className = "filter_" + filter.type;
var ul = document.getElementById( 'searchFilters' );
ul.appendChild( li );
var delIcon = document.createElement('img');
delIcon.className = "clickable";
YAHOO.util.Event.on( delIcon, "click", function(){
self.removeFilter( filter.li );
} );
var name = menuitem.cfg.getProperty('text');
var nameElem = document.createElement('span');
nameElem.className = "name";
nameElem.appendChild( document.createTextNode( name ) );
li.appendChild( nameElem );
if ( filter.type == "title" ) {
var inputElem = document.createElement('input');
filter.inputElem = inputElem;
inputElem.type = "text";
li.appendChild( inputElem );
YAHOO.util.Event.on( inputElem, 'keyup', this.updateLocationBarQuery, this, true );
inputElem.focus();
}
else if ( filter.type == "ownerUserId" ) {
var container = document.createElement( 'div' );
container.className = "autocomplete";
li.appendChild( container );
var inputElem = document.createElement('input');
filter.inputElem = inputElem;
inputElem.type = "text";
container.appendChild( inputElem );
filter.dataSource = new YAHOO.util.XHRDataSource( '?op=admin;method=findUser;' );
filter.dataSource.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
filter.dataSource.responseSchema = {
resultsList : "results",
fields : [ 'username', 'name', 'userId', 'avatar', 'email' ]
};
// Auto-complete container
var acDiv = document.createElement('div');
filter.acDiv = acDiv;
container.appendChild( acDiv );
filter.autocomplete = new YAHOO.widget.AutoComplete( inputElem, acDiv, filter.dataSource );
filter.autocomplete.queryQuestionMark = false;
filter.autocomplete.animVert = true;
filter.autocomplete.animSpeed = 0.1;
filter.autocomplete.minQueryLength = 1;
filter.autocomplete.queryDelay = 0.2;
filter.autocomplete.typeAhead = true;
filter.autocomplete.resultTypeList = false;
filter.autocomplete.applyLocalFilter = true;
filter.autocomplete.formatResult = function ( result, query, match ) {
var subtext = ( result.name ? result.name : "" )
+ ( result.email ? " &lt;" + result.email + "&gt;" : "" )
;
return '<div style="float: left; width: 50px; height: 50px; background: url(' + result.avatar + ') no-repeat 50% 50%;"></div>'
+ '<div class="autocomplete_value">' + result.username + "</div>"
+ '<div class="autocomplete_subtext">' + subtext + '</div>';
};
inputElem.focus();
}
};
/**
* updateLocationBarQuery( )
* Update the location bar text with the filters in the search box
*/
WebGUI.Admin.LocationBar.prototype.updateLocationBarQuery
= function () {
var query = "";
// First add filters
var filterVals = [];
for ( var i = 0; i < this.filters.length; i++ ) {
var filter = this.filters[i];
if ( filter.type == "title" ) {
var value = filter.inputElem.value;
if ( !value ) continue;
var quote = "";
if ( value.match(/\s/) ) {
quote = '"';
}
filterVals.push( "title:" + quote + filter.inputElem.value + quote );
}
}
query += filterVals.join(" ");
// Then add keywords
if ( query != "" ) {
query += " "; // Add a space between filters and keywords
}
query += document.getElementById( 'searchKeywords' ).value;
// Set the new value
document.getElementById( 'locationInput' ).value = query;
};
/****************************************************************************
*
* WebGUI.Admin.Tree

View file

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 451 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

View file

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 470 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

View file

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 332 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 B

View file

Before

Width:  |  Height:  |  Size: 355 B

After

Width:  |  Height:  |  Size: 355 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 465 B

After

Width:  |  Height:  |  Size: 465 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Some files were not shown because too many files have changed in this diff Show more