From 7bdf22e412809b6314d36ef8a33bb9847b0c5037 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Wed, 28 May 2008 21:43:22 +0000 Subject: [PATCH] removed SQL Form from the distro --- docs/changelog/7.x.x.txt | 3 + docs/gotcha.txt | 6 + docs/upgrades/upgrade_7.5.10-7.5.11.pl | 26 + etc/WebGUI.conf.original | 1 - lib/WebGUI/Asset/Wobject/SQLForm.pm | 4367 ----------------- lib/WebGUI/Help/Asset_SQLForm.pm | 234 - lib/WebGUI/i18n/English/Asset_SQLForm.pm | 1507 ------ www/extras/assets/small/sqlform.gif | Bin 158 -> 0 bytes www/extras/assets/sqlform.gif | Bin 1426 -> 0 bytes .../wobject/SQLForm/SQLFormEditField.js | 94 - .../wobject/SQLForm/SQLFormJoinSelector.js | 375 -- www/extras/wobject/SQLForm/SQLFormSearch.js | 69 - .../wobject/SQLForm/SQLFormViewButton.gif | Bin 1175 -> 0 bytes 13 files changed, 35 insertions(+), 6647 deletions(-) delete mode 100644 lib/WebGUI/Asset/Wobject/SQLForm.pm delete mode 100644 lib/WebGUI/Help/Asset_SQLForm.pm delete mode 100644 lib/WebGUI/i18n/English/Asset_SQLForm.pm delete mode 100644 www/extras/assets/small/sqlform.gif delete mode 100644 www/extras/assets/sqlform.gif delete mode 100644 www/extras/wobject/SQLForm/SQLFormEditField.js delete mode 100644 www/extras/wobject/SQLForm/SQLFormJoinSelector.js delete mode 100644 www/extras/wobject/SQLForm/SQLFormSearch.js delete mode 100644 www/extras/wobject/SQLForm/SQLFormViewButton.gif diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 7bf4011db..425c7acfb 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -1,5 +1,8 @@ 7.5.11 - rfe: Not being limited to single-worded Tags + - SQL Form no longer ships with WebGUI. Use Thingy instead. However, out of + respect for those using it, we only uninstall it if you have no sites using + it. - AssetProxy macro can now use asset id as a parameter like so: ^AssetProxy(abcdefghijklmnopqrstuv,assetId); - Exposed keywords API to all assets through edit screen. Now keywords are diff --git a/docs/gotcha.txt b/docs/gotcha.txt index 1415670d6..59feefde2 100644 --- a/docs/gotcha.txt +++ b/docs/gotcha.txt @@ -16,6 +16,12 @@ save you many hours of grief. Image::ExifTool List::MoreUtils + * SQL Form is no longer part of the official distribution of WebGUI, + but is still being actively maintained by third-parties. However, if you + don't want to use SQL Form any longer, make sure you delete all SQL Forms + from your site prior to the upgrade *and* purge them from your trash. Then + the upgrade will automatically uninstall the SQL Form from your site. + * WebGUI versions since 7.3.0 (when the new Calendar was added) have allowed users to post Events to Calendars, but the owner of the Event has been saved as Admin (user ID 3). Also, anyone who diff --git a/docs/upgrades/upgrade_7.5.10-7.5.11.pl b/docs/upgrades/upgrade_7.5.10-7.5.11.pl index f3cbba9cc..0c42a53cc 100644 --- a/docs/upgrades/upgrade_7.5.10-7.5.11.pl +++ b/docs/upgrades/upgrade_7.5.10-7.5.11.pl @@ -64,10 +64,36 @@ migrateSubscriptions( $session ); updateUsersOfCommerceMacros($session); addDBLinkAccessToSQLMacro($session); addAssetManager( $session ); +removeSqlForm($session); migratePaymentPlugins( $session ); finish($session); # this line required +#---------------------------------------------------------------------------- +sub removeSqlForm { + my $session = shift; + print "\tOptionally removing SQL Form...\n" unless $quiet; + my $db = $session->db; + unless ($db->quickScalar("select count(*) from asset where className='WebGUI::Asset::Wobject::SQLForm'")) { + print "\t\tNot using it, so we're uninstalling it.\n" unless $quiet; + $session->config->deleteFromArray("assets","WebGUI::Asset::Wobject::SQLForm"); + my @ids = $db->buildArray("select distinct assetId from template where namespace like 'SQLForm%'"); + push @ids, qw(GnrXtoFFeXia3vDQuSHojw k8vxD4fuKKf5cGwNTw0sLw); + foreach my $id (@ids) { + my $asset = WebGUI::Asset->newByDynamicClass($session, $id); + if (defined $asset) { + $asset->purge; + } + } + foreach my $table (qw(SQLForm_fieldDefinitions SQLForm SQLForm_fieldTypes SQLForm_regexes)) { + $db->write("drop table $table"); + } + } + else { + print "\t\tThis site uses SQL Form, so we won't uninstall it.\n" unless $quiet; + } +} + #---------------------------------------------------------------------------- sub changeRealtimeWorkflows { my $session = shift; diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index 90e0492ad..dc8d818e1 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -237,7 +237,6 @@ "WebGUI::Asset::File::ZipArchive", "WebGUI::Asset::Wobject::WSClient", "WebGUI::Asset::Wobject::Shelf", - "WebGUI::Asset::Wobject::SQLForm", "WebGUI::Asset::Wobject::Thingy" ], diff --git a/lib/WebGUI/Asset/Wobject/SQLForm.pm b/lib/WebGUI/Asset/Wobject/SQLForm.pm deleted file mode 100644 index 3524ed2ef..000000000 --- a/lib/WebGUI/Asset/Wobject/SQLForm.pm +++ /dev/null @@ -1,4367 +0,0 @@ -package WebGUI::Asset::Wobject::SQLForm; - -=head1 LEGAL - - ------------------------------------------------------------------- - /SQLForm is Copyright 2006 Procolix - ------------------------------------------------------------------- - Please read the legal notices (legal.txt) and the license - (license.txt) that came with this distribution before using - this software. - ------------------------------------------------------------------- - http://www.procolix.nl info@procolix.com - ------------------------------------------------------------------- - -=cut - -use strict; -use WebGUI::Asset; -use WebGUI::HTMLForm; -use WebGUI::Form; -use WebGUI::Asset::Wobject; -use WebGUI::Utility; -use WebGUI::DatabaseLink; -use WebGUI::International; -use WebGUI::User; -use Storable; -use Tie::IxHash; - -our @ISA = qw(WebGUI::Asset::Wobject); - -=head1 NAME - -Package WebGUI::Asset::Wobject::SQLForm - -=cut - -#------------------------------------------------------------------- -# This hash contains the allowed database field types. Keys indicate the MySQL name of the field type and -# the values are the the way they are showed in the form. -my ($allowedDbFieldTypes, $allowedFormFieldTypes); -tie %{$allowedDbFieldTypes}, 'Tie::IxHash'; -tie %{$allowedFormFieldTypes}, 'Tie::IxHash'; - - -=head1 Usage of reserved keywords - -It is not allowed to use columnnames that are in the list of reserved keywords. These -keywords are in the @reservedKeywords variable. - -The list with reserved keywords is MySQL specific and is generously copy-pasted from: - http://dev.mysql.com/doc/mysql/en/reserved-words.html - -=cut - -my @reservedKeywords = qw( - ACTION ADD AFTER - AGAINST AGGREGATE ALGORITHM - ALL ALTER ANALYZE - AND ANY AS - ASC ASCII ASENSITIVE - AUTO_INCREMENT AVG AVG_ROW_LENGTH - BACKUP BDB BEFORE - BEGIN BERKELEYDB BETWEEN - BIGINT BINARY BINLOG - BIT BLOB BOOL - BOOLEAN BOTH BTREE - BY BYTE CACHE - CALL CASCADE CASCADED - CASE CHAIN CHANGE - CHANGED CHAR CHARACTER - CHARSET CHECK CHECKSUM - CIPHER CLIENT CLOSE - COLLATE COLLATION COLUMN - COLUMNS COMMENT COMMIT - COMMITTED COMPACT COMPRESSED - CONCURRENT CONDITION CONNECTION - CONSISTENT CONSTRAINT CONTAINS - CONTINUE CONVERT CREATE - CROSS CUBE CURRENT_DATE - CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER - CURSOR DATA DATABASE - DATABASES DATE DATETIME - DAY DAY_HOUR DAY_MICROSECOND - DAY_MINUTE DAY_SECOND DEALLOCATE - DEC DECIMAL DECLARE - DEFAULT DEFINER DELAYED - DELAY_KEY_WRITE DELETE DESC - DESCRIBE DES_KEY_FILE DETERMINISTIC - DIRECTORY DISABLE DISCARD - DISTINCT DISTINCTROW DIV - DO DOUBLE DROP - DUAL DUMPFILE DUPLICATE - DYNAMIC EACH ELSE - ELSEIF ENABLE ENCLOSED - END ENGINE ENGINES - ENUM ERRORS ESCAPE - ESCAPED EVENTS EXECUTE - EXISTS EXIT EXPANSION - EXPLAIN EXTENDED FALSE - FAST FETCH FIELDS - FILE FIRST FIXED - FLOAT FLOAT4 FLOAT8 - FLUSH FOR FORCE - FOREIGN FOUND FRAC_SECOND - FROM FULL FULLTEXT - FUNCTION GEOMETRY GEOMETRYCOLLECTION - GET_FORMAT GLOBAL GOTO - GRANT GRANTS GROUP - HANDLER HASH HAVING - HELP HIGH_PRIORITY HOSTS - HOUR HOUR_MICROSECOND HOUR_MINUTE - HOUR_SECOND IDENTIFIED IF - IGNORE IMPORT IN - INDEX INDEXES INFILE - INNER INNOBASE INNODB - INOUT INSENSITIVE INSERT - INSERT_METHOD INT INT1 - INT2 INT3 INT4 - INT8 INTEGER INTERVAL - INTO INVOKER IO_THREAD - IS ISOLATION ISSUER - ITERATE JOIN KEY - KEYS KILL LABEL - LANGUAGE LAST LEADING - LEAVE LEAVES LEFT - LEVEL LIKE LIMIT - LINES LINESTRING LOAD - LOCAL LOCALTIME LOCALTIMESTAMP - LOCK LOCKS LOGS - LONG LONGBLOB LONGTEXT - LOOP LOW_PRIORITY MASTER - MASTER_CONNECT_RETRY MASTER_HOST MASTER_LOG_FILE - MASTER_LOG_POS MASTER_PASSWORD MASTER_PORT - MASTER_SERVER_ID MASTER_SSL MASTER_SSL_CA - MASTER_SSL_CAPATH MASTER_SSL_CERT MASTER_SSL_CIPHER - MASTER_SSL_KEY MASTER_USER MATCH - MAX_CONNECTIONS_PER_HOUR MAX_QUERIES_PER_HOUR MAX_ROWS - MAX_UPDATES_PER_HOUR MAX_USER_CONNECTIONS MEDIUM - MEDIUMBLOB MEDIUMINT MEDIUMTEXT - MERGE MICROSECOND MIDDLEINT - MIGRATE MINUTE MINUTE_MICROSECOND - MINUTE_SECOND MIN_ROWS MOD - MODE MODIFIES MODIFY - MONTH MULTILINESTRING MULTIPOINT - MULTIPOLYGON MUTEX NAME - NAMES NATIONAL NATURAL - NCHAR NDB NDBCLUSTER - NEW NEXT NO - NONE NOT NO_WRITE_TO_BINLOG - NULL NUMERIC NVARCHAR - OFFSET OLD_PASSWORD ON - ONE ONE_SHOT OPEN - OPTIMIZE OPTION OPTIONALLY - OR ORDER OUT - OUTER OUTFILE PACK_KEYS - PARTIAL PASSWORD PHASE - POINT POLYGON PRECISION - PREPARE PREV PRIMARY - PRIVILEGES PROCEDURE PROCESSLIST - PURGE QUARTER QUERY - QUICK RAID0 RAID_CHUNKS - RAID_CHUNKSIZE RAID_TYPE READ - READS REAL RECOVER - REDUNDANT REFERENCES REGEXP - RELAY_LOG_FILE RELAY_LOG_POS RELAY_THREAD - RELEASE RELOAD RENAME - REPAIR REPEAT REPEATABLE - REPLACE REPLICATION REQUIRE - RESET RESTORE RESTRICT - RESUME RETURN RETURNS - REVOKE RIGHT RLIKE - ROLLBACK ROLLUP ROUTINE - ROW ROWS ROW_FORMAT - RTREE SAVEPOINT SCHEMA - SCHEMAS SECOND SECOND_MICROSECOND - SECURITY SELECT SENSITIVE - SEPARATOR SERIAL SERIALIZABLE - SESSION SET SHARE - SHOW SHUTDOWN SIGNED - SIMPLE SLAVE SMALLINT - SNAPSHOT SOME SONAME - SOUNDS SPATIAL SPECIFIC - SQL SQLEXCEPTION SQLSTATE - SQLWARNING SQL_BIG_RESULT SQL_BUFFER_RESULT - SQL_CACHE SQL_CALC_FOUND_ROWS SQL_NO_CACHE - SQL_SMALL_RESULT SQL_THREAD SQL_TSI_DAY - SQL_TSI_FRAC_SECOND SQL_TSI_HOUR SQL_TSI_MINUTE - SQL_TSI_MONTH SQL_TSI_QUARTER SQL_TSI_SECOND - SQL_TSI_WEEK SQL_TSI_YEAR SSL - START STARTING STATUS - STOP STORAGE STRAIGHT_JOIN - STRING STRIPED SUBJECT - SUPER SUSPEND TABLE - TABLES TABLESPACE TEMPORARY - TEMPTABLE TERMINATED TEXT - THEN TIME TIMESTAMP - TIMESTAMPADD TIMESTAMPDIFF TINYBLOB - TINYINT TINYTEXT TO - TRAILING TRANSACTION TRIGGER - TRIGGERS TRUE TRUNCATE - TYPE TYPES UNCOMMITTED - UNDEFINED UNDO UNICODE - UNION UNIQUE UNKNOWN - UNLOCK UNSIGNED UNTIL - UPDATE USAGE USE - USER USER_RESOURCES USE_FRM - USING UTC_DATE UTC_TIME - UTC_TIMESTAMP VALUE VALUES - VARBINARY VARCHAR VARCHARACTER - VARIABLES VARYING VIEW - WARNINGS WEEK WHEN - WHERE WHILE WITH - WORK WRITE X509 - XA XOR YEAR - YEAR_MONTH ZEROFILL -); - -%{$allowedDbFieldTypes} = ( - # Integer column types - tinyint => { - name => 'tinyint', - maxLength => 255, - maxValue => 127, - minValue => -128, - maxValueUnsigned => 255, - hasSign => 1, - canAutoIncrement => 1, - defaultFormElement => 'integer', - defaultRegEx => 'defaultSigned', - }, - smallint => { - name => 'smallint', - maxLength => 255, - maxValue => 32_767, - minValue => -32_768, - maxValueUnsigned => 65_535, - hasSign => 1, - canAutoIncrement => 1, - defaultFormElement => 'integer', - defaultRegEx => 'defaultSigned', - }, - mediumint => { - name => 'mediumint', - maxLength => 255, - maxValue => 8_388_607, - minValue => -8_388_608, - maxValueUnsigned => 16_777_215, - hasSign => 1, - canAutoIncrement => 1, - defaultFormElement => 'integer', - defaultRegEx => 'defaultSigned', - }, - 'int' => { - name => 'int', - maxLength => 255, - maxValue => 2_147_483_647, - minValue => -2_147_483_648, - maxValueUnsigned => 4_294_967_295, - hasSign => 1, - canAutoIncrement => 1, - defaultFormElement => 'integer', - defaultRegEx => 'defaultSigned', - }, - bigint => { - name => 'bigint', - maxLength => 255, - maxValue => 9_223_372_036_854_775_807, - minValue => -9_223_372_036_854_775_808, - maxValueUnsigned => 18_446_744_073_709_551_615, - hasSign => 1, - canAutoIncrement => 1, - defaultFormElement => 'integer', - defaultRegEx => 'defaultSigned', - }, - - # String column types - char => { - name => 'char', - supportsFulltext => 1, - maxLength => 255, - defaultFormElement => 'text', - defaultRegEx => 'defaultText', - }, - varchar => { - name => 'varchar', - supportsFulltext => 1, - maxLength => 255, - defaultFormElement => 'text', - defaultRegEx => 'defaultText', - }, - tinyblob => { - name => 'tinyblob', - supportsFulltext => 1, - maxLength => 255, - defaultFormElement => 'textarea', - defaultRegEx => 'defaultText', - }, - blob => { - name => 'blob', - supportsFulltext => 1, - maxLength => 65_535, - defaultFormElement => 'textarea', - defaultRegEx => 'defaultText', - }, - mediumblob => { - name => 'mediumblob', - supportsFulltext => 1, - maxLength => 16_777_215, - defaultFormElement => 'file', - defaultRegEx => '', - }, - longblob => { - name => 'longblob', - supportsFulltext => 1, - maxLength => 4_294_967_295, - defaultFormElement => 'file', - defaultRegEx => '', - }, - tinytext => { - name => 'tinytext', - supportsFulltext => 1, - maxLength => 255, - defaultFormElement => 'textarea', - defaultRegEx => 'defaultText', - }, - text => { - name => 'text', - supportsFulltext => 1, - maxLength => 65_535, - defaultFormElement => 'textarea', - defaultRegEx => 'defaultText', - }, - mediumtext => { - name => 'mediumtext', - supportsFulltext => 1, - maxLength => 16_777_215, - defaultFormElement => 'file', - defaultRegEx => '', - }, - longtext => { - name => 'longtext', - supportsFulltext => 1, - maxLength => 4_294_967_295, - defaultFormElement => 'file', - defaultRegEx => '', - }, - - # Temporal column types - datetime => { - name => 'datetime', - defaultFormElement => 'dateTime', - }, - timestamp => { - name => 'timestamp', - readOnly => 1, - }, - date => { - name => 'date', - defaultFormElement => 'date', - }, - 'time' => { - name => 'time', - defaultFormElement => 'timeField', - }, - set => { - name => 'set', - supportsFulltext => 0, - maxLength => 65_535, - defaultFormElement => 'selectList', - multipleAllowed => 1, - }, -); - -=head1 Form element definitions - -The $allowedFormFieldTypes hashref contains the allowed WebGUI form elements. Method names are indicated -by the keys of the hash while the values are the screen labels in the form. - -If you want to add addional form elements, you must add them to this hash. The elements you define here -should be implemented in WebGUI::Form::myELement. - -=cut - -%{$allowedFormFieldTypes} = ( - text => { - name => 'Text', - widthParam => 'size', - maxLength => 255, - searchElement => 'text', - type => 'text', - }, - textarea => { - name => 'Text area', - widthParam => 'columns', - heightParam => 'rows', - searchElement => 'text', - type => 'text', - }, - HTMLArea => { - name => 'HTML area', - widthParam => 'columns', - heightParam => 'rows', - searchElement => 'text', - type => 'text', - }, - integer => { - name => 'Integer', - widthParam => 'size', - maxLength => 255, - searchElement => 'integer', - type => 'number', - }, - float => { - name => 'Float', - widthParam => 'size', - maxLength => 255, - searchElement => 'float', - type => 'number', - }, - selectList => { - name => 'Select list', - heightParam => 'size', - hasOptions => 1, - canHaveMultipleValues => 1, - searchElement => 'selectList', - type => 'list', - }, - radioList => { - name => 'Radio list', - hasOptions => 1, - searchElement => 'radioList', -# type => 'list', - }, - checkList => { - name => 'Check list', - hasOptions => 1, - canHaveMultipleValues => 1, - searchElement => 'checkList', - type => 'list', - }, - date => { - name => 'Date', - searchElement => 'date', - type => 'temporal', - }, - timeField => { - name => 'Time', - searchElement => 'timeField', - type => 'temporal', - }, - dateTime => { - name => 'Date/Time combo', - searchElement => 'dateTime', - type => 'temporal', - }, - email => { - name => 'Email address', - searchElement => 'text', - type => 'text', - }, - url => { - name => 'URL', - searchElement => 'text', - type => 'text', - }, - file => { - name => 'File', - }, -); - -# The two hasrefs below are used by the search system -my $types = { - text => {'' => 'Don\'t care', 1 => '=', 100 => 'like', 101 => 'regexp'}, - number => {'' => 'Don\'t care', 1 => '=', 2 => '<', 3 => '>', 4 => '<=', 5 => '>=', 6 => '!=', 10 => 'is between'}, - temporal => {'' => 'Don\'t care', 1 => '=', 2 => '<', 3 => '>', 4 => '<=', 5 => '>=', 6 => '!=', 10 => 'is between'}, - list => {'' => 'Don\'t care', 200 => 'match any', 201 => 'match all', 100 => 'like', 101 => 'regexp'}, -}; - -my $typeFunctions = { - text => 'switchTextField', - number => 'switchNumberField', - temporal => 'switchTemporalField', - list => 'switchListField', -}; - -=head1 METHODS - -These methods are available from this class: - -=cut - -#------------------------------------------------------------------- - -=head2 _canAlterTable ( ) - -Returns a boolean indicating whether the user is allowed to change (alter) the table structure. Ie. manage field etc. - -=cut - -sub _canAlterTable { - my $self = shift; - - return ($self->canEdit || $self->session->user->isInGroup($self->get('alterGroupId'))); -} - -#------------------------------------------------------------------- - -=head2 _canEditRecord ( ) - -Returns a boolean indicating whether the user is allowed to edit, delete and restore records. - -=cut - -sub _canEditRecord { - my $self = shift; - - return ($self->canEdit || $self->session->user->isInGroup($self->get('submitGroupId'))); -} - -#------------------------------------------------------------------- - -=head2 _canPurge ( ) - -Returns a boolean indictating whether the user is allowed to purge deleted records. - -=cut - -sub _canPurge { - my $self = shift; - - return $self->_canAlterTable; -} - -#------------------------------------------------------------------- - -=head2 _constructColumnType ( fieldProperties ) - -Will construct a MySQL column definition string from the field properties passed as argument. - -=head3 fieldProperties - -A hashref containing the properties of the field for which this column definition is made. Properties -taken into account are: - - * dbFieldType, - * maxFieldLength, - * formPopulationKeys, - * signed - -=cut - -sub _constructColumnType { - my $self = shift; - my $processed = shift; - - # Construct the type specifier - my $type = $processed->{dbFieldType}; - if ($type eq 'varchar' && $allowedDbFieldTypes->{$type}->{maxLength}) { - $type .= '('.$processed->{maxFieldLength}.')' if ($processed->{maxFieldLength}); - } - - if ($type eq 'set') { - my $formPopulationKeys = $self->session->form->process("formPopulationKeys"); - $formPopulationKeys =~ s/\r?\n/\',\'/g; - $type .= '(\''.$formPopulationKeys.'\')'; - } - - if ($allowedDbFieldTypes->{$processed->{dbFieldType}}->{hasSign}) { - if ($processed->{signed}) { - # Explicitly add the signed flag, so we won't have to worry if mysql changes its defaults. - $type .= ' signed'; - } else { - $type .= ' unsigned'; - } - } - - return $type; -} - -#------------------------------------------------------------------- - -=head2 _createFieldType ( dbFieldType, formFieldType ) - -Inserts a new field type into the SQLForm_fieldTypes table. - -=head3 dbFieldType - -The column type connected to this field type. - -=head3 formFieldType - -The form element to be used for this field type. - -=cut - -sub _createFieldType { - my $self = shift; - my $dbFieldType = shift; - my $formFieldType = shift; - - my $fieldTypeId = $self->session->id->generate; - - $self->session->db->write('insert into SQLForm_fieldTypes (fieldTypeId, dbFieldType, formFieldType) '. - ' values ('.$self->session->db->quote($fieldTypeId).', '.$self->session->db->quote($dbFieldType).', '.$self->session->db->quote($formFieldType).')'); - - return $fieldTypeId; -} - -#------------------------------------------------------------------- - -=head2 _databaseLinkHasPrivileges ( wantedPrivileges, databaseLink ) - -Returns true if the database link has at least the given privileges. This method is -deprecated. Please use the checkPrivileges method in WebGUI::DatabaseLink instead. - -=head3 wantedPrivileges - -Arrayref containing the desired privileges (eg. ['SELECT','ALTER']) - -=head3 databaseName - -The name of the database you want to check the privileges of. - -=head3 databaseLink - -An instanciated databaselink object. Defaults to the databaselink of the sqlform table. - -=cut - -sub _databaseLinkHasPrivileges { - my (@privileges, @grants, $databaseName, @dsnEntries); - my $self = shift; - my $wantedPrivileges = shift; - my $dbLink = shift || $self->_getDbLink; - - # DSN can have a potpourri of forms - # DBI:mysql:dbName:dbHost:dbPort (databaseHost and dbPort are optional) - # DBI:mysql:database=dbName;host=dbHost (databaseHost is optional) - # But also this: - # DBI:mysql:db=dbName;dbHost:dbPort etc, etc. - # The following code tries to extract the databasename - @dsnEntries = split(/[:;]/, $dbLink->get->{DSN}); - - if ($dsnEntries[2] !~ /=/) { - $databaseName = $dsnEntries[2]; - } else { - foreach (@dsnEntries) { - if ($_ =~ m/^(database|db|dbname)=(.+)$/) { - $databaseName = $2; - last; - } - } - } - - # Get all the grants for the db link user and fetch the one referring to the - # database of the db link. - @grants = $dbLink->db->buildArray('show grants for current_user'); - - foreach (@grants) { - ##Checks for grants on all databases '*' or grants on a specific database - if (m/GRANT ([\w\s\d,]*?) ON (?:\*|.$databaseName.)\./) { - push(@privileges, (split(/, /,$1))); - } - } - - # Check if we found any privileges at all - if (!@privileges) { - $self->session->errorHandler->warn( - "SQLForm: Could not find SQL privileges or no privileges on database '$databaseName' for user '".$dbLink->get->{username}."' with database link ID '".$dbLink->getId."' using DSN '".$dbLink->get->{dsn}."'" - ); - return 0; - } - - # Check if all required privs are present. - return 1 if (isIn('ALL PRIVILEGES', @privileges)); - - foreach (@$wantedPrivileges) { - return 0 unless (isIn(uc($_), @privileges)); - } - - return 1; -} - -#------------------------------------------------------------------- - -=head2 _getDbLink ( ) - -Returns a WebGUI::DatabaseLink object for the database the SQLForm table is in. - -=cut - -sub _getDbLink { - my $self = shift; - - return WebGUI::DatabaseLink->new($self->session, $self->getValue('databaseLinkId')); -} - -#------------------------------------------------------------------- - -=head2 _getFieldProperties ( fieldId ) - -Returns a hashref containing the properties of the field indicated by fieldId. - -=head3 fieldId - -The id of the field of which the properties should be returned. - -=cut - -sub _getFieldProperties { - my ($dbLink, $fieldId, %definition, $properties, @tables, @where, $query, $options, @keys, @values, $numberOfJoins); - my $self = shift; - $fieldId = shift; - - return $self->{_fieldPropertiesCache}->{$fieldId} if exists ($self->{_fieldPropertiesCache}->{$fieldId}); - - $dbLink = $self->_getDbLink; - %definition = $self->session->db->buildHash("select property, value from SQLForm_fieldDefinitions where fieldId = ".$self->session->db->quote($fieldId)); - - $properties = { %{$allowedFormFieldTypes->{$definition{formFieldType}}}, %{$allowedDbFieldTypes->{$definition{dbFieldType}}} }; - - #### This should be preprocessed in editFieldSave to increase performance #### - # Calculate the number of tables in the join - foreach (keys(%definition)) { - if (m/^table(\d+)$/) { - $numberOfJoins = $1 if ($1 > $numberOfJoins); - } - } - $definition{numberOfJoins} = $numberOfJoins; - - tie %$options, "Tie::IxHash"; - if (exists $definition{formPopulationKeys}) { - @keys = split(/[\r\n]+/, $definition{formPopulationKeys}); - @values = split(/[\r\n]+/, $definition{formPopulationValues}); - - ##Assign all values to keys in an ordered, 1:1 way - @{ $options }{@keys} = @values; - } - - - if ($definition{selectField1} && $definition{selectField2}) { -my $sth = $dbLink->db->unconditionalRead($definition{sqlQuery}." order by ".$definition{selectField2}); - while (my @row = $sth->array) { - $options->{$row[0]} = $row[1]; - } -# $options = $dbLink->db->buildHashRef($definition{sqlQuery}." order by ".$definition{selectField2}); - } - - if (exists $definition{sqlQueryAllOptions}) { - $properties->{allOptions} = $dbLink->db->buildHashRef($definition{sqlQueryAllOptions}); - } else { - $properties->{allOptions} = $options; - } - - $properties->{options} = $options; - $properties->{processedDefaultValue} = $definition{defaultValue}; - WebGUI::Macro::process($self->session,\$properties->{processedDefaultValue}); - $properties->{fieldId} = $fieldId; - - $self->{_fieldPropertiesCache}->{$fieldId} = {%definition, %$properties}; - - return {%definition, %$properties}; -} - -#------------------------------------------------------------------- - -=head2 _getDatabaseInfo ( ) - -Returns a hashref containing all tables and columns including column properties in the database in which the SQLForm -resides. - -=cut - -sub _getDatabaseInfo { - my (@tables, $sth, $columnDefinition, $currentColumn, $databaseDefinition); - my $self = shift; - - my $dbLink = $self->_getDbLink; - @tables = $dbLink->db->buildArray("show tables"); - - foreach my $tableName (@tables) { - $sth = $dbLink->db->read("describe ".$tableName); - - while ($columnDefinition = $sth->hashRef) { - - $currentColumn = { - name => $columnDefinition->{Field}, - type => $columnDefinition->{Type}, - canBeNull => $columnDefinition->{Null}, - defaultValue => $columnDefinition->{Default}, - # Might need these fields in the future - #extra => $columnDefinition->{Extra}, - #key => $columnDefinition->{Key}, - }; - $databaseDefinition->{$tableName}->{$currentColumn->{name}} = $currentColumn; - } - } - - $dbLink->disconnect; - return $databaseDefinition; -} - -#------------------------------------------------------------------- - -=head2 _getFileFromDatabase ( recordId, fieldName, [ revision ] ) - -Returns the file contents and mime type of files stored in file fields. - -=head3 recordId - -The recordId of the record you want the file contents of. - -=head3 fieldName - -The the name of the column containing the actual file data. - -=head3 revision - -The revision number of the record you wan to select. If this is omitted the most -recent revision will be fetched. - -=cut - -sub _getFileFromDatabase { - my ($constraint, $dbLink); - my $self = shift; - my $recordId = shift || return undef; - my $fieldName = shift || return undef; - my $revision = shift; - - $dbLink = $self->_getDbLink; - - if ($revision =~ m/^\d+$/) { - $constraint = '__revision='.$self->session->db->quote($revision); - } else { - $constraint = '__archived = 0'; - } - - my $sql = - 'select '. - ' __'.$fieldName.'_mimeType, '. - $fieldName. - ' from '. - $self->get('tableName'). - ' where '. - '__recordId='.$self->session->db->quote($recordId).' and '. - $constraint; - - return $dbLink->db->quickArray($sql); -} - - - -#------------------------------------------------------------------- - -=head2 _getManagementLinks ( ) - -Returns a string containg all of the management function the user is allowed to use. - -=cut - -sub _getManagementLinks { - my (@links, $i18n); - my $self = shift; - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - push(@links, ''.$i18n->get('add record title').'') if ($self->_canEditRecord); - push(@links, ''.$i18n->get('search records title').'') if ($self->canView); - push(@links, ''.$i18n->get('manage fields').'') if ($self->_canAlterTable); - push(@links, ''.$i18n->get('manage regexes').'') if ($self->_canAlterTable); - push(@links, ''.$i18n->get('manage field types').'') if ($self->_canAlterTable); - - return join('·',@links); -} - -#------------------------------------------------------------------- - -=head2 _matchField ( string, regexId ) - -Excutes the regex identified by regexId on the string passed as first argument and return a boolean indicating -whether it is a match or not. Will return true if no regex id or a non-existing regex id is passed. - -=head3 string - -The string to be matched. - -=head3 regexId - -The id of the regex to used. - -=cut - -sub _matchField { - my $self = shift; - my $data = shift; - my $regexId = shift; - - return 1 unless ($regexId); - - my ($regex) = $self->session->db->quickArray('select regex from SQLForm_regexes where regexId='.$self->session->db->quote($regexId)); - - return 1 unless ($regex); - - if ($data =~ m/$regex/) { - return 1; - } else { - return 0; - } -} - -#------------------------------------------------------------------- - -=head2 _resolveFieldConstraintType ( type ) - -Translates the numerical value used in field constraint types to a perl operator. - -=head3 type - -The numerical id for the operator. If omitted this method will return a hasref containing -all numerical <-> operator mappings. - -=cut - -sub _resolveFieldConstraintType { - my $self = shift; - my $type = shift; - - my $i18n = WebGUI::International->new($self->session, 'Asset_SQLForm'); - - my $types = {'0' => $i18n->get('none'), 1 => '>', 2 => '>=', 3 => '<', 4 => '<=', 5 => '='}; - - return $types->{$type} if ($type); - return $types; -} - -#------------------------------------------------------------------- - -=head2 _uncacheFieldProperties ( fieldId ) - -Removes the cached properties of the given field. Fiekd properties are automatically cached -by _getFieldProperties. - -=head3 fieldId - -The GUID of the field to uncache the properties of. - -=cut - -sub _uncacheFieldProperties { - my $self = shift; - my $fieldId = shift; - - delete($self->{_fieldPropertiesCache}->{$fieldId}); -} - -#------------------------------------------------------------------- - -=head2 definition ( ) - -The asset definition of the SQLForm. - -=cut - -sub definition { - my $class = shift; - my $session = shift; - my $definition = shift; - - my $i18n = WebGUI::International->new($session, 'Asset_SQLForm'); - push(@{$definition}, { - tableName=>'SQLForm', - className=>'WebGUI::Asset::Wobject::SQLForm', - assetName=>$i18n->get('assetName'), - icon=>'sqlform.gif', - properties=>{ - formId => { - fieldType => 'text', - defaultValue => undef, - }, - tableName => { - fieldType => 'text', - defaultValue => undef, - }, - maxFileSize => { - fieldType => 'integer', - defaultValue => 1_500_000, - }, - sendMailTo => { - fieldType => 'email', - defaultValue => undef, - }, - showMetaData => { - fieldType => 'yesNo', - defaultValue => 1, - }, - searchTemplateId=> { - fieldType => 'template', - defaultValue => 'SQLFormSearchTmpl00001', - }, - editTemplateId => { - fieldType => 'template', - defaultValue => 'SQLFormEditTmpl0000001', - }, - submitGroupId => { - fieldType => 'group', - defaultValue => undef, - }, - alterGroupId => { - fieldType => 'group', - defaultValue => undef, - }, - databaseLinkId => { - fieldType => 'databaseLink', - defaultValue => 0, - }, - defaultView => { - fieldType => 'selectBox', - defaultValue => 'normalSearch', - }, - } - }); - return $class->SUPER::definition($session, $definition); -} - -#------------------------------------------------------------------- - -=head2 uiLevel ( ) - -The uiLevel of the SQLForm asset. It is a power tool so the uiLevel is set to 9. - -=cut - -sub uiLevel { - return 9; -} - -#------------------------------------------------------------------- - -=head2 getAdminConsoleWithSubmenu ( ) - -Return the adminconsole but adds three submenu items for manage fields/field types/regexes. - -=cut - -sub getAdminConsoleWithSubmenu { - my $self = shift; - my $ac = $self->getAdminConsole; - - my $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - $ac->addSubmenuItem($self->getUrl('func=listFields'), $i18n->get('manage fields')); - $ac->addSubmenuItem($self->getUrl('func=listFieldTypes'), $i18n->get('manage field types')); - $ac->addSubmenuItem($self->getUrl('func=listRegexes'), $i18n->get('manage regexes')); - - return $ac; -} - -#------------------------------------------------------------------- - -=head2 getEditForm ( ) - -Creates the edit form of the SQLForm asset. - -=cut - -sub getEditForm { - my ($availableDbLinks, $i18n); - my $self = shift; - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - $availableDbLinks = WebGUI::DatabaseLink->getList($self->session); - delete($availableDbLinks->{'0'}); - - my $tabform = $self->SUPER::getEditForm; - - unless (keys(%$availableDbLinks)) { - $tabform->getTab('properties')->readOnly( - -value => - '', - ); - - return $tabform; - } - - $tabform->submit({ - id => 'zeSubmitButton', - }); - - $tabform->getTab('properties')->text( - -name => 'tableName', - -label => $i18n->get('gef table name'), - -hoverHelp => $i18n->get('gef table name description'), - -value => $self->get('tableName'), - -extras => 'onkeyup="e = document.getElementById(\'zeSubmitButton\'); ' - .' if (this.value != \'\' ) { e.disabled = false} else {e.disabled = true};"', - ); - $tabform->getTab('properties')->checkbox( - -name => 'importTable', - -label => $i18n->get('gef import table'), - -hoverHelp => $i18n->get('gef import table description'), - -value => [1], - -checked => $self->session->form->process('importTable'), - ); - $tabform->getTab('properties')->selectList( - -name => 'databaseLinkId', - -label => $i18n->get('gef database to use'), - -hoverHelp => $i18n->get('gef database to use description'), - -options => $availableDbLinks, - -value => [$self->get('databaseLinkId') || (keys(%$availableDbLinks))[0]], - -size => 1, - -multiple => 0, - ); - $tabform->getTab('properties')->integer( - -name => 'maxFileSize', - -label => $i18n->get('gef max file size'), - -hoverHelp => $i18n->get('gef max file size description'), - -value => $self->getValue('maxFileSize'), - ); - $tabform->getTab('properties')->text( - -name => 'sendMailTo', - -label => $i18n->get('gef send mail to'), - -hoverHelp => $i18n->get('gef send mail to description'), - -value => $self->getValue('sendMailTo'), - ); - $tabform->getTab('properties')->yesNo( - -name => 'showMetaData', - -label => $i18n->get('gef show meta data'), - -hoverHelp => $i18n->get('gef show meta data description'), - -value => $self->getValue('showMetaData'), - ); - $tabform->getTab('display')->template( - -name => 'editTemplateId', - -label => $i18n->get('gef edit template'), - -hoverHelp => $i18n->get('gef edit template description'), - -value => $self->get('editTemplateId'), - -namespace => 'SQLForm/Edit', - ); - $tabform->getTab('display')->template( - -name => 'searchTemplateId', - -label => $i18n->get('gef search template'), - -hoverHelp => $i18n->get('gef search template description'), - -value => $self->get('searchTemplateId'), - -namespace => 'SQLForm/Search', - ); - $tabform->getTab('display')->selectBox( - -name => 'defaultView', - -label => $i18n->get('gef default view'), - -hoverHelp => $i18n->get('gef default view description'), - -value => [$self->get('defaultView')], - -options => { - 'normalSearch' => $i18n->get('s normal search'), - 'superSearch' => $i18n->get('s advanced search') - }, - -multiple => 0, - ); - $tabform->getTab('security')->group( - -name => 'submitGroupId', - -label => $i18n->get('gef submit group'), - -hoverHelp => $i18n->get('gef submit group description'), - -value => [ $self->get('submitGroupId') ], - ); - - $tabform->getTab('properties')->readOnly( - -value => '', - ) unless ($self->get('tableName')); - - return $tabform; -} - -#------------------------------------------------------------------- - -=head2 getIndexerParams ( ) - -Should index the data in the table of this SQLForm. Not functional in 6.8.x due to a crippled -search framework. - -=cut - -sub getIndexerParams { - my $self = shift; - my $now = shift; - my $sth = $self->session->db->read("select t1.url, t2.* from asset as t1, SQLForm as t2 where t1.assetId = t2.assetId"); - - my $result = {}; - while (my %row = $sth->hash) { - my $tableName = $row{tableName}; - my $assetId = $row{assetId}; - - if ($row{databaseLinkId}) { - my $dbName; - my %dbInfo = WebGUI::DatabaseLink::get($row{databaseLinkId}); - ($dbName = $dbInfo{DSN}) =~ s/DBI\:\w+\:(\w+)/$1/i; - $tableName = $dbName.'.'.$tableName; - } - my @indexFields = $self->session->db->buildArray("select t2.value from SQLForm_fieldDefinitions as t1, SQLForm_fieldDefinitions as t2 where ". - " t1.fieldId=t2.fieldId and t1.property='useFulltext' and t1.value=1 and t2.property='fieldName' and t1.assetId=".$self->session->db->quote($assetId)); - - my $concatFields = 'concat('. join(",' | ',",@indexFields).')'; - $result->{'SQLForm_'.$tableName} = { - sql => "select - * - from - $tableName - where - __archived = 0 and - __deleted = 0 - ", - fieldsToIndex => \@indexFields, - contentType => 'content', - url => 'my $url=\''.$row{url}.'\'; $self->session->url->gateway($url,\'func=editRecord;rid=\'.$data{__recordId})', - headerShortcut => 'select title from asset where assetId = \''.$assetId.'\'', - bodyShortcut => 'select '.$concatFields.' from '.$tableName.' where __recordId = \'$data{__recordId}\'' - }; - } - - return $result; -} - -#------------------------------------------------------------------- - -=head2 processPropertiesFromFormPost ( ) - -Processes the data in the edit form of the SQLForm asset. In WebGUI 6.8.x there's no way to feed back any errors on -asset addition. Therefore if something is wrong this method will use die to stop the processing. This will heave the -effect that an SQLForm asset is added to the asset tree, but it won't have any properties saved. You should delete -the 'empty' asset from your asset tree using the asset manager. - -This problem will be solved in 7.0.0. - -=cut - -sub processPropertiesFromFormPost { - my ($tableName, @tables, @usedTables); - my $self = shift; - - my $dbLinkId = $self->session->form->process("databaseLinkId"); - my $dbLink = WebGUI::DatabaseLink->new($self->session, $dbLinkId); - - # $dbLink->db will raise a fatal error if there is a connection error. -# return ["Can't connect to database through the selected database link"] unless ($dbLink->db); - - unless ($dbLink->checkPrivileges([qw(ALTER CREATE DELETE INDEX INSERT SELECT UPDATE)])) { - return ["Databaselink does not have enough privileges (Needs ALTER, CREATE, DELETE, INDEX, INSERT, SELECT, UPDATE)"]; - } - - $tableName = $self->session->form->process("tableName"); - - if ($self->session->form->process("assetId") eq 'new') { - #if table exists and not in SQLForm format, put in SQLFormFormat. - @tables = $dbLink->db->buildArray("show tables"); - - @usedTables = $self->session->db->buildArray("select tableName from SQLForm, asset where asset.assetID=SQLForm.assetId and state='published' and databaseLinkId = ".$self->session->db->quote($dbLinkId)); - - if (isIn(lc($tableName), map {lc} @usedTables)) { - return ["The table is already used in an SQLForm."]; - } - elsif ($tableName !~ m/^[\w\d_]+$/i) { - return ["The table name is illegal."]; - } - elsif (isIn(lc($tableName), map {lc} @tables) && !$self->session->form->process('importTable')) { - return ["The table already exists in the database but the import flag has not been set."]; - } - elsif (isIn(lc($tableName), map {lc} @tables)) { #&& !(isIn(lc($tableName), map {lc} @usedTables))) { - # exisiting table - # Write column data to db ----------------------------------------------------------------------------- - my $controlDefined = 0; - my $sth = $dbLink->db->read("describe ".$tableName); - my $processed; - my @columnNames; - my $rank = 0; - while (my $columnDefinition = $sth->hashRef) { - if ($columnDefinition->{Field} =~ m/^__*/ ) { - $controlDefined = 1; - } else { - # clear properties hash - $processed = {}; - - my $type = $columnDefinition->{Type}; - my $set = $columnDefinition->{Type}; - my $unsigned; - my $length; - $set =~ s/^.*\(//; - $set =~ s/\)$//; - $set =~ s/,/\r\n/g; - $set =~ s/'//g; - $length = $set + 0; - $type =~ s/\(.*\)//; - - ($type, $unsigned) = split /\s+/, $type; - my $shouldBeUnsigned = lc $unsigned eq 'unsigned'; - - my $currentField = $allowedDbFieldTypes->{$type}; - - # Get the fieldTypeId of this column - my ($fieldType) = $self->session->db->quickArray("select fieldTypeId from SQLForm_fieldTypes where dbFieldType=? and formFieldType=?",[$type, $currentField->{defaultFormElement}]); - - # Create the field type if it doesn't exist - unless ($fieldType) { - $fieldType = $self->_createFieldType($type, $currentField->{defaultFormElement}); - } - - # Check for - if ($columnDefinition->{Extra} =~ /auto_increment/) { - $processed->{useAutoIncrement} = 1; - my $dropAutoIncrementSQL = "alter table $tableName change column ".$columnDefinition->{Field}. - " ".$columnDefinition->{Field}." ". $columnDefinition->{Type}; - $dropAutoIncrementSQL .= " NOT NULL " if ($columnDefinition->{Null} ne 'YES'); - $dropAutoIncrementSQL .= " default '".$columnDefinition->{Default}."' " if ($columnDefinition->{Default} && ($columnDefinition->{Default} ne 'NULL')); - - $dbLink->db->write($dropAutoIncrementSQL); - } - - $processed->{defaultValue} = $columnDefinition->{Default} if ($columnDefinition->{Default} ne 'NULL'); - $processed->{isRequired} = 1 if ($columnDefinition->{Null} ne 'YES'); - $processed->{formPopulationValues} = $set if ($type =~ m/^set/i); - $processed->{formPopulationKeys} = $set if ($type =~ m/^set/i); - $processed->{dbFieldType} = $type; - $processed->{formFieldType} = $currentField->{defaultFormElement}; - $processed->{fieldType} = $fieldType; - $processed->{maxFieldLength} = $currentField->{maxLength} if ($currentField->{maxLength}); - $processed->{regex} = $currentField->{defaultRegEx} if ($currentField->{defaultRegEx}); - $processed->{fieldName} = $columnDefinition->{Field}; - $processed->{displayName} = $columnDefinition->{Field}; - $processed->{signed} = $shouldBeUnsigned ? 0 : 1; - $processed->{showInSearchResults} = '1'; - $processed->{isSearchable} = '1'; - my $fieldId = $self->session->id->generate; - $self->session->db->write('delete from SQLForm_fieldDefinitions where fieldId='.$self->session->db->quote($fieldId)); - foreach (keys(%$processed)) { - $self->session->db->write('insert into SQLForm_fieldDefinitions (fieldId, assetId, property, value) values '. - '('.$self->session->db->quote($fieldId).','.$self->session->db->quote($self->get('assetId')).','.$self->session->db->quote($_).','.$self->session->db->quote($processed->{$_}).')'); - } - $self->session->db->write('insert into SQLForm_fieldOrder (fieldId, assetId, rank) values '. - '('.$self->session->db->quote($fieldId).','.$self->session->db->quote($self->get('assetId')).','.$self->session->db->quote($rank).')'); - $rank++; - - push (@columnNames, $columnDefinition->{Field}); - } - } - - # We can't allow primary keys in the table because of the versioning. - # A composite pk with __recordId and __revision would work but makes no sense because - # __recordId and __revision are always unique and hence the pk. -my %dropKeys; -my $hasPrimaryKey = 0; - $sth = $dbLink->db->read("show keys from $tableName"); - while (my %row = $sth->hash) { - if ($row{Key_name} eq 'PRIMARY') { - $hasPrimaryKey = 1; - } else { - $dropKeys{$row{Key_name}} = 1; - } - } - - $dbLink->db->write("alter table $tableName drop primary key") if ($hasPrimaryKey); - - foreach (keys(%dropKeys)) { - $dbLink->db->write("alter table $tableName drop index $_ "); - } - - if ($controlDefined == 0){ - # add control fields - $dbLink->db->write("alter table $tableName ". - " add __recordId varchar(22) binary not null,". - " add __creationDate bigint(20),". - " add __createdBy varchar(22) binary,". - " add __initDate bigint(20),". - " add __userId varchar(22) binary,". - " add __deletionDate bigint(20),". - " add __deleted tinyint(1) default 0,". - " add __deletedBy varchar(22),". - " add __archived tinyint(1) default 0,". - " add __revision int(11) not null". - " "); - - # fill status fields - my $sql = - "update $tableName set ". - "__recordId = (select concat(rand(),rand())),". - "__creationDate = ".$self->session->db->quote(time).", ". - "__createdBy = ".$self->session->db->quote($self->session->user->userId).", ". - "__initDate = ".$self->session->db->quote(time).", ". - "__userId = ".$self->session->db->quote($self->session->user->userId).", ". - "__archived = 0, ". - "__revision = 1 "; - $dbLink->db->write($sql); - #print "$sql\n"; - } - - $dbLink->db->write("alter table $tableName add primary key (__recordId, __revision)"); - $dbLink->db->write("alter table $tableName add key recordId_archived (__recordId, __archived)"); - } - else { - #new table - $dbLink->db->write("create table $tableName (". - " __recordId varchar(22) binary not null,". - " __creationDate bigint(20) not null,". - " __createdBy varchar(22) not null,". - " __initDate bigint(20) not null,". - " __userId varchar(22) not null,". - " __deletionDate bigint(20),". - " __deleted tinyint(1) default 0,". - " __deletedBy varchar(22),". - " __archived tinyint(1) default 0,". - " __revision int(11) not null,". - " primary key (__recordId, __revision),". - " key recordId_archived (__recordId, __archived)". - ")"); - } - } - else { - if ($self->get('tableName') ne $tableName) { - $dbLink->db->write("rename table ".$self->get('tableName')." to $tableName"); - } - } - - $dbLink->disconnect; - return $self->SUPER::processPropertiesFromFormPost; -} - -#------------------------------------------------------------------- - -=head2 purge ( ) - -This method purges the Asset completely from the WebGUI instance. - -=cut - -sub purge { - my $self = shift; - - $self->session->db->write("delete from SQLForm_fieldDefinitions where assetId=".$self->session->db->quote($self->getId)); - $self->session->db->write("delete from SQLForm_fieldOrder where assetId=".$self->session->db->quote($self->getId)); - - return $self->SUPER::purge; -} - -#------------------------------------------------------------------- - -=head2 view ( ) - -The view function of the Asset. - -=cut - -sub view { - my $self = shift; - my ($output, @links); - - if ($self->get('defaultView') eq 'superSearch') { - return $output .$self->www_superSearch; - }else{ - return $output .$self->www_search; - } -} - -#------------------------------------------------------------------- - -=head2 www_deleteFieldType ( ) - -This will delete the field type with the id that is passed in a form param called 'ftid'. - -=cut - -sub www_deleteFieldType { - my ($isUsed); - my $self = shift; - - my $i18n = WebGUI::International->new($self->session, 'Asset_SQLForm'); - - return $self->session->privilege->insufficient unless ($self->_canAlterTable); - - ($isUsed) = $self->session->db->quickArray(' select count(fieldId) '. - ' from SQLForm_fieldDefinitions '. - ' where property="fieldType" and value='.$self->session->db->quote($self->session->form->process("ftid"))); - - if ($isUsed) { - return $self->processStyle($i18n->get('dft cannot delete')." $isUsed ".$i18n->get('sqlforms')."."); - } else { - $self->session->db->write('delete from SQLForm_fieldTypes where fieldTypeId='.$self->session->db->quote($self->session->form->process("ftid"))); - return $self->www_listFieldTypes; - } -} - -#------------------------------------------------------------------- - -=head2 www_deleteRecord ( ) - -Will put the record with the id given by the form param 'rid', in the trash of the SQLForm. - -=cut - -sub www_deleteRecord { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canEditRecord); - my $dbLink = $self->_getDbLink; - - $dbLink->db->write("update ".$self->get('tableName')." set ". - " __deleted=1,". - " __deletionDate=".$self->session->db->quote(time).",". - " __deletedBy=".$self->session->db->quote($self->session->user->userId). - " where __recordId=".$self->session->db->quote($self->session->form->process("rid")) - ); - - $dbLink->disconnect; - return $self->www_view; -} - -#------------------------------------------------------------------- - -=head2 www_deleteRegex ( ) - -Deletes the regex with the id given in the form param 'regexId'. - -=cut - -sub www_deleteRegex { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - unless ($self->session->form->process("regexId") =~ /^default/) { - $self->session->db->write('delete from SQLForm_regexes where regexId='.$self->session->db->quote($self->session->form->process("regexId"))); - } else { - return $self->session->privilege->vitalComponent; - } - - return $self->www_listRegexes; -} - -#------------------------------------------------------------------- - -=head2 www_disableField ( ) - -Will mark the field indicated by the id given by the form param 'fid' as deleted. This means -that the field is not included in searches and edits. No data is actually purged though. - -=cut - -sub www_disableField { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $self->session->db->write('delete from SQLForm_fieldDefinitions '. - ' where property="disabled" and assetId='.$self->session->db->quote($self->getId).' and fieldId='.$self->session->db->quote($self->session->form->process("fid"))); - $self->session->db->write('insert into SQLForm_fieldDefinitions '. - ' (assetId, fieldId, property, value) values '. - ' ('.$self->session->db->quote($self->getId).', '.$self->session->db->quote($self->session->form->process("fid")).', "disabled", 1)'); - - return $self->www_listFields; -} - -#------------------------------------------------------------------- - -=head2 www_enableField ( ) - -Will mark the 'deleted' field identified by the id given in the form param 'fid' as normal again. - -=cut - -sub www_enableField { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $self->session->db->write('delete from SQLForm_fieldDefinitions '. - ' where property="disabled" and assetId='.$self->session->db->quote($self->getId).' and fieldId='.$self->session->db->quote($self->session->form->process("fid"))); - - return $self->www_listFields; -} - -#------------------------------------------------------------------- - -=head2 www_editField ( ) - -Returns the 'edit field properties' form of the field attached to the id given in form param 'fid'. If fid is set -to 'new' it will add a new field. The form generated relies heavily on three javascript files included in the -/extras/SQLForm directory. - -=cut - -sub www_editField { - my ($databaseDefinition, $fieldId, $properties, $f, $tabForm, $jsDatabaseDef, $table, $jsInitForm, $regexes, - %dbFields, %formFields, $output, $i18n, @jsFieldTypeList); - my $self = shift; - my $errors = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - my $dbLink = $self->_getDbLink; - - # generate column properties hash in javascript - my $jsDataStruct = "var fieldTypes = new Object;\n"; - $jsDataStruct .= "fieldTypes = {\n"; - foreach my $type (keys(%{$allowedDbFieldTypes})) { - my $jsFieldType = "\t'$type' : {\n"; - $jsFieldType .= join(",\n", map {"\t\t'$_' : '".$allowedDbFieldTypes->{$type}->{$_}."'"} keys(%{$allowedDbFieldTypes->{$type}})); - $jsFieldType .= "\n\t}"; - - push(@jsFieldTypeList, $jsFieldType); - } - - $jsDataStruct.= join(",\n", @jsFieldTypeList)."};"; - $self->session->style->setRawHeadTags(''); - - $fieldId = $self->session->form->process("fid"); - return $self->www_view unless ($fieldId); - - if ($self->session->form->process("func") eq 'editFieldSave') { - $properties = $self->session->form->paramsHashRef; - } elsif ($fieldId eq 'new') { - $properties = { - signed => 1, - useAutoIncrement => 0, - isSearchable => 1, - isReadOnly => 0, - useFulltext => 0, - showInSearchResults => 1, - }; - } else { - $properties = $self->session->db->buildHashRef('select property, value from SQLForm_fieldDefinitions where fieldId = '.$self->session->db->quote($fieldId)); - } - - tie %$regexes, "Tie::IxHash"; - $regexes = $self->session->db->buildHashRef("select regexId, concat(name, ' (', regex, ')') from SQLForm_regexes order by name"); - $regexes->{''} = 'No regex'; - - $databaseDefinition = $self->_getDatabaseInfo; - - tie %dbFields, 'Tie::IxHash'; - tie %formFields, 'Tie::IxHash'; - %dbFields = map {$_ => $allowedDbFieldTypes->{$_}->{name}} keys %{$allowedDbFieldTypes}; - %formFields = map {$_ => $allowedFormFieldTypes->{$_}->{name}} keys %{$allowedFormFieldTypes}; -my %fieldTypes = $self->session->db->buildHash('select fieldTypeId, concat(formFieldType, "/", dbFieldType) from SQLForm_fieldTypes'); - - unless (%fieldTypes) { - return $self->processStyle('There are no field types defined. Please define field types first.
'. - 'To add a field type please go to Manage field types.' - ); - } - - $tabForm = WebGUI::TabForm->new($self->session, undef, undef, $self->getUrl('func=listFields')); - $tabForm->hidden({ - name => 'func', - value => 'editFieldSave' - }); - $tabForm->hidden({ - name => 'fid', - value => $fieldId - }); - - # Insert warning - unless ($fieldId eq 'new') { -my $message = $i18n->get('change field warning'); - $tabForm->formHeader({ - extras => 'onsubmit="'. - "if (document.getElementById('SQLFormFieldType').value != '".$properties->{fieldType}."' || ". - "document.getElementById('SQLFormMaxFieldLength').value < ".($properties->{maxFieldLength} || '0'). -# " || "."document.getElementById('SQLFormSigned').value != '".$properties->{signed}."'" - ") ". - "return confirm('$message')\"" - }); - } - - # Field definition - $tabForm->addTab('general', 'General Properties'); - $f = $tabForm->getTab('general'); - $f->text( - -name => 'fieldName', - -label => $i18n->get('ef field name'), - -hoverHelp => $i18n->get('ef field name description'), - -value => $properties->{fieldName}, - -maxlength => 64, - ); - $f->text( - -name => 'displayName', - -label => $i18n->get('ef display name'), - -hoverHelp => $i18n->get('ef display name description'), - -value => $properties->{displayName}, - ); - $f->selectList( - -name => 'fieldType', - -label => $i18n->get('ef field type'), - -hoverHelp => $i18n->get('ef field type description'), - -value => [$properties->{fieldType}], - -options=> \%fieldTypes, - -extras => 'onchange="updateFormFields()"', - -id => "SQLFormFieldType", - -multiple => 0, - -size => 1, - ); - $f->trClass('SQLFormSignedRow'); - $f->radioList( - -name => 'signed', - -label => $i18n->get('ef signed'), - -hoverHelp => $i18n->get('ef signed description'), - -value => $properties->{signed} || '0', - -options=> { - '1' => $i18n->get('ef signed label'), - '0' => $i18n->get('ef unsigned label') - }, - -id => 'SQLFormSigned', - ); - $f->trClass('SQLFormAutoIncrementRow'); - $f->yesNo( - -name => 'useAutoIncrement', - -label => $i18n->get('ef autoincrement'), - -hoverHelp => $i18n->get('ef autoincrement description'), - -value => $properties->{useAutoIncrement}, - -id => 'SQLFormAutoIncrement', - ); - $f->trClass(''); - $f->integer( - -name => 'formFieldHeight', - -label => $i18n->get('ef form height'), - -hoverHelp => $i18n->get('ef form height description'), - -value => $properties->{formFieldHeight}, - ); - $f->integer( - -name => 'formFieldWidth', - -label => $i18n->get('ef form width'), - -hoverHelp => $i18n->get('ef form width description'), - -value => $properties->{formFieldWidth}, - ); - $f->trClass('SQLFormMaxFieldLengthRow'); - $f->integer( - -name => 'maxFieldLength', - -label => $i18n->get('ef max field length'), - -hoverHelp => $i18n->get('ef max field length description'), - -value => $properties->{maxFieldLength}, - -id => 'SQLFormMaxFieldLength', - ); - $f->trClass('SQLFormRegexRow'); - $f->selectList( - -name => 'regex', - -label => $i18n->get('ef regex'), - -hoverHelp => $i18n->get('ef regex description'), - -value => [ $properties->{regex} ], - -options=> $regexes, - -id => 'SQLFormRegex', - -size => 1, - -multiple=> 0, - ); - $f->trClass(''); - $f->yesNo( - -name => 'isRequired', - -label => $i18n->get('ef required'), - -hoverHelp => $i18n->get('ef required description'), - -value => $properties->{isRequired}, - ); - $f->trClass('SQLFormReadOnlyRow'); - $f->yesNo( - -name => 'isReadOnly', - -label => $i18n->get('ef read only'), - -hoverHelp => $i18n->get('ef read only description'), - -value => $properties->{isReadOnly}, - -id => 'SQLFormReadOnly', - ); - $f->trClass(''); - $f->text( - -name => 'defaultValue', - -label => $i18n->get('ef default value'), - -hoverHelp => $i18n->get('ef default value description'), - -value => $properties->{defaultValue}, - ); - $f->readOnly( - -label => $i18n->get('ef field constraint'), - -hoverHelp => $i18n->get('ef field constraint description'), - -value => WebGUI::Form::selectList($self->session, { - name => 'fieldConstraintType', - options => {'0' => 'none', 1 => '>', 2 => '>=', 3 => '<', 4 => '<=', 5 => '='}, - value => [ $properties->{fieldConstraintType} || '0' ], - extras => 'onchange="updateFormFields()"', - id => 'SQLFormFieldConstraintType', - size => 1, - multiple=> 0, - }). - WebGUI::Form::selectList($self->session, { - name => 'fieldConstraintTarget', - options => {}, #{'value' => 'Value', 'joinColumn1' => 'Join field 1', joinColumn2 => 'Join field 2'}, - value => [ $properties->{fieldConstraintTarget} ], - extras => 'onchange="updateFormFields()"', - id => 'SQLFormFieldConstraintTarget', - size => 1, - multiple=> 0, - }). - WebGUI::Form::text($self->session, { - name => 'fieldConstraintValue', - value => $properties->{fieldConstraintValue}, - id => 'SQLFormFieldConstraintValue', - }), - ); - - # Search and summary options - $tabForm->addTab('search', 'Search and Summary'); - $f = $tabForm->getTab('search'); - $f->yesNo( - -name => 'isSearchable', - -label => $i18n->get('ef searchable'), - -hoverHelp => $i18n->get('ef searchable description'), - -value => $properties->{isSearchable}, - ); - $f->yesNo( - -name => 'useFulltext', - -label => $i18n->get('ef fulltext'), - -hoverHelp => $i18n->get('ef fulltext description'), - -value => $properties->{useFulltext}, - ); - $f->yesNo( - -name => 'showInSearchResults', - -label => $i18n->get('ef show in search'), - -hoverHelp => $i18n->get('ef show in search description'), - -value => $properties->{showInSearchResults}, - ); - $f->integer( - -name => 'summaryLength', - -label => $i18n->get('ef summary length'), - -hoverHelp => $i18n->get('ef summary length description'), - -value => $properties->{summaryLength}, - ); - - # Form pouplation params - $tabForm->addTab('population', 'Form Population'); - $f = $tabForm->getTab('population'); - $f->textarea( - -name => 'formPopulationKeys', - -label => $i18n->get('ef populate keys'), - -hoverHelp => $i18n->get('ef populate keys description'), - -value => $properties->{formPopulationKeys}, - ); - $f->textarea( - -name => 'formPopulationValues', - -label => $i18n->get('ef populate values'), - -hoverHelp => $i18n->get('ef populate values description'), - -value => $properties->{formPopulationValues}, - ); - - $f->readOnly( - -value => 'Query generation', - ); - # This is quite a special field and is completely built by javascript. The file sqlform.js contains the HTML - # for the row layout. - $f->readOnly( - -label => $i18n->get('ef join selector'), - -hoverHelp => $i18n->get('ef join selector description'), - -value => '
', - ); - $f->readOnly( - -label => $i18n->get('ef join constraint'), - -hoverHelp => $i18n->get('ef join constraint description'), - -value => WebGUI::Form::selectList($self->session, { - name => 'joinConstraintColumn', - options => {}, - id => 'joinConstraintColumn', - size => 1, - multiple=> 0, - }).' = '. - WebGUI::Form::selectList($self->session, { - name => 'joinConstraintField', - options => $self->session->db->buildHashRef('select fieldId, value from SQLForm_fieldDefinitions where property="displayname" and assetId='.$self->session->db->quote($self->getId)), - value => [ $properties->{joinConstraintField} ], - id => 'joinConstraintField', - size => 1, - multiple=> 0, - }), - ); - $f->selectList( - -name => 'selectField1', - -label => $i18n->get('ef join keys'), - -hoverHelp => $i18n->get('ef join keys description'), - -options=> {}, - -id => 'selectField1', - -size => 1, - -multiple=> 0, - ); - $f->selectList( - -name => 'selectField2', - -label => $i18n->get('ef join values'), - -hoverHelp => $i18n->get('ef join values description'), - -options=> {}, - -id => 'selectField2', - -size => 1, - -multiple=> 0, - ); - - # This js file contains code to handle the dynamics of this form. - $self->session->style->setScript($self->session->url->extras('wobject/SQLForm/SQLFormJoinSelector.js'), {type => 'text/javascript'}); - $self->session->style->setScript($self->session->url->extras('js/at/AjaxRequest.js'), {type => 'text/javascript'}); - $self->session->style->setScript($self->session->url->extras('wobject/SQLForm/SQLFormEditField.js'), {type => 'text/javascript'}); - -my $jsDatabases = '[' . join(',', map {"{key : '$_', value : '$_'}"} $dbLink->db->buildArray('show databases')) . ']'; -my $jsInitJoinSelector; -my $js = "\n"; - - $output = '

