Rename Interfaces to Contracts to better match Laravel conventions

This commit is contained in:
Nabeel Shahzad
2019-07-15 15:44:31 -04:00
parent 31f16d693b
commit a720f12e0b
223 changed files with 241 additions and 241 deletions

104
app/Contracts/Award.php Normal file
View File

@@ -0,0 +1,104 @@
<?php
namespace App\Contracts;
use App\Facades\Utils;
use App\Models\Award as AwardModel;
use App\Models\User;
use App\Models\UserAward;
use Log;
/**
* Base class for the Awards, you need to extend this, and implement:
* $name
* $param_description (optional)
* public function check($parameter=null)
*
* See: http://docs.phpvms.net/customizing/awards
*/
abstract class Award
{
public $name = '';
public $param_description = '';
/**
* Each award class just needs to return true or false if it should actually
* be awarded to a user. This is the only method that needs to be implemented
*
* @param null $parameter Optional parameters that are passed in from the UI
*
* @return bool
*/
abstract public function check($parameter = null): bool;
/*
* You don't really need to mess with anything below here
*/
protected $award;
protected $user;
/**
* AwardInterface constructor.
*
* @param AwardModel $award
* @param User $user
*/
public function __construct(AwardModel $award = null, User $user = null)
{
$this->award = $award;
$this->user = $user;
}
/**
* Run the main handler for this award class to determine if
* it should be awarded or not. Declared as final to prevent a child
* from accidentally overriding and breaking something
*/
final public function handle(): void
{
// Check if the params are a JSON object or array
$param = $this->award->ref_model_params;
if (Utils::isObject($this->award->ref_model_params)) {
$param = json_decode($this->award->ref_model_params);
}
if ($this->check($param)) {
$this->addAward();
}
}
/**
* Add the award to this user, if they don't already have it
*
* @return bool|UserAward
*/
final protected function addAward()
{
$w = [
'user_id' => $this->user->id,
'award_id' => $this->award->id,
];
$found = UserAward::where($w)->count('id');
if ($found > 0) {
return true;
}
// Associate this award to the user now
$award = new UserAward($w);
try {
$award->save();
} catch (\Exception $e) {
Log::error(
'Error saving award: '.$e->getMessage(),
$e->getTrace()
);
return false;
}
return $award;
}
}

99
app/Contracts/Controller.php Executable file
View File

@@ -0,0 +1,99 @@
<?php
namespace App\Contracts;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
/**
* Class Controller
*/
abstract class Controller extends \Illuminate\Routing\Controller
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* Write a error to the flash and redirect the user to a route
*
* @param $message
* @param $route
*
* @return mixed
*/
public function flashError($message, $route)
{
flash()->error($message);
return redirect(route($route))->withInput();
}
/**
* Shortcut function to get the attributes from a request while running the validations
*
* @param Request $request
* @param array $attrs_or_validations
* @param array $addtl_fields
*
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
*
* @return array
*/
public function getFromReq($request, $attrs_or_validations, $addtl_fields = null)
{
// See if a list of values is passed in, or if a validation list is passed in
$is_validation = false;
if (\count(array_filter(array_keys($attrs_or_validations), '\is_string')) > 0) {
$is_validation = true;
}
if ($is_validation) {
$this->validate($request, $attrs_or_validations);
}
$fields = [];
foreach ($attrs_or_validations as $idx => $field) {
if ($is_validation) {
$field = $idx;
}
if ($request instanceof Request) {
if ($request->filled($field)) {
$fields[$field] = $request->input($field);
}
} else {
/* @noinspection NestedPositiveIfStatementsInspection */
if (array_key_exists($field, $request)) {
$fields[$field] = $request[$field];
}
}
}
if (!empty($addtl_fields) && \is_array($addtl_fields)) {
$fields = array_merge($fields, $addtl_fields);
}
return $fields;
}
/**
* Simple normalized method for forming the JSON responses
*
* @param $message
* @param null|mixed $count
*
* @return \Illuminate\Http\JsonResponse
*/
public function message($message, $count = null)
{
$attrs = [
'message' => $message,
];
if ($count !== null) {
$attrs['count'] = $count;
}
return response()->json($attrs);
}
}

167
app/Contracts/Enum.php Normal file
View File

