function getAllFieldsCargo($templateTitle)
 {
     $cargoFieldsOfTemplateParams = array();
     $templateFields = array();
     // First, get the table name, and fields, declared for this
     // template.
     $templatePageID = $templateTitle->getArticleID();
     $tableSchemaString = CargoUtils::getPageProp($templatePageID, 'CargoFields');
     // See if there even is DB storage for this template - if not,
     // exit.
     if (is_null($tableSchemaString)) {
         return null;
     }
     $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($templateTitle);
     // Ignore 'noinclude' sections and 'includeonly' tags.
     $templateText = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $templateText);
     $templateText = strtr($templateText, array('<includeonly>' => '', '</includeonly>' => ''));
     // Let's find every #cargo_store tag.
     // Unfortunately, it doesn't seem possible to use a regexp
     // search for this, because it's hard to know which set of
     // double brackets represents the end of such a call. Instead,
     // we'll do some manual parsing.
     $cargoStoreLocations = array();
     $curPos = 0;
     while (true) {
         $newPos = strpos($templateText, "#cargo_store:", $curPos);
         if ($newPos === false) {
             break;
         }
         $curPos = $newPos + 13;
         $cargoStoreLocations[] = $curPos;
     }
     $cargoStoreCalls = array();
     foreach ($cargoStoreLocations as $locNum => $startPos) {
         $numUnclosedBrackets = 2;
         if ($locNum < count($cargoStoreLocations) - 1) {
             $lastPos = $cargoStoreLocations[$locNum + 1];
         } else {
             $lastPos = strlen($templateText) - 1;
         }
         $curCargoStoreCall = '';
         $curPos = $startPos;
         while ($curPos <= $lastPos) {
             $curChar = $templateText[$curPos];
             $curCargoStoreCall .= $curChar;
             if ($curChar == '}') {
                 $numUnclosedBrackets--;
             } elseif ($curChar == '{') {
                 $numUnclosedBrackets++;
             }
             if ($numUnclosedBrackets == 0) {
                 break;
             }
             $curPos++;
         }
         $cargoStoreCalls[] = $curCargoStoreCall;
     }
     foreach ($cargoStoreCalls as $cargoStoreCall) {
         if (preg_match_all('/([^|{]*?)=\\s*{{{([^|}]*)/mis', $cargoStoreCall, $matches)) {
             foreach ($matches[1] as $i => $cargoFieldName) {
                 $templateParameter = trim($matches[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;
 }
 function getAllFieldsCargo($templateTitle)
 {
     $cargoFieldsOfTemplateParams = array();
     $templateFields = array();
     // First, get the table name, and fields, declared for this
     // template.
     $templatePageID = $templateTitle->getArticleID();
     $tableSchemaString = CargoUtils::getPageProp($templatePageID, 'CargoFields');
     // See if there even is DB storage for this template - if not,
     // exit.
     if (is_null($tableSchemaString)) {
         return null;
     }
     $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($templateTitle);
     // 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;
 }