'.$i18n->get('ef errors occurred').'


' if ($errors); - $output .= $tabForm->print . $js; - - return $self->getAdminConsoleWithSubmenu->render($output, $i18n->get('edit field title')); -} - -#------------------------------------------------------------------- - -=head2 www_editFieldSave ( ) - -Processes and stores the field properties, and will alter the table according to these properties. - -=cut - -sub www_editFieldSave { - my ($databaseDef, $joinNumber, @tables, $processed, $tableName, - $joinAColumnName, $joinATableName, $joinBColumnName, $joinBTableName, - @joinConstraints, @differenceConstraints, $maxAllowedLength, $fieldId, - @error, $properties, $i18n); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - $databaseDef = $self->_getDatabaseInfo; - - # Get the right field id and load properties if applicable ------------------------------------ - if ($self->session->form->process("fid") eq 'new') { - $fieldId = $self->session->id->generate; - } else { - $fieldId = $self->session->form->process("fid"); - $properties = $self->session->db->buildHashRef("select property, value from SQLForm_fieldDefinitions where fieldId=".$self->session->db->quote($fieldId)); - $self->_uncacheFieldProperties($fieldId); - } - - # If no value (or zero) is given for any of these values just discard them and use the WebGUI defaults. - - push (@error, $i18n->get('efs height error')) unless ($self->session->form->process("formFieldHeight") =~ m/^\d*$/); - $processed->{formFieldHeight} = $self->session->form->integer('formFieldHeight') if ($self->session->form->process("formFieldHeight")); - push (@error, $i18n->get('efs width error')) unless ($self->session->form->process("formFieldWidth") =~ m/^\d*$/); - $processed->{formFieldWidth} = $self->session->form->integer('formFieldWidth') if ($self->session->form->process("formFieldWidth")); - - push (@error, $i18n->get('efs populate error')) if (scalar(split(/\n/,$self->session->form->process("formPopulationKeys"))) != scalar(split(/\n/,$self->session->form->process("formPopulationValues")))); - $processed->{formPopulationKeys} = $self->session->form->process("formPopulationKeys"); - $processed->{formPopulationValues} = $self->session->form->process("formPopulationValues"); - - $processed->{isSearchable} = 1 if $self->session->form->process("isSearchable"); - $processed->{showInSearchResults} = 1 if ($self->session->form->process("showInSearchResults")); - - $processed->{summaryLength} = $self->session->form->process("summaryLength") if ($self->session->form->process("summaryLength") =~ m/^\d+$/); - $processed->{useAutoIncrement} = 1 if ($self->session->form->process("useAutoIncrement")); - $processed->{signed} = 1 if ($self->session->form->process("signed")); - $processed->{isRequired} = 1 if ($self->session->form->process("isRequired")); - $processed->{isReadOnly} = 1 if ($self->session->form->process("isReadOnly")); - $processed->{defaultValue} = $self->session->form->process("defaultValue"); - - if ($self->session->form->process("fieldConstraintType") > 0 && defined $self->session->form->process("fieldConstraintTarget")) { - $processed->{fieldConstraintType} = $self->session->form->process("fieldConstraintType"); - $processed->{fieldConstraintTarget} = $self->session->form->process("fieldConstraintTarget"); - if ($processed->{fieldConstraintTarget} eq 'value') { - $processed->{fieldConstraintValue} = $self->session->form->process("fieldConstraintValue"); - push (@error, $i18n->get('efs constraint error')) unless (defined $self->session->form->process("fieldConstraintValue")); - } - if ($processed->{fieldConstraintTarget} eq 'joinColumn1' && !$self->session->form->process("selectField1")) { - push (@error, $i18n->get('efs jf1 error')); - } - if ($processed->{fieldConstraintTarget} eq 'joinColumn2' && !$self->session->form->process("selectField2")) { - push (@error, $i18n->get('efs jf2 error')); - } - - } - - $processed->{joinConstraintColumn} = $self->session->form->process("joinConstraintColumn"); - $processed->{joinConstraintField} = $self->session->form->process("joinConstraintField"); - - # Process fieldType ---------------------------------------------------------------------------- -my ($dbFieldType, $formFieldType) = $self->session->db->quickArray('select dbFieldType, formFieldType from SQLForm_fieldTypes '. - ' where fieldTypeId='.$self->session->db->quote($self->session->form->process("fieldType"))); - if ($dbFieldType && $formFieldType) { - $processed->{dbFieldType} = $dbFieldType; - $processed->{formFieldType} = $formFieldType; - $processed->{fieldType} = $self->session->form->process("fieldType"); - } else { - push(@error, $i18n->get('efs field type error')); - } - - # Process the join stuff ----------------------------------------------------------------------- - if ($allowedFormFieldTypes->{$processed->{formFieldType}}->{hasOptions} && - $self->session->form->process("table1") && - !($self->session->form->process("selectField1") && $self->session->form->process("selectField2"))) { - push(@error, $i18n->get('efs join populate error')); - } - if ($self->session->form->process("table1")) { - $processed->{selectField1} = $self->session->form->process("selectField1"); - $processed->{selectField2} = $self->session->form->process("selectField2"); - } - - #### Will break if there are more than 9 joins #### -my @columnConstraints; -my %fingerprint; -my $dbLink = $self->_getDbLink; - - foreach my $key (sort(keys(%{$self->session->form->paramsHashRef}))) { - if ($key =~ m/^database(\d+)/ && $self->session->form->process($key)) { - $joinNumber = $1; -my $databaseName = $self->session->form->process("database$joinNumber"); - if (isIn($databaseName, $dbLink->db->buildArray('show databases'))) { - $processed->{"database$joinNumber"} = $databaseName; - - $tableName = $self->session->form->process("table$joinNumber"); - if (isIn($tableName, $dbLink->db->buildArray("show tables from $databaseName"))) { - unless ($self->session->form->process("joinFunction$joinNumber") eq 'difference') { - push(@tables, "$databaseName.$tableName as table$joinNumber"); - } - $processed->{"table$joinNumber"} = $tableName; - - -my @columns = $dbLink->db->buildArray("describe $databaseName.$tableName"); - if (isIn('__deleted', @columns) && isIn('__archived', @columns)) { - push(@columnConstraints, "table$joinNumber.__deleted=0 and table$joinNumber.__archived=0") if ($joinNumber == 1); - $fingerprint{$joinNumber} = 1; - } - -my $joinAIsSQLForm = 0; - if ($joinNumber > 1) { -my $joinADatabaseName; - if ($self->session->form->process('joinOnA'.$joinNumber) =~ m/^table(\d+)\.(.+)$/) { - $joinAColumnName = $2; - $joinATableName = $self->session->form->process('table'.$1); - $joinADatabaseName = $self->session->form->process('database'.$1); - $joinAIsSQLForm = $fingerprint{$1}; - } else { - push(@error, $i18n->get('efs left join column error').$joinNumber."."); - } - -my $joinBDatabaseName; - if ($self->session->form->process('joinOnB'.$joinNumber) =~ m/^table(\d+)\.(.+)$/) { - $joinBColumnName = $2; - $joinBTableName = $self->session->form->process('table'.$1); - $joinBDatabaseName = $self->session->form->process('database'.$1); - } else { - push(@error, $i18n->get('efs right join column error').$joinNumber."."); - } - if ($joinATableName && $joinBTableName && - isIn($joinAColumnName, $dbLink->db->buildArray("describe $joinADatabaseName.$joinATableName")) && - isIn($joinBColumnName, $dbLink->db->buildArray("describe $joinBDatabaseName.$joinBTableName"))) { - if ($self->session->form->process("joinFunction$joinNumber") eq 'difference') { -my $subSelect = "select $joinAColumnName from $joinADatabaseName.$joinATableName"; - $subSelect .= " where __deleted=0 and __archived=0" if ($joinAIsSQLForm); - push(@differenceConstraints, $self->session->form->process('joinOnB'.$joinNumber).' not in ('.$subSelect.')'); - } else { - push(@joinConstraints, $self->session->form->process('joinOnA'.$joinNumber) .'='. $self->session->form->process('joinOnB'.$joinNumber)); - push(@columnConstraints, "table$joinNumber.__deleted=0 and table$joinNumber.__archived=0") if ($fingerprint{$joinNumber}); - } - - $processed->{'joinOnA'.$joinNumber} = $self->session->form->process('joinOnA'.$joinNumber); - $processed->{'joinOnB'.$joinNumber} = $self->session->form->process('joinOnB'.$joinNumber); - $processed->{'joinFunction'.$joinNumber} = $self->session->form->process('joinFunction'.$joinNumber); - } else { - push(@error, $i18n->get('efs column name error')." [$joinAColumnName][$joinBColumnName]"); - } - } - } else { - push(@error, $i18n->get('efs table error').' ['.$self->session->form->process($key).'.'.$tableName.']'); - } - } else { - push(@error, $i18n->get('efs database error').' ['.$self->session->form->process("database$joinNumber").']'); - } - - } - } - - # Generate a sqlquery here so we don't have to generate it everytime the form view is called --- - $processed->{sqlQuery} = "select ".$self->session->form->process("selectField1").", ".$self->session->form->process("selectField2"). " from ". - join(', ', @tables); - $processed->{sqlQuery} .= " where " if (@joinConstraints || @differenceConstraints || @columnConstraints); - $processed->{sqlQuery} .= join(' and ', (@joinConstraints, @differenceConstraints, @columnConstraints)); - - # If there are set-differences defined we also need a query without them to be able to show - # the correct values in search results. - if (@differenceConstraints) { - $processed->{sqlQueryAllOptions} = "select ".$self->session->form->process("selectField1").", ".$self->session->form->process("selectField2"). " from ". - join(', ', @tables); - $processed->{sqlQueryAllOptions} .= " where ".join(' and ', @joinConstraints) if (@joinConstraints); - } - - # Check if fulltext search is allowed ---------------------------------------------------------- - if ($self->session->form->process("useFulltext") && $allowedDbFieldTypes->{$processed->{dbFieldType}}->{supportsFulltext}) { - $processed->{useFulltext} = 1; - } elsif ($self->session->form->process("useFulltext")) { - push (@error, $i18n->get('efs fulltext error')); - } - - # Check whether a correct fieldname has been given --------------------------------------------- - if ($self->session->form->process("fieldName") =~ m/^[a-zA-Z0-9_]+$/) { - if (($self->session->form->process("fieldName") ne $properties->{fieldName}) && - isIn($self->session->form->process("fieldName"), keys(%{$databaseDef->{$self->get('tableName')}}))) - { - push(@error, $i18n->get('efs column name exists error')); - } elsif (isIn(uc($self->session->form->process("fieldName")), @reservedKeywords)) { - push(@error, $i18n->get('efs column name is reserved error')); - } else { - $processed->{fieldName} = $self->session->form->process("fieldName"); - } - } elsif (!$self->session->form->process("useAutoIncrement")) { - push(@error, $i18n->get('efs field name error')); - } - - # Make sure the maxlength is supported by the field types -------------------------------------- - $maxAllowedLength = ($allowedDbFieldTypes->{$processed->{dbFieldType}}->{maxLength} > $allowedFormFieldTypes->{$processed->{formFieldType}}->{maxLength}) ? - $allowedDbFieldTypes->{$processed->{dbFieldType}}->{maxLength} : $allowedFormFieldTypes->{$processed->{formFieldType}}->{maxLength}; - if ($self->session->form->integer('maxFieldLength') <= $maxAllowedLength || !$maxAllowedLength) { - $processed->{maxFieldLength} = $self->session->form->integer('maxFieldLength') || $maxAllowedLength || undef; - } else { - push (@error, "Allow maximum length to large for chosen fields"); - } - - # Check if population params are given in case of a set-field ---------------------------------- - if ($processed->{dbFieldType} eq 'set' and scalar(split(/\r?\n/, $processed->{formPopulationKeys})) == 0) { - push (@error, "You have to enter population key/value pairs if you use the set column type"); - } - - # Process regex - $processed->{regex} = $self->session->form->combo('regex'); - if ($self->session->form->process("regex") eq '_new_') { -my $regexName = $self->session->form->process("regex_name") || 'untitled'; - $self->session->db->write('insert into SQLForm_regexes (name, regex) values ('.$self->session->db->quote($regexName).','.$self->session->db->quote($processed->{regex}).')'); - } - - # Process display name - $processed->{displayName} = $self->session->form->process("displayName") || $processed->{fieldName}; - - # Return errors if necessarry, else write the whole lot to the db. - if (@error) { - return $self->www_editField(\@error); - } else { - # Write data to db ----------------------------------------------------------------------------- - my $dbLink = $self->_getDbLink; - - # Store/update definition - $self->session->db->write('delete from SQLForm_fieldDefinitions where fieldId='.$self->session->db->quote($fieldId)); - foreach (keys(%$processed)) { - $self->session->db->write('insert into SQLForm_fieldDefinitions (fieldId, assetId, property, value) values '. - '('.$self->session->db->quote($fieldId).','.$self->session->db->quote($self->get('assetId')).','.$self->session->db->quote($_).','.$self->session->db->quote($processed->{$_}).')'); - } - - # Set new column at the last position - if ($self->session->form->process("fid") eq 'new') { - my ($rank) = $self->session->db->quickArray('select max(rank)+1 from SQLForm_fieldOrder where assetId ='.$self->session->db->quote($self->getId).' group by assetId'); - $rank ||= '0'; - $self->session->db->write( - " insert into SQLForm_fieldOrder (assetId, fieldId, rank) values " - ." (".$self->session->db->quote($self->getId).", ".$self->session->db->quote($fieldId).", $rank )" - ); - } - - # Construct the type specifier - my $type = $self->_constructColumnType($processed); - - # If id = new create column in table - if ($self->session->form->process("fid") eq 'new') { - $dbLink->db->write('alter table '.$self->get('tableName').' add column '.$processed->{fieldName}.' '.$type); - } else { - $dbLink->db->write('alter table '.$self->get('tableName').' change column '.$properties->{fieldName}.' '.$processed->{fieldName}.' '.$type); - } - - # Add mimetype column for file fields. - if ($processed->{formFieldType} eq 'file') { - unless (isIn('__'.$processed->{fieldName}.'_mimeType' , keys(%{$databaseDef->{$self->get('tableName')}}))) { - $dbLink->db->write('alter table '.$self->get('tableName'). - ' add column '.'__'.$processed->{fieldName}.'_mimeType'.' varchar(64)'); - } - } - - # Process fulltext columns - if ($processed->{useFulltext} && !$properties->{useFulltext}) { - $dbLink->db->write('alter table '.$self->get('tableName').' add fulltext ('.$processed->{fieldName}.')'); - } elsif (!$processed->{useFulltext} && $properties->{useFulltext}) { - $dbLink->db->write('alter table '.$self->get('tableName').' drop index '.$processed->{fieldName}); - } - - $dbLink->disconnect; - } - - return $self->www_listFields; -} - -#------------------------------------------------------------------- - -=head2 www_editFieldType ( ) - -Returns the form for editing field types. Only allows editing of field types that are not in use by -any SQLForm asset withing the instance. Pass the field type id through the form param 'ftid'. Pass -ftid=new to add a new field type. - -=cut - -sub www_editFieldType { - my (%dbFields, %formFields, $f, $properties, $i18n); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - tie %dbFields, 'Tie::IxHash'; - tie %formFields, 'Tie::IxHash'; - %dbFields = map {$_ => $allowedDbFieldTypes->{$_}->{name}} keys %{$allowedDbFieldTypes}; - %formFields = map {$_ => $allowedFormFieldTypes->{$_}->{name}} keys %{$allowedFormFieldTypes}; - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - if ($self->session->form->process("ftid") eq 'new') { - $properties = {}; - } else { - $properties = $self->session->db->quickHashRef('select * from SQLForm_fieldTypes where fieldTypeId='.$self->session->db->quote($self->session->form->process("ftid"))); - } - - $f = WebGUI::HTMLForm->new($self->session, - -action => $self->getUrl - ); - $f->hidden( - -name => 'func', - -value => 'editFieldTypeSave' - ); - $f->hidden( - -name => 'ftid', - -value => $self->session->form->process("ftid"), - ); - $f->readOnly( - -label => 'fieldTypeId', - -value => $self->session->form->process("ftid"), - ); - $f->selectList( - -name => 'dbFieldType', - -label => $i18n->get('eft db field type'), - -hoverHelp => $i18n->get('eft db field type description'), - -value => [$properties->{dbFieldType}], - -options=> \%dbFields, - -id => 'SQLFormDbFieldType', - -size => 1, - -multiple=> 0, - ); - $f->selectList( - -name => 'formFieldType', - -label => $i18n->get('eft form field type'), - -hoverHelp => $i18n->get('eft form field type description'), - -value => [$properties->{formFieldType}], - -options=> \%formFields, - -id => 'formTypeSelector', - -size => 1, - -multiple=> 0, - ); - $f->readOnly( - -value => - WebGUI::Form::submit($self->session). - WebGUI::Form::button($self->session, { - value => $i18n->get('cancel'), - extras => 'onClick="location.href=\''.$self->getUrl('func=listFieldTypes').'\'"' - }) - ); - - return $self->getAdminConsoleWithSubmenu->render($f->print, $i18n->get('edit field type title')); -} - -#------------------------------------------------------------------- - -=head2 www_editFieldTypeSave ( ) - -Saves the field type properties entered in the form returned by www_editFieldType to the database. The form -param 'ftid' is used to pass the field type id. Setting the id to 'new' will create a new field type. - -=cut - -sub www_editFieldTypeSave { - my ($fieldTypeId); - my $self = shift; - - if ($self->session->form->process("ftid") eq 'new') { - $self->_createFieldType($self->session->form->process("dbFieldType"), $self->session->form->process("formFieldType")); - } else { - $self->session->db->write('update SQLForm_fieldTypes '. - ' set dbFieldType='.$self->session->db->quote($self->session->form->process("dbFieldType")).', formFieldType='.$self->session->db->quote($self->session->form->process("formFieldType")). - ' where fieldTypeId='.$self->session->db->quote($self->session->form->process("ftid"))); - } - - return $self->www_listFieldTypes; -} - -#------------------------------------------------------------------- - -=head2 _getFieldValue ( field, recordValues, readOnly ) - -Returns the the value for the field represented by the field hashref for the current record, If the record -has no value for this field it will return the default value. The returned value has the correct data type -for the for element that belongs to the field. - -=head3 field - -A hashref containing the field properties of this field. - -=head3 recordValues - -A hasref containg the values of this record. - -=head3 readOnly - -A boolean indicating the value should be outputted in read only mode. - -=cut - -sub _getFieldValue { - my $self = shift; - my $field = shift; - my $recordValues = shift; - my $readOnly = shift; - - my $i18n = WebGUI::International->new($self->session, 'Asset_SQLForm'); - - my $fieldValue = $self->session->form->process($field->{fieldName}) || $recordValues->{$field->{fieldName}} || $field->{processedDefaultValue}; - - if ($fieldValue && !$readOnly) { -# $fieldValue = $self->session->datetime->setToEpoch($fieldValue) if (isIn($field->{formFieldType}, qw(date dateTime))); - if (isIn($field->{formFieldType}, qw(date dateTime))) { - $fieldValue = '' if $fieldValue eq '0000-00-00'; #undef the value if the date is a mysql null (date will then default to time() ) - $fieldValue = $self->session->datetime->setToEpoch($fieldValue) if $fieldValue; - } - $fieldValue = $self->session->datetime->timeToSeconds($fieldValue) if ($field->{formFieldType} eq 'timeField'); - } - - #### This might break? #### - if ($field->{canHaveMultipleValues}) { - $fieldValue = [ split(/\n/, $recordValues->{$field->{fieldName}}) ]; - $fieldValue = [ $self->session->request->param($field->{fieldName}) ] if (defined $self->session->form->process($field->{fieldName})); - } - - # Handle file uploads - if ($field->{formFieldType} eq 'file') { - unless ($recordValues->{$field->{fieldName}}) { -# $fieldValue .= 'No file uploaded yet'; - } else { - $fieldValue = ''; - if ($recordValues->{'__'.$field->{fieldName}.'_mimeType'} =~ /^image/i) { - $fieldValue .= ''; - } else { - $fieldValue .= $i18n->get('click here for file'); - } - $fieldValue .= ''; - } - } - - return $fieldValue; -} - -#------------------------------------------------------------------- - -=head2 _getFormElement ( field, recordValues, readOnly ) - -Returns the for element tied to this field. - -=head3 field - -A hashref containing the field properties of this field. - -=head3 recordValues - -A hasref containg the values of this record. - -=head3 readOnly - -A boolean indicating the value should be outputted in read only mode. - -=cut - -sub _getFormElement { - my ($fieldValue, $fieldParameters, $maxLength, $fieldType, $formElement, $cmd, $i18n); - my $self = shift; - my $field = shift; - my $recordValues = shift; - my $readOnly = shift || !$self->_canEditRecord || $field->{isReadOnly} || $field->{readOnly} || $field->{useAutoIncrement}; - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - # Get field type and value - $fieldType = $field->{formFieldType}; - $fieldValue = $self->_getFieldValue($field, $recordValues, $readOnly); - - # Resolve value to key in case of read only and key/value pairs - if ($field->{canHaveMultipleValues}) { - $fieldValue = join(', ', @{$field->{allOptions}}{@$fieldValue}) if ($field->{hasOptions} && $readOnly); - }else{ - $fieldValue = $field->{allOptions}->{$fieldValue} if ($field->{hasOptions} && $readOnly); - } - $maxLength = $field->{maxFieldLength} || $allowedDbFieldTypes->{$field->{dbFieldType}}->{maxLength}; - - # Construct the form element - if ($readOnly) { - $formElement = $fieldValue; - } else { - # Set up form element parameters - $fieldParameters->{options} = $field->{options}; - # make sure that previously selected items still appear for this for element, even if - # if is set to a set difference. - if ($fieldValue && $field->{hasOptions}) { - if ($field->{canHaveMultipleValues}) { - @{$fieldParameters->{options}}{@$fieldValue} = @{$field->{allOptions}}{@$fieldValue}; - } else { - $fieldParameters->{options}->{$fieldValue} = $field->{allOptions}->{$fieldValue}; - } - } - $fieldParameters->{options}->{''} = '-leave empty-' if (!$field->{isRequired}); - $fieldParameters->{name} = $field->{fieldName}; - $fieldParameters->{value} = $fieldValue unless ($fieldType eq 'file'); - $fieldParameters->{multiple} = $field->{canHaveMultipleValues} == 1; - $fieldParameters->{$field->{widthParam}} = $field->{formFieldWidth} if ($field->{formFieldWidth}); - $fieldParameters->{$field->{heightParam}} = $field->{formFieldHeight} if ($field->{formFieldHeight}); - $fieldParameters->{maxlength} = $maxLength; - if ($fieldType eq 'textarea') { - $fieldParameters->{extras} = 'onkeyup="if (this.value.length > '.$maxLength.') {this.value = this.value.substring(0,'.$maxLength.');}"'; - } - $fieldParameters->{id} = 'sqlform'.$field->{fieldId}; - - # Show file if a file is uploaded - $formElement = $fieldValue.'
' if ($fieldType eq 'file' && $fieldValue); - - # Add form element - $cmd = 'WebGUI::Form::'.$fieldType.'($self->session, $fieldParameters)'; - $formElement .= eval($cmd); - $self->session->errorHandler->fatal('Could not instanciate formelement via WebGUI::Form: '.$@) if ($@); - - if ($fieldType eq 'selectList' && !$field->{isRequired}) { - $formElement .= WebGUI::Form::button($self->session, { - value => $i18n->get('clear'), - extras => 'onclick="var a =document.getElementById(\'sqlform'.$field->{fieldId}.'\'); for (i=0; i < a.options.length; i++) { a.options[i].selected = false;};"', - }); - } - - # Add file upload controls if necessary - if ($fieldType eq 'file') { - if ($fieldValue) { - $formElement .= WebGUI::Form::radioList($self->session, { - name => '_'.$field->{fieldName}.'_action', - options => { - 'keep' => $i18n->get('keep'), - 'overwrite' => $i18n->get('overwrite'), - 'delete' => $i18n->get('delete'), - }, - value => 'keep', - }); - } else { - $formElement .= WebGUI::Form::hidden($self->session, { - name => '_'.$field->{fieldName}.'_action', - value => 'overwrite', - }); - } - } - } - - return $formElement; -} - -#------------------------------------------------------------------- - -=head2 www_editRecord ( ) - -Generates the record edit form for the record with the id given by the form param 'rid'. Setting rid to 'new' will -cause a new record to be added. If the user is not allowed to edit but can view, this method will output in view -mode, which means that only the contents of the record are shown. The view mode is also initiated when the form -param 'viewOnly' is set to a non-zero value. - -=cut - -sub www_editRecord { - my ($recordId, $fieldType, $canEditRecord, @fields, $properties, $f, $field, @fieldParameters, $cmd, $var, @formLoop, - $formElement, $numberOfFields, $i18n, $recordControls); - my $self = shift; - my $errors = shift || []; - - return $self->session->privilege->insufficient() unless ($self->canView); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - my $dbLink = $self->_getDbLink; - - @fields = $self->session->db->buildArray( - " select distinct t1.fieldId " - ." from SQLForm_fieldDefinitions as t1, SQLForm_fieldOrder as t2 " - ." where t1.fieldId=t2.fieldId and t1.assetId=t2.assetId and t1.assetId=".$self->session->db->quote($self->getId) - ." order by t2.rank"); - - if ($self->session->form->process("rid") eq 'new') { - $recordId = $self->session->form->process("copyRecordId"); - } else { - $recordId = $self->session->form->process("rid"); - } - - if ($recordId) { - $properties = $dbLink->db->quickHashRef("select * from ".$self->get('tableName'). - " where __archived=0 and __recordId=".$self->session->db->quote($recordId)); - return $i18n->get("invalid record id") unless ($properties->{__recordId}); - } else { - $properties = {}; - } - - $canEditRecord = ($self->_canEditRecord && $properties->{__deleted} == 0) ? 1 : 0; - $canEditRecord = 0 if ($self->session->form->process("viewOnly")); - - $f = WebGUI::HTMLForm->new($self->session, - -action => $self->getUrl, - ); - $f->hidden( - -name => 'func', - -value => 'editRecordSave', - ); - $f->hidden( - -name => 'rid', - -value => $self->session->form->process("rid"), - ); - - foreach (@fields) { - $field = $self->_getFieldProperties($_, $properties); - - # Skip 'deleted' columns. - next if ($field->{disabled} || ($self->session->form->process("rid") eq 'new' && $field->{useAutoIncrement})); - - $numberOfFields++; - - # Add element to preconstructed form - my $formElement = $self->_getFormElement($field, $properties, !$canEditRecord); - $f->readOnly( - -label => $field->{displayName}, - -value => $formElement - ); - - my $fieldValue = $self->_getFieldValue($field, $properties, !$canEditRecord); - - # Add element to the form loop - push(@formLoop, { - 'field.label' => $field->{displayName}, - 'field.formElement' => $formElement, - 'field.value' => $fieldValue, - }); - - $var->{'field.'.$field->{fieldName}.'.formElement'} = $formElement; - $var->{'field.'.$field->{fieldName}.'.label'} = $field->{displayName}; - $var->{'field.'.$field->{fieldName}.'.value'} = $fieldValue; - } - - if ($canEditRecord) { - $f->submit; - push(@formLoop, {'field.formElement' => WebGUI::Form::submit($self->session)}); - } - - if ($self->_canEditRecord) { - unless ($properties->{__deleted}) { - $recordControls = $self->session->icon->delete('func=deleteRecord'.';rid='.$properties->{__recordId},$self->get("url"), - $i18n->get('_psq confirm delete message', 'Asset_SQLForm')); - $recordControls .= $self->session->icon->edit('func=editRecord;rid='.$properties->{__recordId},$self->get("url")); - $recordControls .= $self->session->icon->copy('func=editRecord;rid=new;copyRecordId='.$properties->{__recordId},$self->get("url")); - } - - $var->{'record.controls'} = $recordControls; - } - - - $var->{formHeader} = WebGUI::Form::formHeader($self->session). - WebGUI::Form::hidden($self->session, {name=>'func', value=>'editRecordSave'}). - WebGUI::Form::hidden($self->session, {name=>'rid', value=>$self->session->form->process("rid")}); - $var->{formFooter} = WebGUI::Form::formFooter($self->session); - $var->{formLoop} = \@formLoop; - $var->{completeForm} = $f->print; - $var->{errorOccurred} = scalar(@$errors); - $var->{errorLoop} = $errors; - $var->{isNew} = 1 if ($self->session->form->process("rid") eq 'new'); - $var->{'viewHistory.label'} = $i18n->get('view history'); - $var->{'viewHistory.url'} = $self->getUrl('func=viewHistory;rid='.$self->session->form->process("rid")); - $var->{managementLinks} = $self->_getManagementLinks; - - $dbLink->disconnect; - - unless ($numberOfFields) { - return $self->processStyle($i18n->get('no fields defined message').' '.$i18n->get('manage fields title').'.'); - } - - return $self->processStyle($self->processTemplate($var, $self->getValue('editTemplateId'))); -} - -#------------------------------------------------------------------- - -=head2 www_editRecordSave ( ) - -Will process and save the record data inputted in the form generated by www_editRecord. In errors occur they will -be fed back to www_editRecord. Set the record id using the form param 'rid', and use 'new' as id to add a new -record. - -=cut - -sub www_editRecordSave { - my (@fields, $field, $fieldName, @error, @update, $recordId, $lastRevision, $revision, $previousRecord, $value, $i18n); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canEditRecord); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - my $dbLink = $self->_getDbLink; - @fields = $self->session->db->buildArray("select distinct fieldId from SQLForm_fieldDefinitions where assetId=".$self->session->db->quote($self->getId)); -my %regexes = $self->session->db->buildHash("select regex, concat(name, ' (', regex, ')') from SQLForm_regexes"); - -my $now = time; -my ($creationDate, $creator); - - if ($self->session->form->process("rid") eq 'new') { - $recordId = $self->session->id->generate; - $creationDate = $now; - $creator = $self->session->user->userId; - - $revision = 0; - } elsif (defined $self->session->form->process("rid")) { - $recordId = $self->session->form->process("rid"); - ($lastRevision) = $dbLink->db->quickArray('select max(__revision) from '.$self->get('tableName').' where __recordId='.$self->session->db->quote($recordId)); - return $i18n->get('invalid record id') unless (defined $lastRevision); - - $revision = $lastRevision + 1; - $previousRecord = $dbLink->db->quickHashRef("select * from ".$self->get('tableName')." where __archived=0 and __recordId=".$self->session->db->quote($recordId)); - $creationDate = $previousRecord->{__creationDate}; - $creator = $previousRecord->{__createdBy}; - } - - # Set the metadata fields - push(@update, "__creationDate=$creationDate"); - push(@update, "__createdBy=".$self->session->db->quote($creator)); - push(@update, "__revision=$revision"); - push(@update, "__initDate = ".$now); - push(@update, "__userId = ".$self->session->db->quote($self->session->user->userId)); - push(@update, "__recordId = ".$self->session->db->quote($recordId)); - push(@update, "__archived = 0"); - - foreach (@fields) { - $field = $self->_getFieldProperties($_); - $fieldName = $field->{fieldName}; - - # Skip 'deleted' columns. - next if $field->{disabled}; - - # Get field constraint -my $fieldConstraint = undef; - if ($field->{fieldConstraintType} && $field->{fieldConstraintTarget} ne 'value') { -my $sql = $field->{sqlQuery}; - if ($field->{joinConstraintColumn}) { - #### This will still fail if a column is called 'from'. It's better to seperate the join construction - #### from the column selection. Even better would be giving the contraint settings their own join selector. - $sql =~ s/^select .+? from/select $field->{fieldConstraintTarget} from/; - if ($sql =~ / where /) { - $sql .= ' and '; - } else { - $sql .= ' where '; - } - $sql .= $field->{joinConstraintColumn} . ' = ' . - $self->session->db->quote($self->session->form->process($self->_getFieldProperties($field->{joinConstraintField})->{fieldName})); - } - -my @results = $self->session->db->quickArray($sql); - $fieldConstraint = $results[0]; - } - - # Process autoincrement fields. - if ($field->{useAutoIncrement}) { - if ($revision == 0 || $previousRecord->{$fieldName} eq '') { - ($value) = $dbLink->db->quickArray("select max($fieldName) + 1 from ".$self->get('tableName')); - $value = 0 unless $value; - } else { - $value = $previousRecord->{$fieldName}; - } - push (@update, "$fieldName = ".$self->session->db->quote($value)); - # Process timestamp fields. - } elsif ($field->{dbFieldType} eq 'timestamp') { - push (@update, "$fieldName = now()"); - } elsif ($field->{isReadOnly}) { - push (@update, "$fieldName =".$self->session->db->quote($field->{processedDefaultValue})); - # Process file uploads. - } elsif ($field->{formFieldType} eq 'file') { - if ($self->session->form->process('_'.$fieldName.'_action') eq 'keep') { - push(@update, "$fieldName = ".$self->session->db->quote($previousRecord->{$fieldName})); - push(@update, "__".$fieldName."_mimeType=".$self->session->db->quote($previousRecord->{"__".$fieldName."_mimeType"})); - } elsif ($self->session->form->process('_'.$fieldName.'_action') eq 'overwrite' && $self->session->form->process($fieldName . '_file')) { - require Apache2::Request; - require Apache2::Upload; - - # Get Apache2::Upload object - my $upload = $self->session->request->upload($fieldName . '_file'); - - # Check file size - my $maxFileSize = ($self->get('maxFileSize') > $self->session->setting->get("maxAttachmentSize")) ? - $self->session->setting->get("maxAttachmentSize") : $self->get('maxFileSize'); - if ($upload->size > $maxFileSize * 1024) { - push(@error, $i18n->get('ers file too large')); - } else { - my $fileType = $upload->type; - my $fileContents = ''; - - # Slurp file into scalar for use in query. Blocked reads will save memory, but then you - # have to stream the data, which is not possible in mysql queries as far as I know. - $upload->slurp($fileContents); - - # Include file content and mime type in query. - push(@update, "$fieldName = ".$self->session->db->quote($fileContents)); - push(@update, "__".$fieldName."_mimeType=".$self->session->db->quote($fileType)); - } - } else { - push(@error, $i18n->get('ers field required').' '.$field->{displayName}) if ($field->{isRequired}); - } - # Throw error if field is required and empty. - } elsif ($self->session->form->process($fieldName) eq '' && $field->{isRequired}) { - push(@error, $i18n->get('ers field required').' '.$field->{displayName}) if ($field->{isRequired}); - # Process other fields. - } else { - # Get input in correct format. -my $fieldValue; - if (defined $self->session->form->process($fieldName)) { -my $cmd = '$self->session->form->'.$field->{formFieldType}.'($fieldName)'; - $fieldValue = eval($cmd); #$self->session->form->process($fieldName) - - if ($field->{formFieldType} eq 'dateTime' && $field->{dbFieldType} eq 'datetime') { - $fieldValue = $self->session->form->process($fieldName); - } - if ($field->{formFieldType} eq 'date' && $field->{dbFieldType} eq 'date') { - $fieldValue = $self->session->form->process($fieldName); - } - if ($field->{formFieldType} eq 'timeField' && $field->{dbFieldType} eq 'time') { - $fieldValue = $self->session->form->process($fieldName); - } - } else { - $fieldValue = $field->{processedDefaultValue}; - } - - # Check if input matches its regex - if ($self->session->form->process($fieldName) eq '' && !$field->{isRequired} || - _matchField($self, $self->session->form->process($fieldName), $field->{regex})) { - push(@update, "$fieldName = ".$self->session->db->quote($fieldValue)); - } else { - push(@error, $i18n->get('ers regex mismatch').' '.$regexes{$field->{regex}}.' '.$field->{displayName}); - } - - # Check if input is of allowed length. - if ($field->{maxLength} && length($fieldValue) > $field->{maxLength}) { - push (@error, $i18n->get('ers too long').' '.$field->{maxLength}.' '.$field->{displayName}); - } - - # Check if input is in compliance with field constraint - if ($field->{fieldConstraintType}) { -my $result = 1; -my $fieldValueCompare = $fieldValue; - if ($field->{formFieldType} eq 'dateTime' || $field->{formFieldType} eq 'date') { - $fieldValueCompare = $self->session->datetime->setToEpoch($self->session->form->process($fieldName)); - $fieldConstraint = $self->session->datetime->setToEpoch($fieldConstraint); - } - if ($field->{formFieldType} eq 'timeField'){ - $fieldValueCompare = $self->session->datetime->timeToSeconds($self->session->form->process($fieldName)); - $fieldConstraint = $self->session->datetime->timeToSeconds($fieldConstraint); - } - -my $cmd = '$result = 0 if ($fieldValueCompare '.$self->_resolveFieldConstraintType($field->{fieldConstraintType}).' $fieldConstraint)'; - eval($cmd); - - push(@error, $i18n->get('ers value not allowed').' '.$field->{displayName}) if $result; - } - - # Check if input is within field range - if ($allowedDbFieldTypes->{$field->{dbFieldType}}->{maxValue}) { - my $maxValue = ($field->{signed}) ? $allowedDbFieldTypes->{$field->{dbFieldType}}->{maxValue} : $allowedDbFieldTypes->{$field->{dbFieldType}}->{maxValueUnsigned}; - my $minValue = ($field->{signed}) ? $allowedDbFieldTypes->{$field->{dbFieldType}}->{minValue} : 0; - if ($self->session->form->process($fieldName) > $maxValue || $self->session->form->process($fieldName) < $minValue) { - push (@error, $i18n->get('ers out of range').' '.$field->{displayName}); - } - } - } - } - - # Return with a list of errors if there are any. - if (@error) { - return $self->www_editRecord([ map {{'error.message'=>$_}} @error ]); - return "'; - } - - # In case of no errors write the new values to a new version. - if (@update) { - $dbLink->db->write('update '.$self->get('tableName').' set __archived=1 where __recordId='.$self->session->db->quote($recordId)); - $dbLink->db->write('insert into '.$self->get('tableName').' set '.join(', ', @update)); - } - - $dbLink->disconnect; - - # Send an email notification. - if ($self->get('sendMailTo')) { - my $mail = WebGUI::Mail::Send->create($self->session, { - to => $self->get('sendMailTo'), - subject => $i18n->get('ers change notification'), - }); - $mail->addText($i18n->get('ers change on table').' '.$self->get('tableName'). - ' '.$i18n->get('ers by user').' '.$self->session->user->username."\n". - $i18n->get('ers view url').' '.$self->getUrl('func=editRecord;rid='.$recordId) - ); - $mail->queue; - } - - return $self->www_view; -} - -#------------------------------------------------------------------- - -=head2 www_editRegex ( ) - -Returns the form for editing regexes. Pass the id of the regex you want to edit in the form param 'regexId'. To -add a new regex pass 'new' for the regex id. - -=cut - -sub www_editRegex { - my ($output, $properties, $f, $i18n); - my $self = shift; - my $errors = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - if ($errors) { - $output = ''.$i18n->get('er error message').''; - } - - if ($self->session->form->process("regexId") eq 'new') { - $properties = {}; - } else { - $properties = $self->session->db->quickHashRef('select * from SQLForm_regexes where regexId='.$self->session->db->quote($self->session->form->process("regexId"))); - } - - $f = WebGUI::HTMLForm->new($self->session, - -action => $self->getUrl - ); - $f->hidden( - -name => 'func', - -value => 'editRegexSave', - ); - $f->hidden( - -name => 'regexId', - -value => $self->session->form->process("regexId"), - ); - $f->readOnly( - -label => 'Id', - -value => $self->session->form->process("regexId"), - ); - $f->text( - -name => 'name', - -label => $i18n->get('er name'), - -hoverHelp => $i18n->get('er name description'), - -value => $self->session->form->process("name") || $properties->{name}, - ); - $f->text( - -name => 'regex', - -label => $i18n->get('er regex'), - -hoverHelp => $i18n->get('er regex description'), - -value => $self->session->form->process("regex")|| $properties->{regex}, - -size => 30, - ); - $f->readOnly( - -value => - WebGUI::Form::submit($self->session). - WebGUI::Form::button($self->session, { - value => $i18n->get('cancel'), - extras => 'onClick="location.href=\''.$self->getUrl('func=listRegexes').'\'"' - }) - ); - - return $self->getAdminConsoleWithSubmenu->render($f->print, $i18n->get('edit regex title')); -} - -#------------------------------------------------------------------- - -=head2 www_editRegexSave ( ) - -Saves the regex properties entered in the form generated by www_editRegex to the database. Pass the regex id -in the form param 'regexId'. Set the id to 'new' to add a regex. - -=cut - -sub www_editRegexSave { - my (@error, $regexId, $i18n); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - push(@error, $i18n->get('ers no name')) unless ($self->session->form->process("name")); - push(@error, $i18n->get('ers no regex')) unless ($self->session->form->process("regex")); - - return $i18n->get('er error message').''.$self->www_editRegex if (@error); - - if ($self->session->form->process("regexId") eq 'new') { - $regexId = $self->session->id->generate(); - $self->session->db->write("insert into SQLForm_regexes set ". - " regexId=".$self->session->db->quote($regexId).", name=".$self->session->db->quote($self->session->form->process("name")).", regex=".$self->session->db->quote($self->session->form->process("regex"))); - } elsif ($self->session->form->process("regexId")) { - $regexId = $self->session->form->process("regexId"); - $self->session->db->write("update SQLForm_regexes set ". - "name=".$self->session->db->quote($self->session->form->process("name")).", regex=".$self->session->db->quote($self->session->form->process("regex"))." where regexId=".$self->session->db->quote($self->session->form->process("regexId"))); - } - - return $self->www_listRegexes; -} - -#------------------------------------------------------------------- - -=head2 www_listFields ( ) - -Shows the list of fields, including edit and delete buttons. - -=cut - -sub www_listFields { - my (@fields, $output, $thisField, $fieldTypesDefined, $i18n); - my $self = shift; - - return $self->session->privilege->insufficient unless ($self->_canAlterTable); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - -# $output = '

