Skip to content

Commit

Permalink
Merge pull request #12 from loadsys/f/improve-import
Browse files Browse the repository at this point in the history
Support entityOptions, improve repeat imports.
  • Loading branch information
beporter committed Oct 14, 2015
2 parents 7845a8b + d608010 commit 30369b1
Showing 1 changed file with 102 additions and 24 deletions.
126 changes: 102 additions & 24 deletions src/Shell/BasicSeedShell.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,26 @@ class BasicSeedShell extends Shell {
*/
public $seedDevFile = 'seed_dev.php';

/**
* Set up the Shell.
*
* @return void
*/
public function initialize() {
$this->_io->styles('success', ['text' => 'green']);
// quiet = (none)/warning, white/yellow
// out = info, cyan
// verbose = success, green
}

/**
* Public method used for creating a new blank seed file.
*
* @return void
*/
public function init() {
$path = $this->absolutePath($this->getFile());
$this->out('Initializing seed file: ' . $this->shortPath($path));
$this->quiet('Initializing seed file: ' . $this->shortPath($path));
$this->existsOrCreate($path);
}

Expand All @@ -54,7 +66,7 @@ public function init() {
*/
public function main() {
$this->includeFile($this->absolutePath($this->getFile()));
$this->out("...Done!");
$this->quiet("...Done!");
}

/**
Expand Down Expand Up @@ -105,15 +117,28 @@ public function importTables(array $data) {
if (array_key_exists('_defaults', $records)) {
$defaults = $records['_defaults'];
unset($records['_defaults']);
$this->out("<info>{$table}: Default values set.</info>");
$this->verbose("<success>{$table}: Default values set.</success>");
}

// Set entity options, if present.
$options = [];
$entityOptions = [];
if (array_key_exists('_options', $records)) {
$options = $records['_options'];
$entityOptions = $records['_options'];
unset($records['_options']);
$this->out("<info>{$table}: Entity options set.</info>");
$this->verbose("<success>{$table}: Entity options set, but...</success>");
$this->quiet("<warning>{$table}: Deprecation notice: Change [_options] to [_entityOptions].</warning>");
} elseif (array_key_exists('_entityOptions', $records)) {
$entityOptions = $records['_entityOptions'];
unset($records['_entityOptions']);
$this->verbose("<success>{$table}: Entity options set.</success>");
}

// Set save options, if present.
$saveOptions = [];
if (array_key_exists('_saveOptions', $records)) {
$saveOptions = $records['_saveOptions'];
unset($records['_saveOptions']);
$this->verbose("<success>{$table}: Table save() options set.</success>");
}

// Truncate the table, if requested.
Expand All @@ -125,7 +150,11 @@ public function importTables(array $data) {
unset($records['_truncate']);

// Create or update all defined records.
$this->importTable($Table, $this->entityGenerator($Table, $records, $defaults, $options));
$this->importTable(
$Table,
$this->entityGenerator($Table, $records, $defaults, $entityOptions),
$saveOptions
);
}

$this->out("<info>Seeding complete.</info>");
Expand All @@ -148,21 +177,54 @@ public function importTables(array $data) {
* @param array $options Optional array of newEntity() options to use.
* @return void
*/
public function entityGenerator(Table $Table, array $records, array $defaults = [], array $options = []) {
public function entityGenerator(
Table $Table,
array $records,
array $defaults = [],
array $options = []
) {
$defaultOptions = [
'validate' => true,
];
$options = $options + $defaultOptions;

foreach ($records as $i => $r) {
$r = $Table->newEntity(Hash::merge($defaults, $r), $options);
$errors = $r->errors();
$keyField = $Table->primaryKey();

foreach ($records as $r) {
$r = Hash::merge($defaults, $r);

$id = (!empty($r[$keyField]) ? $r[$keyField] : false);
if ($id) {
$entity = $Table->find()->where([$keyField => $id])->first();
if ($entity) {
$entity = $Table->patchEntity($entity, $r, $options);
if (!$entity->dirty()) {
$this->verbose("<success>{$Table->alias()} ({$id}): No changes.</success>");
continue;
}

} else {
$entity = $Table->newEntity([], $options);
$entity->set($r, ['guard' => false]);
$entity->isNew(true);
}

} else {
$entity = $Table->newEntity($r, $options);
}

$errors = $entity->errors();
if ($errors) {
$this->printValidationErrors($Table->alias(), $this->findKey($Table, $r), $errors);
$this->printValidationErrors(
$Table->alias(),
$key,
$errors
);

continue;
}

yield $r;
yield $entity;
}
}

Expand All @@ -172,17 +234,30 @@ public function entityGenerator(Table $Table, array $records, array $defaults =
* Used by imporTables().
*
* @param Cake\ORM\Table $Table A Table instance to save records into.
* @param array $records An array of Entity records to save into the Table.
* @param array|\Generator $records An array of Entity records to save into the Table.
* @param array $options Options to pass to save().
* @return void
*/
public function importTable(Table $Table, $records) {
public function importTable(Table $Table, $records, array $options = []) {
$defaultOptions = [
'checkRules' => true,
];
$options = $options + $defaultOptions;

foreach ($records as $record) {
$result = $Table->save($record);
$action = ($record->isNew() ? 'Create' : 'Update');
$result = $Table->save($record, $options);
$key = $this->findKey($Table, $record);

if ($result) {
$this->out("{$Table->alias()} ({$key}): Save successful.");
$this->verbose("<success>{$Table->alias()} ({$key}): {$action} successful.</success>");
} else {
$this->out("{$Table->alias()} ({$key}): <warning>Save failed.</warning>");
$this->quiet("<warning>{$Table->alias()} ({$key}): {$action} failed.</warning>");
$this->printValidationErrors(
$Table->alias(),
$this->findKey($Table, $record),
$record->errors()
);
}
}
}
Expand All @@ -202,9 +277,9 @@ protected function truncateTable($Table) {
$truncateSql = $Table->schema()->truncateSql($Table->connection())[0];
$success = $Table->connection()->query($truncateSql);
if ($success) {
$this->out("<info>{$Table->alias()}: Existing DB records truncated.</info>");
$this->verbose("<success>{$Table->alias()}: Existing DB records truncated.</success>");
} else {
$this->out("<warning>{$Table->alias()}: Can not truncate existing records.</warning>");
$this->quiet("<warning>{$Table->alias()}: Can not truncate existing records.</warning>");
}

return $success;
Expand Down Expand Up @@ -238,7 +313,7 @@ protected function findKey(Table $Table, Entity $entity) {
protected function printValidationErrors($table, $id, $errors) {
foreach ($errors as $field => $messages) {
foreach ((array)$messages as $message) {
$this->out("<warning>{$table} ({$id}): {$field}: {$message}</warning>");
$this->quiet("<warning>{$table} ({$id}): {$field}: {$message}</warning>");
}
}
}
Expand Down Expand Up @@ -274,7 +349,7 @@ protected function getFile() {
* @return void
*/
protected function includeFile($file) {
$this->out('Loading seed file: ' . $this->shortPath($file));
$this->quiet('Loading seed file: ' . $this->shortPath($file));
include $file;
}

Expand All @@ -291,7 +366,7 @@ protected function includeFile($file) {
*/
protected function existsOrCreate($file) {
if (!file_exists($file)) {
$this->out('Creating empty seed file: ' . $this->shortPath($file));
$this->out('<info>Creating empty seed file: ' . $this->shortPath($file) . '</info>');

file_put_contents($file, <<<'EOD'
<?php
Expand All @@ -307,9 +382,12 @@ protected function existsOrCreate($file) {
$data = [
'TableName' => [
//'_truncate' => true,
//'_options' => [
//'_entityOptions' => [
// 'validate' => false,
//],
//'_saveOptions' => [
// 'checkRules' => false,
//],
'_defaults' => [],
[
'id' => 1,
Expand Down

0 comments on commit 30369b1

Please sign in to comment.