Yaron Koren has submitted this change and it was merged.

Change subject: Added support for the new Cargo extension
......................................................................


Added support for the new Cargo extension

Change-Id: I8fdb35045576cf1bb5d3f1cdb36fdddf6c2ca246
---
M SemanticForms.php
M includes/SF_AutocompleteAPI.php
M includes/SF_FormField.php
M includes/SF_FormPrinter.php
M includes/SF_FormUtils.php
M includes/SF_TemplateField.php
M includes/SF_TemplateInForm.php
M includes/SF_Utils.php
M includes/forminputs/SF_CheckboxInput.php
M includes/forminputs/SF_CheckboxesInput.php
M includes/forminputs/SF_ComboBoxInput.php
M includes/forminputs/SF_DateInput.php
M includes/forminputs/SF_DateTimeInput.php
M includes/forminputs/SF_DropdownInput.php
M includes/forminputs/SF_EnumInput.php
M includes/forminputs/SF_FormInput.php
M includes/forminputs/SF_MultiEnumInput.php
M includes/forminputs/SF_OpenLayersInput.php
M includes/forminputs/SF_TextAreaInput.php
M includes/forminputs/SF_TextAreaWithAutocompleteInput.php
M includes/forminputs/SF_TextInput.php
M includes/forminputs/SF_TextWithAutocompleteInput.php
M includes/forminputs/SF_TokensInput.php
M includes/forminputs/SF_TreeInput.php
M includes/forminputs/SF_YearInput.php
M libs/SemanticForms.js
M libs/ext.sf.select2.combobox.js
M libs/ext.sf.select2.tokens.js
28 files changed, 582 insertions(+), 65 deletions(-)

Approvals:
  Yaron Koren: Verified; Looks good to me, approved



diff --git a/SemanticForms.php b/SemanticForms.php
index 43dfcfd..fc19946 100644
--- a/SemanticForms.php
+++ b/SemanticForms.php
@@ -502,7 +502,10 @@
 # ##
 $GLOBALS['sfgShowOnSelect'] = array();
 $GLOBALS['sfgAutocompleteValues'] = array();
+// SMW
 $GLOBALS['sfgFieldProperties'] = array();