'.$self->get('title').'

' if $self->get('displayTitle'); - $output .= $self->_getManagementLinks.'
'; - - ($fieldTypesDefined) = $self->session->db->quickArray("select count(*) from SQLForm_fieldTypes"); - unless ($fieldTypesDefined) { - return $self->processStyle($output. - $i18n->get('no field types message').' '.''.$i18n->get('manage field types').'.' - ); - } - - - @fields = $self->session->db->buildArray( - " select fieldId " - ." from SQLForm_fieldOrder " - ." where assetId=".$self->session->db->quote($self->getId) - ." order by rank" - ); - - $output .= ''; - foreach (@fields) { - $thisField = $self->_getFieldProperties($_); - $output .= ''; - $output .= '' unless ($thisField->{disabled}); - $output .= '' if ($thisField->{disabled}); - $output .= ''; - $output .= ''; - $output .= ''; - $output .= ''; - $output .= ''; - } - $output .= '
'.$self->session->icon->delete('func=disableField;fid='.$_).''.'Undelete'.''.$self->session->icon->moveDown('func=moveFieldDown;fid='.$_).''.$self->session->icon->moveUp('func=moveFieldUp;fid='.$_).''.$self->session->icon->edit('func=editField;fid='.$_, $self->get("url")).''.$thisField->{fieldName}." (".$thisField->{displayName}.")".'
'; - - $output .= '
'.$i18n->get('lf add field').''; - - return $self->getAdminConsoleWithSubmenu->render($output, $i18n->get('manage fields title')); -} - -#------------------------------------------------------------------- - -=head2 www_listFieldTypes ( ) - -Shows the list of field types. - -=cut - -sub www_listFieldTypes { - my ($sth, $row, $output, $i18n); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - -# $output = '