@@ -0,0 +1,167 @@
<?php
namespace App\Contracts;
/**
* Borrowed some ideas from myclabs/php-enum after this was created
*/
abstract class Enum
{
protected static $cache = [];
protected static $codes = [];
protected static $labels = [];
/**
* @var int
*/
protected $value;
/**
* Create an instance of this Enum
*
* @param $val
*/
public function __construct($val)
{
$this->value = $val;
}
/**
* Return the value that's been set if this is an instance
*
* @return mixed
*/
final public function getValue()
{
return $this->value;
}
/**
* Return the label, try to return the translated version as well
*
* @param $value
*
* @return mixed
*/
final public static function label($value)
{
if (isset(static::$labels[$value])) {
return trans(static::$labels[$value]);
}
}
/**
* Return all of the (translated) labels
*/
final public static function labels(): array
{
$labels = [];
foreach (static::$labels as $key => $label) {
$labels[$key] = trans($label);
}
return $labels;
}
/**
* Get the numeric value from a string code
*
* @param $code
*
* @return mixed|null
*/
public static function getFromCode($code)
{
return array_search($code, static::$codes, true);
}
/**
* Convert the integer value into one of the codes
*
* @param $value
*
* @return false|int|string
*/
public static function convertToCode($value)
{
$value = (int) $value;
if (!array_key_exists($value, static::$codes)) {
return;
}
return static::$codes[$value];
}
/**
* Select box entry items
*
* @param bool $add_blank
*
* @return array
*/
public static function select($add_blank = false): array
{
$labels = [];
if ($add_blank) {
$labels[] = '';
}
foreach (static::$labels as $key => $label) {
$labels[$key] = trans($label);
}
return $labels;
}
/**
* Returns all possible values as an array
*
* @throws \ReflectionException
*
* @return array Constant name in key, constant value in value
*/
public static function toArray(): array
{
$class = static::class;
if (!array_key_exists($class, static::$cache)) {
$reflection = new \ReflectionClass($class);
static::$cache[$class] = $reflection->getConstants();
}
return static::$cache[$class];
}
/**
* @param Enum $enum
*
* @return bool
*/
final public function equals(self $enum): bool
{
return $this->getValue() === $enum->getValue() && static::class === \get_class($enum);
}
/**
* Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a
* class constant
*
* @param string $name
* @param array $arguments
*
* @throws \BadMethodCallException
* @throws \ReflectionException
*
* @return static
*/
public static function __callStatic($name, $arguments)
{
$array = static::toArray();
if (isset($array[$name])) {
return new static($array[$name]);
}
throw new \BadMethodCallException(
"No static method or enum constant '$name' in class ".static::class
);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Contracts;
/**
* Class FormRequest
*/
class FormRequest extends \Illuminate\Foundation\Http\FormRequest
{
protected $sanitizer;
/**
* @return bool
*/
public function authorize()
{
return true;
}
/**
* @return array
*/
public function rules()
{
return [];
}
}

View File

@@ -0,0 +1,246 @@
<?php
namespace App\Contracts;
use App\Models\Airline;
use Illuminate\Validation\ValidationException;
use Log;
use Validator;
/**
* Common functionality used across all of the importers
*/
class ImportExport
{
public $assetType;
public $status = [
'success' => [],
'errors' => [],
];
/**
* Hold the columns for the particular table
*/
public static $columns = [];
/**
* @param mixed $row
*
* @return array
*/
public function export($row): array
{
throw new \RuntimeException('export not implemented');
}
/**
* @param array $row
* @param mixed $index
*
* @throws \RuntimeException
*
* @return bool
*/
public function import(array $row, $index): bool
{
throw new \RuntimeException('import not implemented');
}
/**
* Get the airline from the ICAO. Create it if it doesn't exist
*
* @param $code
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function getAirline($code)
{
$airline = Airline::firstOrCreate([
'icao' => $code,
], ['name' => $code]);
return $airline;
}
/**
* @return array
*/
public function getColumns()
{
return static::$columns;
}
/**
* Do a basic check that the number of columns match
*
* @param $row
*
* @return bool
*/
public function checkColumns($row): bool
{
return \count($row) === \count($this->getColumns());
}
/**
* Bubble up an error to the interface that we need to stop
*
* @param $error
* @param $e
*
* @throws ValidationException
*/
protected function throwError($error, \Exception $e = null): void
{
Log::error($error);
if ($e) {
Log::error($e->getMessage());
}
$validator = Validator::make([], []);
$validator->errors()->add('csv_file', $error);
throw new ValidationException($validator);
}
/**
* Add to the log messages for this importer
*
* @param $msg
*/
public function log($msg): void
{
$this->status['success'][] = $msg;
Log::info($msg);
}
/**
* Add to the error log for this import
*
* @param $msg
*/
public function errorLog($msg): void
{
$this->status['errors'][] = $msg;
Log::error($msg);
}
/**
* Set a key-value pair to an array
*
* @param $kvp_str
* @param array $arr
*/
protected function kvpToArray($kvp_str, array &$arr)
{
$item = explode('=', $kvp_str);
if (\count($item) === 1) { // just a list?
$arr[] = trim($item[0]);
} else { // actually a key-value pair
$k = trim($item[0]);
$v = trim($item[1]);
$arr[$k] = $v;
}
}
/**
* Parse a multi column values field. E.g:
* Y?price=200&cost=100; F?price=1200
* or
* gate=B32;cost index=100
*
* Converted into a multi-dimensional array
*
* @param $field
*
* @return array|string
*/
public function parseMultiColumnValues($field)
{
$ret = [];
$split_values = explode(';', $field);
// No multiple values in here, just a straight value
if (\count($split_values) === 1) {
if (trim($split_values[0]) === '') {
return [];
}
return [$split_values[0]];
}
foreach ($split_values as $value) {
// This isn't in the query string format, so it's
// just a straight key-value pair set
if (strpos($value, '?') === false) {
$this->kvpToArray($value, $ret);
continue;
}
// This contains the query string, which turns it
// into the multi-level array
$query_str = explode('?', $value);
$parent = trim($query_str[0]);
$children = [];
$kvp = explode('&', trim($query_str[1]));
foreach ($kvp as $items) {
if (!$items) {
continue;
}
$this->kvpToArray($items, $children);
}
$ret[$parent] = $children;
}
return $ret;
}
/**
* @param $obj
*
* @return mixed
*/
public function objectToMultiString($obj)
{
if (!\is_array($obj)) {
return $obj;
}
$ret_list = [];
foreach ($obj as $key => $val) {
if (is_numeric($key) && !\is_array($val)) {
$ret_list[] = $val;
continue;
}
$key = trim($key);
if (!\is_array($val)) {
$val = trim($val);
$ret_list[] = "{$key}={$val}";
} else {
$q = [];
foreach ($val as $subkey => $subval) {
if (is_numeric($subkey)) {
$q[] = $subval;
} else {
$q[] = "{$subkey}={$subval}";
}
}
$q = implode('&', $q);
if (!empty($q)) {
$ret_list[] = "{$key}?{$q}";
} else {
$ret_list[] = $key;
}
}
}
return implode(';', $ret_list);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Contracts;
/**
* Class Listener
*/
abstract class Listener
{
}

57
app/Contracts/Metar.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
namespace App\Contracts;
use Cache;
use Log;
/**
* Base class for implementing retrieving METARs
*/
abstract class Metar
{
/**
* Implement retrieving the METAR- Return the string
* Needs to be protected, since this shouldn't be
* directly called. Call `get_metar($icao)` instead
*
* @param $icao
*
* @return mixed
*/
abstract protected function metar($icao): string;
/**
* @param $icao
*
* @return string
*/
//abstract protected function taf($icao): string;
/**
* Download the METAR, wrap in caching
*
* @param $icao
*
* @return string
*/
public function get_metar($icao): string
{
$cache = config('cache.keys.WEATHER_LOOKUP');
$key = $cache['key'].$icao;
$raw_metar = Cache::remember($key, $cache['time'], function () use ($icao) {
try {
return $this->metar($icao);
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace());
return '';
} catch (\Exception $e) {
Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace());
return '';
}
});
return $raw_metar;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Contracts;
use DB;
/**
* Class Migration
*/
abstract class Migration extends \Illuminate\Database\Migrations\Migration
{
/**
* At a minimum, this function needs to be implemented
*
* @return mixed
*/
abstract public function up();
/**
* A method to reverse a migration doesn't need to be made
*/
public function down()
{
}
/**
* Add rows to a table
*
* @param $table
* @param $rows
*/
public function addData($table, $rows)
{
foreach ($rows as $row) {
try {
DB::table($table)->insert($row);
} catch (\Exception $e) {
// setting already exists, just ignore it
if ($e->getCode() === 23000) {
continue;
}
}
}
}
}

21
app/Contracts/Model.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
namespace App\Contracts;
/**
* Class Model
*
* @property mixed $id
* @property bool $skip_mutator
*/
abstract class Model extends \Illuminate\Database\Eloquent\Model
{
public const ID_MAX_LENGTH = 12;
/**
* For the factories, skip the mutators. Only apply to one instance
*
* @var bool
*/
public $skip_mutator = false;
}

View File

@@ -0,0 +1,111 @@
<?php
namespace App\Contracts;
use Illuminate\Validation\Validator;
/**
* Class Repository
*/
abstract class Repository extends \Prettus\Repository\Eloquent\BaseRepository
{
/**
* @param $id
* @param array $columns
*
* @return mixed|null
*/
public function findWithoutFail($id, array $columns = ['*'])
{
try {
return $this->find($id, $columns);
} catch (\Exception $e) {
return;
}
}
/**
* @param $values
*
* @return bool
*/
public function validate($values)
{
$validator = Validator::make(
$values,
$this->model()->rules
);
if ($validator->fails()) {
return $validator->messages();
}
return true;
}
/**
* Return N most recent items, sorted by created_at
*
* @param int $count
* @param string $sort_by created_at (default) or updated_at
*
* @return mixed
*/
public function recent($count = null, $sort_by = 'created_at')
{
return $this->orderBy($sort_by, 'desc')->paginate($count);
}
/**
* Find records with a WHERE clause but also sort them
*
* @param $where
* @param $sort_by
* @param $order_by
*
* @return $this
*/
public function whereOrder($where, $sort_by, $order_by = 'asc')
{
return $this->scopeQuery(function ($query) use ($where, $sort_by, $order_by) {
$q = $query->where($where);
// See if there are multi-column sorts
if (\is_array($sort_by)) {
foreach ($sort_by as $key => $sort) {
$q = $q->orderBy($key, $sort);
}
} else {
$q = $q->orderBy($sort_by, $order_by);
}
return $q;
});
}
/**
* Find records where values don't match a list but sort the rest
*
* @param string $col
* @param array $values
* @param string $sort_by
* @param string $order_by
*
* @return $this
*/
public function whereNotInOrder($col, $values, $sort_by, $order_by = 'asc')
{
return $this->scopeQuery(function ($query) use ($col, $values, $sort_by, $order_by) {
$q = $query->whereNotIn($col, $values);
// See if there are multi-column sorts
if (\is_array($sort_by)) {
foreach ($sort_by as $key => $sort) {
$q = $q->orderBy($key, $sort);
}
} else {
$q = $q->orderBy($sort_by, $order_by);
}
return $q;
});
}
}

10
app/Contracts/Service.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace App\Contracts;
/**
* Class Service
*/
abstract class Service
{
}

121
app/Contracts/Unit.php Normal file
View File

@@ -0,0 +1,121 @@
<?php
namespace App\Contracts;
use ArrayAccess;
/**
* Class Unit
*
* @property mixed $instance
* @property string $unit
* @property array $units
*/
class Unit implements ArrayAccess
{
/**
* The unit this is kept as
*/
public $unit;
/**
* All of the units of this class
*/
public $units;
/**
* Holds an instance of the PhpUnit type
*/
protected $instance;
/**
* Units that are included as part of the REST response
*/
public $responseUnits = [];
/**
* @return mixed
*/
public function value()
{
return $this->__toString();
}
/**
* Just call toUnit() on the PhpUnitOfMeasure instance
*
* @param string $unit
*
* @return mixed
*/
public function toUnit($unit)
{
return $this->instance->toUnit($unit);
}
/**
* Return all of the units that get sent back in a response
*/
public function getResponseUnits(): array
{
$response = [];
foreach ($this->responseUnits as $unit) {
$response[$unit] = $this[$unit];
}
return $response;
}
/**
* Implements ArrayAccess
*
* @param $offset
*
* @return bool
*/
public function offsetExists($offset)
{
return array_key_exists($offset, $this->units);
}
/**
* Implements ArrayAccess
*
* @param $offset
*
* @return mixed
*/
public function offsetGet($offset)
{
return round($this->instance->toUnit($offset), 2);
}
/**
* Implements ArrayAccess
*
* @param $offset
* @param $value
*/
public function offsetSet($offset, $value)
{
// $this->units[$offset] = $value;
}
/**
* Implements ArrayAccess
*
* @param $offset
*/
public function offsetUnset($offset)
{
// $this->units[$offset] = null;
}
/**
* @return mixed
*/
public function __toString()
{
return (string) $this->units[$this->unit];
}
}

26
app/Contracts/Widget.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
namespace App\Contracts;
use Arrilot\Widgets\AbstractWidget;
/**
* Class Widget
*/
abstract class Widget extends AbstractWidget
{
public $cacheTime = 0;
/**
* Render the template
*
* @param string $template
* @param array $vars
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function view(string $template, array $vars = [])
{
return view($template, $vars);
}
}