+// Cargo
+$GLOBALS['sfgCargoFields'] = array();
 $GLOBALS['sfgDependentFields'] = array();
 
 /**
diff --git a/includes/SF_AutocompleteAPI.php b/includes/SF_AutocompleteAPI.php
index 2712d78..a6407a0 100644
--- a/includes/SF_AutocompleteAPI.php
+++ b/includes/SF_AutocompleteAPI.php
@@ -25,12 +25,17 @@
                $property = $params['property'];
                $category = $params['category'];
                $concept = $params['concept'];
+               $cargo_table = $params['cargo_table'];
+               $cargo_field = $params['cargo_field'];
+               $field_is_array = $params['field_is_array'];
                $external_url = $params['external_url'];
                $baseprop = $params['baseprop'];
+               $base_cargo_table = $params['base_cargo_table'];
+               $base_cargo_field = $params['base_cargo_field'];
                $basevalue = $params['basevalue'];
                //$limit = $params['limit'];
 
-               if ( is_null( $baseprop ) && strlen( $substr ) == 0 ) {
+               if ( is_null( $baseprop ) && is_null( $base_cargo_table ) && 
strlen( $substr ) == 0 ) {
                        $this->dieUsage( 'The substring must be specified', 
'param_substr' );
                }
 
@@ -44,6 +49,8 @@
                        $data = SFUtils::getAllPagesForCategory( $category, 3, 
$substr );
                } elseif ( !is_null( $concept ) ) {
                        $data = SFUtils::getAllPagesForConcept( $concept, 
$substr );
+               } elseif ( !is_null( $cargo_table ) && !is_null( $cargo_field ) 
) {
+                       $data = self::getAllValuesForCargoField( $cargo_table, 
$cargo_field, $field_is_array, $substr, $base_cargo_table, $base_cargo_field, 
$basevalue );
                } elseif ( !is_null( $namespace ) ) {
                        $data = SFUtils::getAllPagesForNamespace( $namespace, 
$substr );
                } elseif ( !is_null( $external_url ) ) {
@@ -96,9 +103,14 @@
                        'property' => null,
                        'category' => null,
                        'concept' => null,
+                       'cargo_table' => null,
+                       'cargo_field' => null,
+                       'field_is_array' => null,
                        'namespace' => null,
                        'external_url' => null,
                        'baseprop' => null,
+                       'base_cargo_table' => null,
+                       'base_cargo_field' => null,
                        'basevalue' => null,
                );
        }
@@ -167,21 +179,21 @@
                if ( $propertyHasTypePage ) {
                        $valueField = 'o_ids.smw_title';
                        if ( $smwgDefaultStore === 'SMWSQLStore3' ) {
-                               $idsTable =  $db->tableName( 'smw_object_ids' );
+                               $idsTable = $db->tableName( 'smw_object_ids' );
                                $propsTable = $db->tableName( 'smw_di_wikipage' 
);
                        } else {
-                               $idsTable =  $db->tableName( 'smw_ids' );
+                               $idsTable = $db->tableName( 'smw_ids' );
                                $propsTable = $db->tableName( 'smw_rels2' );
                        }
                        $fromClause = "$propsTable p JOIN $idsTable p_ids ON 
p.p_id = p_ids.smw_id JOIN $idsTable o_ids ON p.o_id = o_ids.smw_id";
                } else {
                        if ( $smwgDefaultStore === 'SMWSQLStore3' ) {
                                $valueField = 'p.o_hash';
-                               $idsTable =  $db->tableName( 'smw_object_ids' );
+                               $idsTable = $db->tableName( 'smw_object_ids' );
                                $propsTable = $db->tableName( 'smw_di_blob' );
                        } else {
                                $valueField = 'p.value_xsd';
-                               $idsTable =  $db->tableName( 'smw_ids' );
+                               $idsTable = $db->tableName( 'smw_ids' );
                                $propsTable = $db->tableName( 'smw_atts2' );
                        }
                        $fromClause = "$propsTable p JOIN $idsTable p_ids ON 
p.p_id = p_ids.smw_id";
@@ -195,10 +207,10 @@
                        $conditions['base_p_ids.smw_title'] = $basePropertyName;
                        if ( $basePropertyHasTypePage ) {
                                if ( $smwgDefaultStore === 'SMWSQLStore3' ) {
-                                       $idsTable =  $db->tableName( 
'smw_object_ids' );
+                                       $idsTable = $db->tableName( 
'smw_object_ids' );
                                        $propsTable = $db->tableName( 
'smw_di_wikipage' );
                                } else {
-                                       $idsTable =  $db->tableName( 'smw_ids' 
);
+                                       $idsTable = $db->tableName( 'smw_ids' );
                                        $propsTable = $db->tableName( 
'smw_rels2' );
                                }
                                $fromClause .= " JOIN $propsTable p_base ON 
p.s_id = p_base.s_id";
@@ -208,11 +220,11 @@
                        } else {
                                if ( $smwgDefaultStore === 'SMWSQLStore3' ) {
                                        $baseValueField = 'p_base.o_hash';
-                                       $idsTable =  $db->tableName( 
'smw_object_ids' );
+                                       $idsTable = $db->tableName( 
'smw_object_ids' );
                                        $propsTable = $db->tableName( 
'smw_di_blob' );
                                } else {
                                        $baseValueField = 'p_base.value_xsd';
-                                       $idsTable =  $db->tableName( 'smw_ids' 
);
+                                       $idsTable = $db->tableName( 'smw_ids' );
                                        $propsTable = $db->tableName( 
'smw_atts2' );
                                }
                                $fromClause .= " JOIN $propsTable p_base ON 
p.s_id = p_base.s_id";
@@ -244,4 +256,70 @@
                return $values;
        }
 
+       private static function getAllValuesForCargoField( $cargoTable, 
$cargoField, $fieldIsArray, $substring, $baseCargoTable = null, $baseCargoField 
= null, $baseValue = null ) {
+               global $sfgMaxAutocompleteValues, $sfgCacheAutocompleteValues, 
$sfgAutocompleteCacheTimeout;
+               global $sfgAutocompleteOnAllChars;
+
+               $values = array();
+               $tablesStr = $cargoTable;
+               $fieldsStr = $cargoField;
+               $joinOnStr = '';
+               $whereStr = '';
+
+               // Use cache if allowed
+               if ( $sfgCacheAutocompleteValues ) {
+                       $cache = SFFormUtils::getFormCache();
+                       // Remove trailing whitespace to avoid unnecessary 
database selects
+                       $cacheKeyString = $cargoTable . '|' . $cargoField . '|' 
. rtrim( $substring );
+                       if ( !is_null( $baseCargoTable ) ) {
+                               $cacheKeyString .= '|' . $baseCargoTable . '|' 
. $baseCargoField . '|' . $baseValue;
+                       }
+                       $cacheKey = wfMemcKey( 'sf-autocomplete' , md5( 
$cacheKeyString ) );            
+                       $values = $cache->get( $cacheKey );
+
+                       if ( !empty( $values ) ){
+                               // Return with results immediately
+                               return $values;
+                       }
+               }
+
+               if ( !is_null( $baseCargoTable ) && !is_null( $baseCargoField ) 
) {
+                       if ( $baseCargoTable != $cargoTable ) {
+                               $tablesStr .= ", $baseCargoTable";
+                               $joinOnStr = "$cargoTable._pageName = 
$baseCargoTable._pageName";
+                       }
+                       $whereStr = "$baseCargoTable.$baseCargoField = 
\"$baseValue\"";
+               }
+
+               if ( !is_null( $substring ) ) {
+                       if ( $whereStr != '' ) {
+                               $whereStr .= " AND ";
+                       }
+                       $operator = ( $fieldIsArray ) ? "HOLDS LIKE" : "LIKE";
+                       if ( $sfgAutocompleteOnAllChars ) {
+                               $whereStr .= "($cargoField $operator 
\"%$substring%\")";
+                       } else {
+                               $whereStr .= "($cargoField $operator 
\"$substring%\" OR $cargoField $operator \"% $substring%\")";
+                       }
+               }
+
+               $sqlQuery = CargoSQLQuery::newFromValues( $tablesStr, 
$fieldsStr, $whereStr, $joinOnStr, $cargoField, $cargoField, 
$sfgMaxAutocompleteValues );
+               $cargoFieldAlias = str_replace( '_', ' ', $cargoField );
+               $queryResults = $sqlQuery->run();
+
+               foreach ( $queryResults as $row ) {
+                       // @TODO - this check should not be neceaary.
+                       if ( ( $value = $row[$cargoFieldAlias] ) != '' ) {
+                               $values[] = $value;
+                       }
+               }
+
+               if ( $sfgCacheAutocompleteValues ) {
+                       // Save to cache.
+                       $cache->set( $cacheKey, $values, 
$sfgAutocompleteCacheTimeout );
+               }
+
+               return $values;
+       }
+
 }
diff --git a/includes/SF_FormField.php b/includes/SF_FormField.php
index 591d7ec..b0dd44e 100644
--- a/includes/SF_FormField.php
+++ b/includes/SF_FormField.php
@@ -333,24 +333,7 @@
                return $text;
        }
 
-       /**
-        * Since Semantic Forms uses a hook system for the functions that
-        * create HTML inputs, most arguments are contained in the "$other_args"
-        * array - create this array, using the attributes of this form
-        * field and the template field it corresponds to, if any
-        */
-       function getArgumentsForInputCall( $default_args = null ) {
-               // start with the arguments array already defined
-               $other_args = $this->mFieldArgs;
-               // a value defined for the form field should always supersede
-               // the coresponding value for the template field
-               if ( $this->mPossibleValues != null ) {
-                       $other_args['possible_values'] = $this->mPossibleValues;
-               } else {
-                       $other_args['possible_values'] = 
$this->template_field->getPossibleValues();
-                       $other_args['value_labels'] = 
$this->template_field->getValueLabels();
-               }
-               $other_args['is_list'] = ( $this->mIsList || 
$this->template_field->isList() );
+       function getArgumentsForInputCallSMW( &$other_args ) {
                if ( $this->template_field->getSemanticProperty() !== '' &&
                        ! array_key_exists( 'semantic_property', $other_args ) 
) {
                        $other_args['semantic_property'] = 
$this->template_field->getSemanticProperty();
@@ -369,6 +352,50 @@
                                $other_args['autocomplete field type'] = 
'property';
                        }
                }
+       }
+
+       function getArgumentsForInputCallCargo( &$other_args ) {
+               $fullCargoField = $this->template_field->getFullCargoField();
+               if ( $fullCargoField !== null &&
+                       ! array_key_exists( 'full_cargo_field', $other_args ) ) 
{
+                       $other_args['full_cargo_field'] = $fullCargoField;
+               }
+
+               if ( ! array_key_exists( 'autocompletion source', $other_args ) 
) {
+                       if ( $this->template_field->getPropertyType() == '_wpg' 
|| array_key_exists( 'autocomplete', $other_args ) || array_key_exists( 'remote 
autocompletion', $other_args ) ) {
+                               $other_args['autocompletion source'] = 
$this->template_field->getFullCargoField();
+                               $other_args['autocomplete field type'] = 'cargo 
field';
+                       }
+               }
+       }
+
+       /**
+        * Since Semantic Forms uses a hook system for the functions that
+        * create HTML inputs, most arguments are contained in the "$other_args"
+        * array - create this array, using the attributes of this form
+        * field and the template field it corresponds to, if any.
+        */
+       function getArgumentsForInputCall( $default_args = null ) {
+               // start with the arguments array already defined
+               $other_args = $this->mFieldArgs;
+               // a value defined for the form field should always supersede
+               // the coresponding value for the template field
+               if ( $this->mPossibleValues != null ) {
+                       $other_args['possible_values'] = $this->mPossibleValues;
+               } else {
+                       $other_args['possible_values'] = 
$this->template_field->getPossibleValues();
+                       $other_args['value_labels'] = 
$this->template_field->getValueLabels();
+               }
+               $other_args['is_list'] = ( $this->mIsList || 
$this->template_field->isList() );
+
+               // Now add some extension-specific arguments to the input call.
+               if ( defined( 'CARGO_VERSION' ) ) {
+                       $this->getArgumentsForInputCallCargo( $other_args );
+               }
+               if ( defined( 'SMW_VERSION' ) ) {
+                       $this->getArgumentsForInputCallSMW( $other_args );
+               }
+
                // Now merge in the default values set by SFFormPrinter, if
                // there were any - put the default values first, so that if
                // there's a conflict they'll be overridden.
diff --git a/includes/SF_FormPrinter.php b/includes/SF_FormPrinter.php
index 09fc734..654a298 100644
--- a/includes/SF_FormPrinter.php
+++ b/includes/SF_FormPrinter.php
@@ -16,6 +16,7 @@
 class SFFormPrinter {
 
        public $mSemanticTypeHooks;
+       public $mCargoTypeHooks;
        public $mInputTypeHooks;
        public $standardInputsIncluded;
        public $mPageTitle;
@@ -23,12 +24,17 @@
        public function __construct() {
                // Initialize variables.
                $this->mSemanticTypeHooks = array();
+               $this->mCargoTypeHooks = array();
                $this->mInputTypeHooks = array();
                $this->mInputTypeClasses = array();
                $this->mDefaultInputForPropType = array();
                $this->mDefaultInputForPropTypeList = array();
                $this->mPossibleInputsForPropType = array();
                $this->mPossibleInputsForPropTypeList = array();
+               $this->mDefaultInputForCargoType = array();
+               $this->mDefaultInputForCargoTypeList = array();
+               $this->mPossibleInputsForCargoType = array();
+               $this->mPossibleInputsForCargoTypeList = array();
 
                $this->standardInputsIncluded = false;
 
@@ -64,6 +70,10 @@
                $this->mSemanticTypeHooks[$type][$is_list] = array( 
$function_name, $default_args );
        }
 
+       public function setCargoTypeHook( $type, $is_list, $function_name, 
$default_args ) {
+               $this->mCargoTypeHooks[$type][$is_list] = array( 
$function_name, $default_args );
+       }
+
        public function setInputTypeHook( $input_type, $function_name, 
$default_args ) {
                $this->mInputTypeHooks[$input_type] = array( $function_name, 
$default_args );
        }
@@ -88,6 +98,17 @@
                foreach ( $defaultPropertyLists as $propertyType => 
$additionalValues ) {
                        $this->setSemanticTypeHook( $propertyType, true, array( 
$inputTypeClass, 'getHTML' ), $additionalValues );
                        $this->mDefaultInputForPropTypeList[$propertyType] = 
$inputTypeName;
+               }
+
+               $defaultCargoTypes = call_user_func( array( $inputTypeClass, 
'getDefaultCargoTypes' ) );
+               foreach ( $defaultCargoTypes as $fieldType => $additionalValues 
) {
+                       $this->setCargoTypeHook( $fieldType, false, array( 
$inputTypeClass, 'getHTML' ), $additionalValues );
+                       $this->mDefaultInputForCargoType[$fieldType] = 
$inputTypeName;
+               }
+               $defaultCargoTypeLists = call_user_func( array( 
$inputTypeClass, 'getDefaultCargoTypeLists' ) );
+               foreach ( $defaultCargoTypeLists as $fieldType => 
$additionalValues ) {
+                       $this->setCargoTypeHook( $fieldType, true, array( 
$inputTypeClass, 'getHTML' ), $additionalValues );
+                       $this->mDefaultInputForCargoTypeList[$fieldType] = 
$inputTypeName;
                }
 
                $otherProperties = call_user_func( array( $inputTypeClass, 
'getOtherPropTypesHandled' ) );
@@ -302,7 +323,7 @@
                // in the query string, the form ends up being
                // parsed twice.
                if ( array_key_exists( 'is_list', $value ) ) {
-                       unset($value['is_list']);
+                       unset( $value['is_list'] );
                        return implode( "$delimiter ", $value );
                }
 
@@ -459,8 +480,8 @@
                // Unfortunately, we can't just call userCan() here because,
                // since MW 1.16, it has a bug in which it ignores a setting of
                // "$wgEmailConfirmToEdit = true;". Instead, we'll just get the
-               // permission errors from the start, and use those to determine 
whether
-               // the page is editable.
+               // permission errors from the start, and use those to determine
+               // whether the page is editable.
                if ( !$is_query ) {
                        // $userCanEditPage = ( $wgUser->isAllowed( 'edit' ) && 
$this->mPageTitle->userCan( 'edit' ) );
                        $permissionErrors = 
$this->mPageTitle->getUserPermissionsErrors( 'edit', $wgUser );
@@ -506,8 +527,8 @@
 
                $form_def = SFFormUtils::getFormDefinition( $wgParser, 
$form_def, $form_id );
 
-               // Turn form definition file into an array of sections, one for 
each
-               // template definition (plus the first section)
+               // Turn form definition file into an array of sections, one for
+               // each template definition (plus the first section).
                $form_def_sections = array();
                $start_position = 0;
                $section_start = 0;
@@ -520,8 +541,8 @@
                // that themselves contain form elements - the escaping was 
needed
                // to make sure that those elements don't get parsed too early.
                $form_def = str_replace( array( '{', '|', '}' ), 
array( '{', '|', '}' ), $form_def );
-               // And another hack - replace the 'free text' standard input 
with
-               // a field declaration to get it to be handled as a field.
+               // And another hack - replace the 'free text' standard input
+               // with a field declaration to get it to be handled as a field.
                $form_def = str_replace( 'standard input|free text', 
'field|<freetext>', $form_def );
                while ( $brackets_loc = strpos( $form_def, "{{{", 
$start_position ) ) {
                        $brackets_end_loc = strpos( $form_def, "}}}", 
$brackets_loc );
@@ -857,6 +878,8 @@
                                        $values = null;
                                        $possible_values = null;
                                        $semantic_property = null;
+                                       $cargo_table = null;
+                                       $cargo_field = null;
                                        $preload_page = null;
                                        $holds_template = false;
 
@@ -974,6 +997,10 @@
                                                                
$sfgDependentFields[] = array( $sub_components[1], $fullFieldName );
                                                        } elseif ( 
$sub_components[0] == 'property' ) {
                                                                
$semantic_property = $sub_components[1];
+                                                       } elseif ( 
$sub_components[0] == 'cargo table' ) {
+                                                               $cargo_table = 
$sub_components[1];
+                                                       } elseif ( 
$sub_components[0] == 'cargo field' ) {
+                                                               $cargo_field = 
$sub_components[1];
                                                        } elseif ( 
$sub_components[0] == 'default filename' ) {
                                                                
$default_filename = str_replace( '&lt;page name&gt;', $page_name, 
$sub_components[1] );
                                                                // Parse value, 
so default filename can include parser functions.
@@ -1061,7 +1088,7 @@
                                                                        // this 
should be replaced with an input type neutral way of
                                                                        // 
figuring out if this scalar input type is a list
                                                                        if ( 
$input_type == "tokens" ) {
-                                                                               
$is_list=true;
+                                                                               
$is_list = true;
                                                                        }
                                                                        if ( 
$is_list ) {
                                                                                
$cur_values = array_map( 'trim', explode( $delimiter, $field_query_val ) );
@@ -1226,21 +1253,35 @@
                                                        $input_name, 
$is_mandatory, $is_hidden, $is_uploadable,
                                                        $possible_values, 
$is_disabled, $is_list, $input_type,
                                                        $field_args, 
$all_fields, $strict_parsing );
-                                               // If a property was set in the 
form definition, overwrite whatever
-                                               // is set in the template field 
- this is somewhat of a hack, since
-                                               // parameters set in the form 
definition are meant to go into the
-                                               // SFFormField object, not the 
SFTemplateField object it contains;
-                                               // it seemed like too much 
work, though, to create an
-                                               // 
SFFormField::setSemanticProperty() function just for this call
-                                               if ( $semantic_property != null 
) {
-                                                       
$form_field->template_field->setSemanticProperty( $semantic_property );
-                                               }
-                                               $semantic_property = 
$form_field->template_field->getSemanticProperty();
-                                               if ( !is_null( 
$semantic_property ) ) {
-                                                       global 
$sfgFieldProperties;
-                                                       
$sfgFieldProperties[$fullFieldName] = $semantic_property;
-                                               }
 
+                                               // Do some data storage 
specific to the Semantic MediaWiki and
+                                               // Cargo extensions.
+                                               if ( defined( 'SMW_VERSION' ) ) 
{
+                                                       // If a property was 
set in the form definition, overwrite whatever
+                                                       // is set in the 
template field - this is somewhat of a hack, since
+                                                       // parameters set in 
the form definition are meant to go into the
+                                                       // SFFormField object, 
not the SFTemplateField object it contains;
+                                                       // it seemed like too 
much work, though, to create an
+                                                       // 
SFFormField::setSemanticProperty() function just for this call.
+                                                       if ( $semantic_property 
!= null ) {
+                                                               
$form_field->template_field->setSemanticProperty( $semantic_property );
+                                                       }
+                                                       $semantic_property = 
$form_field->template_field->getSemanticProperty();
+                                                       if ( !is_null( 
$semantic_property ) ) {
+                                                               global 
$sfgFieldProperties;
+                                                               
$sfgFieldProperties[$fullFieldName] = $semantic_property;
+                                                       }
+                                               }
+                                               if ( defined( 'CARGO_VERSION' ) 
) {
+                                                       if ( $cargo_table != 
null && $cargo_field != null ) {
+                                                               
$form_field->template_field->setCargoFieldData( $cargo_table, $cargo_field );
+                                                       }
+                                                       $fullCargoField = 
$form_field->template_field->getFullCargoField();
+                                                       if ( !is_null( 
$fullCargoField ) ) {
+                                                               global 
$sfgCargoFields;
+                                                               
$sfgCargoFields[$fullFieldName] = $fullCargoField;
+                                                       }
+                                               }
 
                                                // call hooks - unfortunately 
this has to be split into two
                                                // separate calls, because of 
the different variable names in
@@ -1806,7 +1847,8 @@
 
                // Send the autocomplete values to the browser, along with the
                // mappings of which values should apply to which fields.
-               // If doing a replace, the data text is actually the modified 
original page
+               // If doing a replace, the data text is actually the modified
+               // original page.
                if ( $wgRequest->getCheck( 'partial' ) ) {
                        $data_text = $existing_page_content;
                }
@@ -1857,9 +1899,22 @@
                        $funcArgs[] = $other_args;
                        $text = call_user_func_array( $hook_values[0], 
$funcArgs );
                } else { // input type not defined in form
+                       $cargo_field_type = $template_field->getFieldType();
                        $property_type = $template_field->getPropertyType();
                        $is_list = ( $form_field->isList() || 
$template_field->isList() );
-                       if ( $property_type !== '' &&
+                       if ( $cargo_field_type !== '' &&
+                               array_key_exists( $cargo_field_type, 
$this->mCargoTypeHooks ) &&
+                               isset( 
$this->mCargoTypeHooks[$cargo_field_type][$is_list] ) ) {
+                               $funcArgs = array();
+                               $funcArgs[] = $cur_value;
+                               $funcArgs[] = $form_field->getInputName();
+                               $funcArgs[] = $form_field->isMandatory();
+                               $funcArgs[] = $form_field->isDisabled();
+                               $hook_values = 
$this->mCargoTypeHooks[$cargo_field_type][$is_list];
+                               $other_args = 
$form_field->getArgumentsForInputCall( $hook_values[1] );
+                               $funcArgs[] = $other_args;
+                               $text = call_user_func_array( $hook_values[0], 
$funcArgs );
+                       } elseif ( $property_type !== '' &&
                                array_key_exists( $property_type, 
$this->mSemanticTypeHooks ) &&
                                isset( 
$this->mSemanticTypeHooks[$property_type][$is_list] ) ) {
                                $funcArgs = array();
diff --git a/includes/SF_FormUtils.php b/includes/SF_FormUtils.php
index 755fa9f..5a004a6 100644
--- a/includes/SF_FormUtils.php
+++ b/includes/SF_FormUtils.php
@@ -13,7 +13,7 @@
 class SFFormUtils {
        static function setGlobalJSVariables( &$vars ) {
                global $sfgAutocompleteValues, $sfgAutocompleteOnAllChars;
-               global $sfgFieldProperties, $sfgDependentFields;
+               global $sfgFieldProperties, $sfgCargoFields, 
$sfgDependentFields;
                global $sfgShowOnSelect, $sfgScriptPath;
                global $edgValues, $sfgEDSettings;
 //             global $sfgInitJSFunctions, $sfgValidationJSFunctions;
@@ -21,6 +21,7 @@
                $vars['sfgAutocompleteValues'] = $sfgAutocompleteValues;
                $vars['sfgAutocompleteOnAllChars'] = $sfgAutocompleteOnAllChars;
                $vars['sfgFieldProperties'] = $sfgFieldProperties;
+               $vars['sfgCargoFields'] = $sfgCargoFields;
                $vars['sfgDependentFields'] = $sfgDependentFields;
                $vars['sfgShowOnSelect'] = $sfgShowOnSelect;
                $vars['sfgScriptPath'] = $sfgScriptPath;
diff --git a/includes/SF_TemplateField.php b/includes/SF_TemplateField.php
index 831a255..65df646 100644
--- a/includes/SF_TemplateField.php
+++ b/includes/SF_TemplateField.php
@@ -13,8 +13,16 @@
        private $mFieldName;
        private $mValueLabels;
        private $mLabel;
+
+       // SMW-specific
        private $mSemanticProperty;
        private $mPropertyType;
+
+       // Cargo-specific
+       private $mCargoTable;
+       private $mCargoField;
+       private $mFieldType;
+
        private $mPossibleValues;
        private $mIsList;
        private $mDelimiter;
@@ -117,6 +125,42 @@
                $this->setTypeAndPossibleValues();
        }
 
+       /**
+        * Equivalent to setSemanticProperty(), but called when using Cargo
+        * instead of SMW.
+        */
+       function setCargoFieldData( $tableName, $fieldName, $fieldDescription = 
null ) {
+               $this->mCargoTable = $tableName;
+               $this->mCargoField = $fieldName;
+
+               if ( is_null( $fieldDescription ) ) {
+                       $tableSchemas = CargoUtils::getTableSchemas( array( 
$tableName ) );
+                       if ( count( $tableSchemas ) == 0 ) {
+                               return;
+                       }
+                       $tableSchema = $tableSchemas[$tableName];
+                       $fieldDescriptions = $tableSchema->mFieldDescriptions;
+                       if ( array_key_exists( $fieldName, $fieldDescriptions ) 
) {
+                               $fieldDescription = 
$fieldDescriptions[$fieldName];
+                       } else {
+                               return;
+                       }
+               }
+
+               // We have some "pseudo-types", used for setting the correct
+               // form input.
+               if ( $fieldDescription->mAllowedValues != null ) {
+                       $this->mFieldType = 'Enumeration';
+               } elseif ( $fieldDescription->mType == 'Text' && 
$fieldDescription->mSize <= 100 ) {
+                       $this->mFieldType = 'String';
+               } else {
+                       $this->mFieldType = $fieldDescription->mType;
+               }
+               $this->mIsList = $fieldDescription->mIsList;
+               $this->mDelimiter = $fieldDescription->mDelimiter;
+               $this->mPossibleValues = $fieldDescription->mAllowedValues;
+       }
+
        function getFieldName() {
                return $this->mFieldName;
        }
@@ -137,6 +181,17 @@
                return $this->mPropertyType;
        }
 
+       function getFullCargoField() {
+               if ( $this->mCargoTable == '' || $this->mCargoField == '' ) {
+                       return null;
+               }
+               return $this->mCargoTable . '|' . $this->mCargoField;
+       }
+
+       function getFieldType() {
+               return $this->mFieldType;
+       }
+
        function getPossibleValues() {
                return $this->mPossibleValues;
        }
diff --git a/includes/SF_TemplateInForm.php b/includes/SF_TemplateInForm.php
index 67f2da8..76cbdd4 100644
--- a/includes/SF_TemplateInForm.php
+++ b/includes/SF_TemplateInForm.php
@@ -24,11 +24,18 @@
                $templateFields[$cur_pos] = $templateField;
        }
 
+       function getAllFields() {
+               if ( defined( 'CARGO_VERSION' ) ) {
+                       return $this->getAllFieldsCargo();
+               }
+               return $this->getAllFieldsSMW();
+       }
+
        /**
         * Get the fields of the template, along with the semantic property
         * attached to each one (if any), by parsing the text of the template.
         */
-       function getAllFields() {
+       function getAllFieldsSMW() {
                global $wgContLang;
                $templateFields = array();
                $fieldNamesArray = array();
@@ -130,6 +137,58 @@
                return $templateFields;
        }
 
+       function getAllFieldsCargo() {
+               $cargoFieldsOfTemplateParams = array();
+               $templateFields = array();
+               $template_title = Title::makeTitleSafe( NS_TEMPLATE, 
$this->mTemplateName );
+               if ( !isset( $template_title ) ) {
+                       return array();
+               }
+
+               // First, get the table name, and fields, declared for this
+               // template.
+               $templatePageID = $template_title->getArticleID();
+                $tableSchemaString = CargoUtils::getPageProp( $templatePageID, 
'CargoFields' );
+                // First, see if there even is DB storage for this template -
+                // if not, exit.
+                if ( is_null( $tableSchemaString ) ) {
+                        return array();
+                }
+                $tableSchema = CargoTableSchema::newFromDBString( 
$tableSchemaString );
+                $tableName = CargoUtils::getPageProp( $templatePageID, 
'CargoTableName' );
+
+               // Then, match template params to Cargo table fields, by
+               // parsing call(s) to #cargo_store.
+               $templateText = SFUtils::getPageText( $template_title );
+               // Ignore 'noinclude' sections and 'includeonly' tags.
+               $templateText = StringUtils::delimiterReplace( '<noinclude>', 
'</noinclude>', '', $templateText );
+               $templateText = strtr( $templateText, array( '<includeonly>' => 
'', '</includeonly>' => '' ) );
+               if ( preg_match_all( '/#cargo_store:(.*?}})\s*}}/mis', 
$templateText, $matches ) ) {
+                       foreach ( $matches[1] as $match ) {
+                               if ( preg_match_all( 
'/([^|{]*?)=\s*{{{([^|}]*)/mis', $match, $matches2 ) ) {
+                                       foreach ( $matches2[1] as $i => 
$cargoFieldName ) {
+                                               $templateParameter = trim( 
$matches2[2][$i] );
+                                               
$cargoFieldsOfTemplateParams[$templateParameter] = $cargoFieldName;
+                                       }
+                               }
+                       }
+               }
+
+               // Now, combine the two sets of information into an array of
+               // SFTemplateFields objects.
+               $fieldDescriptions = $tableSchema->mFieldDescriptions;
+               foreach ( $cargoFieldsOfTemplateParams as $templateParameter => 
$cargoField ) {
+                       $templateField = SFTemplateField::create( 
$templateParameter, $templateParameter );
+                       if ( array_key_exists( $cargoField, $fieldDescriptions 
) ) {
+                               $fieldDescription = 
$fieldDescriptions[$cargoField];
+                               $templateField->setCargoFieldData( $tableName, 
$cargoField, $fieldDescription );
+                       }
+                       $templateFields[] = $templateField;
+               }
+
+               return $templateFields;
+       }
+
        static function create( $name, $label = null, $allowMultiple = null, 
$maxAllowed = null, $formFields = null ) {
                $tif = new SFTemplateInForm();
                $tif->mTemplateName = str_replace( '_', ' ', $name );
diff --git a/includes/SF_Utils.php b/includes/SF_Utils.php
index a9d33c8..29a4383 100644
--- a/includes/SF_Utils.php
+++ b/includes/SF_Utils.php
@@ -383,6 +383,21 @@
        }
 
        /**
+        * Used with the Cargo extension
+        */
+       public static function getAllValuesForCargoField( $tableName, 
$fieldName ) {
+               $limitStr = 200;
+               $sqlQuery = CargoSQLQuery::newFromValues( $tableName, 
$fieldName, $whereStr = null, $joinOnStr = null, $fieldName, $fieldName, 
$limitStr );
+               $queryResults = $sqlQuery->run();
+               $values = array();
+               $fieldAlias = str_replace( '_', ' ', $fieldName );
+               foreach ( $queryResults as $row ) {
+                       $values[] = $row[$fieldAlias];
+               }
+               return $values;
+       }
+
+       /**
         * Get all the pages that belong to a category and all its
         * subcategories, down a certain number of levels - heavily based on
         * SMW's SMWInlineQuery::includeSubcategories()
@@ -581,7 +596,12 @@
 
                // The query depends on whether this is a property, category,
                // concept or namespace.
-               if ( $source_type == 'property' ) {
+               if ( $source_type == 'cargo field' ) {
+                       list( $table_name, $field_name ) = explode( '|', 
$source_name, 2 );
+                       $names_array = self::getAllValuesForCargoField( 
$table_name, $field_name );
+                       // Remove blank/null values from the array.
+                       $names_array = array_values( array_filter( $names_array 
) );
+               } elseif ( $source_type == 'property' ) {
                        $names_array = self::getAllValuesForProperty( 
$source_name );
                } elseif ( $source_type == 'category' ) {
                        $names_array = self::getAllPagesForCategory( 
$source_name, 10 );
diff --git a/includes/forminputs/SF_CheckboxInput.php 
b/includes/forminputs/SF_CheckboxInput.php
index 753888b..ac33b22 100644
--- a/includes/forminputs/SF_CheckboxInput.php
+++ b/includes/forminputs/SF_CheckboxInput.php
@@ -20,6 +20,10 @@
                return array( '_boo' => array() );
        }
 
+       public static function getDefaultCargoTypes() {
+               return array( 'Boolean' => array() );
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                global $sfgTabIndex, $sfgFieldNum, $sfgShowOnSelect;
 
diff --git a/includes/forminputs/SF_CheckboxesInput.php 
b/includes/forminputs/SF_CheckboxesInput.php
index 32fc3cd..e8afc4b 100644
--- a/includes/forminputs/SF_CheckboxesInput.php
+++ b/includes/forminputs/SF_CheckboxesInput.php
@@ -27,6 +27,16 @@
                return array();
        }
 
+       public static function getDefaultCargoTypeLists() {
+               return array(
+                       'Enumeration' => array()
+               );
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array();
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                global $sfgTabIndex, $sfgFieldNum, $sfgShowOnSelect;
 
diff --git a/includes/forminputs/SF_ComboBoxInput.php 
b/includes/forminputs/SF_ComboBoxInput.php
index 1a4a69c..3dec4dd 100644
--- a/includes/forminputs/SF_ComboBoxInput.php
+++ b/includes/forminputs/SF_ComboBoxInput.php
@@ -20,6 +20,14 @@
                return array( '_wpg', '_str' );
        }
 
+        public static function getDefaultCargoTypes() {
+                 return array( 'Page' => array() );
+        }
+
+       public static function getOtherCargoTypesHandled() {
+               return array( 'String' );
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                // For backward compatibility with pre-SF-2.1 forms
                if ( array_key_exists( 'no autocomplete', $other_args ) &&
diff --git a/includes/forminputs/SF_DateInput.php 
b/includes/forminputs/SF_DateInput.php
index 12227d2..ee65d15 100644
--- a/includes/forminputs/SF_DateInput.php
+++ b/includes/forminputs/SF_DateInput.php
@@ -20,6 +20,10 @@
                return array( '_dat' => array() );
        }
 
+       public static function getDefaultCargoTypes() {
+               return array( 'Date' => array() );
+       }
+
        public static function monthDropdownHTML( $cur_month, $input_name, 
$is_disabled ) {
                global $sfgTabIndex, $wgAmericanDates;
 
diff --git a/includes/forminputs/SF_DateTimeInput.php 
b/includes/forminputs/SF_DateTimeInput.php
index b2205b8..471f2b0 100644
--- a/includes/forminputs/SF_DateTimeInput.php
+++ b/includes/forminputs/SF_DateTimeInput.php
@@ -24,6 +24,10 @@
                return array( '_dat' );
        }
 
+       public static function getDefaultCargoTypes() {
+               return array( 'Datetime' => array() );
+       }
+
        public static function getHTML( $datetime, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                global $sfgTabIndex, $sfg24HourTime;
 
diff --git a/includes/forminputs/SF_DropdownInput.php 
b/includes/forminputs/SF_DropdownInput.php
index a6c0c80..c9e11cd 100644
--- a/includes/forminputs/SF_DropdownInput.php
+++ b/includes/forminputs/SF_DropdownInput.php
@@ -26,6 +26,16 @@
                return array( '_boo' );
        }
 
+       public static function getDefaultCargoTypes() {
+               return array(
+                       'Enumeration' => array()
+               );
+       }
+
+       public static function getOtherCargoTypesHandled() {
+               return array( 'Boolean' );
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                global $sfgTabIndex, $sfgFieldNum, $sfgShowOnSelect;
 
diff --git a/includes/forminputs/SF_EnumInput.php 
b/includes/forminputs/SF_EnumInput.php
index c0a5aa2..aea47ba 100644
--- a/includes/forminputs/SF_EnumInput.php
+++ b/includes/forminputs/SF_EnumInput.php
@@ -19,6 +19,10 @@
                return array( 'enumeration', '_boo' );
        }
 
+       public static function getOtherCargoTypesHandled() {
+               return array( 'Enumeration', 'Boolean' );
+       }
+
        public static function getValuesParameters() {
                $params = array();
                $params[] = array(
diff --git a/includes/forminputs/SF_FormInput.php 
b/includes/forminputs/SF_FormInput.php
index 13b2db8..766d5e1 100644
--- a/includes/forminputs/SF_FormInput.php
+++ b/includes/forminputs/SF_FormInput.php
@@ -283,6 +283,23 @@
                return array();
        }
 
+       // Now the same set of methods, but for Cargo instead of SMW.
+       public static function getDefaultCargoTypes() {
+               return array();
+       }
+
+       public static function getDefaultCargoTypeLists() {
+               return array();
+       }
+
+       public static function getOtherCargoTypesHandled() {
+               return array();
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array();
+       }
+
        /**
         * Method to make new style input types compatible with old-style call 
from
         * the SF parser.
diff --git a/includes/forminputs/SF_MultiEnumInput.php 
b/includes/forminputs/SF_MultiEnumInput.php
index 7842ca6..497fbef 100644
--- a/includes/forminputs/SF_MultiEnumInput.php
+++ b/includes/forminputs/SF_MultiEnumInput.php
@@ -23,6 +23,14 @@
                return array( 'enumeration' );
        }
 
+       public static function getOtherCargoTypesHandled() {
+               return array();
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array( 'Enumeration' );
+       }
+
        public static function getParameters() {
                $params = parent::getParameters();
                $params[] = array(
diff --git a/includes/forminputs/SF_OpenLayersInput.php 
b/includes/forminputs/SF_OpenLayersInput.php
index 4c67988..0d6db70 100644
--- a/includes/forminputs/SF_OpenLayersInput.php
+++ b/includes/forminputs/SF_OpenLayersInput.php
@@ -20,6 +20,10 @@
                return array();
        }
 
+       public static function getDefaultCargoTypes() {
+               return array( 'Coordinates' );
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                global $sfgTabIndex, $sfgFieldNum;
                global $wgOut;
diff --git a/includes/forminputs/SF_TextAreaInput.php 
b/includes/forminputs/SF_TextAreaInput.php
index 23b4902..b47a2e6 100644
--- a/includes/forminputs/SF_TextAreaInput.php
+++ b/includes/forminputs/SF_TextAreaInput.php
@@ -15,6 +15,10 @@
 class SFTextAreaInput extends SFFormInput {
 
        protected $mUseWikieditor = false;
+
+        public static function getDefaultCargoTypes() {
+                return array( 'Text' => array() );
+        }
        
        /**
         * Constructor for the SFTextAreaInput class.
diff --git a/includes/forminputs/SF_TextAreaWithAutocompleteInput.php 
b/includes/forminputs/SF_TextAreaWithAutocompleteInput.php
index 7244035..84094af 100644
--- a/includes/forminputs/SF_TextAreaWithAutocompleteInput.php
+++ b/includes/forminputs/SF_TextAreaWithAutocompleteInput.php
@@ -20,6 +20,10 @@
                return array();
        }
 
+       public static function getDefaultCargoTypes() {
+               return array();
+       }
+
        public static function getParameters() {
                $params = parent::getParameters();
                $params = array_merge( $params, 
SFTextWithAutocompleteInput::getAutocompletionParameters() );
diff --git a/includes/forminputs/SF_TextInput.php 
b/includes/forminputs/SF_TextInput.php
index 0ad8559..290aa61 100644
--- a/includes/forminputs/SF_TextInput.php
+++ b/includes/forminputs/SF_TextInput.php
@@ -54,6 +54,33 @@
                return array( '_wpg' );
        }
 
+       public static function getDefaultCargoTypes() {
+               return array(
+                       'Integer' => array( 'field_type' => 'number' ),
+                       'Float' => array( 'field_type' => 'number' ),
+                       'URL' => array( 'field_type' => 'URL' ),
+                       'Email' => array( 'field_type' => 'email' ),
+                       'String' => array( 'field_type' => 'string' )
+               );
+       }
+
+       public static function getOtherCargoTypesHandled() {
+               return array( 'Page', 'Coordinates' );
+       }
+
+       public static function getDefaultCargoTypeLists() {
+               return array(
+                       'Number' => array( 'field_type' => 'number', 'is_list' 
=> 'true', 'size' => '100' ),
+                       'URL' => array( 'field_type' => 'URL', 'is_list' => 
'true' ),
+                       'Email' => array( 'field_type' => 'email', 'is_list' => 
'true' ),
+                       'String' => array( 'field_type' => 'text', 'is_list' => 
'true', 'size' => '100' )
+               );
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array( 'Page' );
+       }
+
        /**
         * Gets the HTML for the preview image or null if there is none.
         *
diff --git a/includes/forminputs/SF_TextWithAutocompleteInput.php 
b/includes/forminputs/SF_TextWithAutocompleteInput.php
index df2d830..58cda94 100644
--- a/includes/forminputs/SF_TextWithAutocompleteInput.php
+++ b/includes/forminputs/SF_TextWithAutocompleteInput.php
@@ -44,8 +44,30 @@
                }
        }
 
+       public static function getDefaultCargoTypes() {
+               return array();
+       }
+
+       public static function getOtherCargoTypesHandled() {
+               return array( 'Page', 'String' );
+       }
+
+       public static function getDefaultCargoTypeLists() {
+               return array();
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array( 'String' );
+       }
+
+
        public static function getAutocompletionTypeAndSource( &$field_args ) {
-               if ( array_key_exists( 'values from property', $field_args ) ) {
+               if ( array_key_exists( 'cargo field', $field_args ) ) {
+                       $fieldName = $field_args['cargo field'];
+                       $tableName = $field_args['cargo table'];
+                       $autocompletionSource = "$tableName|$fieldName";
+                       $autocompleteFieldType = 'cargo field';
+               } elseif ( array_key_exists( 'values from property', 
$field_args ) ) {
                        $autocompletionSource = $field_args['values from 
property'];
                        $autocompleteFieldType = 'property';
                } elseif ( array_key_exists( 'values from category', 
$field_args ) ) {
@@ -69,6 +91,9 @@
                } elseif ( array_key_exists( 'autocomplete field type', 
$field_args ) ) {
                        $autocompleteFieldType = $field_args['autocomplete 
field type'];
                        $autocompletionSource = $field_args['autocompletion 
source'];
+               } elseif ( array_key_exists( 'full_cargo_field', $field_args ) 
) {
+                       $autocompletionSource = $field_args['full_cargo_field'];
+                       $autocompleteFieldType = 'cargo field';
                } elseif ( array_key_exists( 'semantic_property', $field_args ) 
) {
                        $autocompletionSource = 
$field_args['semantic_property'];
                        $autocompleteFieldType = 'property';
diff --git a/includes/forminputs/SF_TokensInput.php 
b/includes/forminputs/SF_TokensInput.php
index 69c05d4..a9ad179 100644
--- a/includes/forminputs/SF_TokensInput.php
+++ b/includes/forminputs/SF_TokensInput.php
@@ -46,6 +46,24 @@
                }
        }
 
+       public static function getDefaultCargoTypes() {
+               return array();
+       }
+
+       public static function getOtherCargoTypesHandled() {
+               return array( 'Page', 'String' );
+       }
+
+       public static function getDefaultCargoTypeLists() {
+               return array(
+                       'Page' => array( 'is_list' => true, 'size' => 100 )
+               );
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array( 'String' );
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                global $sfgTabIndex, $sfgFieldNum, $sfgEDSettings;
 
diff --git a/includes/forminputs/SF_TreeInput.php 
b/includes/forminputs/SF_TreeInput.php
index 762a52b..40dea4d 100644
--- a/includes/forminputs/SF_TreeInput.php
+++ b/includes/forminputs/SF_TreeInput.php
@@ -40,6 +40,14 @@
                }
        }
 
+       public static function getOtherCargoTypesHandled() {
+               return array( 'String', 'Page' );
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array( 'String', 'Page' );
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                // Handle the now-deprecated 'category' and 'categories'
                // input types.
diff --git a/includes/forminputs/SF_YearInput.php 
b/includes/forminputs/SF_YearInput.php
index 7c0e74c..3f4d579 100644
--- a/includes/forminputs/SF_YearInput.php
+++ b/includes/forminputs/SF_YearInput.php
@@ -32,6 +32,22 @@
                return array();
        }
 
+       public static function getDefaultCargoTypes() {
+               return array();
+       }
+
+       public static function getOtherCargoTypesHandled() {
+               return array( 'Date' );
+       }
+
+       public static function getDefaultCargoTypeLists() {
+               return array();
+       }
+
+       public static function getOtherCargoTypeListsHandled() {
+               return array();
+       }
+
        public static function getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args ) {
                $other_args['size'] = 4;
                return parent::getHTML( $cur_value, $input_name, $is_mandatory, 
$is_disabled, $other_args );
diff --git a/libs/SemanticForms.js b/libs/SemanticForms.js
index 49e07ae..f26ba15 100644
--- a/libs/SemanticForms.js
+++ b/libs/SemanticForms.js
@@ -10,7 +10,7 @@
  * @author Harold Solbrig
  * @author Eugene Mednikov
  */
- /*global sfgShowOnSelect, sfgFieldProperties, validateAll, alert, sf*/
+ /*global sfgShowOnSelect, sfgFieldProperties, sfgCargoFields, validateAll, 
alert, sf*/
 
 // Activate autocomplete functionality for the specified field
 (function(jQuery) {
@@ -879,10 +879,24 @@
 // regular inputs, and the 'origName' attribute for inputs in multiple-instance
 // templates.
 jQuery.fn.setDependentAutocompletion = function( dependentField, baseField, 
baseValue ) {
-       var propName = sfgFieldProperties[dependentField];
-       var baseProp = sfgFieldProperties[baseField];
+       // Get data from either Cargo or Semantic MediaWiki.
        var myServer = mw.config.get( 'wgScriptPath' ) + "/api.php";
-       myServer += "?action=sfautocomplete&format=json&property=" + propName + 
"&baseprop=" + baseProp + "&basevalue=" + baseValue;
+       myServer += "?action=sfautocomplete&format=json";
+       if ( sfgCargoFields.hasOwnProperty( dependentField ) ) {
+               var cargoTableAndFieldStr = sfgCargoFields[dependentField];
+               var cargoTableAndField = cargoTableAndFieldStr.split('|');
+               var cargoTable = cargoTableAndField[0];
+               var cargoField = cargoTableAndField[1];
+               var baseCargoTableAndFieldStr = sfgCargoFields[baseField];
+               var baseCargoTableAndField = 
baseCargoTableAndFieldStr.split('|');
+               var baseCargoTable = baseCargoTableAndField[0];
+               var baseCargoField = baseCargoTableAndField[1];
+               myServer += "&cargo_table=" + cargoTable + "&cargo_field=" + 
cargoField + "&is_array=true" + "&base_cargo_table=" + baseCargoTable + 
"&base_cargo_field=" + baseCargoField + "&basevalue=" + baseValue;
+       } else {
+               var propName = sfgFieldProperties[dependentField];
+               var baseProp = sfgFieldProperties[baseField];
+               myServer += "&property=" + propName + "&baseprop=" + baseProp + 
"&basevalue=" + baseValue;
+       }
        var dependentValues = [];
        var thisInput = jQuery(this);
        // We use jQuery.ajax() here instead of jQuery.getJSON() so that the
@@ -936,7 +950,7 @@
        var self = this;
        jQuery.each( dependent_on_me, function() {
                var dependentField = this;
-    var dependent_field_element;
+               var dependent_field_element;
                if ( partOfMultiple ) {
                        dependent_field_element = 
jQuery(self).closest(".multipleTemplateInstance")
                                .find('[origName="' + dependentField + '"]');
@@ -947,7 +961,7 @@
                if ( class_name.indexOf( 'sfComboBox' ) != -1 ) {
                        var cmbox = new sf.select2.combobox();
                        cmbox.refresh(dependent_field_element);
-               } else  if ( class_name.indexOf( 'sfTokens' ) != -1 ) {
+               } else if ( class_name.indexOf( 'sfTokens' ) != -1 ) {
                        var tokens = new sf.select2.tokens();
                        tokens.refresh(dependent_field_element);
                } else {
diff --git a/libs/ext.sf.select2.combobox.js b/libs/ext.sf.select2.combobox.js
index 9a5daea..f5551aa 100644
--- a/libs/ext.sf.select2.combobox.js
+++ b/libs/ext.sf.select2.combobox.js
@@ -114,7 +114,7 @@
                                        if ( data.title !== undefined && 
data.title !== null ) {
                                                data.title.forEach(function() {
                                                        values.push({
-                                                       id: i + 1, text: 
data.title[i]
+                                                       id: i + 1, text: 
data.title[i]
                                                    });
                                                    i++;
                                                });
@@ -158,7 +158,25 @@
                } else { //Dependent field autocompletion
                        var dep_field_opts = this.getDependentFieldOpts( dep_on 
);
                        var my_server = mw.config.get( 'wgScriptPath' ) + 
"/api.php";
-                       my_server += 
"?action=sfautocomplete&format=json&property=" + dep_field_opts.prop + 
"&baseprop=" + dep_field_opts.base_prop + "&basevalue=" + 
dep_field_opts.base_value;
+                       my_server += "?action=sfautocomplete&format=json";
+                       // URL depends on whether Cargo or Semantic MediaWiki
+                       // is being used.
+                       if ( dep_field_opts.prop.indexOf('|') == -1 ) {
+                               // SMW
+                               my_server += "&property=" + dep_field_opts.prop 
+ "&baseprop=" + dep_field_opts.base_prop + "&basevalue=" + 
dep_field_opts.base_value;
+                       } else {
+                               // Cargo
+                               var cargoTableAndFieldStr = dep_field_opts.prop;
+                               var cargoTableAndField = 
cargoTableAndFieldStr.split('|');
+                               var cargoTable = cargoTableAndField[0];
+                               var cargoField = cargoTableAndField[1];
+                               var baseCargoTableAndFieldStr = 
dep_field_opts.base_prop;
+                               var baseCargoTableAndField = 
baseCargoTableAndFieldStr.split('|');
+                               var baseCargoTable = baseCargoTableAndField[0];
+                               var baseCargoField = baseCargoTableAndField[1];
+                               my_server += "&cargo_table=" + cargoTable + 
"&cargo_field=" + cargoField + "&base_cargo_table=" + baseCargoTable + 
"&base_cargo_field=" + baseCargoField + "&basevalue=" + 
dep_field_opts.base_value;
+                       }
+                       //alert(my_server);
                        $.ajax({
                                url: my_server,
                                dataType: 'json',
@@ -187,8 +205,14 @@
         */
        combobox_proto.getAjaxOpts = function() {
                var autocomplete_opts = this.getAutocompleteOpts();
+               var data_source = 
autocomplete_opts.autocompletesettings.split(',')[0];
                var my_server = mw.util.wikiScript( 'api' );
-               my_server += "?action=sfautocomplete&format=json&" + 
autocomplete_opts.autocompletedatatype + "=" + 
autocomplete_opts.autocompletesettings;
+               if ( autocomplete_type == 'cargo field' ) {
+                       var table_and_field = data_source.split('|');
+                       my_server += 
"?action=sfautocomplete&format=json&cargo_table=" + table_and_field[0] + 
"&cargo_field=" + table_and_field[1];
+               } else {
+                       my_server += "?action=sfautocomplete&format=json&" + 
autocomplete_opts.autocompletedatatype + "=" + data_source;
+               }
 
                var ajaxOpts = {
                        url: my_server,
diff --git a/libs/ext.sf.select2.tokens.js b/libs/ext.sf.select2.tokens.js
index a044f84..2c29a79 100644
--- a/libs/ext.sf.select2.tokens.js
+++ b/libs/ext.sf.select2.tokens.js
@@ -232,7 +232,13 @@
                var autocomplete_opts = this.getAutocompleteOpts();
                var data_source = 
autocomplete_opts.autocompletesettings.split(',')[0];
                var my_server = mw.util.wikiScript( 'api' );
-               my_server += "?action=sfautocomplete&format=json&" + 
autocomplete_opts.autocompletedatatype + "=" + data_source;
+               var autocomplete_type = autocomplete_opts.autocompletedatatype;
+               if ( autocomplete_type == 'cargo field' ) {
+                       var table_and_field = data_source.split('|');
+                       my_server += 
"?action=sfautocomplete&format=json&cargo_table=" + table_and_field[0] + 
"&cargo_field=" + table_and_field[1] + "&field_is_array=true";
+               } else {
+                       my_server += "?action=sfautocomplete&format=json&" + 
autocomplete_opts.autocompletedatatype + "=" + data_source;
+               }
 
                var ajaxOpts = {
                        url: my_server,

-- 
To view, visit https://gerrit.wikimedia.org/r/183076
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I8fdb35045576cf1bb5d3f1cdb36fdddf6c2ca246
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SemanticForms
Gerrit-Branch: master
Gerrit-Owner: Yaron Koren <[email protected]>
Gerrit-Reviewer: Yaron Koren <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to