'.$self->get('title').'

' if $self->get('displayTitle'); - $output .= $self->_getManagementLinks.'
'; - - $sth = $self->session->db->read("select * from SQLForm_fieldTypes order by dbFieldType"); - -my $js = "function toggleList(id) {\n" - ."\tvar a = document.getElementById(id);\n" - ."\tif (a.style.display == 'none') {\n" - ."\t\ta.style.display = ''\n" - ."\t} else { \n" - ."\t\ta.style.display = 'none'\n" - ."\t}\n" - ."}"; - -my (@usedTypes, @unusedTypes); - while ($row = $sth->hashRef) { -my $assetsUsing = $self->session->db->read( - ' select distinct t2.url, t2.title, t1.fieldId, t3.value '. - ' from SQLForm_fieldDefinitions as t1, assetData as t2, SQLForm_fieldDefinitions as t3 '. - ' where t1.assetId=t2.assetId and '. - ' t1.fieldId=t3.fieldId and t3.property="fieldName" and '. - ' t1.property="fieldType" and t1.value='.$self->session->db->quote($row->{fieldTypeId})); -my $currentRow = ''; - $currentRow .= ""; - $currentRow .= $self->session->icon->delete('func=deleteFieldType;ftid='.$row->{fieldTypeId}, $self->get('url'), $i18n->get('lft delete confirm message')) unless ($assetsUsing->rows); - $currentRow .= ""; - - $currentRow .= "".$row->{dbFieldType}."".$row->{formFieldType}.""; - if ($assetsUsing->rows) { - $currentRow .= ''; - $currentRow .= '' - .$i18n->get('lft show assets using').''; - $currentRow .= ''.''; - push(@usedTypes, $currentRow); - } else { - $currentRow .= ""; - push(@unusedTypes, $currentRow); - } - } - - $output .= ''; - $output .= ''; - $output .= ''; - $output .= ''; - $output .= join('',@unusedTypes); - $output .= ''; - $output .= ''; - $output .= join('',@usedTypes); - $output .= '

'.$i18n->get('lft unused field types').'

