public static function run($mode = 'test')
 {
     $testMode = $mode != 'run';
     print "Fix Meaning->Definition and Example->Sentence labels.\n";
     $projectlist = new ProjectListModel();
     $projectlist->read();
     $fixCount = 0;
     $definitionLabelsUpdated = 0;
     $sentenceLabelsUpdated = 0;
     foreach ($projectlist->entries as $projectParams) {
         // foreach existing project
         $projectId = $projectParams['id'];
         $project = new ProjectModel($projectId);
         if ($project->appName == 'lexicon') {
             $project = new LexProjectModel($projectId);
             $projectChanged = false;
             $entryFieldsArray = $project->config->entry->fields->getArrayCopy();
             if (array_key_exists("senses", $entryFieldsArray)) {
                 $senseFieldsArray = $entryFieldsArray["senses"]->fields->getArrayCopy();
                 if ($senseFieldsArray["definition"]->label != "Definition") {
                     $senseFieldsArray["definition"]->label = "Definition";
                     //print "  Fixed \"Definition\" label\n";
                     $definitionLabelsUpdated++;
                     $projectChanged = true;
                 }
                 if (array_key_exists("examples", $senseFieldsArray)) {
                     $exampleFieldsArray = $senseFieldsArray["examples"]->fields->getArrayCopy();
                     if ($exampleFieldsArray["sentence"]->label != "Sentence") {
                         $exampleFieldsArray["sentence"]->label = "Sentence";
                         //print "  Fixed \"Sentence\" label\n";
                         $sentenceLabelsUpdated++;
                         $projectChanged = true;
                     }
                 }
             }
             $senseFieldsArray["examples"]->fields->exchangeArray($exampleFieldsArray);
             $entryFieldsArray["senses"]->fields->exchangeArray($senseFieldsArray);
             $project->config->entry->fields->exchangeArray($entryFieldsArray);
             if ($projectChanged) {
                 $fixCount++;
                 if (!$testMode) {
                     print "  Saving changes to project {$project->projectName}.\n";
                     $project->write();
                 }
             }
             unset($exampleFieldsArray);
             unset($senseFieldsArray);
             unset($entryFieldsArray);
         }
     }
     if ($fixCount > 0) {
         print "{$fixCount} projects were fixed\n";
         print "{$definitionLabelsUpdated} \"meaning\" labels changed to \"definition\"\n";
         print "{$sentenceLabelsUpdated} \"example\" labels changed to \"sentence\"\n";
     } else {
         print "No projects needed fixing\n";
     }
 }
 public function run($userId, $mode = 'test')
 {
     $testMode = $mode != 'run';
     $message = "Remove Environment and Reversal Entries from field order config\n\n";
     // Note: LF projects that don't have config data in mongo will use the default PHP model.
     // In these cases, the migration script won't find these field orders to remove, so nothing gets written out
     $projectlist = new ProjectListModel();
     $projectlist->read();
     $projectsAffected = 0;
     foreach ($projectlist->entries as $projectParams) {
         // foreach existing project
         $projectId = $projectParams['id'];
         $project = new ProjectModel($projectId);
         if ($project->appName == 'lexicon') {
             $project = new LexProjectModel($projectId);
             $fieldOrderUpdated = 0;
             $this->RemoveFromArray("environments", $project->config->entry->fieldOrder, $message, $fieldOrderUpdated);
             $fieldsArray = $project->config->entry->fields->getArrayCopy();
             if (array_key_exists("senses", $fieldsArray)) {
                 $this->RemoveFromArray("reversalEntries", $fieldsArray["senses"]->fieldOrder, $message, $fieldOrderUpdated);
                 $project->config->entry->fields->exchangeArray($fieldsArray);
             }
             if ($fieldOrderUpdated > 0) {
                 $projectsAffected++;
                 $message .= "\tRemoved: {$fieldOrderUpdated} field orders from {$project->projectName}\n";
                 if (!$testMode) {
                     $message .= "\tSaving changes to project {$project->projectName}.\n\n";
                     $project->write();
                 }
             }
         }
         unset($project);
     }
     if ($projectsAffected > 0) {
         $message .= "{$projectsAffected} projects were fixed\n";
     } else {
         $message .= "No projects needed fixing\n";
     }
     return $message;
 }
 /**
  * Update Role Views and User Views for each custom field
  * Designed to be externally called (e.g. from LfMerge)
  *
  * @param string $projectCode
  * @param array<string> $customFieldSpecs
  * @return bool|string returns the project id on success, false otherwise
  */
 public static function updateCustomFieldViews($projectCode, $customFieldSpecs)
 {
     $project = new LexProjectModel();
     if (!$project->readByProperty('projectCode', $projectCode)) {
         return false;
     }
     self::removeDeletedCustomFieldViews($customFieldSpecs, $project->config);
     foreach ($customFieldSpecs as $customFieldSpec) {
         self::createNewCustomFieldViews($customFieldSpec['fieldName'], $customFieldSpec['fieldType'], $project->config);
     }
     return $project->write();
 }
 public function run($userId, $mode = 'test')
 {
     $testMode = $mode != 'run';
     $message = "Fix Lexicon View Settings (except Environments and ReversalEntries) to default to visible\n\n";
     $fixCount = 0;
     $projectlist = new ProjectListModel();
     $projectlist->read();
     foreach ($projectlist->entries as $projectParams) {
         // foreach existing project
         $projectId = $projectParams['id'];
         $project = new ProjectModel($projectId);
         if ($project->appName == 'lexicon') {
             $project = new LexProjectModel($projectId);
             //$message .= "\nInspecting project $project->projectName.\n";
             $showFieldUpdated = 0;
             $roleShowFieldUpdated = 0;
             //$hideFieldUpdated = 0;
             $roleHideFieldUpdated = 0;
             $disabledFields = array("environments", "reversalEntries");
             foreach ($project->config->roleViews as $role => $roleView) {
                 foreach ($roleView->fields as $fieldName => $field) {
                     if (in_array($fieldName, $disabledFields)) {
                         if ($field->show) {
                             // Hide disabled fields
                             //$message .= "Hiding role $role view of $fieldName\n";
                             $field->show = false;
                             $showFieldUpdated++;
                             $roleHideFieldUpdated++;
                         }
                     } else {
                         if (!$field->show) {
                             // enable all other fields by default
                             $field->show = true;
                             $showFieldUpdated++;
                             $roleShowFieldUpdated++;
                         }
                     }
                 }
             }
             $userShowFieldUpdated = 0;
             $userHideFieldUpdated = 0;
             foreach ($project->config->userViews as $userId => $userView) {
                 foreach ($userView->fields as $fieldName => $field) {
                     if (in_array($fieldName, $disabledFields)) {
                         if ($field->show) {
                             // Hide disabled fields
                             //$message .= "Hiding user $userId view of $fieldName\n";
                             $field->show = false;
                             $showFieldUpdated++;
                             $userHideFieldUpdated++;
                         }
                     } else {
                         if (!$field->show) {
                             // enable all other fields by default
                             $field->show = true;
                             $showFieldUpdated++;
                             $userShowFieldUpdated++;
                         }
                     }
                 }
             }
             if ($showFieldUpdated > 0) {
                 $fixCount++;
                 $message .= "  Toggled {$showFieldUpdated} View Settings fields. This comprised: \n";
                 if ($roleShowFieldUpdated > 0) {
                     $message .= "   - Changed {$roleShowFieldUpdated} role-based View Settings fields to be visible.\n";
                 }
                 if ($userShowFieldUpdated > 0) {
                     $message .= "   - Changed {$userShowFieldUpdated} user-based View Settings fields to be visible.\n";
                 }
                 if ($roleHideFieldUpdated > 0) {
                     $message .= "   - Changed {$roleHideFieldUpdated} role-based View Settings fields to be invisible.\n";
                 }
                 if ($userHideFieldUpdated > 0) {
                     $message .= "   - Changed {$userHideFieldUpdated} user-based View Settings fields to be invisible.\n";
                 }
                 if (!$testMode) {
                     $message .= "  Saving changes to project {$project->projectName}.\n";
                     $project->write();
                 }
             } else {
                 //$message .= "  No invisible View Settings fields found/changed.\n";
             }
         }
     }
     if ($fixCount > 0) {
         $message .= "{$fixCount} projects were fixed\n";
     } else {
         $message .= "No projects needed fixing\n";
     }
     return $message;
 }
    $template2 = QuestionTemplateCommands::updateTemplate($testProjectId, array('id' => '', 'title' => 'second template', 'description' => 'not entirely interesting'));
    $answer1 = QuestionCommands::updateAnswer($testProjectId, $question1, array('id' => '', 'content' => $constants['testText1Question1Answer']), $managerUserId);
    $answer1Id = array_keys($answer1)[0];
    $answer2 = QuestionCommands::updateAnswer($testProjectId, $question2, array('id' => '', 'content' => $constants['testText1Question2Answer']), $managerUserId);
    $answer2Id = array_keys($answer2)[0];
    $comment1 = QuestionCommands::updateComment($testProjectId, $question1, $answer1Id, array('id' => '', 'content' => $constants['testText1Question1Answer1Comment']), $managerUserId);
    $comment2 = QuestionCommands::updateComment($testProjectId, $question2, $answer2Id, array('id' => '', 'content' => $constants['testText1Question2Answer2Comment']), $managerUserId);
} elseif ($site == 'languageforge') {
    // Set up LanguageForge E2E test envrionment here
    ProjectCommands::updateUserRole($testProjectId, $observerUserId, LexRoles::OBSERVER);
    $testProjectModel = new LexProjectModel($testProjectId);
    $testProjectModel->addInputSystem('th-fonipa', 'tipa', 'Thai');
    $testProjectModel->config->entry->fields[LexConfig::LEXEME]->inputSystems[] = 'th-fonipa';
    $testProjectModel->addInputSystem('th-Zxxx-x-audio', 'taud', 'Thai Voice');
    $testProjectModel->config->entry->fields[LexConfig::LEXEME]->inputSystems[] = 'th-Zxxx-x-audio';
    $testProjectId = $testProjectModel->write();
    // setup to mimic file upload
    $fileName = $constants['testEntry1']['lexeme']['th-Zxxx-x-audio']['value'];
    $file = array();
    $file['name'] = $fileName;
    $_FILES['file'] = $file;
    // put a copy of the test file in tmp
    $tmpFilePath = sys_get_temp_dir() . "/CopyOf{$fileName}";
    copy(TestPath . "php/common/{$fileName}", $tmpFilePath);
    $response = LexUploadCommands::uploadAudioFile($testProjectId, 'audio', $tmpFilePath);
    // cleanup tmp file if it still exists
    if (file_exists($tmpFilePath) and !is_dir($tmpFilePath)) {
        @unlink($tmpFilePath);
    }
    // put uploaded file into entry1
    $constants['testEntry1']['lexeme']['th-Zxxx-x-audio']['value'] = $response->data->fileName;