/**
  * Apply changes from the CSV file
  *
  * @param string $path Path to the CSV file
  * @return void
  */
 protected function _handleCsv($path = '')
 {
     $tableName = Inflector::pluralize(Inflector::classify($this->_table->getName()));
     if ('' === trim($path)) {
         $pathFinder = new MigrationPathFinder();
         $path = $pathFinder->find($tableName);
     }
     $parser = new MigrationParser();
     $csvData = $parser->wrapFromPath($path);
     $csvData = array_merge($csvData, $this->_requiredFields);
     $tableFields = $this->_getTableFields();
     if (empty($tableFields)) {
         $this->_createFromCsv($csvData);
     } else {
         $this->_updateFromCsv($csvData, $tableFields);
     }
 }
 /**
  * Method that retrieves fields from csv file and returns them in associate array format.
  *
  * @param  string $moduleName Module Name
  * @return array
  */
 public function getFieldsDefinitions($moduleName = null)
 {
     if (!empty($this->_fieldDefinitions)) {
         return $this->_fieldDefinitions;
     }
     if (is_null($moduleName)) {
         if (is_callable([$this, 'alias'])) {
             $moduleName = $this->alias();
         } else {
             throw new RuntimeException("Failed getting field definitions for unknown module");
         }
     }
     $pathFinder = new MigrationPathFinder();
     $path = $pathFinder->find($moduleName);
     // Parser knows how to make sure that the file exists.  But it can
     // also throw other exceptions, which we don't want to avoid for
     // now.
     if (is_readable($path)) {
         $parser = new MigrationParser();
         $this->_fieldDefinitions = $parser->wrapFromPath($path);
     }
     return $this->_fieldDefinitions;
 }
 /**
  * Check migration.csv fields
  *
  * @param array $modules List of modules to check
  * @return int Count of errors found
  */
 protected function _checkMigrationFields(array $modules = [])
 {
     $errors = [];
     $warnings = [];
     $this->out('Checking migration fields:', 2);
     foreach ($modules as $module => $path) {
         $moduleErrors = [];
         $this->out(' - ' . $module . ' ... ', 0);
         $fields = null;
         try {
             $pathFinder = new MigrationPathFinder();
             $path = $pathFinder->find($module);
             $parser = new MigrationParser();
             $fields = $parser->parseFromPath($path);
         } catch (\Exception $e) {
             // We've already reported this problem in _checkMigrationPresence();
         }
         if ($fields) {
             $seenFields = [];
             // Check each field one by one
             foreach ($fields as $field) {
                 // Field name is required
                 if (empty($field['name'])) {
                     $moduleErrors[] = $module . " migration has a field without a name";
                 } else {
                     // Check for field duplicates
                     if (in_array($field['name'], $seenFields)) {
                         $moduleErrors[] = $module . " migration specifies field '" . $field['name'] . "' more than once";
                     } else {
                         $seenFields[] = $field['name'];
                     }
                     // Field type is required
                     if (empty($field['type'])) {
                         $moduleErrors[] = $module . " migration does not specify type for field  '" . $field['name'] . "'";
                     } else {
                         $type = null;
                         $limit = null;
                         // Matches:
                         // * date, time, string, and other simple types
                         // * list(something), related(Others) and other simple limits
                         // * related(Vendor/Plugin.Model) and other complex limits
                         if (preg_match('/^(\\w+?)\\(([\\w\\/\\.]+?)\\)$/', $field['type'], $matches)) {
                             $type = $matches[1];
                             $limit = $matches[2];
                         } else {
                             $type = $field['type'];
                         }
                         // Field type must be valid
                         if (!$this->_isValidFieldType($type)) {
                             $moduleErrors[] = $module . " migration specifies invalid type '" . $type . "' for field  '" . $field['name'] . "'";
                         } else {
                             switch ($type) {
                                 case 'related':
                                     // Only check for simple modules, not the vendor/plugin ones
                                     if (preg_match('/^\\w+$/', $limit) && !$this->_isValidModule($limit, array_keys($modules))) {
                                         $moduleErrors[] = $module . " migration relates to unknown module '{$limit}' in '" . $field['name'] . "' field";
                                     }
                                     // Documents module can be used as `files(Documents)` for a container of the uploaded files,
                                     // or as `related(Documents)` as a regular module relationship.  It's often easy to overlook
                                     // which one was desired.  Failing on either one is incorrect, as both are valid.  A
                                     // warning is needed instead for the `related(Documents)` case instead.
                                     // The only known legitimate case is in the Files, which is join table between Documents and FileStorage.
                                     if ('Documents' == $limit && 'Files' != $module) {
                                         $warnings[] = $module . " migration uses 'related' type for 'Documents' in '" . $field['name'] . "'. Maybe wanted 'files(Documents)'?";
                                     }
                                     break;
                                 case 'list':
                                 case 'money':
                                 case 'metric':
                                     if (!$this->_isValidList($limit)) {
                                         $moduleErrors[] = $module . " migration uses unknown or empty list '{$limit}' in '" . $field['name'] . "' field";
                                     }
                                     break;
                             }
                         }
                     }
                 }
             }
             // Check for the required fields
             // TODO: Allow specifying the required fields as the command line argument (for things like trashed)
             $requiredFields = ['id', 'created', 'modified'];
             foreach ($requiredFields as $requiredField) {
                 if (!in_array($requiredField, $seenFields)) {
                     $moduleErrors[] = $module . " migration is missing a required field '{$requiredField}'";
                 }
             }
         }
         $result = empty($moduleErrors) ? '<success>OK</success>' : '<error>FAIL</error>';
         $this->out($result);
         $errors = array_merge($errors, $moduleErrors);
     }
     $this->_printCheckStatus($errors, $warnings);
     return count($errors);
 }
 /**
  * Get csv file's last modified time.
  *
  * @param  string $tableName target table name
  * @return string
  */
 protected function _getLastModifiedTime($tableName)
 {
     $tableName = Inflector::camelize($tableName);
     $pathFinder = new MigrationPathFinder();
     $path = $pathFinder->find($tableName);
     // Unit time stamp to YYYYMMDDhhmmss
     $result = date('YmdHis', filemtime($path));
     return $result;
 }
 /**
  * Method that retrieves and returns csv migration fields.
  *
  * @param  Request $request Request object
  * @return array
  */
 protected function _getMigrationFields(Request $request)
 {
     $result = [];
     try {
         $pathFinder = new MigrationPathFinder();
         $path = $pathFinder->find($request->controller);
         $parser = new MigrationParser();
         $result = $parser->wrapFromPath($path);
     } catch (InvalidArgumentException $e) {
         Log::error($e);
     }
     return $result;
 }