'.$i18n->get('lft db type').''.$i18n->get('lft form type').'

'.$i18n->get('lft used field types').'

'.$i18n->get('lft db type').''.$i18n->get('lft form type').'
'; - $output .= ''.$i18n->get('lft add field type').''; - - return $self->getAdminConsoleWithSubmenu->render($output,$i18n->get('manage field types title')); -} - -#------------------------------------------------------------------- - -=head2 www_listRegexes ( ) - -Displays the list of regexes. - -=cut - -sub www_listRegexes { - my ($sth, $row, $output, $i18n); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - -# $output = '

'.$self->get('title').'

' if $self->get('displayTitle'); - $output .= $self->_getManagementLinks.'
'; - - $sth = $self->session->db->read("select * from SQLForm_regexes order by name"); - -my $js = "function toggleList(id) {\n" - ."\tvar a = document.getElementById(id);\n" - ."\tif (a.style.display == 'none') {\n" - ."\t\ta.style.display = ''\n" - ."\t} else { \n" - ."\t\ta.style.display = 'none'\n" - ."\t}\n" - ."}"; - -my (@usedTypes, @unusedTypes); - while ($row = $sth->hashRef) { -my $assetsUsing = $self->session->db->read( - ' select distinct t2.url, t2.title, t1.fieldId, t3.value '. - ' from SQLForm_fieldDefinitions as t1, assetData as t2, SQLForm_fieldDefinitions as t3 '. - ' where t1.assetId=t2.assetId and '. - ' t1.fieldId=t3.fieldId and t3.property="fieldName" and '. - ' t1.property="regex" and t1.value='.$self->session->db->quote($row->{regexId})); -my $currentRow = ''; - $currentRow .= ""; - $currentRow .= $self->session->icon->delete('func=deleteRegex;regexId='.$row->{regexId}, $self->get('url'), 'Are you sure?') unless ($assetsUsing->rows); - $currentRow .= ""; - - $currentRow .= "".$row->{name}."".$row->{regex}.""; - if ($assetsUsing->rows) { - $currentRow .= ''; - $currentRow .= '' - .$i18n->get('lr show assets using').''; - $currentRow .= ''.''; - push(@usedTypes, $currentRow); - } else { - $currentRow .= ""; - push(@unusedTypes, $currentRow); - } - } - - $output .= ''; - $output .= ''; - $output .= ''; - $output .= ''; - $output .= join('',@unusedTypes); - $output .= ''; - $output .= ''; - $output .= join('',@usedTypes); - $output .= '

'.$i18n->get('lr unused regexes').'

'.$i18n->get('lr name').''.$i18n->get('lr regex').'

'.$i18n->get('lr used regexes').'

