Skip to content

Commit

Permalink
Merge pull request #7 from codefornebraska/task/5-import-state-table
Browse files Browse the repository at this point in the history
[WL5] Import State Data
  • Loading branch information
barobba authored Oct 4, 2022
2 parents 258cd71 + 768ed3e commit 4c5a4e2
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 127 deletions.
113 changes: 78 additions & 35 deletions app/Console/Commands/LegiScanImport.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,101 @@

namespace App\Console\Commands;

use App\Models\LegiScan\State;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
* @codeCoverageIgnore
*/
class LegiScanImport extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'legiscan:import';

/**
* The console command description.
*
* @var string
*/
protected $signature = 'legiscan:import {--d|debug}';

protected $description = 'Regularly scheduled LegiScan import command';

/**
* Execute the console command.
*
* @return int
*/
protected string $separator = '--------------------------------';

public function handle()
{
// RUN THIS COMMAND USING "SAIL" (WHEN IN LOCAL MODE) !!!!!!!!!!!!
$start = now();

$this->importLegiscanData()
->translateStates();

$this->info('');
$this->info(
'Finished in ' . now()->diff($start)->format('%I:%S')
);
$this->info('');
}

protected function translateStates(): static
{
$this->info('Translating State Data');

$states = DB::select('SELECT * FROM ls_state');

$script_filepath = base_path('lib/legiscan/legiscan-bulk.php');
$progress = $this->output->createProgressBar(count($states));

$command = '';
$progress->start();

$command .= ' HOST='.config('database.connections.mysql.host');
$command .= ' PORT='.config('database.connections.mysql.port');
$command .= ' NAME='.config('database.connections.mysql.database');
$command .= ' USER='.config('database.connections.mysql.username');
$command .= ' PASS='.config('database.connections.mysql.password');
foreach ($states as $state) {
State::updateOrCreate(
['id' => $state->state_id],
[
'id' => $state->state_id,
'name' => $state->state_name,
'abbreviation' => $state->state_abbr,
'biennium' => $state->biennium,
'carry_over' => $state->carry_over,
'capitol' => $state->capitol,
'latitude' => $state->latitude,
'longitude' => $state->longitude,
]
);

$command .= ' LEGISCAN_API_KEY='.config('legiscan.api_key');
$command .= ' MAIL_FROM_ADDRESS='.config('mail.from.address');
$progress->advance();
}

$command .= ' php';
// $command .= ' -d display_errors 0';
// $command .= ' -d error_reporting 5'; // Same as (E_ERROR | E_PARSE); see https://www.php.net/manual/en/errorfunc.constants.php
$command .= ' ' . $script_filepath;
$command .= ' --bulk';
$command .= ' --import';
$command .= ' --yes';
$progress->finish();

// echo $command;
$this->info("\n".$this->separator);

return $this;
}

protected function importLegiscanData(): static
{
$mysqlConfig = config('database.connections.mysql');
$apiKey = config('legiscan.api_key');
$mailFrom = config('mail.from.address');
$debug = $this->option('debug') ? '-d display_errors 0 -d error_reporting 5 ' : '';
$scriptFilepath = base_path('lib/legiscan/legiscan-bulk.php');

$command = sprintf(
'HOST=%s PORT=%s NAME=%s USER=%s PASS=%s LEGISCAN_API_KEY=%s MAIL_FROM_ADDRESS=%s php %s%s --bulk --import --yes',
$mysqlConfig['host'],
$mysqlConfig['port'],
$mysqlConfig['database'],
$mysqlConfig['username'],
$mysqlConfig['password'],
$apiKey,
$mailFrom,
$debug,
$scriptFilepath,
);

$this->info('Importing LegiScan data. This may take a minute.');

exec($command);

Log::info('LegiScan import completed');

$this->info('LegiScan import completed.');
$this->info($this->separator);

return $this;
}
}
9 changes: 9 additions & 0 deletions app/Exceptions/InvalidEnumException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace App\Exceptions;

use Exception;

class InvalidEnumException extends Exception
{
}
75 changes: 0 additions & 75 deletions app/Models/LegiScan/Bill.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,79 +128,4 @@ public function votes()
{
return $this->hasMany(BillVote::class, 'bill_id');
}

#endregion

#region Foreign model assignment attributes

public function setStateAttribute(State|int $state)
{
$state = is_int($state) ? State::find($state) : $state;

$this->state_id = is_int($state) ? $state : $state->getKey();
$this->setRelation('state', $state);
}

public function setSessionAttribute(Session|int $session)
{
$session = is_int($session) ? Session::find($session) : $session;

$this->session_id = $session->getKey();
$this->setRelation('session', $session);
}

