forked from frictionlessdata/tableschema-php
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WIP] add field types (frictionlessdata#24)
* added field types: time, year, yearmonth, added formats for string * code style fixes * misc. improvements to time format handling * added all field types + tests for cast and for require and enum constraints * style fix
- Loading branch information
Showing
23 changed files
with
1,156 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
namespace frictionlessdata\tableschema\Fields; | ||
|
||
class AnyField extends BaseField | ||
{ | ||
public static function type() | ||
{ | ||
return 'any'; | ||
} | ||
|
||
protected function validateCastValue($val) | ||
{ | ||
return $val; | ||
} | ||
|
||
protected function isEmptyValue($val) | ||
{ | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
namespace frictionlessdata\tableschema\Fields; | ||
|
||
class ArrayField extends BaseField | ||
{ | ||
protected function validateCastValue($val) | ||
{ | ||
if (is_array($val)) { | ||
return $val; | ||
} elseif (is_string($val)) { | ||
try { | ||
$val = json_decode($val); | ||
} catch (\Exception $e) { | ||
throw $this->getValidationException($e->getMessage(), $val); | ||
} | ||
if (!is_array($val)) { | ||
throw $this->getValidationException('json string must decode to array', $val); | ||
} else { | ||
return $val; | ||
} | ||
} else { | ||
throw $this->getValidationException('must be array or string', $val); | ||
} | ||
} | ||
|
||
public static function type() | ||
{ | ||
return 'array'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
namespace frictionlessdata\tableschema\Fields; | ||
|
||
class BooleanField extends BaseField | ||
{ | ||
protected function validateCastValue($val) | ||
{ | ||
if (isset($this->descriptor()->trueValues)) { | ||
$trueValues = $this->descriptor()->trueValues; | ||
} else { | ||
$trueValues = ['true', 'True', 'TRUE', '1']; | ||
} | ||
if (isset($this->descriptor()->falseValues)) { | ||
$falseValues = $this->descriptor()->falseValues; | ||
} else { | ||
$falseValues = ['false', 'False', 'FALSE', '0']; | ||
} | ||
if (is_bool($val)) { | ||
return $val; | ||
} elseif (is_string($val)) { | ||
if (in_array($val, $trueValues)) { | ||
return true; | ||
} elseif (in_array($val, $falseValues)) { | ||
return false; | ||
} else { | ||
throw $this->getValidationException('invalid bool value', $val); | ||
} | ||
} else { | ||
throw $this->getValidationException('value must be a bool or string', $val); | ||
} | ||
} | ||
|
||
public static function type() | ||
{ | ||
return 'boolean'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
namespace frictionlessdata\tableschema\Fields; | ||
|
||
use Carbon\Carbon; | ||
|
||
class DateField extends BaseField | ||
{ | ||
protected function validateCastValue($val) | ||
{ | ||
switch ($this->format()) { | ||
case 'default': | ||
try { | ||
list($year, $month, $day) = explode('-', $val); | ||
|
||
return Carbon::create($year, $month, $day, 0, 0, 0, 'UTC'); | ||
} catch (\Exception $e) { | ||
throw $this->getValidationException($e->getMessage(), $val); | ||
} | ||
case 'any': | ||
try { | ||
$date = new Carbon($val); | ||
$date->setTime(0, 0, 0); | ||
|
||
return $date; | ||
} catch (\Exception $e) { | ||
throw $this->getValidationException($e->getMessage(), $val); | ||
} | ||
default: | ||
$date = strptime($val, $this->format()); | ||
if ($date === false || $date['unparsed'] != '') { | ||
throw $this->getValidationException("couldn't parse date/time according to given strptime format '{$this->format()}''", $val); | ||
} else { | ||
return Carbon::create( | ||
(int) $date['tm_year'] + 1900, (int) $date['tm_mon'] + 1, (int) $date['tm_mday'], | ||
0, 0, 0 | ||
); | ||
} | ||
} | ||
} | ||
|
||
public static function type() | ||
{ | ||
return 'date'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
namespace frictionlessdata\tableschema\Fields; | ||
|
||
use Carbon\Carbon; | ||
|
||
class DatetimeField extends BaseField | ||
{ | ||
protected function validateCastValue($val) | ||
{ | ||
$val = trim($val); | ||
switch ($this->format()) { | ||
case 'default': | ||
if (substr($val, -1) != 'Z') { | ||
throw $this->getValidationException('must have trailing Z', $val); | ||
} else { | ||
try { | ||
$val = rtrim($val, 'Z'); | ||
$val = explode('T', $val); | ||
list($year, $month, $day) = explode('-', $val[0]); | ||
list($hour, $minute, $second) = explode(':', $val[1]); | ||
|
||
return Carbon::create($year, $month, $day, $hour, $minute, $second, 'UTC'); | ||
} catch (\Exception $e) { | ||
throw $this->getValidationException($e->getMessage(), $val); | ||
} | ||
} | ||
case 'any': | ||
try { | ||
return new Carbon($val); | ||
} catch (\Exception $e) { | ||
throw $this->getValidationException($e->getMessage(), $val); | ||
} | ||
default: | ||
$date = strptime($val, $this->format()); | ||
if ($date === false || $date['unparsed'] != '') { | ||
throw $this->getValidationException("couldn't parse date/time according to given strptime format '{$this->format()}''", $val); | ||
} else { | ||
return Carbon::create( | ||
(int) $date['tm_year'] + 1900, (int) $date['tm_mon'] + 1, (int) $date['tm_mday'], | ||
(int) $date['tm_hour'], (int) $date['tm_min'], (int) $date['tm_sec'] | ||
); | ||
} | ||
} | ||
} | ||
|
||
public static function type() | ||
{ | ||
return 'datetime'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
namespace frictionlessdata\tableschema\Fields; | ||
|
||
use Carbon\CarbonInterval; | ||
|
||
class DurationField extends BaseField | ||
{ | ||
protected function validateCastValue($val) | ||
{ | ||
if (!is_string($val)) { | ||
throw $this->getValidationException('must be string', $val); | ||
} else { | ||
$val = trim($val); | ||
try { | ||
// we create a dateInterval first, because it's more restrictive | ||
return CarbonInterval::instance(new \DateInterval($val)); | ||
} catch (\Exception $e) { | ||
throw $this->getValidationException($e->getMessage(), $val); | ||
} | ||
} | ||
} | ||
|
||
public static function type() | ||
{ | ||
return 'duration'; | ||
} | ||
|
||
protected function checkAllowedValues($allowedValues, $val) | ||
{ | ||
foreach ($allowedValues as $allowedValue) { | ||
if ( | ||
$val->years == $allowedValue->years | ||
&& $val->months == $allowedValue->months | ||
&& $val->days == $allowedValue->days | ||
&& $val->hours == $allowedValue->hours | ||
&& $val->minutes == $allowedValue->minutes | ||
&& $val->seconds == $allowedValue->seconds | ||
) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.