'.$i18n->get('lr name').''.$i18n->get('lr regex').'
'; - $output .= ''.$i18n->get('lr add regex').''; - - return $self->getAdminConsoleWithSubmenu->render($output,$i18n->get('manage regexes title')); -} - -#------------------------------------------------------------------- - -=head2 www_moveFieldDown ( ) - -Moves the field one position to the end in the field ordering. The field id should be passed in the form param 'fid'. - -=cut - -sub www_moveFieldDown { - my (@fieldOrder, $currentField, $i, $nextField); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - @fieldOrder = $self->session->db->buildArray('select fieldId from SQLForm_fieldOrder where assetId = '.$self->session->db->quote($self->getId).' order by rank'); - $currentField = $self->session->form->process("fid"); - - for ($i = 0; $i < scalar(@fieldOrder); $i++) { - if ($fieldOrder[$i] eq $currentField && $i < (scalar(@fieldOrder) - 1)) { - $nextField = $fieldOrder[$i + 1]; - last; - } - } - - if ($nextField) { - $self->session->db->write('update SQLForm_fieldOrder set rank = rank + 1 where assetId='.$self->session->db->quote($self->getId).' and fieldId='.$self->session->db->quote($currentField)); - $self->session->db->write('update SQLForm_fieldOrder set rank = rank - 1 where assetId='.$self->session->db->quote($self->getId).' and fieldId='.$self->session->db->quote($nextField)); - } - - return $self->www_listFields; -} - -#------------------------------------------------------------------- - -=head2 www_moveFieldUp ( ) - -Moves the field one position to the beginning in the field ordering. The field id should be passed in the form param 'fid'. - -=cut - -sub www_moveFieldUp { - my (@fieldOrder, $currentField, $i, $previousField); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canAlterTable); - - @fieldOrder = $self->session->db->buildArray('select fieldId from SQLForm_fieldOrder where assetId = '.$self->session->db->quote($self->getId).' order by rank'); - $currentField = $self->session->form->process("fid"); - - for ($i = 0; $i < scalar(@fieldOrder); $i++) { - if ($fieldOrder[$i] eq $currentField) { - $previousField = $fieldOrder[$i - 1]; - last; - } - } - - if ($i > 0 && $previousField) { - $self->session->db->write('update SQLForm_fieldOrder set rank = rank - 1 where assetId='.$self->session->db->quote($self->getId).' and fieldId='.$self->session->db->quote($currentField)); - $self->session->db->write('update SQLForm_fieldOrder set rank = rank + 1 where assetId='.$self->session->db->quote($self->getId).' and fieldId='.$self->session->db->quote($previousField)); - } - - return $self->www_listFields; -} - -#------------------------------------------------------------------- - -=head2 www_purgeRecord ( ) - -Will purge a record from the record trash. The id of the record must be passed in form param 'rid'. - -=cut - -sub www_purgeRecord { - my (@recordIds, $whereClause, $dbLink); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canPurge); - - @recordIds = $self->session->request->param('rid'); - $whereClause = join(' or ', map {'__recordId = '.$self->session->db->quote($_)} @recordIds); - - $dbLink = $self->_getDbLink; - $dbLink->db->write("delete from ".$self->get('tableName')." where $whereClause") if ($whereClause); - $dbLink->disconnect; - - return $self->processStyle($self->www_search); -} - -#------------------------------------------------------------------- - -=head2 www_purgeTrash ( ) - -Purges every record that is in the record trash. - -=cut - -sub www_purgeTrash { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canPurge); - - my $dbLink = $self->_getDbLink; - $dbLink->db->write('delete from '.$self->get('tableName').' where __deleted=1'); - $dbLink->disconnect; - - return $self->processStyle($self->www_search); -} - -#------------------------------------------------------------------- - -=head2 www_viewHistory ( ) - -Shows the history of a record. The record id should be passed through the form param 'rid'. - -=cut - -sub www_viewHistory { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->canView); - - my $dbLink = $self->_getDbLink; - my $recordId = $self->session->form->process('rid'); - - my @includeMetaFields = qw|__recordId __initDate __userId __revision|; - my @metaFieldHeadings = ("Record ID", "Changed on", "Changed by", "Revision #"); - - my @fieldIds = $self->session->db->buildArray( - " select fieldId " - ." from SQLForm_fieldOrder " - ." where assetId=".$self->session->db->quote($self->getId) - ." order by rank" - ); - - my $tableHeading = ''.join('', (@metaFieldHeadings, map {$self->_getFieldProperties($_)->{displayName}} @fieldIds)).''; - - my $sth = $dbLink->db->read('select * from '.$self->get('tableName').' where __recordId='.$dbLink->db->quote($recordId).' order by __revision'); - - my ($tableBody); - while (my $row = $sth->hashRef) { - $row->{__initDate} = $self->session->datetime->epochToHuman($row->{__initDate}); - $row->{__userId} = WebGUI::User->new($self->session, $row->{__userId})->username; - $tableBody .= ''; - $tableBody .= ''.join('', map {$row->{$_}} @includeMetaFields).''; - - foreach (@fieldIds) { - my $field = $self->_getFieldProperties($_); - $tableBody .= ''; - if ($field->{formFieldType} eq 'file') { - $tableBody .= ''; - if ($row->{'__'.$field->{fieldName}.'_mimeType'} =~ /^image/) { - $tableBody .= ''; - } else { - $tableBody .= 'Click here for file.'; - } - $tableBody .= ''; - } else { - if ($field->{hasOptions}) { - $tableBody .= $field->{allOptions}->{$row->{$field->{fieldName}}}; - } else { - $tableBody .= $row->{$field->{fieldName}}; - } - } - $tableBody .= ''; - } - $tableBody .= ''; - } - - my $output = $self->_getManagementLinks; - $output .= ''; - $output .= ''; - $output .= $tableHeading; - $output .= $tableBody; - $output .= '
'; - - $dbLink->disconnect; - return $self->processStyle($output); -} - -#------------------------------------------------------------------- - -=head2 www_viewFile ( ) - -Returns the file saved in a file upload field, and sets the mime-type to the correct value. Pass the record id -via form param 'rid' and the field id of the upload field through form param 'fid'. Optionally you can pass the -revision number in form param 'rev'; otherwise the latest revision is used. - -=cut - -sub www_viewFile { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->canView); - - my $fieldId = $self->session->form->process('fid'); - my $recordId = $self->session->form->process('rid'); - my $revision = $self->session->form->process('rev'); - - my $field = $self->_getFieldProperties($fieldId); - - if ($field->{formFieldType} eq 'file') { - my ($mimeType, $data) = $self->_getFileFromDatabase($recordId, $field->{fieldName}, $revision); - $self->session->http->setMimeType($mimeType); - - return $data; - } - - return "No file found"; -} - -#------------------------------------------------------------------- - -=head2 www_viewThumbnail ( ) - -Returns a thumbnail of the image stored in an upload field. - -This particular caching scheme is used in stead of storage, since privileges should still be checked. - -=cut - -sub www_viewThumbnail { - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->canView); - - my $fieldId = $self->session->form->process('fid'); - my $recordId = $self->session->form->process('rid'); - my $revision = $self->session->form->process('rev'); - my $field = $self->_getFieldProperties($self->session->form->process("fid")); - - if ($field->{formFieldType} eq 'file') { - my $cache = WebGUI::Cache->new($self->session, ["sqlform",$recordId,$fieldId,$revision], 24*60*60); - - my $thumbnailData = $cache->get; - - unless ($thumbnailData) { - my ($mimeType, $data) = $self->_getFileFromDatabase($recordId, $field->{fieldName}, $revision); - - # Create thumbnail. I use this method b/c it seems to be impossible to feed - # image magick scalars containing pictures. Even using IO::Scalar or PerlIO::Scalar. - # This is b/c Image::Magick cannot handle perl GLOBS. - my $tempStorage = WebGUI::Storage::Image->createTemp($self->session); - $tempStorage->addFileFromScalar('tempthumb.png', $data); - $tempStorage->generateThumbnail('tempthumb.png', 100); - - open my $FH1, "<", $tempStorage->getPath().'/thumb-tempthumb.png'; - while (<$FH1>) { - $thumbnailData .= $_; - } - close $FH1; - - $tempStorage->delete; - $cache->set($thumbnailData); - } - - $self->session->http->setMimeType('image/png'); - - return $thumbnailData; - } - - return "No file found"; -} - - -#------------------------------------------------------------------- - -=head2 www_restoreRecord ( ) - -Restores a record in the record trash. Pass the record id through for param 'rid'. - -=cut - -sub www_restoreRecord { - my ($dbLink, @recordIds, $whereClause); - my $self = shift; - - return $self->session->privilege->insufficient() unless ($self->_canEditRecord); - - @recordIds = $self->session->request->param('rid'); - $whereClause = join(' or ', map {'__recordId = '.$self->session->db->quote($_)} @recordIds); - - $dbLink = $self->_getDbLink; - $dbLink->db->write("update ".$self->get('tableName')." set ". - " __deleted=0,". - " __deletionDate=NULL,". - " __deletedBy=NULL". - " where $whereClause" - ) if ($whereClause); - $dbLink->disconnect; - - return $self->www_view; -} - -#------------------------------------------------------------------- - -=head2 www_search ( ) - -Generates the normal search form. - -=cut - -sub www_search { - my (%searchableFields, @showFields, $query, $searchInTrash, @searchIn, $f, $output, %fieldProperties, - $useRegex, $sortColumn, $sortAscending, $recordControls, $queryLike, - %row, $sth, @headerLoop, $var, @recordLoop, %searchInTrashOptions, $i18n); - my $self = shift; - my $error = shift; - - return $self->session->privilege->insufficient() unless ($self->canView); - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - my $dbLink = $self->_getDbLink; - - # Get field properties; - tie %searchableFields, "Tie::IxHash"; -my @fields = $self->session->db->buildArray("select distinct fieldId from SQLForm_fieldOrder where assetId=".$self->session->db->quote($self->getId)." order by rank"); - - # if this is a form submission, delete everything from scratch - if ($self->session->form->get('searchMode') || $self->session->form->get('searchType')) { - $self->_clearScratch(\@fields); - } - - foreach (@fields) { - $fieldProperties{$_} = $self->_getFieldProperties($_); - unless ($fieldProperties{$_}->{disabled}) { - $searchableFields{$_} = $fieldProperties{$_}->{displayName} if $fieldProperties{$_}->{isSearchable}; - push(@showFields, $_) if $fieldProperties{$_}->{showInSearchResults}; - } - } - - $var->{showFieldsDefined} = 1 if (@showFields); - - # Set up search parameters -# @searchIn = @{Storable::thaw($self->session->scratch->get('SQLForm_'.$self->getId.'searchIn'))} if (defined $self->session->scratch->get('SQLForm_'.$self->getId.'searchIn')); - @searchIn = $self->session->form->checkList('searchIn') if (defined $self->session->form->process("searchIn")); - @searchIn = split(/\n/,$self->session->scratch->get('SQLForm_'.$self->getId.'searchIn')) unless (defined $self->session->form->process("searchIn")); - @searchIn = keys(%searchableFields) unless (@searchIn); - - $query = $self->session->form->process("searchQuery"); - $query = $self->session->scratch->get('SQLForm_'.$self->getId.'query') unless ($query); - - $useRegex = $self->session->form->process("searchMode"); - $useRegex = $self->session->scratch->get('SQLForm_'.$self->getId.'searchMode') unless (defined $self->session->form->process("useRegex")); - $useRegex ||= 'normal'; - - $searchInTrash = $self->session->form->process("searchInTrash"); - $searchInTrash = $self->session->scratch->get('SQLForm_'.$self->getId.'searchInTrash') unless (defined $self->session->form->process("searchInTrash")); - $searchInTrash ||= '0'; - - $sortColumn = $self->session->form->process("sortColumn"); - $sortColumn = $self->session->scratch->get('SQLForm_'.$self->getId.'sortColumn') unless ($sortColumn); - - $sortAscending = $self->session->form->process("sortAscending"); - $sortAscending = $self->session->scratch->get('SQLForm_'.$self->getId.'sortAscending') unless (defined $self->session->form->process("sortAscending")); - - # Save search parameters - $self->session->scratch->set('SQLForm_'.$self->getId.'searchIn', join("\n", @searchIn)) if (@searchIn); - $self->session->scratch->set('SQLForm_'.$self->getId.'query', $query); - $self->session->scratch->set('SQLForm_'.$self->getId.'searchMode', $useRegex); - $self->session->scratch->set('SQLForm_'.$self->getId.'searchInTrash', $searchInTrash); - $self->session->scratch->set('SQLForm_'.$self->getId.'searchType', 'or'); - - tie %searchInTrashOptions, "Tie::IxHash"; - %searchInTrashOptions = (0 => 'Only normal', 1 => 'Only trash', 2 => 'Normal and trash'); - - my $elementCounter = 0; - my $searchInFormElement = ''; - foreach (keys %searchableFields) { - $elementCounter++; - $searchInFormElement .= '"; - $searchInFormElement .= '' if ($elementCounter % 2 == 0); - } - $searchInFormElement .= '
'; - $searchInFormElement .= WebGUI::Form::Checkbox($self->session, { - -name => 'searchIn', - -value => $_, - -checked=> WebGUI::Utility::isIn($_, @searchIn), - }); - $searchInFormElement .= " $searchableFields{$_}
'; - $searchInFormElement .= ' All'; - $searchInFormElement .= '
'; - - $f = WebGUI::HTMLForm->new($self->session, - -action => $self->getUrl - ); - $f->hidden( - -name => 'func', - -value => 'search', - ); - $f->hidden( - -name => 'searchType', - -value => 'or', - ); - $f->text( - -name => 'searchQuery', - -label => $i18n->get('s query'), - -value => $query, - ); - $f->radioList( - -name => 'searchMode', - -label => $i18n->get('s mode'), - -value => $useRegex , - -options=> {'normal' => 'Normal search', 'regexp' => 'Regex search'}, - ); - $f->readOnly( - -label => $i18n->get('s search in fields'), - -value => $searchInFormElement, - ); - $f->radioList( - -name => 'searchInTrash', - -label => $i18n->get('s location'), - -options=> \%searchInTrashOptions, - -value => $searchInTrash, - ); - $f->submit( - -value => $i18n->get('s search button'), - ); - - $var->{searchForm} = qq| - |.$f->print; - - foreach (@showFields) { - $fieldProperties{$_} = $self->_getFieldProperties($_); - push(@headerLoop, { - 'header.title' => $fieldProperties{$_}->{displayName}, - 'header.sort.url' => $self->getUrl('func=search;sortColumn='.$_.';sortAscending='.($sortAscending ? '0' : '1')), - 'header.sort.onThis' => ($sortColumn eq $_), - 'header.sort.ascending' => $sortAscending, - }); - } - - $var->{'headerLoop'} = \@headerLoop; - - $var->{searchFormHeader} = WebGUI::Form::formHeader($self->session, - {action => $self->getUrl}). - WebGUI::Form::hidden($self->session, {name=>'func', value=>'search'}). - WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'or'}); - - $var->{'searchFormQuery.label'} = $i18n->get('s query'); - $var->{'searchFormQuery.form'} = WebGUI::Form::text($self->session,{ - name=>'searchQuery', - value=>$query - }); - $var->{'searchFormMode.label'} = $i18n->get('s mode'); - $var->{'searchFormMode.form'} = WebGUI::Form::radioList($self->session,{ - name=>'searchMode', - value=>$useRegex, - options=> {'normal' => 'Normal search', 'regexp' => 'Regex search'}, - }); - $var->{'searchFormSearchIn.label'} = $i18n->get('s search in fields'); - $var->{'searchFormSearchIn.form'} = WebGUI::Form::checkList($self->session,{ - name=>'searchIn', - value=>\@searchIn, - options=> \%searchableFields, - }); - $var->{'searchFormTrash.label'} = $i18n->get('s location'); - $var->{'searchFormTrash.form'} = WebGUI::Form::radioList($self->session,{ - name=>'searchInTrash', - value=>$searchInTrash, - options=> \%searchInTrashOptions, - }); - $var->{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => $i18n->get('s search button')}); - $var->{searchFormFooter} = WebGUI::Form::formFooter($self->session); - - if (@searchIn && ($query || $searchInTrash)) { -my $sql = $self->_constructSearchQuery(\@searchIn, \@showFields, \%fieldProperties, $query); - - if ($sql) { - # Execute query - $sth = $dbLink->db->unconditionalRead($sql); - - # Handle invalid queries - push(@$error, $i18n->get('s query error').' '. $sth->errorMessage) unless ($sth->errorCode < 1); - - $var->{'searchResults.recordLoop'} = $self->_processSearchQuery($sth, \@showFields, \%fieldProperties); - } - } - - $var->{'superSearch.url'} = $self->getUrl('func=superSearch'); - $var->{'superSearch.label'} = $i18n->get('s advanced search'); - $var->{'normalSearch.url'} = $self->getUrl('func=search'); - $var->{'normalSearch.label'} = $i18n->get('s normal search'); - - $var->{'searchResults.header'} = WebGUI::Form::formHeader($self->session). - WebGUI::Form::hidden($self->session, {name=>'func',value=>'', id=>'SearchResultsAction'}); - $var->{'searchResults.footer'} = WebGUI::Form::formFooter($self->session); - $var->{'searchResults.actionButtons'} = - WebGUI::Form::button($self->session, { - value => $i18n->get('s restore'), - extras => "onclick=\"document.getElementById('SearchResultsAction').value='restoreRecord'; this.form.submit();\"", - }). - WebGUI::Form::button($self->session, { - value => $i18n->get('s purge'), - extras => "onclick=\"document.getElementById('SearchResultsAction').value='purgeRecord'; this.form.submit();\"", - }) if ($searchInTrash); - - $var->{showMetaData} = $self->get('showMetaData'); - $var->{managementLinks} = $self->_getManagementLinks; - $var->{errorOccurred} = defined $error; - $var->{errorLoop} = [ map {{'error.message' => $_}} @$error ]; - - $dbLink->disconnect; - - # Only process style if search is called directly; - return $self->processTemplate($var, $self->getValue('searchTemplateId')) unless ($self->session->form->process("func") eq 'search'); - return $self->processStyle($self->processTemplate($var, $self->getValue('searchTemplateId'))); -} - -#------------------------------------------------------------------- - -=head2 www_processAjaxRequest ( ) - -Returns an XML string containing database information, depending on the form params passed. If you pass a database -name in form param 'dbName' only, this method will return an XML string containing the tables available within that -database. If you also pass a table name through form param 'tName' an XML string containing the columns in that table -are returned. - -Format of the XML must follow the next convention: - - - - - - ...etc... - - - -=cut - -sub www_processAjaxRequest { - my $self = shift; - - my $dbLink = $self->_getDbLink; - return $self->session->privilege->insufficient unless $self->_canAlterTable; - - $self->session->http->setMimeType('text/xml'); - -my $xml = "\n"; - - if (isIn($self->session->form->process("dbName"), $dbLink->db->buildArray('show databases'))) { - -my @zut; - if ($self->session->form->process("tName") && isIn($self->session->form->process("tName"), $dbLink->db->buildArray('show tables from '.$self->session->form->process("dbName")))) { - @zut = $dbLink->db->buildArray('describe '.$self->session->form->process("dbName").'.'.$self->session->form->process("tName")); - } else { - @zut = $dbLink->db->buildArray('show tables from '.$self->session->form->process("dbName")); - } - - foreach (@zut) { - $xml .= "\t\n"; - } - } - - $xml .= ""; - - return $xml; -} - -#------------------------------------------------------------------- - -=head2 _constructSearchForm ( fieldList, fieldProperties ) - -Returns the form for super search. - -=head3 fieldList - -Arrayref containing the field that should be included in the search. - -=head3 fieldProperties - -Hashref containing the properties of the fields that are in the search. - -=cut - -sub _constructSearchForm { - my ($form, $js, %searchInTrashOptions, $i18n); - my $self = shift; - my $var = shift; - my $fieldList = shift; - my $fieldProperties = shift; - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - tie %searchInTrashOptions, "Tie::IxHash"; - %searchInTrashOptions = ( - 0 => $i18n->get('_csf only normal'), - 1 => $i18n->get('_csf only trash'), - 2 => $i18n->get('_csf normal and trash') - ); - -my $searchType = $self->session->form->process("searchType") || $self->session->scratch->get('SQLForm_'.$self->getId.'searchType') || 'or'; - -my $searchInTrash = $self->session->form->process("searchInTrash"); - $searchInTrash = $self->session->scratch->get('SQLForm_'.$self->getId.'searchInTrash') unless (defined $self->session->form->process("searchInTrash")); - $searchInTrash ||= '0'; - - $var->{searchFormHeader} = WebGUI::Form::formHeader($self->session ,{action => $self->getUrl}); - $var->{searchFormHeader} .= WebGUI::Form::hidden($self->session, {name => 'func', value => 'superSearch'}); - $var->{searchFormHeader} .= WebGUI::Form::hidden($self->session, {name => 'searchQueried', value => 1}); - - $form = $var->{searchFormHeader}; - $form .= ''; - $form .= ''; - - $var->{'searchFormTrash.label'} = $i18n->get('s location'); - $var->{'searchFormTrash.form'} = WebGUI::Form::radioList($self->session, { - name => "searchInTrash", - options => \%searchInTrashOptions, - value => $searchInTrash, - }); - - $form .= ''; - $var->{'searchFormType.label'} = $i18n->get('s search type'); - $var->{'searchFormType.form'} = WebGUI::Form::radioList($self->session, { - name => "searchType", - options => {'or' => $i18n->get('or'), 'and' => $i18n->get('and')}, - value => $searchType, - }); - - $form .= ''; - - $self->session->scratch->set('SQLForm_'.$self->getId.'searchType', $searchType); - $self->session->scratch->set('SQLForm_'.$self->getId.'searchInTrash', $searchInTrash); - - my @field_loop; - foreach (@$fieldList) { - my ($searchForm1, $searchForm2, $conditionalForm); - if ($self->session->form->process("searchQueried")) { - $self->session->scratch->delete('SQLForm_'.$self->getId.'---'.$_.'v1'); - $self->session->scratch->delete('SQLForm_'.$self->getId.'---'.$_.'v2'); - $self->session->scratch->delete('SQLForm_'.$self->getId.'---'.$_.'c'); - } - - my $formValue1 = $self->session->form->process($_.'-1') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$_.'v1'); - my $formValue2 = $self->session->form->process($_.'-2') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$_.'v2'); - my $formConditional = $self->session->form->process('_'.$_.'_conditional'); - my $scratchConditional = $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$_.'c'); - my $fieldType = $fieldProperties->{$_}->{type}; - my $conditional = defined $formConditional ? $formConditional - : defined $scratchConditional ? $scratchConditional - : exists $types->{$fieldType}{'200'} ? 200 # mach any - : 100 # like - ; - - $self->session->scratch->set('SQLForm_'.$self->getId.'---'.$_.'v1', $formValue1); - $self->session->scratch->set('SQLForm_'.$self->getId.'---'.$_.'v2', $formValue2); - $self->session->scratch->set('SQLForm_'.$self->getId.'---'.$_.'c', $conditional); - - if ($fieldType eq 'list') { - if ($self->session->form->process($_.'-2')) { - $formValue2 = [ $self->session->request->param($_.'-2') ]; - $self->session->scratch->set('SQLForm_'.$self->getId.'---'.$_.'v2', Storable::freeze($formValue2)); - } else { - $formValue2 = eval('Storable::thaw($formValue2)'); - } - } - - $form .= ''; - $form .= ''; - - $form .= ''; - $form .= ''; - $form .= ''; - - push (@field_loop, { - 'field.'.$fieldProperties->{$_}->{fieldName}.'.id' => $_, - 'field.label' => $fieldProperties->{$_}->{displayName}, - 'field.conditionalForm' => $conditionalForm, - 'field.searchForm1' => $searchForm1, - 'field.searchForm2' => $searchForm2, - 'field.formValue1' => $formValue1, - 'field.formValue2' => $formValue2, - 'field.conditional' => $conditional, - }); - - } - $var->{'searchForm.field_loop'} = \@field_loop; - - $var->{searchFormSubmit} = WebGUI::Form::submit($self->session, {value => $i18n->get('s search button')}); - $var->{searchFormFooter} = WebGUI::Form::formFooter($self->session); - $var->{searchFormJavascript} = ''; - $var->{searchFormJavascript} .= ''; - - $form .= ''; - $form .= '
'.$var->{'searchFormTrash.label'}.''.$var->{'searchFormTrash.form'}; - $form .= '
'.$var->{'searchFormType.label'}.''.$var->{'searchFormType.form'}; - $form .= '
'.$fieldProperties->{$_}->{displayName}.''; - if (exists $types->{$fieldProperties->{$_}->{type}}) { - $conditionalForm = WebGUI::Form::selectList($self->session, { - name => '_'.$_.'_conditional', - value => [ $conditional || '' ], - options => $types->{$fieldProperties->{$_}->{type}}, - extras => 'onchange="'.$typeFunctions->{$fieldProperties->{$_}->{type}}.'(this.value, \''.$_.'\')"', - size => 1, - multiple=> 0, - }); - $js .= $typeFunctions->{$fieldProperties->{$_}->{type}}."('".$conditional."', '$_');"; - } - $form .= $conditionalForm; - $form .= ''; - - my $parameters = {}; - $parameters->{name} = $_.'-1'; - $parameters->{value} = $formValue1; - $parameters->{options} = $fieldProperties->{$_}->{options} if ($fieldProperties->{$_}->{hasOptions}); - $parameters->{id} = $_.'-1"'; - -my $searchElement = $fieldProperties->{$_}->{searchElement}; - $searchElement = 'text' if ($searchElement eq 'selectList'); -my $cmd = "WebGUI::Form::$searchElement".'($self->session, $parameters)'; - $searchForm1 = eval($cmd); - $form .= $searchForm1; - - unless ($fieldProperties->{$_}->{type} eq 'text') { - $searchElement = $fieldProperties->{$_}->{searchElement}; - $parameters->{name} = $_.'-2'; - $parameters->{value} = $formValue2; - $parameters->{size} = undef; - $parameters->{id} = $_.'-2"'; - if ($fieldProperties->{$_}->{type} eq 'list') { - $parameters->{multiple} = 1; - $parameters->{size} = 5; - $parameters->{value} = $formValue2; - } - - $cmd = "WebGUI::Form::$searchElement".'($self->session, $parameters)'; - $searchForm2 = eval($cmd); - $form .= $searchForm2; - } - - $form .= '
'.$var->{searchFormSubmit}.'
'; - $form .= $var->{searchFormFooter}; - $form .= $var->{searchFormJavascript}; - - $var->{searchForm} = $form; -} - -#------------------------------------------------------------------- - -=head2 _constructSearchQuery ( searchInFields, showFields, fieldProperties ) - -Constructs an SQL query from the search query - -=head3 searchInFields - -Arrayref containing the field id's that should be included in the search. - -=head3 showFields - -List of field id's that should be shown in the results. - -=head3 fieldProperties - -Hashref containing the properties of the fields that are in the search. - -=cut - -my %sortWeights = ( - title => 7, - name => 7, - description => 3, - synopsis => 3, -); - -sub _constructSearchQuery { - my (@tables, @joinConstraints, $tableCounter, @constraints, $conditional, @joinSequence); - my $self = shift; - my $searchInFields = shift; - my $showFields = shift; - my $fieldProperties = shift; - my $passedQuery = shift; - - # order the results by a calculated field - # each clause is something like this: IF(test,$weight,0) where weight is higher for fields with - # certain names, like 7 'title' or 'name', 3 for 'description', and 1 for everything else - # the tests are the same as those in the where clause - # the final result is: " SELECT ..., (test + test + ...) AS sqlforms_orderby_field - # ... ORDER BY sqlforms_orderby_field " - my @sortClauses = (); - - # This variable should be set to value of the minimum word length for fulltext searches - # as it is set in your MySQL database. Normally this is 3. - my $minimumFulltextLength = 3; - - # Include the table the form writes to. - $tableCounter = 2; - - # Process search fields. - foreach my $currentField (@$searchInFields) { - # Set conditional given for this field or to like or regexp mode if in normal search - my $searchMode = $self->session->form->process("searchMode") || $self->session->scratch->get('SQLForm_'.$self->getId.'searchMode'); - if ($searchMode) { - $conditional = 100 if ($searchMode eq 'normal'); - $conditional = 101 if ($searchMode eq 'regexp'); - } else { - $conditional = $self->session->form->process('_'.$currentField.'_conditional') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'c'); - } - - $tableCounter++; - - if ($conditional ne '') { - my $currentFieldProperties = $fieldProperties->{$currentField}; - my $fieldName = $currentFieldProperties->{fieldName}; - my $fieldType = $currentFieldProperties->{type}; - my $fullFieldName = "t1.$fieldName"; - my $constraint; - my $query = $passedQuery || $self->session->form->process("searchQuery") || $self->session->form->process($currentField.'-1') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v1') || $self->session->scratch->get('SQLForm_'.$self->getId.'query'); - my $queryLike; - if ($conditional == 100 || $conditional == 101) { - $query =~ s/\\/\\\\/g; - $query =~ s/'/\\'/g; - - # Search on 'like' - if ($conditional == 100) { - $queryLike = $query; - $queryLike =~ s/%/\\%/g; - $queryLike =~ s/\*/%/g; - $queryLike = "'%".$queryLike."%'"; - } - $query = "'$query'"; - } - - my $formValue1 = $self->session->form->process($currentField.'-1') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v1'); - my $formValue2 = $self->session->form->process($currentField.'-2') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v2'); - - # don't search this field unless there's something to search for -# next if ($query eq qq[''] and $formValue1 eq "" and (ref $formValue2 ne 'ARRAY' || @$formValue2 == 0)); - - if ($fieldType eq 'list') { - if ($self->session->form->process($currentField.'-2')) { - $formValue2 = [ $self->session->request->param($currentField.'-2') ]; - } else { - $formValue2 = Storable::thaw($formValue2); - } - } - - if ($conditional == 200 && ref $formValue2 eq 'ARRAY') { - if (@$formValue2) { - $constraint = "(".join(' or ', map {"$fullFieldName RegExp CONCAT('(^|\\n)',$_,'(\\n|\$)')"} map $self->session->db->quote($_), @$formValue2).")"; - } - } elsif ($conditional == 201 && $formValue2) { # match all - if (@$formValue2) { - $constraint = "(".join(' and ', map {"$fullFieldName RegExp CONCAT('(^|\\n)',$_,'(\\n|\$)')"} map $self->session->db->quote($_), @$formValue2).")"; - } - # Match the joined columns only if type is a list and has joins. - # Else the regular like and regex will handle this. - } elsif ($fieldType eq 'list' && $currentFieldProperties->{numberOfJoins}) { - my $prepend = "t$tableCounter"; - for my $joinCounter (1 .. $currentFieldProperties->{numberOfJoins}) { - my $joinStatement = $currentFieldProperties->{"database$joinCounter"}.'.'. - $currentFieldProperties->{"table$joinCounter"}." as ".$prepend."table$joinCounter"; - - if ($joinCounter > 1) { - $joinStatement .= " on ". - $prepend.$currentFieldProperties->{"joinOnA$joinCounter"}.'='. - $prepend.$currentFieldProperties->{"joinOnB$joinCounter"}; - } else { - $joinStatement .= " on ". - $fullFieldName." RegExp CONCAT('(^|\\n)',".$prepend.$currentFieldProperties->{selectField1}.",'(\\n|\$)')"; -# $fullFieldName." = ".$prepend.$currentFieldProperties->{selectField1}; - $joinStatement .= " or ".$fullFieldName." = ''" if (!$currentFieldProperties->{isRequired}); - } - push(@joinConstraints, $prepend."table$joinCounter.__archived='0'"); - push(@joinSequence, $joinStatement); - } - if ($conditional == 100) { - if ($queryLike ne q['%%']) { - $constraint .= $prepend.$currentFieldProperties->{selectField2}." like ".$queryLike; - } - elsif (defined $formValue1 && $formValue1 ne '') { - $constraint = "$fullFieldName like ".$self->session->db->quote('%'.$formValue1.'%'); - } - } else { - if ($query and $query ne "''") { - $constraint .= $prepend.$currentFieldProperties->{selectField2}." regexp($query)"; - } - elsif (defined $formValue1 && $formValue1 ne '') { - $constraint = "$fullFieldName like ".$self->session->db->quote($formValue1); - } - } - # 10 = between - } elsif ($conditional == 10) { - $constraint = - "($fullFieldName > ".$self->session->db->quote($formValue1)." and ". - " $fullFieldName <".$self->session->db->quote($formValue2).")"; - # 100 = like - } elsif ($conditional == 100) { - if ($currentFieldProperties->{useFulltext} && length($query) >= $minimumFulltextLength) { - $constraint = "match($fullFieldName) against($query in boolean mode)"; - } else { - if ($queryLike ne q['%%']) { - $constraint = "$fullFieldName like $queryLike"; - } - elsif (defined $formValue1 && $formValue1 ne '') { - $constraint = "$fullFieldName like ".$self->session->db->quote('%'.$formValue1.'%'); - } - } - # 101 = regexp - } elsif ($conditional == 101) { - if ($query) { - $constraint = "$fullFieldName regexp($query)"; - } - } else { - $constraint = "$fullFieldName ".$types->{$fieldType}->{$conditional}." ".$self->session->db->quote($formValue1); - } - - next unless $constraint; - - my $sortWeight = exists $sortWeights{lc $fieldName} ? $sortWeights{lc $fieldName} : 1; - push @sortClauses, "IF($constraint,$sortWeight,0)"; - push(@constraints, $constraint) if $constraint; - } - } - - my @selectColumns = qw(t1.__recordId t1.__deletionDate t1.__deletedBy t1.__initDate t1.__userId t1.__deleted t1.__archived t1.__revision); - foreach (@$showFields) { - my $fieldName = $fieldProperties->{$_}->{fieldName}; - - push(@selectColumns, "t1.$fieldName"); - - # In case of files also select mimetype - if ($fieldProperties->{$_}->{formFieldType} eq 'file') { - push(@selectColumns, 't1.__'.$fieldName.'_mimeType'); - } - } - - my $searchInTrash = $self->session->scratch->get('SQLForm_'.$self->getId.'searchInTrash') || $self->session->form->process("searchInTrash") || '0'; - - my $searchType = ($self->session->form->process("searchType") || $self->session->scratch->get('SQLForm_'.$self->getId.'searchType')) eq 'and' ? 'and' : 'or'; - - return undef if (!@constraints); - - # Construct the search query - my $sortField = @sortClauses ? ('('.join('+', @sortClauses).') AS sqlform_orderby') : '1 AS sqlform_orderby'; - $sortField = ' 1 AS sqlform_orderby ' if $searchType eq 'and'; - - my $sql = " select distinct ".join(', ', @selectColumns, $sortField); - $sql .= " from ".$self->get('tableName').' as t1 '; - $sql .= " left join ".join(" left join \n", @joinSequence)."\n" if (@joinSequence); - $sql .= " where "; - $sql .= "(".join(" $searchType \n", @constraints).")\n" if (@constraints); - $sql .= " and " if (@constraints); - $sql .= "(".join(" and \n", @joinConstraints).")\n" if (@joinConstraints); - $sql .= " and " if (@joinConstraints); - $sql .= " t1.__archived=0 "; - $sql .= " and t1.__deleted=".$self->session->db->quote($searchInTrash) if ($searchInTrash < 2); - - $sql .= " GROUP BY $selectColumns[0] "; - - my $sortColumn = $self->session->form->process("sortColumn"); - $sortColumn = $self->session->scratch->get('SQLForm_'.$self->getId.'sortColumn') unless ($sortColumn); - $self->session->scratch->set('SQLForm_'.$self->getId.'sortColumn', $sortColumn); - - my $sortAscending = $self->session->form->process("sortAscending"); - $sortAscending = $self->session->scratch->get('SQLForm_'.$self->getId.'sortAscending') unless (defined $self->session->form->process("sortAscending")); - $self->session->scratch->set('SQLForm_'.$self->getId.'sortAscending', $sortAscending); - - if (isIn($sortColumn, @$showFields)) { - $sql .= " order by ".$fieldProperties->{$sortColumn}->{fieldName}; - $sql .= " desc " unless ($sortAscending); - } - else { - $sql .= " ORDER BY sqlform_orderby DESC "; - } - -#$self->session->errorHandler->warn($sql); - return $sql; -} - -#------------------------------------------------------------------- - -=head2 _processSearchQuery ( sth, showFields, fieldProperties ) - -Processes the results of a search query and returns an arrayref suitable for use as a template loop. - -=head3 sth - -Statement handle of the executed query. - -=head3 showFields - -List of field id's that should be shown in the results. - -=head3 fieldProperties - -Hashref containing the properties of the fields that are in the search. - -=cut - -sub _processSearchQuery { - my $self = shift; - my $sth = shift; - my $showFields = shift; - my $fieldProperties = shift; - - my $i18n = WebGUI::International->new($self->session, 'Asset_SQLForm'); - -my $recordControls; -my $searchInTrash; -my @recordLoop; - - while (my %row = $sth->hash) { - my %record; - my $fieldValues; - $record{'record.id'} = $row{__recordId}; - if ($self->_canEditRecord) { - if ($row{__deleted}) { - $recordControls = WebGUI::Form::checkbox($self->session, {name=>'rid', value=>$row{__recordId}}); - $recordControls .= ''. - ''; - } else { - $recordControls = $self->session->icon->delete('func=deleteRecord'.';rid='.$row{__recordId},$self->get("url"), - $i18n->get('_psq confirm delete message')); - $recordControls .= $self->session->icon->edit('func=editRecord;rid='.$row{__recordId},$self->get("url")); - $recordControls .= $self->session->icon->copy('func=editRecord;rid=new;copyRecordId='.$row{__recordId},$self->get("url")); - } - $record{'record.controls'} = $recordControls; - } - - $record{'record.controls'} .= ''. - ''; - - if ($searchInTrash) { - $record{'record.deletionDate'} = $self->session->datetime->epochToHuman($row{__deletionDate}); - $record{'record.deletedBy'} = WebGUI::User->new($self->session, $row{__deletedBy})->username; - } else { - $record{'record.updateDate'} = $self->session->datetime->epochToHuman($row{__initDate}); - $record{'record.updatedBy'} = WebGUI::User->new($self->session, $row{__userId})->username; - } - - foreach (@$showFields) { -my $value; - - $fieldProperties->{$_} = $self->_getFieldProperties($_) unless (exists $fieldProperties->{$_}); - - if ($fieldProperties->{$_}->{hasOptions}) { - my @options = split(/\n/, $row{$fieldProperties->{$_}->{fieldName}}); - $value = join(', ', @{$fieldProperties->{$_}->{allOptions}}{@options}); - } else { - $value = $row{$fieldProperties->{$_}->{fieldName}}; - } - - $value = substr($value, 0, $fieldProperties->{$_}->{summaryLength}) if ($fieldProperties->{$_}->{summaryLength}); - - $value =~ s/\n/
/g if (1); - - my $props = { - 'record.value' => $value, - }; - - if ($fieldProperties->{$_}->{formFieldType} eq 'file') { - $props->{'record.value.isFile'} = 1; - $props->{'record.value.isImage'} = 1 if ($row{'__'.$fieldProperties->{$_}->{fieldName}.'_mimeType'} =~ m/^image/); - $props->{'record.value.thumbnailUrl'} = - $self->getUrl('func=viewThumbnail;rid='.$row{__recordId}.';fid='.$_); - - $props->{'record.value.downloadUrl'} = - $self->getUrl('func=viewFile;rid='.$row{__recordId}.';fid='.$_); - } - - push(@$fieldValues, $props); - } - - $record{'record.valueLoop'} = $fieldValues; - - push(@recordLoop, {%record}); - } - - return \@recordLoop; -} - -#------------------------------------------------------------------- - -=head2 _clearScratch - -Clear all of the previous search criteria and settings in preparation for a newly submitted search. - -=cut - -sub _clearScratch { - my($self, $fields_aref) = @_; - - my $scratch = $self->session->scratch(); - - my $id = $self->getId(); - - my @static_tags = qw( - query - searchIn - searchInTrash - searchType - sortAscending - sortColumn - ); - - my @tags = (@static_tags, map "---$_", @$fields_aref); - - # for each field, and also delete some other things - for my $tag (@tags) { - $scratch->delete("SQLForm_${id}$tag"); - } - - return undef; # nothing explicitly -} - -#------------------------------------------------------------------- - -=head2 www_superSearch - -Returns the super search. - -=cut - -sub www_superSearch { - my (@searchableFields, %fieldProperties, $var, @headerLoop, $sortAscending, $sortColumn, $i18n); - my $self = shift; - - $i18n = WebGUI::International->new($self->session,'Asset_SQLForm'); - - $sortColumn = $self->session->form->process("sortColumn"); - $sortColumn = $self->session->scratch->get('SQLForm_'.$self->getId.'sortColumn') unless ($sortColumn); - - $sortAscending = $self->session->form->process("sortAscending"); - $sortAscending = $self->session->scratch->get('SQLForm_'.$self->getId.'sortAscending') unless (defined $self->session->form->process("sortAscending")); - - - $self->session->scratch->delete('SQLForm_'.$self->getId.'searchMode'); - -my @fields = $self->session->db->buildArray("select distinct fieldId from SQLForm_fieldOrder where assetId=".$self->session->db->quote($self->getId)." order by rank"); - - # if this is a form submission, delete everything from scratch - if ($self->session->form->get('searchMode') || $self->session->form->get('searchType')) { - $self->_clearScratch(\@fields); - } - -my @showFields; - foreach (@fields) { - $fieldProperties{$_} = $self->_getFieldProperties($_); - unless ($fieldProperties{$_}->{disabled}) { - push(@searchableFields, $_) if ($fieldProperties{$_}->{isSearchable}); - push(@showFields, $_) if ($fieldProperties{$_}->{showInSearchResults}); - } - } - - foreach (@showFields) { - $fieldProperties{$_} = $self->_getFieldProperties($_); - push(@headerLoop, { - 'header.title' => $fieldProperties{$_}->{displayName}, - 'header.sort.url' => $self->getUrl('func=superSearch;sortColumn='.$_.';sortAscending='.($sortAscending ? '0' : '1')), - 'header.sort.onThis' => ($sortColumn eq $_), - 'header.sort.ascending' => $sortAscending, - }); - } - - $var->{'headerLoop'} = \@headerLoop; - - - # Construct search form - $self->_constructSearchForm($var, \@searchableFields, \%fieldProperties); - - # Build search query -my $sql = $self->_constructSearchQuery(\@searchableFields, \@showFields, \%fieldProperties); - - if ($sql) { - # Retrieve search results -my $dbLink = $self->_getDbLink; -my $sth = $dbLink->db->unconditionalRead($sql); - - # Process search results - $var->{'searchResults.recordLoop'} = $self->_processSearchQuery($sth, \@showFields, \%fieldProperties); - - # Close db connections to prevent memory leaks - $sth->finish; - $dbLink->disconnect; - } - - $var->{'superSearch.url'} = $self->getUrl('func=superSearch'); - $var->{'superSearch.label'} = $i18n->get('s advanced search'); - $var->{'normalSearch.url'} = $self->getUrl('func=search'); - $var->{'normalSearch.label'} = $i18n->get('s normal search'); - - $var->{showFieldsDefined} = 1 if (@showFields); - $var->{'searchResults.header'} = WebGUI::Form::formHeader($self->session). - WebGUI::Form::hidden($self->session, {name=>'func',value=>'', id=>'SearchResultsAction'}); - $var->{'searchResults.footer'} = WebGUI::Form::formFooter($self->session); - $var->{'searchResults.actionButtons'} = - WebGUI::Form::button($self->session, { - value => $i18n->get('s restore'), - extras => "onclick=\"document.getElementById('SearchResultsAction').value='restoreRecord'; this.form.submit();\"", - }). - WebGUI::Form::button($self->session, { - value => $i18n->get('s purge'), - extras => "onclick=\"document.getElementById('SearchResultsAction').value='purgeRecord'; this.form.submit();\"", - }) if ($self->session->form->process("searchInTrash")); - - $var->{showMetaData} = $self->get('showMetaData'); - $var->{managementLinks} = $self->_getManagementLinks; - - # Only process style if search is called directly; - return $self->processTemplate($var, $self->getValue('searchTemplateId')) unless ($self->session->form->process("func") eq 'superSearch'); - return $self->processStyle($self->processTemplate($var, $self->getValue('searchTemplateId'))); -} - -1; diff --git a/lib/WebGUI/Help/Asset_SQLForm.pm b/lib/WebGUI/Help/Asset_SQLForm.pm deleted file mode 100644 index 549d24276..000000000 --- a/lib/WebGUI/Help/Asset_SQLForm.pm +++ /dev/null @@ -1,234 +0,0 @@ -package WebGUI::Help::Asset_SQLForm; -use strict; - -our $HELP = { - 'search record template' => { - title => 'search template help title', - body => '', - isa => [ - { namespace => "Asset_SQLForm", - tag => "sql form asset template variables" - }, - { namespace => "Asset_Template", - tag => "template variables" - }, - { namespace => "Asset", - tag => "asset template" - }, - ], - variables => [ - { 'name' => 'showFieldsDefined' }, - { 'name' => 'searchForm' }, - { 'name' => 'searchFormHeader' }, - { 'name' => 'searchFormTrash.label' }, - { 'name' => 'searchFormTrash.form' }, - { 'name' => 'searchFormMode.label' }, - { 'name' => 'searchFormMode.form' }, - { 'name' => 'searchFormQuery.label' }, - { 'name' => 'searchFormSearchIn.label' }, - { 'name' => 'searchFormSearchIn.form' }, - { 'name' => 'searchFormType.label' }, - { 'name' => 'searchFormType.form' }, - { 'name' => 'searchFormFooter' }, - { 'name' => 'searchFormSubmit' }, - { 'name' => 'searchFormJavascript' }, - { 'name' => 'searchForm.field_loop', - 'variables' => [ - { 'name' => 'field.label', }, - { 'name' => 'field.conditionalForm' }, - { 'name' => 'field.conditional' }, - { 'name' => 'field.searchForm1' }, - { 'name' => 'field.searchForm2' }, - { 'name' => 'field.formValue1' }, - { 'name' => 'field.formValue2' }, - { 'name' => 'field.__FIELDNAME__.id' } - ] - }, - { 'name' => 'headerLoop', - 'variables' => [ - { 'name' => 'header.title' }, - { 'name' => 'header.sort.url' }, - { 'name' => 'header.sort.onThis' }, - { 'name' => 'header.sort.ascending' } - ] - }, - { 'name' => 'searchResults.header' }, - { 'name' => 'searchResults.footer' }, - { 'name' => 'searchResults.actionButtons' }, - { 'name' => 'searchResults.recordLoop', - 'variables' => [ - { 'name' => 'record.id', }, - { 'name' => 'record.controls', }, - { 'name' => 'record.deletionDate' }, - { 'name' => 'record.deletedBy' }, - { 'name' => 'record.updateDate' }, - { 'name' => 'record.updatedBy' }, - { 'name' => 'record.valueLoop', - 'variables' => [ - { 'name' => 'record.value' }, - { 'name' => 'record.value.isFile' }, - { 'name' => 'record.value.isImage' }, - { 'name' => 'record.value.downloadUrl' } - ] - } - ] - }, - { 'name' => 'superSearch.url' }, - { 'name' => 'superSearch.label' }, - { 'name' => 'normalSearch.url' }, - { 'name' => 'normalSearch.label' }, - { 'name' => 'showMetaData' }, - { 'name' => 'managementLinks', }, - { 'name' => 'errorOccurred', }, - { 'name' => 'errorLoop', - 'variables' => [ { 'name' => 'error.message', } ], - } - ], - related => [], - }, - - 'advanced search record template' => { - title => 'advanced search template help title', - body => '', - isa => [ - { namespace => "Asset_SQLForm", - tag => "sql form asset template variables" - }, - { namespace => "Asset_Template", - tag => "template variables" - }, - { namespace => "Asset", - tag => "asset template" - }, - ], - variables => [ - { 'name' => 'headerLoop', - 'variables' => [ - { 'name' => 'header.title' }, - { 'name' => 'header.sort.url' }, - { 'name' => 'header.sort.onThis' }, - { 'name' => 'header.sort.ascending' } - ] - }, - { 'name' => 'searchResults.recordLoop', - 'variables' => [ - { 'name' => 'record.id', }, - { 'name' => 'record.controls', }, - { 'name' => 'record.deletionDate' }, - { 'name' => 'record.deletedBy' }, - { 'name' => 'record.updateDate' }, - { 'name' => 'record.updatedBy' }, - { 'name' => 'record.valueLoop', - 'variables' => [ - { 'name' => 'record.value' }, - { 'name' => 'record.value.isFile' }, - { 'name' => 'record.value.isImage' }, - { 'name' => 'record.value.downloadUrl' } - ] - } - ] - }, - { 'name' => 'superSearch.url' }, - { 'name' => 'superSearch.label' }, - { 'name' => 'normalSearch.url' }, - { 'name' => 'normalSearch.label' }, - { 'name' => 'showFieldsDefined' }, - { 'name' => 'searchResults.header' }, - { 'name' => 'searchResults.footer' }, - { 'name' => 'searchResults.actionButtons' }, - { 'name' => 'showMetaData' }, - { 'name' => 'managementLinks', }, - { 'name' => 'searchFormTrash.label' }, - { 'name' => 'searchFormTrash.form' }, - { 'name' => 'searchFormType.label' }, - { 'name' => 'searchFormType.form' }, - { 'name' => 'searchFormHeader' }, - { 'name' => 'searchFormFooter' }, - { 'name' => 'searchFormSubmit' }, - { 'name' => 'searchFormJavascript' }, - { 'name' => 'searchForm.field_loop', - 'variables' => [ - { 'name' => 'field.label', }, - { 'name' => 'field.conditionalForm' }, - { 'name' => 'field.conditional' }, - { 'name' => 'field.searchForm1' }, - { 'name' => 'field.searchForm2' }, - { 'name' => 'field.formValue1' }, - { 'name' => 'field.formValue2' }, - { 'name' => 'field.__FIELDNAME__.id' } - ] - }, - { 'name' => 'searchForm' }, - ], - related => [], - }, - - 'edit record template' => { - title => 'edit template help title', - body => '', - isa => [ - { namespace => "Asset_SQLForm", - tag => "sql form asset template variables" - }, - { namespace => "Asset_Template", - tag => "template variables" - }, - { namespace => "Asset", - tag => "asset template" - }, - ], - variables => [ - { 'name' => 'completeForm' }, - { 'name' => 'formLoop', - 'variables' => [ - { 'name' => 'field.label' }, { 'name' => 'field.formElement' }, { 'name' => 'field.value' } - ] - }, - { 'name' => 'field.__FIELDNAME__.formElement' }, - { 'name' => 'field.__FIELDNAME__.label' }, - { 'name' => 'field.__FIELDNAME__.value' }, - { 'name' => 'formHeader' }, - { 'name' => 'formFooter' }, - { 'name' => 'errorOccurred' }, - { 'name' => 'errorLoop', - 'variables' => [ { 'name' => 'error.message' } ] - }, - { 'name' => 'isNew' }, - { 'name' => 'viewHistory.url' }, - { 'name' => 'viewHistory.label' }, - { 'name' => 'managementLinks' }, - { 'name' => 'record.controls' } - ], - related => [], - }, - - 'sql form asset template variables' => { - private => 1, - title => 'sql form asset template variables title', - body => '', - isa => [ - { namespace => "Asset_Wobject", - tag => "wobject template variables" - }, - ], - fields => [], - variables => [ - { 'name' => 'formId' }, - { 'name' => 'tableName' }, - { 'name' => 'maxFileSize' }, - { 'name' => 'sendMailTo' }, - { 'name' => 'showMetaData' }, - { 'name' => 'searchTemplateId' }, - { 'name' => 'editTemplateId' }, - { 'name' => 'submitGroupId' }, - { 'name' => 'alterGroupId' }, - { 'name' => 'databaseLinkId' }, - { 'name' => 'defaultView' }, - ], - related => [] - }, - -}; - -1; - diff --git a/lib/WebGUI/i18n/English/Asset_SQLForm.pm b/lib/WebGUI/i18n/English/Asset_SQLForm.pm deleted file mode 100644 index 72a81f5ba..000000000 --- a/lib/WebGUI/i18n/English/Asset_SQLForm.pm +++ /dev/null @@ -1,1507 +0,0 @@ -package WebGUI::i18n::English::Asset_SQLForm; -use strict; - -our $I18N = { - 'change field warning' => { - message => q|Changing the following properties can result in permanent loss of data in this field:\n\n -\t - Database field type.\n -\t - Decreasing the Maximum field length.\n -\t - Switching the Sign.\n\n\n -Are you sure to continue?|, - lastUpdated => 0, - }, - - 'ef field name' => { - message => q|Field name (column name)|, - lastUpdated => 0, - }, - - 'ef field name description' => { - message => q|

This sets the name of the column in the database -tied to this field.

