Skip to content

Commit

Permalink
Merge pull request #50 from brianjmiller/php7
Browse files Browse the repository at this point in the history
PHP 7 support
  • Loading branch information
brianjmiller authored Sep 21, 2016
2 parents 522afdb + 0ca5ab4 commit abb63a0
Show file tree
Hide file tree
Showing 17 changed files with 348 additions and 227 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ composer.lock
sample/vendor
sample/composer.lock
doc/api
doc/coverage

# wild
todo.md
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
sudo: false
language: php
php:
- 7.0
- 5.6
- 5.5
- 5.4
- hhvm
before_script:
- cp tests/config/config.travis-ci.php tests/config/config.php
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
A PHP library for implementing Tin Can API.
A PHP library for implementing the Experience API (Tin Can API).

[![Build Status](https://travis-ci.org/RusticiSoftware/TinCanPHP.png)](https://travis-ci.org/RusticiSoftware/TinCanPHP)
[![Latest Stable Version](https://poser.pugx.org/rusticisoftware/tincan/v/stable)](https://packagist.org/packages/rusticisoftware/tincan)
[![License](https://poser.pugx.org/rusticisoftware/tincan/license)](https://packagist.org/packages/rusticisoftware/tincan)
[![Total Downloads](https://poser.pugx.org/rusticisoftware/tincan/downloads)](https://packagist.org/packages/rusticisoftware/tincan)

For hosted API documentation, basic usage instructions, supported version listing, etc. visit the main project website at:

http://rusticisoftware.github.io/TinCanPHP/

For more information about the Tin Can API visit:
For more information about the Experience API visit:

http://tincanapi.com/
http://experienceapi.com/

Requires PHP 5.4 or later. (If you must run something older you should look at the PHP_5_2 branch.)
Requires PHP 5.5 or later. (If you must run something older you should look at the 0.x release series or the PHP_5_2 branch.)

### Installation

Expand All @@ -28,7 +31,7 @@ require 'path/to/TinCan/autoload.php';

### Testing

Tests are implemented using the latest stable version of PHPUnit. It will be installed when using Composer. Configure the LRS endpoint and credentials by copying the `tests/config/config.dist.php` to `tests/config/config.php` then setting the values for your LRS.
Tests are implemented using the latest stable version of PHPUnit. It will be installed when using Composer. Configure the LRS endpoint and credentials by copying the `tests/config/config.dist.php` to `tests/config/config.php` then setting the values for your LRS.

Once configured run:

Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "rusticisoftware/tincan",
"type": "library",
"description": "Tin Can API Library",
"description": "Experience API (Tin Can API) Library",
"homepage": "http://rusticisoftware.github.io/TinCanPHP/",
"keywords": [
"tin can",
Expand All @@ -24,10 +24,10 @@
"issues": "https://github.com/RusticiSoftware/TinCanPHP/issues"
},
"require": {
"php": "~5.4",
"php": "~5.5 || ^7.0.3",
"ext-openssl": "*",
"namshi/jose": "~4.0",
"willdurand/negotiation": "~1.3"
"namshi/jose": "^7.2.1",
"willdurand/negotiation": "^2.0"
},
"require-dev": {
"phpdocumentor/phpdocumentor": "2.*",
Expand Down
16 changes: 5 additions & 11 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,18 @@
</exclude>
</testsuite>
</testsuites>

<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"
lowUpperBound="50" highLowerBound="80" />
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true" lowUpperBound="50" highLowerBound="80" />
<!--log type="coverage-html" target="doc/coverage" showUncoveredFiles="true" lowUpperBound="50" highLowerBound="80" /-->
</logging>

<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
<exclude>
<directory>doc</directory>
<directory>sample</directory>
<directory>tests</directory>
<directory>vendor</directory>
</exclude>
</whitelist>
</filter>

<php>
<const name="COMMON_NAME" value="Example User" />
<const name="COMMON_EMAIL" value="tincanphp@tincanapi.com" />
Expand Down
4 changes: 2 additions & 2 deletions src/FromJSONTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ public static function fromJSON($jsonStr) {
$cfg = json_decode($jsonStr, true);

if (is_null($cfg)) {
$err = json_last_error();
throw new \InvalidArgumentException("Invalid JSON: $err");
throw new JSONParseErrorException($jsonStr, json_last_error(), json_last_error_msg());
}
$called_class = get_called_class();
return new $called_class($cfg);
}

}
49 changes: 49 additions & 0 deletions src/JSONParseErrorException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
/*
Copyright 2016 Rustici Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

namespace TinCan;

class JSONParseErrorException extends \Exception
{
private static $format = 'Invalid JSON "%s": %s (%d)';

private $malformedValue;
private $jsonErrorNumber;
private $jsonErrorMessage;

public function __construct($malformedValue, $jsonErrorNumber, $jsonErrorMessage, \Exception $previous = null) {
$this->malformedValue = $malformedValue;
$this->jsonErrorNumber = (int) $jsonErrorNumber;
$this->jsonErrorMessage = $jsonErrorMessage;

$message = sprintf(self::$format, $malformedValue, $jsonErrorMessage, $jsonErrorNumber);

parent::__construct($message, $jsonErrorNumber, $previous);
}

public function malformedValue() {
return $this->malformedValue;
}

public function jsonErrorNumber() {
return $this->jsonErrorNumber;
}

public function jsonErrorMessage() {
return $this->jsonErrorMessage;
}
}
21 changes: 17 additions & 4 deletions src/LanguageMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,26 @@
class LanguageMap extends Map
{
public function getNegotiatedLanguageString ($acceptLanguage = null) {
$negotiator = new \Negotiation\Negotiator();
$negotiator = new \Negotiation\LanguageNegotiator();
if ($acceptLanguage === null) {
$acceptLanguage = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE']. ', *' : '*';
//
// include the q=0 on * because of an issue in the library not picking up
// the earlier configured language correctly, see
// https://github.com/willdurand/Negotiation/issues/83
//
$acceptLanguage = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE']. ', *;q=0' : '*';
}
$availableLanguages = array_keys ($this->_map);
$availableLanguages = array_keys($this->_map);
$preferredLanguage = $negotiator->getBest($acceptLanguage, $availableLanguages);

return $this->_map[$preferredLanguage->getValue()];
$key = $availableLanguages[0];
if (isset($preferredLanguage)) {
$key = $preferredLanguage->getValue();
}
elseif (isset($this->_map['und'])) {
$key = 'und';
}

return $this->_map[$key];
}
}
88 changes: 42 additions & 46 deletions src/Score.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/**
* An optional field that represents the outcome of a graded Activity achieved
* by an Agent.
* by an actor.
*/
class Score implements VersionableInterface, ComparableInterface
{
Expand All @@ -32,7 +32,6 @@ class Score implements VersionableInterface, ComparableInterface
*
* @var int
*/
const DEFAULT_PRECISION = 2;
const SCALE_MIN = -1;
const SCALE_MAX = 1;
/**#@- */
Expand Down Expand Up @@ -69,66 +68,38 @@ class Score implements VersionableInterface, ComparableInterface
/**
* Constructor
*
* @param float|array $aRawValue the score value, may also be an array of properties
* @param float|array $aRawValue the raw score value, may also be an array of properties
* @param float $aMin the score minimum
* @param float $aMax the score maximum
* @param float $aScalingFactor the score scaling factor
* @param float $aScaledValue the scaled score
*/
public function __construct($aRawValue = null, $aMin = null, $aMax = null, $aScalingFactor = null) {
public function __construct($aRawValue = null, $aMin = null, $aMax = null, $aScaledValue = null) {
if (!is_array($aRawValue)) {
$aRawValue = [
'raw' => $aRawValue,
'min' => $aMin,
'max' => $aMax,
'scaled' => $aScalingFactor
'scaled' => $aScaledValue
];
}
$this->_fromArray($aRawValue);
}

/**
* @param float $aValue
* @throws InvalidArgumentException
* @return null
*/
public function validate($aValue) {
if (!isset($this->min, $this->max)) {
return;
}
if ($aValue < $this->min || $aValue > $this->max) {
throw new InvalidArgumentException(
sprintf("Value must be between %s and %s", $this->min, $this->max)
);
}
}

/**
* @param int $aPrecision a rounding precision integer
* @return null|float
*/
public function getValue($aPrecision = self::DEFAULT_PRECISION) {
if (!isset($this->raw)) {
return null;
}
if (isset($this->scaled)) {
return round($this->raw * $this->scaled, $aPrecision);
}
return round($this->raw, $aPrecision);
}

/**
* @param float $value
* @throws InvalidArgumentException
* @return self
*/
public function setScaled($value) {
if ($value < static::SCALE_MIN || $value > static::SCALE_MAX) {
throw new InvalidArgumentException(sprintf(
"Scale must be between %s and %s [%s]",
static::SCALE_MIN,
static::SCALE_MAX,
$value
));
if ($value < static::SCALE_MIN) {
throw new InvalidArgumentException(
sprintf( "Value must be greater than or equal to %s [%s]", static::SCALE_MIN, $value)
);
}
if ($value > static::SCALE_MAX) {
throw new InvalidArgumentException(
sprintf( "Value must be less than or equal to %s [%s]", static::SCALE_MAX, $value)
);
}
$this->scaled = (float) $value;
return $this;
Expand All @@ -143,10 +114,21 @@ public function getScaled() {

/**
* @param float $value
* @throws InvalidArgumentException
* @return self
*/
public function setRaw($value) {
$this->validate($value);
if (isset($this->min) && $value < $this->min) {
throw new InvalidArgumentException(
sprintf("Value must be greater than or equal to 'min' (%s) [%s]", $this->min, $value)
);
}
if (isset($this->max) && $value > $this->max) {
throw new InvalidArgumentException(
sprintf("Value must be less than or equal to 'max' (%s) [%s]", $this->max, $value)
);
}

$this->raw = (float) $value;
return $this;
}
Expand All @@ -164,8 +146,15 @@ public function getRaw() {
* @return self
*/
public function setMin($value) {
if (isset($this->raw) && $value > $this->raw) {
throw new InvalidArgumentException(
sprintf("Value must be less than or equal to 'raw' (%s) [%s]", $this->raw, $value)
);
}
if (isset($this->max) && $value >= $this->max) {
throw new InvalidArgumentException("Min must be less than max");
throw new InvalidArgumentException(
sprintf("Value must be less than 'max' (%s) [%s]", $this->max, $value)
);
}
$this->min = (float) $value;
return $this;
Expand All @@ -184,8 +173,15 @@ public function getMin() {
* @return self
*/
public function setMax($value) {
if (isset($this->raw) && $value < $this->raw) {
throw new InvalidArgumentException(
sprintf("Value must be greater than or equal to 'raw' (%s) [%s]", $this->raw, $value)
);
}
if (isset($this->min) && $value <= $this->min) {
throw new InvalidArgumentException("Max must be greater than min");
throw new InvalidArgumentException(
sprintf("Value must be greater than 'min' (%s) [%s]", $this->min, $value)
);
}
$this->max = (float) $value;
return $this;
Expand Down
15 changes: 3 additions & 12 deletions tests/ActivityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,17 @@ public function testInstantiation() {
}

public function testFromJSONInvalidNull() {
$this->setExpectedException(
'InvalidArgumentException',
'Invalid JSON: ' . JSON_ERROR_NONE
);
$this->setExpectedException('TinCan\JSONParseErrorException');
$obj = Activity::fromJSON(null);
}

public function testFromJSONInvalidEmptyString() {
$this->setExpectedException(
'InvalidArgumentException',
'Invalid JSON: ' . JSON_ERROR_NONE
);
$this->setExpectedException('TinCan\JSONParseErrorException');
$obj = Activity::fromJSON('');
}

public function testFromJSONInvalidMalformed() {
$this->setExpectedException(
'InvalidArgumentException',
'Invalid JSON: ' . JSON_ERROR_SYNTAX
);
$this->setExpectedException('TinCan\JSONParseErrorException');
$obj = Activity::fromJSON('{id:"some value"}');
}

Expand Down
Loading

0 comments on commit abb63a0

Please sign in to comment.