public function setBodyAttribute(Body|int $body)
{
$body = is_int($body) ? Body::find($body) : $body;

$this->body_id = $body->getKey();
$this->setRelation('body', $body);
}

public function setCurrentBodyAttribute(Body|int $current_body)
{
$current_body = is_int($current_body) ? Body::find($current_body) : $current_body;

$this->body_id = $current_body->getKey();
$this->setRelation('current_body', $current_body);
}

public function setBillTypeAttribute(Type|int $bill_type)
{
$bill_type = is_int($bill_type) ? Type::find($bill_type) : $bill_type;

$this->body_id = $bill_type->getKey();
$this->setRelation('bill_type', $bill_type);
}

public function setStatusAttribute(Progress|int $status)
{
$status = is_int($status) ? Progress::find($status) : $status;

$this->body_id = $status->getKey();
$this->setRelation('progress', $status);
}

public function setPendingCommitteeAttribute(Committee|int $pending_committee)
{
$pending_committee = is_int($pending_committee) ? Committee::find($pending_committee) : $pending_committee;

$this->body_id = $pending_committee->getKey();
$this->setRelation('pending_committee', $pending_committee);
}

#endregion

#region Simplify naming attributes

public function getNumberAttribute()
{
return $this->bill_number;
}
public function setNumberAttribute($number)
{
$this->bill_number = $number;
}

#endregion
}
22 changes: 16 additions & 6 deletions app/Models/LegiScan/State.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@

namespace App\Models\LegiScan;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Traits\Models\HasEnumProperties;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class State extends Model
{
use HasFactory;

protected $table = 'ls_state';

protected $primaryKey = 'state_id';
use HasEnumProperties, HasFactory;

public $timestamps = false;

protected $fillable = [
'id',
'name',
'abbreviation',
'biennium',
'carry_over',
'capitol',
'latitude',
'longitude',
];

public $enumCarryOvers = ['OE', 'EO', 'NO'];

public function bills()
{
return $this->hasMany(Bill::class, 'state_id');
Expand Down
125 changes: 125 additions & 0 deletions app/Traits/Models/HasEnumProperties.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

namespace App\Traits\Models;

use Illuminate\Support\Str;
use App\Exceptions\InvalidEnumException;

trait HasEnumProperties
{
/**
* Enum property getter
*
* @param string $field
* @return mixed|false
*/
public static function getEnum(string $field)
{
$instance = new static;

if ($instance->hasEnumProperty($field)) {
$property = $instance->getEnumProperty($field);

return $instance->$property;
}

return false;
}

/**
* Check for the presence of a property that starts
* with enum for the provided attribute
*
* @param string $field
* @param mixed $value
* @return $this
* @throws InvalidEnumException
*/
public function setAttribute($field, $value)
{
if ($this->hasEnumProperty($field)) {
if (!$this->isValidEnum($field, $value)) {
throw new InvalidEnumException('Invalid value for ' . static::class . "::$field ($value)");
}

if ($this->isKeyedEnum($field, $value)) {
$value = $this->getKeyedEnum($field, $value);
}
}

return parent::setAttribute($field, $value);
}

/**
* Gets the expected enum property
*
* @param string $field
* @return string
*/
protected function getEnumProperty(string $field)
{
return 'enum' . Str::plural(Str::studly($field));
}

/**
* Gets the enum value by key
*
* @param string $field
* @param mixed $key
* @return mixed
*/
protected function getKeyedEnum(string $field, $key)
{
return static::getEnum($field)[$key];
}

/**
* Is an enum property defined for the provided field
*
* @param string $field
* @return bool
*/
protected function hasEnumProperty(string $field)
{
$property = $this->getEnumProperty($field);

return isset($this->$property) && is_array($this->$property);
}

/**
* Is the provided value a key in the enum
*
* @param string $field
* @param mixed $key
* @return bool
*/
protected function isKeyedEnum(string $field, $key)
{
return in_array($key, array_keys(static::getEnum($field)), true);
}

/**
* Is the value a valid enum in any way
*
* @param string $field
* @param mixed $value
* @return bool
*/
protected function isValidEnum(string $field, $value)
{
return $this->isValueEnum($field, $value) ||
$this->isKeyedEnum($field, $value);
}

/**
* Is the provided value in the enum
*
* @param string $field
* @param mixed $value
* @return bool
*/
protected function isValueEnum(string $field, $value)
{
return in_array($value, static::getEnum($field));
}
}
Loading

0 comments on commit 4c5a4e2

Please sign in to comment.