|, - lastUpdated => 0, - }, - - 'ef display name' => { - message => q|Display name|, - lastUpdated => 0, - }, - - 'ef display name description' => { - message => q|

Use this property to set the name of this field -that is shown to users.

|, - lastUpdated => 0, - }, - - 'ef field type' => { - message => q|Field type|, - lastUpdated => 0, - }, - - 'ef field type description' => { - message => q|

This property defines the column type of the field -in the database as well as the type of form element that is used for input of -new records. You can only select field type combinations that are defined in the -field type manager. For more information please read the help on Manage field -types, which you can visit using the link in the menu on the right.

- -

Please note that some other field properties like Auto increment and -Read only will force the field to be read only and thus render the form -type of no importance. The database field type is very important, though, and -should chosen with proper care.

|, - lastUpdated => 1167187624, - }, - - 'ef signed' => { - message => q|Sign|, - lastUpdated => 0, - }, - - 'ef signed description' => { - message => q|

This property determines whether this field -interprets number as signed or unsigned. The difference lies in the boundaries -of allowed values.

- -

This property is available only for numeric field types like int.

|, - lastUpdated => 1167187652, - }, - - 'ef signed label' => { - message => q|Signed|, - lastUpdated => 0, - }, - - 'ef unsigned label' => { - message => q|Unsigned|, - lastUpdated => 0, - }, - - 'ef autoincrement' => { - message => q|Autoincrement|, - lastUpdated => 0, - }, - - 'ef autoincrement description' => { - message => q|

Setting a field will cause it to assign itself a -value that is the highest value of the field that is already in the database -plus one. In other words each record will have a successive number for this -field. The field value will increment automatically.

- -

Enabling autincrement for a field will mean necessarily that the field is -forced read only and will not accept user input. Therefore the choice of -form field type is irrelevant if autoincrement is enabled.

|, - lastUpdated => 1167187683, - }, - - 'ef form height' => { - message => q|Height of form element|, - lastUpdated => 0, - }, - - 'ef form height description' => { - message => q|

This property sets the height of the form -element, if applicable for the chosen form field type. Not all form elements -have a settable height.

|, - lastUpdated => 0, - }, - - 'ef form width' => { - message => q|Width of form element|, - lastUpdated => 0, - }, - - 'ef form width description' => { - message => q|

This property sets the width of the form -element, if applicable for the chosen form field type. Not all form elements -have a settable width.

|, - lastUpdated => 0, - }, - - 'ef max field length' => { - message => q|Maximum field length|, - lastUpdated => 0, - }, - - 'ef max field length description' => { - message => q|

This property defines the number of characters that -the value that is inputted into this field is allowed to have. This property -applies only to form elements that allow a user to actually type. So if you -chose, for instance, a select list this option will have no -effect.

- -

Please note that some database types define a limit for the value of this -property.

|, - lastUpdated => 1167187734, - }, - - 'ef regex' => { - message => q|Regex|, - lastUpdated => 0, - }, - - 'ef regex description' => { - message => q|

Regex is short for regular expression. A regex -is used to precisely match data against a specific pattern. The regex property -thus allows you to check the user input assigned to this field.

- -

The list of regexes you can choose from is defined in the Regex -manager of the SQLForm asset. For more information regarding it please read -the help on Manage regexes, which you can access by clicking on the link -in the menu on the right.

|, - lastUpdated => 1167187797, - }, - - 'ef required' => { - message => q|Required|, - lastUpdated => 0, - }, - - 'ef required description' => { - message => q|

Setting this property to yes will force users to -fill in a value for this field when adding a record. If set to no users are -allowed to leave the field empty.

|, - lastUpdated => 0, - }, - - 'ef read only' => { - message => q|Read only|, - lastUpdated => 0, - }, - - 'ef read only description' => { - message => q|

Setting this property will cause the field to -be read only, meaning that users cannot input a value for it when adding or -editing a record. The value that is stored in this field on record addition is -the value given by the Default value property.

|, - lastUpdated => 1167187902, - }, - - 'ef default value' => { - message => q|Default value|, - lastUpdated => 0, - }, - - 'ef default value description' => { - message => q|

This property can be used to prepopulate the form -element tied to this field on record addition. If the field is set read only the -value of this property will be used to put in the database.

- -

You can use macro's for this property, to make your default value dynamic. -For instance, if you want a field to default to the username of the person -adding a record, you can use ^User(username); in this property.

- -

If the field is set to autoincrement, the default value property is -neglected.

|, - lastUpdated => 0, - }, - - 'ef field constraint' => { - message => q|Field constraint|, - lastUpdated => 0, - }, - - 'ef field constraint description' => { - message => q|

The field constraint property has a similar use -as the regex. The big difference, however, is that you can use the field -constraint to apply a constraint on the actual value that is input by the user -who adds a record, while a regex is used to constrain the form (or the pattern) -of the input.

- -

There are a number of operators available to define your constraint. If you -set the constraint to another value than none you will be able to select -what you want to compare against. You can use a custom value for comparison, but -if you have defined joins with other tables in the define table(-joins) -you can also match against one of the columns of those tables.

- -

The field constrained property is ignored if the read only or the -autoincrement property is set.

|, - lastUpdated => 1167187945, - }, - - 'ef searchable' => { - message => q|Searchable|, - lastUpdated => 0, - }, - - 'ef searchable description' => { - message => q|

You can include this field in search queries by -setting to 'yes'. If set to 'no' users will be unable to search on this -field.

|, - lastUpdated => 0, - }, - - 'ef fulltext' => { - message => q|Use fulltext index|, - lastUpdated => 0, - }, - - 'ef fulltext description' => { - message => q|

Fulltext indices are used to speed up search -queries, so setting this property to yes may increase performance of the SQLForm -asset. Adding or editing records, however, will be somewhat slowed down by using -a fulltext index.

- -

Fulltext indices are only applicable to certain database field types like -text or longtext but enabling this property on another field type -won't affect the operation of the SQLForm.

|, - lastUpdated => 1167187980, - }, - - 'ef show in search' => { - message => q|Show in search results|, - lastUpdated => 0, - }, - - 'ef show in search description' => { - message => q|

By setting this property to 'yes' this field will -be shown in the list of search results. If you set it to 'no' users will not be -able to see the value of this field in the search results. Users can view the -field when viewing or editing this field regardless of this property -however.

|, - lastUpdated => 0, - }, - - 'ef summary length' => { - message => q|Summary length|, - lastUpdated => 0, - }, - - 'ef summary length description' => { - message => q|

This property determines how much characters of the -value of this field should shown in the search result list. The field value will -be truncated to the number of characters you enter here. Setting this property -to zero will disable this property and cause the field value not to be truncated in -the search results list.

|, - lastUpdated => 1167187996, - }, - - 'ef populate keys' => { - message => q|Keys of form element options|, - lastUpdated => 0, - }, - - 'ef populate keys description' => { - message => q|

You can use this property to populate option based -form elements, like select-, radio- and check lists. Each option consists of a -key and a value. Keys are the values that are stored in the database and values -are the text labels that are shown in the form element to identify the -option.

- -

Use this property to define the keys for the available options. Fill in one -key per line, and make sure that the number of keys here matches the number of -values entered in the Values of form element options property.

- -

Please note that if a connection to another table is defined in the Define -table(-joins) property, the Keys of form element options property is -neglected.

|, - lastUpdated => 0, - }, - - 'ef populate values' => { - message => q|Values of form element options|, - lastUpdated => 0, - }, - - 'ef populate values description' => { - message => q|

You can use this property to populate option based -form elements, like select-, radio- and check lists. Each option consists of a -key and a value. Keys are the values that are stored in the database and values -are the text labels that are shown in the form element to identify the -option.

- -

Use this property to define the values for the available options. Fill in one -value per line, and make sure that the number of values here matches the number of -keys entered in the Keys of form element options property.

- -

Please note that if a connection to another table is defined in the Define -table(-joins) property, the Values of form element options property is -neglected.

|, - lastUpdated => 0, - }, - - 'ef join selector' => { - message => q|Define table(-joins)|, - lastUpdated => 0, - }, - - 'ef join selector description' => { - message => q|

You can connect this field to other tables using -this property. This connection can be used for constraining field values and -setting the keys and values of options of form elements like select list, radio -lists and check lists.

- -

In order to do so you must select -the database in which the table of your choice resides and, of course, the table -itself. You can add more tables by clicking on the join button that appears -below the table selection. In order to do this you must choose the columns that -connect the tables you have selected and the type of that connection.

- -

These columns should identify the rows they are in in exactly the same way so -that the SQLForm knows which record in one table belongs to a record in another. -You can choose from two connection methods: by set-intersection and by -set-difference.

- -

Suppose we have two tables, A and B, that we want to connect to each other in -order to get data out of them into a select list. If you use an intersection the -tables are connected in such a way that only the elements that are in A as well -as B are returned. If you use the difference method, only the rows that are in A, -but not B, are returned.

|, - lastUpdated => 1167188029, - }, - - 'ef join constraint' => { - message => q|Constraint|, - lastUpdated => 0, - }, - - 'ef join constraint description' => { - message => q|

You can use this property to limit the results from -the definition in the Define table(-joins) property by selecting a -column, a constraint type and a value.

|, - lastUpdated => 0, - }, - - 'ef join keys' => { - message => q|Get keys from column|, - lastUpdated => 0, - }, - - 'ef join keys description' => { - message => q|

Use this property to generate the keys for the -options of option based form elements, like select list, from the table -definition.

|, - lastUpdated => 1167188372, - }, - - 'ef join values' => { - message => q|Get values from column|, - lastUpdated => 0, - }, - - 'ef join values description' => { - message => q|

Use this property to generate the values of the -options of option based form elements, like select list, from the table -definition.

|, - lastUpdated => 1167188573, - }, - - - 'ef errors occurred' => { - message => q|Some errors occured:|, - lastUpdated => 0, - }, - - 'efs height error' => { - message => q|Invalid value for Form field height|, - lastUpdated => 0, - }, - - 'efs width error' => { - message => q|Invalid value for Form field width|, - lastUpdated => 0, - }, - - 'efs populate error' => { - message => q|Number of keys and values of form population keys -does not match|, - lastUpdated => 0, - }, - - 'efs constraint error' => { - message => q|You must enter a constraint value|, - lastUpdated => 0, - }, - - 'efs jf1 error' => { - message => q|You cannot select Join field 1 without defining it|, - lastUpdated => 0, - }, - - 'efs jf2 error' => { - message => q|You cannot select Join field 2 without defining it|, - lastUpdated => 0, - }, - - 'efs join populate error' => { - message => q|You should select the key and value columns in the -field population tab|, - lastUpdated => 0, - }, - - 'efs left join column error' => { - message => q|You have to specify the left join column for table|, - lastUpdated => 0, - }, - - 'efs right join column error' => { - message => q|You have to specify the right join column for table|, - lastUpdated => 0, - }, - - 'efs column name error' => { - message => q|Illegal column name in join clause:|, - lastUpdated => 0, - }, - - 'efs table error' => { - message => q|Illegal table selected.|, - lastUpdated => 0, - }, - - 'efs database error' => { - message => q|Illegal database selected.|, - lastUpdated => 0, - }, - - 'efs field type error' => { - message => q|Illegal field type.|, - lastUpdated => 0, - }, - - 'efs fulltext error' => { - message => q|Column type does not support full text search.|, - lastUpdated => 0, - }, - - 'efs column name exists error' => { - message => q|The field name already exists in the table.|, - lastUpdated => 0, - }, - - 'efs column name is reserved error' => { - message => q|The field name is the same as a reserved keyword, -which is not allowed.|, - lastUpdated => 0, - }, - - 'efs field name error' => { - message => q|Illegal field name.|, - lastUpdated => 0, - }, - - 'eft db field type' => { - message => q|Database field type|, - lastUpdated => 0, - }, - - 'eft db field type description' => { - message => q|

This property sets the MySQL column type of the -column in the database that will store the data entered in field with this field -type.

|, - lastUpdated => 0, - }, - - 'eft form field type' => { - message => q|Form element type|, - lastUpdated => 0, - }, - - 'eft form field type description' => { - message => q|

You can select the form element that will be used -to enter data in field with this field type. Please note that some combinations -of form and db types do not make much sense.

|, - lastUpdated => 0, - }, - - 'click here for file' => { - message => q|Click here for file|, - lastUpdated => 0, - }, - - 'keep' => { - message => q|Keep|, - lastUpdated => 0, - }, - - 'overwrite' => { - message => q|Overwrite|, - lastUpdated => 0, - }, - - 'delete' => { - message => q|Delete|, - lastUpdated => 0, - }, - - 'invalid record id' => { - message => q|Not a valid record id.|, - lastUpdated => 0, - }, - - 'view history' => { - message => q|View record history|, - lastUpdated => 0, - }, - 'no fields defined message' => { - message => q|There are no fields defined yet. You can add field -by going to|, - lastUpdated => 0, - }, - - 'manage fields title' => { - message => q|Manage fields|, - lastUpdated => 0, - }, - - 'ers file too large' => { - message => q|File too large|, - lastUpdated => 0, - }, - - 'ers field required' => { - message => q|Field is required:|, - lastUpdated => 0, - }, - - 'ers regex mismatch' => { - message => q|Field does not match its regex:|, - lastUpdated => 0, - }, - - 'ers too long' => { - message => q|Field is too long. Maximum number of characters:|, - lastUpdated => 0, - }, - - 'ers value not allowed' => { - message => q|Value is not allowed for field:|, - lastUpdated => 0, - }, - - 'ers out of range' => { - message => q|The value for this field is out of range:|, - lastUpdated => 0, - }, - - 'er error message' => { - message => q|An error occurred:|, - lastUpdated => 0, - }, - - 'er name' => { - message => q|Name|, - lastUpdated => 0, - }, - - 'er name description' => { - message => q|

Use this property to set the name by which the -regex will be shown on the screen.

|, - lastUpdated => 0, - }, - - 'er regex' => { - message => q|Regex|, - lastUpdated => 0, - }, - - 'er regex description' => { - message => q|

This property defines the actual regular -expression. The regex you enter here should be perl style.

|, - lastUpdated => 0, - }, - - 'ers no name' => { - message => q|Please supply a name for this regex.|, - lastUpdated => 0, - }, - - 'ers no regex' => { - message => q|Please supply a regex.|, - lastUpdated => 0, - }, - - 'no field types message' => { - message => q|In order to add fields to an SQLForm field types -must be defined. Currently there are no field types defined, and therfore it is -not possible ta add fields. Please add at least one field type by going to|, - lastUpdated => 1165517851, - }, - - 'manage field types title' => { - message => q|Manage field types|, - lastUpdated => 0, - }, - - 'lf add field' => { - message => q|Add field|, - lastUpdated => 0, - }, - - 'lft delete confirm message' => { - message => q|Are you sure to delete this field type?|, - lastUpdated => 0, - }, - - 'lft show assets using' => { - message => q|Click here to show SQLForms that use this field type.|, - lastUpdated => 0, - }, - - 'lft in field' => { - message => q|in field|, - lastUpdated => 0, - }, - - 'lft unused field types' => { - message => q|Unused field types|, - lastUpdated => 0, - }, - - 'lft db type' => { - message => q|Database type|, - lastUpdated => 0, - }, - - 'lft form type' => { - message => q|Form element|, - lastUpdated => 0, - }, - - 'lft used field types' => { - message => q|Field types in use|, - lastUpdated => 0, - }, - - 'lft add field type' => { - message => q|Add a new field type|, - lastUpdated => 0, - }, - - 'lr show assets using' => { - message => q|Click here to show SQLForms that use this regular expression.|, - lastUpdated => 0, - }, - - 'lr in field' => { - message => q|in field|, - lastUpdated => 0, - }, - - 'lr unused regexes' => { - message => q|Unused regular expressions|, - lastUpdated => 0, - }, - - 'lr name' => { - message => q|Name|, - lastUpdated => 0, - }, - - 'lr regex' => { - message => q|Regular expression|, - lastUpdated => 0, - }, - - 'lr used regexes' => { - message => q|Regular expressions in use|, - lastUpdated => 0, - }, - - 'lr add regex' => { - message => q|Add a new regular expression|, - lastUpdated => 0, - }, - - 'vh init date' => { - message => q|Init date|, - lastUpdated => 0, - }, - - 'vh user' => { - message => q|User|, - lastUpdated => 0, - }, - - 's query' => { - message => q|Search for|, - lastUpdated => 0, - }, - - 's mode' => { - message => q|Search mode|, - lastUpdated => 0, - }, - - 's type' => { - message => q|Search type|, - lastUpdated => 0, - }, - - 's search in fields' => { - message => q|Search in fields|, - lastUpdated => 0, - }, - - 's location' => { - message => q|Search location|, - lastUpdated => 0, - }, - - 's search button' => { - message => q|Search|, - lastUpdated => 0, - }, - - 's query error' => { - message => q|Your query contains an error:|, - lastUpdated => 0, - }, - - 's advanced search' => { - message => q|Advanced search|, - lastUpdated => 0, - }, - - 's normal search' => { - message => q|Normal search|, - lastUpdated => 0, - }, - - 's restore' => { - message => q|Restore|, - lastUpdated => 0, - }, - - 's purge' => { - message => q|Purge|, - lastUpdated => 0, - }, - - 's search type' => { - message => q|Search Type|, - lastUpdated => 0, - }, - - '_csf only normal' => { - message => q|Only normal|, - lastUpdated => 0, - }, - - '_csf only trash' => { - message => q|Only trash|, - lastUpdated => 0, - }, - - '_csf normal and trash' => { - message => q|Normal and trash|, - lastUpdated => 0, - }, - - 'and' => { - message => q|and|, - lastUpdated => 0, - }, - - 'or' => { - message => q|or|, - lastUpdated => 0, - }, - - '_psq confirm delete message' => { - message => q|Are you sure you want to delete this record?|, - lastUpdated => 0, - }, - - 'add record title' => { - message => q|Add record|, - lastUpdated => 0, - }, - - 'search records title' => { - message => q|Search records|, - lastUpdated => 0, - }, - - 'none' => { - message => q|None|, - lastUpdated => 0, - }, - - 'gef no db links' => { - message => q|You can only use this asset if you define databaselinks. Please define databases in the database links.|, - lastUpdated => 0, - }, - - 'gef table name' => { - message => q|Table name|, - lastUpdated => 0, - }, - - 'gef table name description' => { - message => q|

This is the name the table you want to create -create in the database, or if you want to attach the SQLForm to an existing -table, the name of that table.

|, - lastUpdated => 1169508646, - }, - - 'gef database to use' => { - message => q|Database to use|, - lastUpdated => 0, - }, - - 'gef database to use description' => { - message => q|

This property defines the link to the database -where the table should reside or resides in. Database links can be added and -edited in the Databases section of the Admin Console

|, - lastUpdated => 0, - }, - - 'gef max file size' => { - message => q|Maximum file size|, - lastUpdated => 0, - }, - - 'gef max file size description' => { - message => q|

Using this property you can define the maximum -size of files users can upload through the SQLForm. Specify the size in -kilobytes.

- -

Please note that WebGUI also has a system wide maximum file size setting, -which cannot be overridden by this property. In other words, if you set this -property to a larger value than that of the system wide setting, the maximum -upload size will be the system wide setting.

|, - lastUpdated => 1167187555, - }, - - 'gef send mail to' => { - message => q|Send notification mail to|, - lastUpdated => 0, - }, - - 'gef send mail to description' => { - message => q|

The SQLForm sends a notification email to the -email address specified in this property every time a record is added or edited. -If you do not want to use this feature, simply leave the field blank.

|, - lastUpdated => 0, - }, - - 'gef show meta data' => { - message => q|Show metadata|, - lastUpdated => 0, - }, - - 'gef show meta data description' => { - message => q|

In the SQLForm each record has special meta data -containing the state of the record. If you want some of this information to -be shown in search results, please set this property to yes.

|, - lastUpdated => 1167187571, - }, - - 'gef edit template' => { - message => q|View/Edit template|, - lastUpdated => 0, - }, - - 'gef edit template description' => { - message => q|

This property sets the template that is used to -layout the record edit or view screen.

|, - lastUpdated => 0, - }, - - 'gef search template' => { - message => q|Search template|, - lastUpdated => 0, - }, - - 'gef search template description' => { - message => q|

This property sets the template that formats the -search results.

|, - lastUpdated => 0, - }, - - 'gef default view' => { - message => q|Default view|, - lastUpdated => 0, - }, - - 'gef default view description' => { - message => q|

This property switches the default view between normal and advanced search. The two views have different templates.

|, - lastUpdated => 0, - }, - - 'gef submit group' => { - message => q|Group to submit records|, - lastUpdated => 0, - }, - - 'gef submit group description' => { - message => q|

This is the group of user that can add, edit, -delete and restore but not purge records.

|, - lastUpdated => 0, - }, - - 'assetName' => { - message => q|SQL Form (beta)|, - lastUpdated => 0, - }, - - 'edit field title' => { - message => q|SQLForm, Add/Edit Field|, - lastUpdated => 0, - }, - - 'edit field type title' =>{ - message => q|SQLForm, Add/Edit Field Type|, - lastUpdated => 0, - }, - - 'edit regex title' => { - message => q|SQLForm, Add/Edit Regex|, - lastUpdated => 0, - }, - - 'manage fields' => { - message => q|Manage fields|, - lastUpdated => 0, - }, - - 'manage fields title' => { - message => q|SQLForm, Manage Fields|, - lastUpdated => 0, - }, - - 'manage field types title' => { - message => q|SQLForm, Manage Field Types|, - lastUpdated => 0, - }, - - 'manage field types' => { - message => q|Manage field types|, - lastUpdated => 0, - }, - - 'manage regexes title' => { - message => q|SQLForm, Manage Regexes|, - lastUpdated => 0, - }, - - 'manage regexes' => { - message => q|Manage regexes|, - lastUpdated => 0, - }, - - 'edit template help title' => { - message => q|SQLForm, Add/Edit Record Template|, - lastUpdated => 0, - }, - - 'completeForm' => { - message => q|This contains the entire form, complete -and laid out in a WebGUI-style table. You don't need to add a -separate form header, footer or anything else.|, - lastUpdated => 1167186643, - }, - - 'formLoop' => { - message => q|A loop containing each field. Using -this loop will allow you to use a different layout than that of -completeForm. The formLoop loop provides the following -variables:|, - lastUpdated => 1149822620, - }, - - 'field.label' => { - message => q|The display name of the field.|, - lastUpdated => 1149822620, - }, - - 'field.formElement' => { - message => q|The form Element for the field
-In view mode this is the same as field.value.|, - lastUpdated => 1149822620, - }, - - 'field.value' => { - message => q|The value of the field|, - lastUpdated => 1149822620, - }, - - 'field.__FIELDNAME__.formElement' => { - message => q|Contains the form element of the field -__FIELDNAME__. You must substitute __FIELDNAME__ with the -name of the field you intend to place.
-In view mode this is the same as __FIELDNAME__.value.|, - lastUpdated => 1149822620, - }, - - 'field.__FIELDNAME__.label' => { - message => q|Contains the display name of the field -__FIELDNAME__. You must substitute __FIELDNAME__ with the -field name of the field you intend to place.|, - lastUpdated => 1149822620, - }, - - 'field.__FIELDNAME__.value' => { - message => q|Contains the value of the field -__FIELDNAME__. You must substitute __FIELDNAME__ with the -name of the field you intend to place.|, - lastUpdated => 1149822620, - }, - - 'formHeader' => { - message => q|The header of the form. If you are -not using the completeForm you must include this variable -before any other form variable. If you do use the completeForm -variable, however, you must not use the formHeader -variable.|, - lastUpdated => 1149822620, - }, - - 'formFooter' => { - message => q|The footer of the form. If you are -not using the completeForm you must include this variable -after all form variables. If you do use the completeForm -variable, however, you must not use the formFooter variable.|, - lastUpdated => 1149822620, - }, - - 'errorOccurred' => { - message => q|Conditional indicating whether an error -occurred in the submitted data.|, - lastUpdated => 1149822620, - }, - - 'errorLoop' => { - message => q|Loop containing any errors that occurred while processing data submitted in the form.|, - lastUpdated => 1149822620, - }, - - 'error.message' => { - message => q|The actual error message.|, - lastUpdated => 1149822620, - }, - - 'isNew' => { - message => q|Conditional indicating whether the user -is adding a new record or editing an existing one. It will be true if the record -is new.|, - lastUpdated => 1149822620, - }, - - 'viewHistory.url' => { - message => q|The url to the history of this record.|, - lastUpdated => 1149822620, - }, - - 'viewHistory.label' => { - message => q|The label of the link to the history of this record.|, - lastUpdated => 1149822620, - }, - - 'record.id' => { - message => q|This record's id.|, - lastUpdated => 1169831704, - }, - - 'record.controls' => { - message => q|Delete, edit and copy buttons for this record. Only available if the user is -allowed to edit the record.|, - lastUpdated => 1167189136, - }, - - 'search template help title' => { - message => q|SQLForm, Normal Search Record Template|, - lastUpdated => 0, - }, - - 'showFieldsDefined' => { - message => q|Conditional which returns true if there are fields that are defined to be shown. -In other words, this is false if every field is configured not to be displayed -in the search results.|, - lastUpdated => 1167188632, - }, - - 'searchForm' => { - message => q|Contains the complete form which allows users to search.|, - lastUpdated => 1149822982, - }, - - 'searchFormHeader' => { - message => q|The header of the form, available in normal and advanced search. If you are -not using the complete searchForm, you must include this variable -before any other form variable. If you do use the complete searchForm - variable, however, you must not use the searchFormHeader -variable.|, - lastUpdated => 1167188652, - }, - - 'searchFormTrash.label' => { - message => q|The label for the search in trash option. Available in normal and advanced search. Only use this if you are -not using the complete searchForm.
|, - lastUpdated => 1149822982, - }, - - 'searchFormTrash.form' => { - message => q|The form Element for the search in trash option. Available in normal and advanced search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1172875828, - }, - - 'searchFormMode.label' => { - message => q|The label for the search mode option (with regex or not). Available in normal search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1149822982, - }, - - 'searchFormMode.form' => { - message => q|The form Element for the search mode option (with regex or not). Available in normal search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1149822982, - }, - - 'searchFormQuery.label' => { - message => q|The label for the search query. Available in normal search. Only use this if you are -not using the complete searchForm.
-
searchFormQuery.form
-The form Element for the search query. Available in normal search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1149822982, - }, - - 'searchFormSearchIn.label' => { - message => q|The label for the search in fields select list. Available in normal search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1149822982, - }, - - 'searchFormSearchIn.form' => { - message => q|The form Element for the search in fields select list. Available in normal search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1149822982, - }, - - 'searchFormType.label' => { - message => q|The label for the search type option (or/and). Available in advanced search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1167188797, - }, - - 'searchFormType.form' => { - message => q|The form Element for the search type option (or/and). Available in advanced search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1149822982, - }, - - 'searchFormFooter' => { - message => q|The footer of the form, available in normal and advanced search. If you are -not using the complete searchForm, you must use this variable -after every other searchForm variable. If you do use the complete searchForm -variable, however, you must not use the searchFormFooter variable.|, - lastUpdated => 1167188873, - }, - - 'searchFormSubmit' => { - message => q|The submit button of the form, available in normal and advanced search. Only use this if you are -not using the complete searchForm.|, - lastUpdated => 1149822982, - }, - - 'searchFormJavascript' => { - message => q|Only used for advanced search. This links the SQLFormSearch.js file and contains some inline javascript that is used by advanced search. If you are -not using the complete searchForm you must include this variable -for advanced search. If you do use the complete searchForm -variable, however, you must not use the searchFormJavascript variable.|, - lastUpdated => 1149822982, - }, - - 'searchForm.field_loop' => { - message => q|A loop containing each field, only available in advanced search. -The field_loop provides the following -variables:|, - lastUpdated => 1149822982, - }, - - 'field.conditionalForm' => { - message => q|The form Element for the conditional for this field|, - lastUpdated => 1149822982, - }, - - 'field.conditional' => { - message => q|The value of the conditional form Element for this field|, - lastUpdated => 1149822982, - }, - - 'field.searchForm1' => { - message => q|The first search form Element for this field|, - lastUpdated => 1149822982, - }, - - 'field.searchForm2' => { - message => q|The second search form Element for this field|, - lastUpdated => 1149822982, - }, - - 'field.formValue1' => { - message => q|The value of first search form Element for this field|, - lastUpdated => 1149822982, - }, - - 'field.formValue2' => { - message => q|The value of second search form Element for this field|, - lastUpdated => 1149822982, - }, - - 'field.__FIELDNAME__.id' => { - message => q|Contains the id of the field -__FIELDNAME__. You must substitute __FIELDNAME__ with the -field name of the field.
-You can use this if you want to create a custom Advanced search form that completely overrides the default search form.|, - lastUpdated => 1149822982, - }, - - 'headerLoop' => { - message => q|A loop containing the display names of each field, including sort controls. The -following variables are provided within this loop:|, - lastUpdated => 1167188939, - }, - - 'header.title' => { - message => q|The display name of the current field.|, - lastUpdated => 1149822982, - }, - - 'header.sort.url' => { - message => q|The url that allows you to sort on this field.|, - lastUpdated => 1149822982, - }, - - 'header.sort.onThis' => { - message => q|Conditional indicating whether the search results are sorted on this -field.|, - lastUpdated => 1149822982, - }, - - 'header.sort.ascending' => { - message => q|Conditional indicating whether the search results are sorted ascending -or descending.|, - lastUpdated => 1149822982, - }, - - 'searchResults.header' => { - message => q|Contains the form header for the batch restore and purge functions in the search -results. You should put this somewhere before the searchResults loop.|, - lastUpdated => 1149822982, - }, - - 'searchResults.footer' => { - message => q|Contains the form footer for the search results batch functions. Put this -template variable somewhere after the searchResults loop.|, - lastUpdated => 1149822982, - }, - - 'searchResults.actionButtons' => { - message => q|Contains the restore and purge buttons for the batch operations. Put this -variable between searchResults.header and searchResults.footer.|, - lastUpdated => 1149822982, - }, - - 'searchResults.recordLoop' => { - message => q|The loop containing the results of the search query. This should be between -searchResults.header and searchResults.footer. Within this loop the following -variables are available for use:|, - lastUpdated => 1167189201, - }, - - 'record.deletionDate' => { - message => q|Contains the date this record was deleted. Only available for records.|, - lastUpdated => 1149822982, - }, - - 'record.deletedBy' => { - message => q|Contains the username of the person that deleted this record. Only available for records.|, - lastUpdated => 1167189170, - }, - - 'record.updateDate' => { - message => q|The date of the last time this record has been updated.|, - lastUpdated => 1149822982, - }, - - 'record.updatedBy' => { - message => q|The username of the person that made the most recent update to this.|, - lastUpdated => 1167189177, - }, - - 'record.valueLoop' => { - message => q|A loop containing the values for each field of this record.|, - lastUpdated => 1167189240, - }, - - 'record.value' => { - message => q|The value the record has for this field.|, - lastUpdated => 1149822982, - }, - - 'record.value.isFile' => { - message => q|Conditional being true if this field contains an uploaded file. -Also returns true if the file is an image.|, - lastUpdated => 1149822982, - }, - - 'record.value.isImage' => { - message => q|Conditional indicating if the uploaded file is an image.|, - lastUpdated => 1149822982, - }, - - 'record.value.downloadUrl' => { - message => q|The url to download the uploaded file in this field. Only -available for files and images.|, - lastUpdated => 1149822982, - }, - - 'superSearch.url' => { - message => q|The url to the advanced search mode.|, - lastUpdated => 1149822982, - }, - - 'superSearch.label' => { - message => q|The internationalized name of the advanced search.|, - lastUpdated => 1149822982, - }, - - 'normalSearch.url' => { - message => q|The url to the normal search mode.|, - lastUpdated => 1149822982, - }, - - 'normalSearch.label' => { - message => q|The internationalized name of the normal search.|, - lastUpdated => 1149822982, - }, - - 'showMetaData' => { - message => q|A conditional indicating whether or not the show meta data flag is turned on.|, - lastUpdated => 1167189276, - }, - - 'managementLinks' => { - message => q|A collection of links to the admin functions of the SQLForm like manage fields, -as well as links to add record and search record.|, - lastUpdated => 1149822982, - }, - - 'dft cannot delete' => { - message => q|This field type cannot by deleted beacause it still is in use by|, - lastUpdated => 0, - }, - - 'sqlforms' => { - message => q|SQLForms|, - lastUpdated => 0, - }, - - 'clear' => { - message => q|Clear|, - lastUpdated => 0, - }, - - 'cancel' => { - message => q|Cancel|, - lastUpdated => 0, - }, - - 'gef import table' => { - message => q|Import this table|, - lastUpdated => 0, - }, - - 'gef import table description' => { - message => q|

This option is a safety measure against -accidentally importing existing tables. Importing existing tables will alter -the table by removing primary keys and adding columns. Therefore make sure -that altering the table you want to import will not break other systems. If -you're sure no harm can be done you must select this option to allow importing -the table.

|, - lastUpdated => 1167187507, - }, - - 'ers change notification' => { - message => q|Change notification|, - lastUpdated => 0, - }, - - 'ers change on table' => { - message => q|A change has been made on table|, - lastUpdated => 0, - }, - - 'ers by user' => { - message => q|by user|, - lastUpdated => 0, - }, - - 'ers view url' => { - message => q|You can view this change by clicking on this url:|, - lastUpdated => 0, - }, - - 'sql form asset template variables title' => { - message => q|SQLForm Asset Template Variables|, - lastUpdated => 1164841146 - }, - - 'formId' => { - message => q|This variable will always be empty.|, - lastUpdated => 1169508478 - }, - - 'tableName' => { - message => q|The name of the table in the database that will be used.|, - lastUpdated => 1169508478 - }, - - 'maxFileSize' => { - message => q|The maximum size of files that will be uploaded in this SQLForm.|, - lastUpdated => 1169508478 - }, - - 'sendMailTo' => { - message => q|The email address of the person who will be notified via email every time a row is added or edited.|, - lastUpdated => 1169508478 - }, - - 'showMetaData' => { - message => q|A conditional indicating whether or not record meta data will be shown in search results.|, - lastUpdated => 1169508478 - }, - - 'searchTemplateId' => { - message => q|The ID of the template used to display the search interface to the user.|, - lastUpdated => 1169508478 - }, - - 'editTemplateId' => { - message => q|The ID of the template used to display the editing and viewing interface to the user|, - lastUpdated => 1169508478 - }, - - 'submitGroupId' => { - message => q|The ID of the group allowed to add, edit, delete and restore rows, but not to purge them.|, - lastUpdated => 1169508478 - }, - - 'alterGroupId' => { - message => q|This variable will always be false.|, - lastUpdated => 1169508478 - }, - - 'databaseLinkId' => { - message => q|The ID of the WebGUI Database Link to use.|, - lastUpdated => 1169508478 - }, - - 'defaultView' => { - message => q|A conditional that indicates whether the normal or advanced search interface will be used.|, - lastUpdated => 1169508478 - }, - - - 'advanced search template help title' => { - message => q|SQLForm, Advanced Search Record Template|, - lastUpdated => 0, - }, - -}; - -1; - diff --git a/www/extras/assets/small/sqlform.gif b/www/extras/assets/small/sqlform.gif deleted file mode 100644 index 96cff3d722a30311920606800535856d39efb2c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmZ?wbhEHb6krfw*v!XJQ(ZZEQvZt=FD{=y+|*cCke_$r#EBWxr*(C7XuPk+6AqKWHpLgPlpDQA6?0(S`Yy1O6pI$@@>pr>kW I9|MCm01MVa(f|Me diff --git a/www/extras/assets/sqlform.gif b/www/extras/assets/sqlform.gif deleted file mode 100644 index 1ca2486464495e9787138c159bd2ceec251fde30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1426 zcmd^;i%*kx6o!8-#g-yi%SCjk=yXDZOU;$CS;PZ_}qtEA)%jFh}Woc>2X0wR~28M=)I2?{nrz4Zep-@OD6uMllU@*9_ zurRJxYsSX`08>*_Yiny#iR5{TrROjV4-F1RqcKPzu+Pj)n@kRegU{nVd-iNXqnVhP zaL&$lF&JD9$LsYn`}*V~Bk_2g&*yhPe7L;4tX8X;OeTxTv^yMc-@Y9X3T4B?!&2$W z%F5`dYI$YF?RL{>G@suu85)|OpJ&kNLJ0D}u+3(LJszPD(r7eRo6TS_$Ye5?+bxku zOeT{M5>8BL?DiS6+3a-AiA5s6-xmsnpDr#21A#@acX4qsnM|lgNBKOy8-~Z!V=1jt zseIVgrPu2xwc0snD){W&oYUc$l}e-{k?6^jC-#|CMSD0B>FwzW27*?r)$j8sk_n|k z`KY%ShCPr_7>z_C(J1VJ!{HE{&6bbIwOXx0p@>AnJRV;mmk*>64R}28;NalcSjs%+ zoO?HcKtMIB;;`99gMr88s#Hp!*9$?=q;}F~wK5ot)z#IW?rx=05sSst>anHxl3XE= z#iFhSmrAJ|k;(e{9=}>!6N|-nsnq`d{u!H1z!x~3>oC{nV7l<4GoyH*VZmUtdq% z@&C-OHz))EB2fBn3GaRaVAjDm8HKeHmaY|(L#Q`P`t|L&_m4fQm9mX@3qJbMUwnXW zx?e=179JWtOTY+D4b)qPc{aN6cz(s_GQPdH{3q`p7GfUZtBO|a_G2SZU0>#J+ZwFb zi|3m=1Jp zJ$0ThxpyMFF=#>W%dO`IL-C(q1Side`rBD z)1cYR?X2C1bqS^ju=75}lN+m8rjl5q61(GXof%VebX%}HT0Xqq_23Y?;aqP+xcdU8 z<=}hyaiQtVrl!{${8wb@C+`%0PoBD+aYno=)F!ciZOGY*nfx7rDaKdbEbTl8O7>>6 zN#HQltk26cv#1;U#+%c2UM_c5m)yTpX#wYHji4HTr>?qSFPk`t;ET<>Zz2z{Dp4C~ zud6QR183mYectZ&?E)0C4fit3RfR@7afr-}VyQkC{XxNZgo~v_9W#@abP@8PqKd-P zrzGJoi|}+R68m}-a9guc709+1NfO~+KHUmfA5t`L7V z;S2oc=XCN8?%pnCjDbdewg;qPiET|tOkr7~eJffFkZD^qThF5q9oMY8PWh7*&{MXV zg1JgdTJW6f&X$_n*orEE=dyGg3$GGeH 0) { - enableField('SQLFormFieldConstraintTarget'); - if ( - (document.getElementById('SQLFormFieldConstraintTarget').value == 'value') || - (document.getElementById('SQLFormFieldConstraintTarget').value == '' && document.getElementById('SQLFormFieldConstraintValue').value != '') - ) { - enableField('SQLFormFieldConstraintValue'); - } else { - disableField('SQLFormFieldConstraintValue'); - } - } else { - disableField('SQLFormFieldConstraintTarget'); - disableField('SQLFormFieldConstraintValue'); - } -} - -function enableField(id) { - var e = document.getElementById(id); - - if (e) { - e.disabled = false; - e.style.display = ''; - } - - // also hide row if applicable - var tr = document.getElementsByTagName("tr"); - if (tr == null) return; - for (i=0; i < tr.length; i++) { - if(tr[i].className == id+'Row') { - tr[i].style.display = ''; - } - } - -// document.getElementById(id+'row').style.display = ''; -} - -function disableField(id) { - var e = document.getElementById(id); - - if (e) { - e.disabled = true; - e.style.display = 'none'; - } - - var tr = document.getElementsByTagName("tr"); - if (tr == null) return; - for (i=0; i < tr.length; i++) { - if(tr[i].className == id+'Row') { - tr[i].style.display = 'none'; - } - } - -// document.getElementById(id+'row').style.display = 'none'; -} - diff --git a/www/extras/wobject/SQLForm/SQLFormJoinSelector.js b/www/extras/wobject/SQLForm/SQLFormJoinSelector.js deleted file mode 100644 index b576c5017..000000000 --- a/www/extras/wobject/SQLForm/SQLFormJoinSelector.js +++ /dev/null @@ -1,375 +0,0 @@ -// databaseMap is use to store the available db's -var databaseMap = new Object; - -// tableMap is used to cache array of table options. This could lessen the -// number of requests to the server. -var tableMap = new Object; - -// columnMap will hold the columnnames (including db and tablename) for each -// joinselector -var columnMap = new Object; - -var resultList1, resultList2 = null - -function initDatabaseMap(databases) { - databaseMap = databases; -} - -function setResultFields(field1, field2) { - resultList1 = field1; - resultList2 = field2; -} - -//----------------------------------------------------------------------------- -function setAvailableDatabaseOptions(zup) { - zup.options[zup.options.length] = new Option('Please select a database', ''); - for (var i = 0; i < databaseMap.length; i++) { - zup.options[zup.options.length] = new Option(databaseMap[i].key, databaseMap[i].value); - } -} - -// Processes XML -//----------------------------------------------------------------------------- -function processAjaxXml(req, selectList, cache, prepend) { - var options = req.responseXML.getElementsByTagName("Option"); - - if (!prepend) { - prepend = ''; - } - - for (var i = 0; i < options.length; i++) { - var optionKey = prepend + options[i].getElementsByTagName("Key")[0].firstChild.nodeValue; - var optionValue = prepend + options[i].getElementsByTagName("Value")[0].firstChild.nodeValue; - - if (cache) { - cache[cache.length] = { - key : optionKey, - value : optionValue - }; - } - if (selectList) { - selectList.options[selectList.options.length] = new Option(optionKey, optionValue); //currentOption; - } - } -} - -//----------------------------------------------------------------------------- -function addJoinButtonRow(tableId, rowNumber) { - table = document.getElementById(tableId); - - //rowNumber = table.rows.length - 1; - // Create join button - tr = table.insertRow(table.rows.length); - tr.id = 'joinButtonRow'; - td = tr.insertCell(tr.cells.length); - td.innerHTML = ''; - td.colSpan = 7; - document.getElementById('joinButton'+rowNumber).onclick = function() { - hideElement('joinButton'+rowNumber); - table.deleteRow(table.rows.length - 1); // Delete row with button - addSelectorRow(tableId); - } - hideElement('joinButton'+rowNumber); -} - -//----------------------------------------------------------------------------- -function deleteRows(tableId, stopAtRow) { - table = document.getElementById(tableId); - - for (var i = table.rows.length; i > stopAtRow; i--) { - table.deleteRow(table.rows.length - 1); - } - - addJoinButtonRow(tableId, stopAtRow); -} - -//----------------------------------------------------------------------------- -function hideElement(elementId) { - element = document.getElementById(elementId); - - if (element) { - element.style.display = 'none'; - element.disabled = true; - } - -} - -//----------------------------------------------------------------------------- -function unhideElement(elementId) { - element = document.getElementById(elementId); - - if (element) { - element.style.display = ''; - element.disabled = false; - } - -} - -//----------------------------------------------------------------------------- -function hideJoinConstraints(rowNumber) { - hideElement('on'+rowNumber); - hideElement('joinFunction'+rowNumber); - hideElement('joinOnA'+rowNumber); - hideElement('joinOnB'+rowNumber); -} - -//----------------------------------------------------------------------------- -function unhideJoinConstraints(rowNumber) { - unhideElement('on'+rowNumber); - unhideElement('joinFunction'+rowNumber); - unhideElement('joinOnA'+rowNumber); - unhideElement('joinOnB'+rowNumber); -} - -//----------------------------------------------------------------------------- -function addSelectorRow(tableId, formDatabase, formTable, formJoinOnA, formJoinOnB, formJoinFunction) { - var table = document.getElementById(tableId); - var tr, selectName, tds = ''; - - if (!table) { - alert('Fatal error: tableId does not exist.'); - } - - var rowNumber = table.rows.length + 1; - - // Insert a row - tr = table.insertRow(table.rows.length); - - // Table label - tr.insertCell(tr.cells.length).innerHTML = 'table'+rowNumber+''; - - // Create database selector - selectName = 'database'+rowNumber; - td = tr.insertCell(tr.cells.length); - td.innerHTML = ''; - s = document.getElementById(selectName); - setAvailableDatabaseOptions(s); - s.onchange = function() { - setTablesInSelectList(rowNumber, s.value); - deleteRows(tableId, rowNumber); - hideJoinConstraints(rowNumber); - unhideElement('table'+rowNumber); - toggleJoinButton(rowNumber); - }; - if (formDatabase) { - s.value = formDatabase; - } - - // Create table selector - selectName = 'table'+rowNumber; - td = tr.insertCell(tr.cells.length); - td.innerHTML = ''; - document.getElementById(selectName).onchange = function() { - setJoinOnA(rowNumber); - setJoinOnB(rowNumber); - updateFields(rowNumber); - deleteRows(tableId, rowNumber); - if (rowNumber > 1) { - unhideJoinConstraints(rowNumber); - } - toggleJoinButton(rowNumber); - } - if (formDatabase) { - setTablesInSelectList(rowNumber, formDatabase); - document.getElementById(selectName).value = formTable; - } else { - hideElement(selectName); - } - - // Create on word - td = tr.insertCell(tr.cells.length); - td.innerHTML = ' on '; - td.id = 'on'+rowNumber; - - // Create first join selector - selectName = 'joinOnA'+rowNumber; - td = tr.insertCell(tr.cells.length); - td.innerHTML = ''; - document.getElementById(selectName).onchange = function() { - toggleJoinButton(rowNumber); - } - - // Create joinFunction thingy - selectName = 'joinFunction'+rowNumber; - td = tr.insertCell(tr.cells.length); - td.innerHTML = ''; - document.getElementById(selectName).options[0] = new Option('Intersect on', 'intersection'); - document.getElementById(selectName).options[1] = new Option('Difference on', 'difference'); - - // Create second join selector - selectName = 'joinOnB'+rowNumber; - td = tr.insertCell(tr.cells.length); - td.innerHTML = ''; - document.getElementById(selectName).onchange = function() { - toggleJoinButton(rowNumber); - } - - - if (formDatabase && formTable) { - setJoinOnA(rowNumber, formJoinOnA, formDatabase, formTable); - setJoinOnB(rowNumber); - document.getElementById('joinOnA'+rowNumber).value = formJoinOnA; - document.getElementById('joinOnB'+rowNumber).value = formJoinOnB; - document.getElementById('joinFunction'+rowNumber).value = formJoinFunction; - } else { - // Hide the join constraint controls - hideJoinConstraints(rowNumber); - } - if (rowNumber == 1) { - hideJoinConstraints(rowNumber); - } - - // Finally add a row containing a hidden 'join with' button - if (!(formDatabase || formTable || formJoinOnA || formJoinOnB)) { - addJoinButtonRow(tableId, rowNumber); - } -} - -//----------------------------------------------------------------------------- -function setJoinOnA(rowNumber) { - var databaseName = document.getElementById('database'+rowNumber).value; - var tableName = document.getElementById('table'+rowNumber).value; - var prepend = 'table' + rowNumber + '.'; - var s = document.getElementById('joinOnA'+rowNumber); - - s.length = 0; - s.options[s.options.length] = new Option('Please select a column', ''); - columnMap[rowNumber] = [ ]; - - // Do AJAX request - var r = new AjaxRequest; - var params = { - 'parameters' : { - 'func' : 'processAjaxRequest', - 'dbName' : databaseName, - 'tName' : tableName - }, - 'async' : false, - 'onSuccess' : function(req) { processAjaxXml(req, s, columnMap[rowNumber], prepend); } - }; - - r.method = 'POST'; - r.handleArguments(params); - r.process(); - r.onCompleteInternal(); -} - -//----------------------------------------------------------------------------- -function setJoinOnB(rowNumber) { - if (rowNumber > 1) { - var s = document.getElementById('joinOnB'+rowNumber); - s.length = 0; - s.options[s.options.length] = new Option('Please select a column', ''); - - for (var currentRow = 1; currentRow < rowNumber; currentRow++) { - if (currentRow == 1 || document.getElementById('joinFunction'+currentRow).value != 'difference') { - for (var i = 0; i < columnMap[currentRow].length; i++) { - s.options[s.options.length] = new Option(columnMap[currentRow][i].key, columnMap[currentRow][i].value); - } - } - } - } -} - -//----------------------------------------------------------------------------- -function updateFields(rowNumber,value1,value2, ccValue, fcValue) { - var s1 = document.getElementById(resultList1); - s1.length = 0; - s1.options[s1.options.length] = new Option('Please select a column', ''); - - var s2 = document.getElementById(resultList2); - s2.length = 0; - s2.options[s2.options.length] = new Option('Please select a column', ''); - - var cc = document.getElementById('joinConstraintColumn'); - cc.length = 0; - cc.options[cc.options.length] = new Option('Please select a column', ''); - - var fc = document.getElementById('SQLFormFieldConstraintTarget'); - fc.length = 0; - fc.options[fc.options.length] = new Option('Custom value', 'value'); - - for (var currentRow = 1; currentRow <= rowNumber; currentRow++) { - if (columnMap[currentRow] && (currentRow == 1 || document.getElementById('joinFunction'+currentRow).value != 'difference')) { - for (var i = 0; i < columnMap[currentRow].length; i++) { - s1.options[s1.options.length] = new Option(columnMap[currentRow][i].key, columnMap[currentRow][i].value); - s2.options[s2.options.length] = new Option(columnMap[currentRow][i].key, columnMap[currentRow][i].value); - cc.options[cc.options.length] = new Option(columnMap[currentRow][i].key, columnMap[currentRow][i].value); - fc.options[fc.options.length] = new Option(columnMap[currentRow][i].key, columnMap[currentRow][i].value); - } - } - } - if (value1) { - s1.value = value1; - } - if (value2) { - s2.value = value2; - } - if (ccValue) { - cc.value = ccValue; - } - if (fcValue) { - fc.value = fcValue; - } -} - -//----------------------------------------------------------------------------- -function setTablesInSelectList(rowNumber, database) { - var s = document.getElementById('table'+rowNumber); - - if (!s) { - alert('Fatal error: selectList (table'+rowNumber+') does not exist.'); - } - - // Empty select list. - s.length = 0; - s.options[s.options.length] = new Option('Please select a table', ''); - - // If the tables aren't cached in tableMap yet, fetch them using AJAX. - if (!tableMap[database]) { - tableMap[database] = [ ]; - - // Do AJAX request - var r = new AjaxRequest; - var params = { - 'parameters' : { - 'func' : 'processAjaxRequest', - 'dbName' : database - }, - 'async' : false, - 'onSuccess' : function(req) { processAjaxXml(req, s, tableMap[database]); } - }; - - r.method = 'POST'; - r.handleArguments(params); - r.process(); - // Must run this by hand because in sync-mode the internal event handlers are not called. - r.onCompleteInternal(); - // If they are cached then put them in the select list. - } else { - for (var i = 0; i < tableMap[database].length; i++) { - s.options[s.options.length] = new Option(tableMap[database][i].key, tableMap[database][i].value); - } - } -} - -//----------------------------------------------------------------------------- -function toggleJoinButton(rowNumber) { - if (document.getElementById('database'+rowNumber) && document.getElementById('table'+rowNumber)) { - if ( - (document.getElementById('database'+rowNumber).selectedIndex > 0) && - (document.getElementById('table'+rowNumber).selectedIndex > 0) && - ( - (rowNumber == 1) || - ( - (document.getElementById('joinOnA'+rowNumber).selectedIndex > 0) && - (document.getElementById('joinOnB'+rowNumber).selectedIndex > 0) - ) - ) - ) { - unhideElement('joinButton'+rowNumber); - } else { - hideElement('joinButton'+rowNumber); - } - } -} diff --git a/www/extras/wobject/SQLForm/SQLFormSearch.js b/www/extras/wobject/SQLForm/SQLFormSearch.js deleted file mode 100644 index d0cef1569..000000000 --- a/www/extras/wobject/SQLForm/SQLFormSearch.js +++ /dev/null @@ -1,69 +0,0 @@ -function switchField(id, switchOn) { - - e = document.getElementById(id); - if (!e) { - alert("Not a valid id: ["+id+"]"); - } - - if (switchOn) { - document.getElementById(id).disabled = false; - document.getElementById(id).style.display = ''; - } else { - document.getElementById(id).disabled = true; - document.getElementById(id).style.display = 'none'; - } -} - -function switchListField(conditional, id) { - if (conditional == '') { - switchField(id+'-1', false); - switchField(id+'-2', false); - } else { - if (conditional == 100 || conditional == 101) { - switchField(id+'-1', true); - switchField(id+'-2', false); - } else { - switchField(id+'-1', false); - switchField(id+'-2', true); - } - } -} - -function switchNumberField(conditional, id) { - if (conditional == '') { - switchField(id+'-1', false); - switchField(id+'-2', false); - } else { - if (conditional == 10) { - switchField(id+'-1', true); - switchField(id+'-2', true); - } else { - switchField(id+'-1', true); - switchField(id+'-2', false); - } - } -} - -function switchTemporalField(conditional, id) { - if (conditional == '') { - switchField(id+'-1', false); - switchField(id+'-2', false); - } else { - if (conditional == 10) { - switchField(id+'-1', true); - switchField(id+'-2', true); - } else { - switchField(id+'-1', true); - switchField(id+'-2', false); - } - } -} - -function switchTextField(conditional, id) { - if (conditional == '') { - switchField(id+'-1', false); - } else { - switchField(id+'-1', true); - } -} - diff --git a/www/extras/wobject/SQLForm/SQLFormViewButton.gif b/www/extras/wobject/SQLForm/SQLFormViewButton.gif deleted file mode 100644 index d3fadddf0028d1be68d176b093d1874e4f259694..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1175 zcmds$X-}F50DxZ<9Xgk)vxb>&wdtA})26lcgLd6w)5AH_OwF>mW?S5>QM=hFDvbL* z5EMi}0rBN{xna<*-nI;_7q!^B0Yjp*t-5;52JryWELq~#zp>}T^Zoho6c%00%m4NS zkOaIM2KFNn5CoZ+v8kzPKN6kt2iRpnD5ApJ zv_^K99D*RWMvthm8ZLkI@!ZP##?P*Yi+{e5+wW4Pit+LB?VVk8#KBc-MF#WO*jP9k zt%Nu(e*jcru+Bv4>Sn2RB23rX+R8wXkr}tmW_uahL6jItrr?+?Uawc)KSbB)S`3!@ z`g#f*5_fl3Fu})xg$bX3Hyoi*D6}38*rUGVaNcZcwognupUjyZqeD|J?;lG~<^%K& zah*`i7cwDpbz7-)^;wSRyg3!seG(wn8Dk$wHT- z^Us(0l1{$a3Zp8TOi@Xt^R;?*k7_p@u41svj$f(~E`+Kjw|hk*kz8-Qg{1fD)?5Q>1?7hcFef1$pBRiF(##7bxi#elBple4g-b5K z?~6yelL$aT+NP}F_*+&YtwfMcNKVU&1l=}ysbP>dyjoOD_?_6P5cgdv7N+N+3lR>W zt1i24clt7x23#fAzpia5pQwpRIzj&Yt1lzQYAA*r_BrUdnU;a-+WgX?_0L-Hj9yiL zjCB)=?Kpl^_)j!Q%q{4@L6TK;{`7I-jXc5y^oy;&%HmkFOD}#e=cAKF_fl#vrF`1| z>+I|`!K=`+ozA_v4#$6R`tVEX`OEm!RNOal1(rDG+31#kw8OFH_NKn6wBG> z=gMm8RvKaspDH