12 Commits

92 changed files with 9283 additions and 967 deletions

View File

@@ -1,4 +1,4 @@
FROM php:5.6-cli FROM php:5.4-cli
# #
# Tools & libraries # Tools & libraries
@@ -31,12 +31,15 @@ COPY php.ini /usr/local/etc/php/php.ini
ARG TIMEZONE ARG TIMEZONE
RUN echo "\n""date.timezone = $TIMEZONE""\n" >> /usr/local/etc/php/php.ini RUN echo "\n""date.timezone = $TIMEZONE""\n" >> /usr/local/etc/php/php.ini
#
# Disabled, because:
# PHP versions below 5.5 are not supported
# #
# Xdebug # Xdebug
# #
RUN pecl install xdebug \ #RUN pecl install xdebug \
&& docker-php-ext-enable xdebug # && docker-php-ext-enable xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini #COPY xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
# #
# Phing # Phing

View File

@@ -146,13 +146,18 @@
2017-02-22 2017-02-22
--> -->
<target name="check:cs" description="Checks coding standard"> <target name="check:cs" description="Checks coding standard">
<echo msg="Checking coding standard..." /> <echo msg="Checking coding standard... DISABLED for PHP 5.4" />
<!--
Disabled, because of error while running PHP 5.4.45:
This task requires the PHP_CodeSniffer package installed and available on the include path
<phpcodesniffer standard="PSR2" showWarnings="true"> <phpcodesniffer standard="PSR2" showWarnings="true">
<fileset refid="sourcecode" /> <fileset refid="sourcecode" />
<formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml" /> <formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml" />
<formatter type="csv" outfile="${dir.reports}/checkstyle.csv" /> <formatter type="csv" outfile="${dir.reports}/checkstyle.csv" />
<formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt" /> <formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt" />
</phpcodesniffer> </phpcodesniffer>
-->
</target> </target>
<!-- copy/paste detector --> <!-- copy/paste detector -->

View File

@@ -11,22 +11,24 @@
} }
], ],
"require": { "require": {
"php": ">=5.6", "php": ">=5.4",
"fguillot/json-rpc": "^1.2", "fguillot/json-rpc": "^1.2",
"meritoo/common-library": "~0.0.1" "gedmo/doctrine-extensions": "^2.4",
"symfony/http-foundation": "^2.8"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^5.7", "phpunit/phpunit": "^4.8",
"squizlabs/php_codesniffer": "^2.9", "squizlabs/php_codesniffer": "^3.1",
"phpmd/phpmd": "^2.6", "phpmd/phpmd": "^2.6",
"sebastian/phpcpd": "^3.0", "sebastian/phpcpd": "^2.0",
"pdepend/pdepend": "^2.5", "pdepend/pdepend": "^2.5",
"phploc/phploc": "^4.0", "phploc/phploc": "^2.1",
"friendsofphp/php-cs-fixer": "^2.6" "friendsofphp/php-cs-fixer": "^2.2"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Meritoo\\LimeSurvey\\ApiClient\\": "src/" "Meritoo\\Common\\": "src/Common/",
"Meritoo\\LimeSurvey\\ApiClient\\": "src/LimeSurvey/"
} }
}, },
"autoload-dev": { "autoload-dev": {

View File

@@ -0,0 +1,286 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Collection;
use ArrayAccess;
use ArrayIterator;
use Countable;
use IteratorAggregate;
use Meritoo\Common\Utilities\Arrays;
/**
* Collection of elements.
* It's a set of some elements, e.g. objects.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Collection implements Countable, ArrayAccess, IteratorAggregate
{
const className = 'Meritoo\Common\Collection\Collection';
/**
* The elements of collection
*
* @var array
*/
private $elements;
/**
* Class constructor
*
* @param array $elements (optional) The elements of collection
*/
public function __construct(array $elements = [])
{
$this->elements = $elements;
}
/**
* {@inheritdoc}
* Required by interface Countable
*/
public function count()
{
return count($this->elements);
}
/**
* {@inheritdoc}
* Required by interface ArrayAccess
*/
public function offsetExists($offset)
{
return $this->exists($offset);
}
/**
* {@inheritdoc}
* Required by interface ArrayAccess
*/
public function offsetGet($offset)
{
if ($this->exists($offset)) {
return $this->elements[$offset];
}
return null;
}
/**
* {@inheritdoc}
* Required by interface ArrayAccess
*/
public function offsetSet($offset, $value)
{
$this->elements[$offset] = $value;
}
/**
* {@inheritdoc}
* Required by interface ArrayAccess
*/
public function offsetUnset($offset)
{
if ($this->exists($offset)) {
unset($this->elements[$offset]);
}
}
/**
* {@inheritdoc}
* Required by interface IteratorAggregate
*/
public function getIterator()
{
return new ArrayIterator($this->elements);
}
/**
* Adds given element (at the end of collection)
*
* @param mixed $element The element to add
* @param mixed $index (optional) Index / key of the element
* @return $this
*/
public function add($element, $index = null)
{
if (null === $index) {
$this->elements[] = $element;
} else {
$this->elements[$index] = $element;
}
return $this;
}
/**
* Adds given elements (at the end of collection)
*
* @param array|Collection $elements The elements to add
* @param bool|false $useIndexes (optional) If is set to true, indexes of given elements will be used in
* this collection. Otherwise - not.
* @return $this
*/
public function addMultiple($elements, $useIndexes = false)
{
if (!empty($elements)) {
foreach ($elements as $index => $element) {
if (!$useIndexes) {
$index = null;
}
$this->add($element, $index);
}
}
return $this;
}
/**
* Prepends given element (adds given element at the beginning of collection)
*
* @param mixed $element The element to prepend
* @return $this
*/
public function prepend($element)
{
array_unshift($this->elements, $element);
return $this;
}
/**
* Removes given element
*
* @param mixed $element The element to remove
* @return $this
*/
public function remove($element)
{
if ($this->count() > 0) {
foreach ($this->elements as $index => $existing) {
if ($element === $existing) {
unset($this->elements[$index]);
break;
}
}
}
return $this;
}
/**
* Returns information if collection is empty
*
* @return bool
*/
public function isEmpty()
{
return empty($this->elements);
}
/**
* Returns information if given element is first in the collection
*
* @param mixed $element The element to verify
* @return bool
*/
public function isFirst($element)
{
return reset($this->elements) === $element;
}
/**
* Returns information if given element is last in the collection
*
* @param mixed $element The element to verify
* @return bool
*/
public function isLast($element)
{
return end($this->elements) === $element;
}
/**
* Returns information if the collection has given element, iow. if given element exists in the collection
*
* @param mixed $element The element to verify
* @return bool
*/
public function has($element)
{
$index = Arrays::getIndexOf($this->elements, $element);
return null !== $index && false !== $index;
}
/**
* Returns previous element for given element
*
* @param mixed $element The element to verify
* @return mixed|null
*/
public function getPrevious($element)
{
return Arrays::getPreviousElement($this->elements, $element);
}
/**
* Returns next element for given element
*
* @param mixed $element The element to verify
* @return mixed|null
*/
public function getNext($element)
{
return Arrays::getNextElement($this->elements, $element);
}
/**
* Returns the first element in the collection
*
* @return mixed
*/
public function getFirst()
{
return Arrays::getFirstElement($this->elements);
}
/**
* Returns the last element in the collection
*
* @return mixed
*/
public function getLast()
{
return Arrays::getLastElement($this->elements);
}
/**
* Returns an array representation of the collection
*
* @return array
*/
public function toArray()
{
return $this->elements;
}
/**
* Returns information if element with given index/key exists
*
* @param string|int $index The index/key of element
* @return bool
*/
private function exists($index)
{
return isset($this->elements[$index]) || array_key_exists($index, $this->elements);
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Base;
use Exception;
use Meritoo\Common\Type\Base\BaseType;
use Meritoo\Common\Utilities\Arrays;
/**
* An exception used while type of something is unknown
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class UnknownTypeException extends Exception
{
/**
* Class constructor
*
* @param string|int $unknownType The unknown type of something (value of constant)
* @param BaseType $typeInstance An instance of class that contains type of the something
* @param string $typeName Name of the something
*/
public function __construct($unknownType, BaseType $typeInstance, $typeName)
{
$allTypes = $typeInstance->getAll();
$types = Arrays::values2string($allTypes, '', ', ');
$template = 'The \'%s\' type of %s is unknown. Probably doesn\'t exist or there is a typo. You should use one'
. ' of these types: %s.';
$message = sprintf(sprintf($template, $unknownType, $typeName, $types));
parent::__construct($message);
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Date;
use Meritoo\Common\Exception\Base\UnknownTypeException;
use Meritoo\Common\Type\DatePartType;
/**
* An exception used while type of date part, e.g. "year", is unknown
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class UnknownDatePartTypeException extends UnknownTypeException
{
/**
* Class constructor
*
* @param string $unknownDatePart Type of date part, e.g. "year". One of DatePartType class constants.
* @param string $value Incorrect value
*/
public function __construct($unknownDatePart, $value)
{
parent::__construct($unknownDatePart, new DatePartType(), sprintf('date part (with value %s)', $value));
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\File;
/**
* An exception used while file with given path is empty (has no content)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class EmptyFileException extends \Exception
{
const className = 'Meritoo\Common\Exception\File\EmptyFileException';
/**
* Class constructor
*
* @param string $emptyFilePath Path of the empty file
*/
public function __construct($emptyFilePath)
{
$template = 'File with path \'%s\' is empty (has no content). Did you provide path of proper file?';
$message = sprintf($template, $emptyFilePath);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\File;
/**
* An exception used while path of given file is empty
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class EmptyFilePathException extends \Exception
{
const className = 'Meritoo\Common\Exception\File\EmptyFilePathException';
/**
* Class constructor
*/
public function __construct()
{
parent::__construct('Path of the file is empty. Did you provide path of proper file?');
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\File;
/**
* An exception used while file with given path does not exist
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class NotExistingFileException extends \Exception
{
const className = 'Meritoo\Common\Exception\File\NotExistingFileException';
/**
* Class constructor
*
* @param string $notExistingFilePath Path of not existing (or not readable) file
*/
public function __construct($notExistingFilePath)
{
$template = 'File with path \'%s\' does not exist (or is not readable). Did you provide path of proper file?';
$message = sprintf($template, $notExistingFilePath);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Method;
use Exception;
/**
* An exception used while method cannot be called, because is disabled
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DisabledMethodException extends Exception
{
const className = 'Meritoo\Common\Exception\Method\DisabledMethodException';
/**
* Class constructor
*
* @param string $disabledMethod Name of the disabled method
* @param string $alternativeMethod (optional) Name of the alternative method
*/
public function __construct($disabledMethod, $alternativeMethod = '')
{
$template = 'Method %s() cannot be called, because is disabled.';
if (!empty($alternativeMethod)) {
$template .= ' Use %s() instead.';
}
$message = sprintf($template, $disabledMethod, $alternativeMethod);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Reflection;
use Exception;
/**
* An exception used while name of class or trait cannot be resolved
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class CannotResolveClassNameException extends Exception
{
/**
* Class constructor
*
* @param array|object|string $source Source of the class's / trait's name. It can be an array of objects,
* namespaces, object or namespace.
* @param bool $forClass (optional) If is set to true, message of this exception for class is
* prepared. Otherwise - for trait.
*/
public function __construct($source, $forClass = true)
{
$forWho = 'trait';
$value = '';
if ($forClass) {
$forWho = 'class';
}
if (is_scalar($source)) {
$value = sprintf(' %s', (string)$source);
}
$template = 'Name of %s from given \'%s\'%s cannot be resolved. Is there everything ok?';
$message = sprintf($template, $forWho, gettype($source), $value);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Reflection;
use Exception;
use Meritoo\Common\Utilities\Reflection;
/**
* An exception used while given class has no child classes
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class MissingChildClassesException extends Exception
{
/**
* Class constructor
*
* @param array|object|string $parentClass Class that hasn't child classes, but it should. An array of objects,
* strings, object or string.
*/
public function __construct($parentClass)
{
$template = 'The \'%s\' class requires one child class at least who will extend her (maybe is an abstract'
. ' class), but the child classes are missing. Did you forget to extend this class?';
$parentClassName = Reflection::getClassName($parentClass);
$message = sprintf($template, $parentClassName);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Reflection;
use Exception;
use Meritoo\Common\Utilities\Reflection;
/**
* An exception used while given class has more than one child class
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class TooManyChildClassesException extends Exception
{
/**
* Class constructor
*
* @param array|object|string $parentClass Class that has more than one child class, but it shouldn't. An array
* of objects, strings, object or string.
* @param array $childClasses Child classes
*/
public function __construct($parentClass, array $childClasses)
{
$template = "The '%s' class requires one child class at most who will extend her, but more than one child"
. " class was found:\n- %s\n\nWhy did you create more than one classes that extend '%s' class?";
$parentClassName = Reflection::getClassName($parentClass);
$message = sprintf($template, $parentClassName, implode("\n- ", $childClasses), $parentClassName);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Regex;
/**
* An exception used while length of given hexadecimal value of color is incorrect
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class IncorrectColorHexLengthException extends \Exception
{
/**
* Class constructor
*
* @param string $color Incorrect hexadecimal value of color
*/
public function __construct($color)
{
$template = 'Length of hexadecimal value of color \'%s\' is incorrect. It\'s %d, but it should be 3 or 6.'
. ' Is there everything ok?';
$message = sprintf($template, $color, strlen($color));
parent::__construct($message);
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Regex;
/**
* An exception used while given hexadecimal value of color is invalid
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class InvalidColorHexValueException extends \Exception
{
/**
* Class constructor
*
* @param string $color Invalid hexadecimal value of color
*/
public function __construct($color)
{
$message = sprintf('Hexadecimal value of color \'%s\' is invalid. Is there everything ok?', $color);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Meritoo\Common\Exception\Regex;
/**
* An exception used while url is invalid
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class InvalidUrlException extends \Exception
{
const className = 'Meritoo\Common\Exception\Regex\InvalidUrlException';
/**
* Class constructor
*
* @param string $url Invalid url
*/
public function __construct($url)
{
$message = sprintf('Url \'%s\' is invalid. Is there everything ok?', $url);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Meritoo\Common\Exception\Type;
use Meritoo\Common\Exception\Base\UnknownTypeException;
use Meritoo\Common\Type\OopVisibilityType;
/**
* An exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is unknown
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class UnknownOopVisibilityTypeException extends UnknownTypeException
{
/**
* {@inheritdoc}
*/
public function __construct($unknownType)
{
parent::__construct($unknownType, new OopVisibilityType(), 'OOP-related visibility');
}
}

View File

@@ -0,0 +1,309 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Test\Base;
use DateTime;
use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\Utilities\Miscellaneous;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use ReflectionMethod;
/**
* Base test case with common methods and data providers
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class BaseTestCase extends TestCase
{
/**
* Path of directory with data used by test cases
*
* @var string
*/
private static $testsDataDirPath = '.data/tests';
/**
* Provides an empty value
*
* @return array
* //return Generator
*/
public function provideEmptyValue()
{
return [
[''],
[' '],
[null],
[0],
[false],
[[]],
];
/*
yield[''];
yield[' '];
yield[null];
yield[0];
yield[false];
yield[[]];
*/
}
/**
* Provides boolean value
*
* @return array
* //return Generator
*/
public function provideBooleanValue()
{
return [
[true],
[false],
];
/*
yield[false];
yield[true];
*/
}
/**
* Provides instance of DateTime class
*
* @return array
* //return Generator
*/
public function provideDateTimeInstance()
{
return [
[new DateTime()],
[new DateTime('yesterday')],
[new DateTime('now')],
[new DateTime('tomorrow')],
];
/*
yield[new DateTime()];
yield[new DateTime('yesterday')];
yield[new DateTime('now')];
yield[new DateTime('tomorrow')];
*/
}
/**
* Provides relative / compound format of DateTime
*
* @return array
* //return Generator
*/
public function provideDateTimeRelativeFormat()
{
return [
['now'],
['yesterday'],
['tomorrow'],
['back of 10'],
['front of 10'],
['last day of February'],
['first day of next month'],
['last day of previous month'],
['last day of next month'],
['Y-m-d'],
['Y-m-d 10:00'],
];
/*
yield['now'];
yield['yesterday'];
yield['tomorrow'];
yield['back of 10'];
yield['front of 10'];
yield['last day of February'];
yield['first day of next month'];
yield['last day of previous month'];
yield['last day of next month'];
yield['Y-m-d'];
yield['Y-m-d 10:00'];
*/
}
/**
* Provides path of not existing file, e.g. "lorem/ipsum.jpg"
*
* @return array
* //return Generator
*/
public function provideNotExistingFilePath()
{
return [
['lets-test.doc'],
['lorem/ipsum.jpg'],
['surprise/me/one/more/time.txt'],
];
/*
yield['lets-test.doc'];
yield['lorem/ipsum.jpg'];
yield['surprise/me/one/more/time.txt'];
*/
}
/**
* Returns path of file used by tests.
* It should be placed in /.data/tests directory of this project.
*
* @param string $fileName Name of file
* @param string $directoryPath (optional) Path of directory containing the file
* @return string
*/
public function getFilePathToTests($fileName, $directoryPath = '')
{
$rootPath = Miscellaneous::getProjectRootPath();
$paths = [
$rootPath,
self::$testsDataDirPath,
$directoryPath,
$fileName,
];
return Miscellaneous::concatenatePaths($paths);
}
/**
* Verifies visibility and arguments of method
*
* @param string $classNamespace Namespace of class that contains method to verify
* @param string|ReflectionMethod $method Name of method or just the method to verify
* @param string $visibilityType Expected visibility of verified method. One of
* OopVisibilityType class constants.
* @param int $argumentsCount (optional) Expected count/amount of arguments of the
* verified method
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments
* of the verified method
* @throws UnknownOopVisibilityTypeException
*
* Attention. 2nd argument, the $method, may be:
* - string - name of the method
* - instance of ReflectionMethod - just the method (provided by ReflectionClass::getMethod() method)
*/
protected static function assertMethodVisibilityAndArguments(
$classNamespace,
$method,
$visibilityType,
$argumentsCount = 0,
$requiredArgumentsCount = 0
) {
/*
* Type of visibility is correct?
*/
if (!(new OopVisibilityType())->isCorrectType($visibilityType)) {
throw new UnknownOopVisibilityTypeException($visibilityType);
}
$reflection = new ReflectionClass($classNamespace);
/*
* Name of method provided only?
* Let's find instance of the method (based on reflection)
*/
if (!$method instanceof ReflectionMethod) {
$method = $reflection->getMethod($method);
}
switch ($visibilityType) {
case OopVisibilityType::IS_PUBLIC:
static::assertTrue($method->isPublic());
break;
case OopVisibilityType::IS_PROTECTED:
static::assertTrue($method->isProtected());
break;
case OopVisibilityType::IS_PRIVATE:
static::assertTrue($method->isPrivate());
break;
}
static::assertEquals($argumentsCount, $method->getNumberOfParameters());
static::assertEquals($requiredArgumentsCount, $method->getNumberOfRequiredParameters());
}
/**
* Verifies visibility and arguments of class constructor
*
* @param string $classNamespace Namespace of class that contains constructor to verify
* @param string $visibilityType Expected visibility of verified method. One of OopVisibilityType class
* constants.
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified
* method
* @throws UnknownOopVisibilityTypeException
*/
protected static function assertConstructorVisibilityAndArguments(
$classNamespace,
$visibilityType,
$argumentsCount = 0,
$requiredArgumentsCount = 0
) {
/*
* Let's grab the constructor
*/
$reflection = new ReflectionClass($classNamespace);
$method = $reflection->getConstructor();
return static::assertMethodVisibilityAndArguments($classNamespace, $method, $visibilityType, $argumentsCount, $requiredArgumentsCount);
}
/**
* Asserts that class with given namespace has no constructor
*
* @param string $classNamespace Namespace of class that contains constructor to verify
*/
protected static function assertHasNoConstructor($classNamespace)
{
/*
* Let's grab the constructor
*/
$reflection = new ReflectionClass($classNamespace);
$constructor = $reflection->getConstructor();
static::assertNull($constructor);
}
/**
* Sets path of directory with data used by test cases
*
* @param string $testsDataDirPath Path of directory with data used by test cases
*/
protected static function setTestsDataDirPath($testsDataDirPath)
{
static::$testsDataDirPath = $testsDataDirPath;
}
/**
* Returns a mock object for the specified class
*
* @param string $originalClassName Name of the class to mock
* @return \PHPUnit_Framework_MockObject_MockObject
*/
protected function createMock($originalClassName)
{
$methods = [];
$arguments = [];
$mockClassName = '';
$callOriginalConstructor = false;
return $this->getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor);
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Meritoo\Common\Test\Base;
use Generator;
use Meritoo\Common\Type\Base\BaseType;
/**
* Base test case for the type of something
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class BaseTypeTestCase extends BaseTestCase
{
/**
* Verifies availability of all types
*/
public function testAvailabilityOfAllTypes()
{
$available = $this->getTestedTypeInstance()->getAll();
$all = $this->getAllExpectedTypes();
if (isset($available['className'])) {
unset($available['className']);
}
static::assertEquals($all, $available);
}
/**
* Verifies whether given type is correct or not
*
* @param string $type Type to verify
* @param bool $expected Information if given type is correct or not
*
* @dataProvider provideTypeToVerify
*/
public function testIfGivenTypeIsCorrect($type, $expected)
{
static::assertEquals($expected, $this->getTestedTypeInstance()->isCorrectType($type));
}
/**
* Provides type to verify and information if it's correct
*
* @return Generator
*/
abstract public function provideTypeToVerify();
/**
* Returns instance of the tested type
*
* @return BaseType
*/
abstract protected function getTestedTypeInstance();
/**
* Returns all expected types of the tested type
*
* @return array
*/
abstract protected function getAllExpectedTypes();
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Type\Base;
use Meritoo\Common\Utilities\Reflection;
/**
* Base / abstract type of something, e.g. type of button, order, date etc.
* Child class should contain constants - each of them represent one type.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class BaseType
{
/**
* All types
*
* @var array
*/
private $all;
/**
* Returns all types
*
* @return array
*/
public function getAll()
{
if (null === $this->all) {
$this->all = Reflection::getConstants($this);
}
return $this->all;
}
/**
* Returns information if given type is correct
*
* @param string $type The type to check
* @return bool
*/
public function isCorrectType($type)
{
return in_array($type, $this->getAll(), true);
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Type;
use Meritoo\Common\Type\Base\BaseType;
/**
* Type of date part, e.g. "year"
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DatePartType extends BaseType
{
/**
* The "day" date part
*
* @var string
*/
const DAY = 'day';
/**
* The "hour" date part
*
* @var string
*/
const HOUR = 'hour';
/**
* The "minute" date part
*
* @var string
*/
const MINUTE = 'minute';
/**
* The "month" date part
*
* @var string
*/
const MONTH = 'month';
/**
* The "second" date part
*
* @var string
*/
const SECOND = 'second';
/**
* The "year" date part
*
* @var string
*/
const YEAR = 'year';
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Meritoo\Common\Type;
use Meritoo\Common\Type\Base\BaseType;
/**
* The visibility of a property, a method or (as of PHP 7.1.0) a constant
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*
* @see http://php.net/manual/en/language.oop5.visibility.php
*/
class OopVisibilityType extends BaseType
{
/**
* The "private" visibility of OOP
*
* @var int
*/
const IS_PRIVATE = 3;
/**
* The "protected" visibility of OOP
*
* @var int
*/
const IS_PROTECTED = 2;
/**
* The "public" visibility of OOP
*
* @var int
*/
const IS_PUBLIC = 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,714 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use DateInterval;
use DateTime;
use Meritoo\Common\Exception\Date\UnknownDatePartTypeException;
use Meritoo\Common\Type\DatePartType;
/**
* Useful date methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Date
{
/**
* The 'days' unit of date difference.
* Difference between dates in days.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_DAYS = 'days';
/**
* The 'hours' unit of date difference.
* Difference between dates in hours.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_HOURS = 'hours';
/**
* The 'minutes' unit of date difference.
* Difference between dates in minutes.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_MINUTES = 'minutes';
/**
* The 'months' unit of date difference.
* Difference between dates in months.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_MONTHS = 'months';
/**
* The 'years' unit of date difference.
* Difference between dates in years.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_YEARS = 'years';
/**
* Returns start and end date for given period.
* The dates are returned in an array with indexes 'start' and 'end'.
*
* @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
* @return DatePeriod
*/
public static function getDatesForPeriod($period)
{
$datePeriod = null;
if (DatePeriod::isCorrectPeriod($period)) {
$dateStart = null;
$dateEnd = null;
switch ($period) {
case DatePeriod::LAST_WEEK:
$thisWeekStart = new DateTime('this week');
$dateStart = clone $thisWeekStart;
$dateEnd = clone $thisWeekStart;
$dateStart->sub(new DateInterval('P7D'));
$dateEnd->sub(new DateInterval('P1D'));
break;
case DatePeriod::THIS_WEEK:
$dateStart = new DateTime('this week');
$dateEnd = clone $dateStart;
$dateEnd->add(new DateInterval('P6D'));
break;
case DatePeriod::NEXT_WEEK:
$dateStart = new DateTime('this week');
$dateStart->add(new DateInterval('P7D'));
$dateEnd = clone $dateStart;
$dateEnd->add(new DateInterval('P6D'));
break;
case DatePeriod::LAST_MONTH:
$dateStart = new DateTime('first day of last month');
$dateEnd = new DateTime('last day of last month');
break;
case DatePeriod::THIS_MONTH:
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
$dateStart = $lastMonth->getEndDate();
$dateStart->add(new DateInterval('P1D'));
$dateEnd = $nextMonth->getStartDate();
$dateEnd->sub(new DateInterval('P1D'));
break;
case DatePeriod::NEXT_MONTH:
$dateStart = new DateTime('first day of next month');
$dateEnd = new DateTime('last day of next month');
break;
case DatePeriod::LAST_YEAR:
case DatePeriod::THIS_YEAR:
case DatePeriod::NEXT_YEAR:
$dateStart = new DateTime();
$dateEnd = new DateTime();
if (DatePeriod::LAST_YEAR == $period || DatePeriod::NEXT_YEAR == $period) {
$yearDifference = 1;
if (DatePeriod::LAST_YEAR == $period) {
$yearDifference *= -1;
}
$modifyString = sprintf('%s year', $yearDifference);
$dateStart->modify($modifyString);
$dateEnd->modify($modifyString);
}
$year = $dateStart->format('Y');
$dateStart->setDate($year, 1, 1);
$dateEnd->setDate($year, 12, 31);
break;
}
if (null !== $dateStart && null !== $dateEnd) {
$dateStart->setTime(0, 0, 0);
$dateEnd->setTime(23, 59, 59);
$datePeriod = new DatePeriod($dateStart, $dateEnd);
}
}
return $datePeriod;
}
/**
* Generates and returns random time (the hour, minute and second values)
*
* @param string $format (optional) Format of returned value. A string acceptable by the DateTime::format()
* method.
* @return string|null
*/
public static function generateRandomTime($format = 'H:i:s')
{
$dateTime = new DateTime();
/*
* Format si empty or is incorrect?
* Nothing to do
*/
if (empty($format) || $dateTime->format($format) === $format) {
return null;
}
$hours = [];
$minutes = [];
$seconds = [];
for ($i = 1; $i <= 23; ++$i) {
$hours[] = $i;
}
for ($i = 1; $i <= 59; ++$i) {
$minutes[] = $i;
}
for ($i = 1; $i <= 59; ++$i) {
$seconds[] = $i;
}
/*
* Prepare random time (hour, minute and second)
*/
$hour = $hours[array_rand($hours)];
$minute = $minutes[array_rand($minutes)];
$second = $seconds[array_rand($seconds)];
return $dateTime
->setTime($hour, $minute, $second)
->format($format);
}
/**
* Returns current day of week
*
* @return int
*/
public static function getCurrentDayOfWeek()
{
$now = new DateTime();
$year = $now->format('Y');
$month = $now->format('m');
$day = $now->format('d');
return self::getDayOfWeek($year, $month, $day);
}
/**
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
* Based on the Zeller's algorithm (http://pl.wikipedia.org/wiki/Kalendarz_wieczny).
*
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
*
* @return int
* @throws UnknownDatePartTypeException
*/
public static function getDayOfWeek($year, $month, $day)
{
$year = (int)$year;
$month = (int)$month;
$day = (int)$day;
/*
* Oops, incorrect year
*/
if ($year <= 0) {
throw new UnknownDatePartTypeException(DatePartType::YEAR, $year);
}
/*
* Oops, incorrect month
*/
if ($month < 1 || $month > 12) {
throw new UnknownDatePartTypeException(DatePartType::MONTH, $month);
}
/*
* Oops, incorrect day
*/
if ($day < 1 || $day > 31) {
throw new UnknownDatePartTypeException(DatePartType::DAY, $day);
}
if ($month < 3) {
$count = 0;
$yearValue = $year - 1;
} else {
$count = 2;
$yearValue = $year;
}
$firstPart = floor(23 * $month / 9);
$secondPart = floor($yearValue / 4);
$thirdPart = floor($yearValue / 100);
$fourthPart = floor($yearValue / 400);
return ($firstPart + $day + 4 + $year + $secondPart - $thirdPart + $fourthPart - $count) % 7;
}
/**
* Returns based on locale name of current weekday
*
* @return string
*/
public static function getCurrentDayOfWeekName()
{
$now = new DateTime();
$year = $now->format('Y');
$month = $now->format('m');
$day = $now->format('d');
return self::getDayOfWeekName($year, $month, $day);
}
/**
* Returns name of weekday based on locale
*
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
* @return string
*/
public static function getDayOfWeekName($year, $month, $day)
{
$hour = 0;
$minute = 0;
$second = 0;
$time = mktime($hour, $minute, $second, $month, $day, $year);
$name = strftime('%A', $time);
$encoding = mb_detect_encoding($name);
if (false === $encoding) {
$name = mb_convert_encoding($name, 'UTF-8', 'ISO-8859-2');
}
return $name;
}
/**
* Returns difference between given dates.
*
* The difference is calculated in units based on the 3rd argument or all available unit of date difference
* (defined as DATE_DIFFERENCE_UNIT_* constants of this class).
*
* The difference is also whole / complete value for given unit instead of relative value as may be received by
* DateTime::diff() method, e.g.:
* - 2 days, 50 hours
* instead of
* - 2 days, 2 hours
*
* If the unit of date difference is null, all units are returned in array (units are keys of the array).
* Otherwise - one, integer value is returned.
*
* @param string|DateTime $dateStart The start date
* @param string|DateTime $dateEnd The end date
* @param int $differenceUnit (optional) Unit of date difference. One of this class
* DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are
* returned in the array.
* @return array|int
*/
public static function getDateDifference($dateStart, $dateEnd, $differenceUnit = null)
{
$validDateStart = self::isValidDate($dateStart, true);
$validDateEnd = self::isValidDate($dateEnd, true);
/*
* The start or end date is unknown?
* or
* The start or end date is not valid date?
*
* Nothing to do
*/
if (empty($dateStart) || empty($dateEnd) || !$validDateStart || !$validDateEnd) {
return null;
}
$dateStart = self::getDateTime($dateStart, true);
$dateEnd = self::getDateTime($dateEnd, true);
$difference = [];
$dateDiff = $dateEnd->getTimestamp() - $dateStart->getTimestamp();
$daysInSeconds = 0;
$hoursInSeconds = 0;
$hourSeconds = 60 * 60;
$daySeconds = $hourSeconds * 24;
/*
* These units are related, because while calculating difference in the lowest unit, difference in the
* highest unit is required, e.g. while calculating hours I have to know difference in days
*/
$relatedUnits = [
self::DATE_DIFFERENCE_UNIT_DAYS,
self::DATE_DIFFERENCE_UNIT_HOURS,
self::DATE_DIFFERENCE_UNIT_MINUTES,
];
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS == $differenceUnit) {
$diff = $dateEnd->diff($dateStart);
/*
* Difference between dates in years should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_YEARS == $differenceUnit) {
return $diff->y;
}
$difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
}
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS == $differenceUnit) {
$diff = $dateEnd->diff($dateStart);
/*
* Difference between dates in months should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_MONTHS == $differenceUnit) {
return $diff->m;
}
$difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
}
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits)) {
$days = (int)floor($dateDiff / $daySeconds);
/*
* Difference between dates in days should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_DAYS == $differenceUnit) {
return $days;
}
/*
* All units should be returned?
*/
if (null === $differenceUnit) {
$difference[self::DATE_DIFFERENCE_UNIT_DAYS] = $days;
}
/*
* Calculation for later usage
*/
$daysInSeconds = $days * $daySeconds;
}
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits)) {
$hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);
/*
* Difference between dates in hours should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_HOURS == $differenceUnit) {
return $hours;
}
/*
* All units should be returned?
*/
if (null === $differenceUnit) {
$difference[self::DATE_DIFFERENCE_UNIT_HOURS] = $hours;
}
/*
* Calculation for later usage
*/
$hoursInSeconds = $hours * $hourSeconds;
}
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MINUTES == $differenceUnit) {
$minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
/*
* Difference between dates in minutes should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_MINUTES == $differenceUnit) {
return $minutes;
}
$difference[self::DATE_DIFFERENCE_UNIT_MINUTES] = $minutes;
}
return $difference;
}
/**
* Returns collection / set of dates for given start date and count of dates.
* Start from given date, add next, iterated value to given date interval and returns requested count of dates.
*
* @param DateTime $startDate The start date. Start of the collection / set.
* @param int $datesCount Count of dates in resulting collection / set
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the
* placeholder which is replaced with a number that represents each iteration.
* Default: interval for days.
* @return array
*/
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD')
{
$dates = [];
/*
* The template used to build date interval have to be string.
* Otherwise cannot run preg_match() function and an error occurs.
*/
if (is_string($intervalTemplate)) {
/*
* Let's verify the interval template. It should contains the "%d" placeholder and something before and
* after it.
*
* Examples:
* - P%dD
* - P%dM
* - P1Y%dMT1H
*/
$intervalPattern = '/^(\w*)\%d(\w*)$/';
$matches = [];
$matchCount = preg_match($intervalPattern, $intervalTemplate, $matches);
if ($matchCount > 0 && (!empty($matches[1]) || !empty($matches[2]))) {
$datesCount = (int)$datesCount;
for ($index = 1; $index <= $datesCount; ++$index) {
$date = clone $startDate;
$dates[$index] = $date->add(new DateInterval(sprintf($intervalTemplate, $index)));
}
}
}
return $dates;
}
/**
* Returns random date based on given start date
*
* @param DateTime $startDate The start date. Start of the random date.
* @param int $start (optional) Start of random partition
* @param int $end (optional) End of random partition
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
* with next, iterated value.
* @return DateTime
*/
public static function getRandomDate(DateTime $startDate = null, $start = 1, $end = 100, $intervalTemplate = 'P%sD')
{
if (null === $startDate) {
$startDate = new DateTime();
}
$start = (int)$start;
$end = (int)$end;
/*
* Incorrect end of random partition?
* Use start as the end of random partition
*/
if ($end < $start) {
$end = $start;
}
$randomDate = clone $startDate;
$randomInterval = new DateInterval(sprintf($intervalTemplate, rand($start, $end)));
return $randomDate->add($randomInterval);
}
/**
* Returns the DateTime object for given value.
* If the DateTime object cannot be created, false is returned.
*
* @param mixed $value The value which maybe is a date
* @param bool $allowCompoundFormats (optional) If is set to true, the compound formats used to create an
* instance of DateTime class are allowed (e.g. "now", "last day of next
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
* @param string $dateFormat (optional) Format of date used to verify if given value is actually a date.
* It should be format matched to the given value, e.g. "Y-m-d H:i" for
* "2015-01-01 10:00" value.
* @return DateTime|bool
*/
public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d')
{
/*
* Empty value?
* Nothing to do :)
*/
if (empty($value)) {
return false;
}
/*
* Instance of DateTime class?
* Nothing to do :)
*/
if ($value instanceof DateTime) {
return $value;
}
try {
try {
/*
* Pass the value to the constructor. Maybe it's one of the allowed relative formats.
* Examples: "now", "last day of next month"
*/
$date = new DateTime($value);
/*
* Instance of the DateTime class was created.
* Let's verify if given value is really proper date.
*/
$dateFromFormat = DateTime::createFromFormat($dateFormat, $value);
if (false === $dateFromFormat) {
/*
* Nothing to do more, because:
* a) instance of the DateTime was created
* and
* b) if createFromFormat() method failed, given value is one of the allowed relative formats
* ("now", "last day of next month")
* and...
*/
if ($allowCompoundFormats) {
/*
* ...and
* c) it's not an integer, e.g. not 10 or 100 or 1000
*/
if (!is_numeric($value)) {
return $date;
}
} else {
$specialFormats = [
'now',
];
/*
* ...and
* c) it's special compound format that contains characters that each may be used by
* DateTime::format() method and it raises problem while trying to verify the value at the end
* of this method:
*
* (new DateTime())->format($value);
*
* So, I have to refuse those special compound formats if they are not explicitly declared as
* compound (2nd argument of this method, set to false by default)
*/
if (in_array($value, $specialFormats)) {
return false;
}
}
} /*
* Verify instance of the DateTime created by constructor and by createFromFormat() method.
* After formatting, these dates should be the same.
*/
else {
if ($dateFromFormat->format($dateFormat) === $value) {
return $date;
}
}
} catch (\Exception $exception) {
if (!$allowCompoundFormats) {
return false;
}
}
/*
* Does the value is a string that may be used to format date?
* Example: "Y-m-d"
*/
$dateString = (new DateTime())->format($value);
if ($dateString != $value) {
return new DateTime($dateString);
}
} catch (\Exception $exception) {
}
return false;
}
/**
* Returns information if given value is valid date
*
* @param mixed $value The value which maybe is a date
* @param bool $allowCompoundFormats (optional) If is set to true, the compound formats used to create an
* instance of DateTime class are allowed (e.g. "now", "last day of next
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
* @return bool
*/
public static function isValidDate($value, $allowCompoundFormats = false)
{
return self::getDateTime($value, $allowCompoundFormats) instanceof DateTime;
}
/**
* Returns information if given format of date is valid
*
* @param string $format The validated format of date
* @return bool
*/
public static function isValidDateFormat($format)
{
if (empty($format) || !is_string($format)) {
return false;
}
/*
* Datetime to string
*/
$formatted = (new DateTime())->format($format);
/*
* Formatted date it's the format who is validated?
* The format is invalid
*/
if ($formatted == $format) {
return false;
}
/*
* Validate the format used to create the datetime
*/
$fromFormat = DateTime::createFromFormat($format, $formatted);
/*
* It's instance of DateTime?
* The format is valid
*/
if ($fromFormat instanceof DateTime) {
return true;
}
return $fromFormat instanceof DateTime;
}
}

View File

@@ -0,0 +1,195 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use DateTime;
/**
* A date's period.
* Contains start and end date of the period.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DatePeriod
{
/**
* The period constant: last month
*
* @var int
*/
const LAST_MONTH = 4;
/**
* The period constant: last week
*
* @var int
*/
const LAST_WEEK = 1;
/**
* The period constant: last year
*
* @var int
*/
const LAST_YEAR = 7;
/**
* The period constant: next month
*
* @var int
*/
const NEXT_MONTH = 6;
/**
* The period constant: next week
*
* @var int
*/
const NEXT_WEEK = 3;
/**
* The period constant: next year
*
* @var int
*/
const NEXT_YEAR = 9;
/**
* The period constant: this month
*
* @var int
*/
const THIS_MONTH = 5;
/**
* The period constant: this week
*
* @var int
*/
const THIS_WEEK = 2;
/**
* The period constant: this year
*
* @var int
*/
const THIS_YEAR = 8;
/**
* The start date of period
*
* @var DateTime
*/
private $startDate;
/**
* The end date of period
*
* @var DateTime
*/
private $endDate;
/**
* Class constructor
*
* @param DateTime $startDate (optional) The start date of period
* @param DateTime $endDate (optional) The end date of period
*/
public function __construct(DateTime $startDate = null, DateTime $endDate = null)
{
$this->startDate = $startDate;
$this->endDate = $endDate;
}
/**
* Returns information if given period is correct
*
* @param int $period The period to verify
* @return bool
*/
public static function isCorrectPeriod($period)
{
return in_array($period, Reflection::getConstants(__CLASS__));
}
/**
* Returns formatted one of the period's date: start date or end date
*
* @param string $format Format used to format the date
* @param bool $startDate (optional) If is set to true, start date is formatted. Otherwise - end date.
* @return string
*/
public function getFormattedDate($format, $startDate = true)
{
$date = $this->getEndDate();
/*
* Start date should be formatted?
*/
if ($startDate) {
$date = $this->getStartDate();
}
/*
* Unknown date or format is invalid?
*/
if (null === $date || !Date::isValidDateFormat($format)) {
return '';
}
return $date->format($format);
}
/**
* Returns the end date of period
*
* @return DateTime
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* Sets the end date of period
*
* @param DateTime $endDate (optional) The end date of period
* @return $this
*/
public function setEndDate(DateTime $endDate = null)
{
$this->endDate = $endDate;
return $this;
}
/**
* Returns the start date of period
*
* @return DateTime
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Sets the start date of period
*
* @param DateTime $startDate (optional) The start date of period
* @return $this
*/
public function setStartDate(DateTime $startDate = null)
{
$this->startDate = $startDate;
return $this;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,668 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Common\Util\Inflector;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use ReflectionObject;
use ReflectionProperty;
/**
* Useful reflection methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Reflection
{
/**
* Returns names of methods for given class / object
*
* @param object|string $class The object or name of object's class
* @param bool $withoutInheritance (optional) If is set to true, only methods for given class are returned.
* Otherwise - all methods, with inherited methods too.
* @return array
*/
public static function getMethods($class, $withoutInheritance = false)
{
$effect = [];
$reflection = new ReflectionClass($class);
$methods = $reflection->getMethods();
if (!empty($methods)) {
$className = self::getClassName($class);
foreach ($methods as $method) {
if ($method instanceof ReflectionMethod) {
if ($withoutInheritance && $className !== $method->class) {
continue;
}
$effect[] = $method->name;
}
}
}
return $effect;
}
/**
* Returns constants of given class / object
*
* @param object|string $class The object or name of object's class
* @return array
*/
public static function getConstants($class)
{
$reflection = new ReflectionClass($class);
return $reflection->getConstants();
}
/**
* Returns maximum constant from all constants of given class / object.
* Values of constants should be integers.
*
* @param object|string $class The object or name of object's class
* @return int|null
*/
public static function getMaxNumberConstant($class)
{
$constants = self::getConstants($class);
if (empty($constants)) {
return null;
}
$maxNumber = 0;
foreach ($constants as $constant) {
if (is_numeric($constant) && $constant > $maxNumber) {
$maxNumber = $constant;
}
}
return $maxNumber;
}
/**
* Returns information if given class / object has given method
*
* @param object|string $class The object or name of object's class
* @param string $method Name of the method to find
* @return bool
*/
public static function hasMethod($class, $method)
{
$reflection = new ReflectionClass($class);
return $reflection->hasMethod($method);
}
/**
* Returns information if given class / object has given property
*
* @param object|string $class The object or name of object's class
* @param string $property Name of the property to find
* @return bool
*/
public static function hasProperty($class, $property)
{
$reflection = new ReflectionClass($class);
return $reflection->hasProperty($property);
}
/**
* Returns information if given class / object has given constant
*
* @param object|string $class The object or name of object's class
* @param string $constant Name of the constant to find
* @return bool
*/
public static function hasConstant($class, $constant)
{
$reflection = new ReflectionClass($class);
return $reflection->hasConstant($constant);
}
/**
* Returns value of given constant
*
* @param object|string $class The object or name of object's class
* @param string $constant Name of the constant that contains a value
* @return mixed
*/
public static function getConstantValue($class, $constant)
{
$reflection = new ReflectionClass($class);
if (self::hasConstant($class, $constant)) {
return $reflection->getConstant($constant);
}
return null;
}
/**
* Returns value of given property.
* Looks for proper getter for the property.
*
* @param mixed $object Object that should contains given property
* @param string $property Name of the property that contains a value. It may be also multiple properties
* dot-separated, e.g. "invoice.user.email".
* @param bool $force (optional) If is set to true, try to retrieve value even if the object doesn't have
* property. Otherwise - not.
* @return mixed
*/
public static function getPropertyValue($object, $property, $force = false)
{
$value = null;
/*
* Property is a dot-separated string?
* Let's find all values of the chain, of the dot-separated properties
*/
if (Regex::contains($property, '.')) {
$exploded = explode('.', $property);
$property = $exploded[0];
$object = self::getPropertyValue($object, $property, $force);
/*
* Value of processed property from the chain is not null?
* Let's dig more and get proper value
*
* Required to avoid bug:
* ReflectionObject::__construct() expects parameter 1 to be object, null given
* (...)
* 4. at ReflectionObject->__construct (null)
* 5. at Reflection ::getPropertyValue (null, 'name', true)
* 6. at ListService->getItemValue (object(Deal), 'project.name', '0')
*
* while using "project.name" as property - $project has $name property ($project exists in the Deal class)
* and the $project equals null
*
* Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* 2016-11-07
*/
if (null !== $object) {
unset($exploded[0]);
$property = implode('.', $exploded);
$value = self::getPropertyValue($object, $property, $force);
}
} else {
$className = self::getClassName($object);
$reflectionProperty = null;
/*
* 1st try:
* Use \ReflectionObject class
*/
try {
$reflectionProperty = new ReflectionProperty($className, $property);
$value = $reflectionProperty->getValue($object);
} catch (ReflectionException $exception) {
/*
* 2nd try:
* Look for the get / has / is methods
*/
$class = new ReflectionObject($object);
$valueFound = false;
if ($class->hasProperty($property) || $force) {
$property = Inflector::classify($property);
$getterPrefixes = [
'get',
'has',
'is',
];
foreach ($getterPrefixes as $prefix) {
$getterName = sprintf('%s%s', $prefix, $property);
if ($class->hasMethod($getterName)) {
$method = new ReflectionMethod($object, $getterName);
/*
* Getter is not accessible publicly?
* I have to skip it, to avoid an error like this:
*
* Call to protected method My\ExtraClass::getExtraProperty() from context 'My\ExtraClass'
*/
if ($method->isProtected() || $method->isPrivate()) {
continue;
}
$value = $object->{$getterName}();
$valueFound = true;
break;
}
}
}
if (!$valueFound && null !== $reflectionProperty) {
/*
* Oops, value of the property is still unknown
*
* 3rd try:
* Let's modify accessibility of the property and try again to get value
*/
$reflectionProperty->setAccessible(true);
$value = $reflectionProperty->getValue($object);
$reflectionProperty->setAccessible(false);
}
}
}
return $value;
}
/**
* Returns values of given property for given objects.
* Looks for proper getter for the property.
*
* @param Collection|object|array $objects The objects that should contain given property. It may be also one
* object.
* @param string $property Name of the property that contains a value
* @param bool $force (optional) If is set to true, try to retrieve value even if the
* object does not have property. Otherwise - not.
* @return array
*/
public static function getPropertyValues($objects, $property, $force = false)
{
/*
* No objects?
* Nothing to do
*/
if (empty($objects)) {
return [];
}
if ($objects instanceof Collection) {
$objects = $objects->toArray();
}
$values = [];
$objects = Arrays::makeArray($objects);
foreach ($objects as $entity) {
$value = self::getPropertyValue($entity, $property, $force);
if (null !== $value) {
$values[] = $value;
}
}
return $values;
}
/**
* Returns a class name for given source
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @param bool $withoutNamespace (optional) If is set to true, namespace is omitted. Otherwise -
* not, full name of class is returned, with namespace.
* @return string|null
*/
public static function getClassName($source, $withoutNamespace = false)
{
/*
* First argument is not proper source of class?
* Nothing to do
*/
if (empty($source) || (!is_array($source) && !is_object($source) && !is_string($source))) {
return null;
}
$name = '';
/*
* An array of objects was provided?
* Let's use first of them
*/
if (is_array($source)) {
$source = Arrays::getFirstElement($source);
}
/*
* Let's prepare name of class
*/
if (is_object($source)) {
$name = get_class($source);
} elseif (is_string($source) && (class_exists($source) || trait_exists($source))) {
$name = $source;
}
/*
* Name of class is still unknown?
* Nothing to do
*/
if (empty($name)) {
return null;
}
/*
* Namespace is not required?
* Let's return name of class only
*/
if ($withoutNamespace) {
$classOnly = Miscellaneous::getLastElementOfString($name, '\\');
if (null !== $classOnly) {
$name = $classOnly;
}
return $name;
}
return ClassUtils::getRealClass($name);
}
/**
* Returns namespace of class for given source
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @return string
*/
public static function getClassNamespace($source)
{
$fullClassName = self::getClassName($source);
if (empty($fullClassName)) {
return '';
}
$className = self::getClassName($source, true);
if ($className == $fullClassName) {
return $className;
}
return Miscellaneous::getStringWithoutLastElement($fullClassName, '\\');
}
/**
* Returns information if given interface is implemented by given class / object
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @param string $interface The interface that should be implemented
* @return bool
*/
public static function isInterfaceImplemented($source, $interface)
{
$className = self::getClassName($source);
$interfaces = class_implements($className);
return in_array($interface, $interfaces);
}
/**
* Returns information if given child class is a subclass of given parent class
*
* @param array|object|string $childClass The child class. An array of objects, namespaces, object or namespace.
* @param array|object|string $parentClass The parent class. An array of objects, namespaces, object or namespace.
* @return bool
*/
public static function isChildOfClass($childClass, $parentClass)
{
$childClassName = self::getClassName($childClass);
$parentClassName = self::getClassName($parentClass);
$parents = class_parents($childClassName);
if (is_array($parents)) {
return in_array($parentClassName, $parents);
}
return false;
}
/**
* Returns given object properties
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @param int $filter (optional) Filter of properties. Uses ReflectionProperty class
* constants. By default all properties are returned.
* @param bool $includeParents (optional) If is set to true, properties of parent classes are
* included (recursively). Otherwise - not.
* @return array|ReflectionProperty
*/
public static function getProperties($source, $filter = null, $includeParents = false)
{
$className = self::getClassName($source);
$reflection = new ReflectionClass($className);
if (null === $filter) {
$filter = ReflectionProperty::IS_PRIVATE
+ ReflectionProperty::IS_PROTECTED
+ ReflectionProperty::IS_PUBLIC
+ ReflectionProperty::IS_STATIC;
}
$properties = $reflection->getProperties($filter);
$parentProperties = [];
if ($includeParents) {
$parent = self::getParentClass($source);
if (false !== $parent) {
$parentClass = $parent->getName();
$parentProperties = self::getProperties($parentClass, $filter, $includeParents);
}
}
return array_merge($properties, $parentProperties);
}
/**
* Returns a parent class or false if there is no parent class
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @return ReflectionClass|bool
*/
public static function getParentClass($source)
{
$className = self::getClassName($source);
$reflection = new ReflectionClass($className);
return $reflection->getParentClass();
}
/**
* Returns child classes of given class.
* It's an array of namespaces of the child classes or null (if given class has not child classes).
*
* @param array|object|string $class Class who child classes should be returned. An array of objects, strings,
* object or string.
* @return array|null
* @throws CannotResolveClassNameException
*/
public static function getChildClasses($class)
{
$allClasses = get_declared_classes();
/*
* No classes?
* Nothing to do
*/
if (empty($allClasses)) {
return null;
}
$className = self::getClassName($class);
/*
* Oops, cannot resolve class
*/
if (null === $className) {
throw new CannotResolveClassNameException($class);
}
$childClasses = [];
foreach ($allClasses as $oneClass) {
if (self::isChildOfClass($oneClass, $className)) {
/*
* Attention. I have to use ClassUtils::getRealClass() method to avoid problem with the proxy / cache
* classes. Example:
* - My\ExtraBundle\Entity\MyEntity
* - Proxies\__CG__\My\ExtraBundle\Entity\MyEntity
*
* It's actually the same class, so I have to skip it.
*/
$realClass = ClassUtils::getRealClass($oneClass);
if (in_array($realClass, $childClasses)) {
continue;
}
$childClasses[] = $realClass;
}
}
return $childClasses;
}
/**
* Returns namespace of one child class which extends given class.
* Extended class should has only one child class.
*
* @param array|object|string $parentClass Class who child class should be returned. An array of objects,
* namespaces, object or namespace.
* @return mixed
*
* @throws MissingChildClassesException
* @throws TooManyChildClassesException
*/
public static function getOneChildClass($parentClass)
{
$childClasses = self::getChildClasses($parentClass);
/*
* No child classes?
* Oops, the base / parent class hasn't child class
*/
if (empty($childClasses)) {
throw new MissingChildClassesException($parentClass);
}
/*
* More than 1 child class?
* Oops, the base / parent class has too many child classes
*/
if (count($childClasses) > 1) {
throw new TooManyChildClassesException($parentClass, $childClasses);
}
return trim($childClasses[0]);
}
/**
* Returns property, the ReflectionProperty instance, of given object
*
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @param string $property Name of the property
* @param int $filter (optional) Filter of properties. Uses ReflectionProperty class constants.
* By default all properties are allowed / processed.
* @return null|ReflectionProperty
*/
public static function getProperty($class, $property, $filter = null)
{
$className = self::getClassName($class);
$properties = self::getProperties($className, $filter);
if (!empty($properties)) {
/* @var $reflectionProperty ReflectionProperty */
foreach ($properties as $reflectionProperty) {
if ($reflectionProperty->getName() == $property) {
return $reflectionProperty;
}
}
}
return null;
}
/**
* Returns information if given class / object uses / implements given trait
*
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @param array|string $trait An array of strings or string
* @param bool $verifyParents If is set to true, parent classes are verified if they use given
* trait. Otherwise - not.
* @return bool|null
* @throws CannotResolveClassNameException
*/
public static function usesTrait($class, $trait, $verifyParents = false)
{
$className = self::getClassName($class);
$traitName = self::getClassName($trait);
/*
* Oops, cannot resolve class
*/
if (empty($className)) {
throw new CannotResolveClassNameException($class);
}
/*
* Oops, cannot resolve trait
*/
if (empty($traitName)) {
throw new CannotResolveClassNameException($class, false);
}
$reflection = new ReflectionClass($className);
$traitsNames = $reflection->getTraitNames();
$uses = in_array($traitName, $traitsNames);
if (!$uses && $verifyParents) {
$parentClassName = self::getParentClassName($className);
if (null !== $parentClassName) {
return self::usesTrait($parentClassName, $trait, true);
}
}
return $uses;
}
/**
* Returns name of the parent class.
* If given class does not extend another, returns null.
*
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @return string|null
*/
public static function getParentClassName($class)
{
$className = self::getClassName($class);
$reflection = new ReflectionClass($className);
$parentClass = $reflection->getParentClass();
if (null === $parentClass || false === $parentClass) {
return null;
}
return $parentClass->getName();
}
}

View File

@@ -0,0 +1,726 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use Meritoo\Common\Exception\Regex\IncorrectColorHexLengthException;
use Meritoo\Common\Exception\Regex\InvalidColorHexValueException;
/**
* Useful regular expressions methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Regex
{
/**
* Patterns used to validate / verify values
*
* @var array
*/
private static $patterns = [
'email' => '/[\w-]{2,}@[\w-]+\.[\w]{2,}+/',
'phone' => '/^\+?[0-9 ]+$/',
'camelCasePart' => '/([a-z]|[A-Z]){1}[a-z]*/',
'urlProtocol' => '/^([a-z]+:\/\/)',
'urlDomain' => '([\da-z\.-]+)\.([a-z\.]{2,6})(\/)?([\w\.\-]*)?(\?)?([\w \.\-\/=&]*)\/?$/i',
'letterOrDigit' => '/[a-zA-Z0-9]+/',
'htmlEntity' => '/&[a-z0-9]+;/',
'fileName' => '/.+\.\w+$/',
'isQuoted' => '/^[\'"]{1}.+[\'"]{1}$/',
'windowsBasedPath' => '/^[A-Z]{1}:\\\.*$/',
'money' => '/^[-+]?\d+([\.,]{1}\d*)?$/',
'color' => '/^[a-f0-9]{6}$/i',
];
/**
* Returns information if given e-mail address is valid
*
* @param string $email E-mail address to validate / verify
* @return bool
*
* Examples:
* a) valid e-mails:
* - ni@g-m.pl
* - ni@gm.pl
* - ni@g_m.pl
* b) invalid e-mails:
* - ni@g-m.p
* - n@g-m.pl
*/
public static function isValidEmail($email)
{
$pattern = self::getEmailPattern();
return (bool)preg_match($pattern, $email);
}
/**
* Returns information if given tax ID (in polish: NIP) is valid
*
* @param string $taxidString Tax ID (NIP) string
* @return bool
*/
public static function isValidTaxid($taxidString)
{
if (!empty($taxidString)) {
$weights = [
6,
5,
7,
2,
3,
4,
5,
6,
7,
];
$taxid = preg_replace('/[\s-]/', '', $taxidString);
$sum = 0;
if (10 == strlen($taxid) && is_numeric($taxid)) {
for ($x = 0; $x <= 8; ++$x) {
$sum += $taxid[$x] * $weights[$x];
}
if ((($sum % 11) % 10) == $taxid[9]) {
return true;
}
}
}
return false;
}
/**
* Returns information if given url address is valid
*
* @param string $url The url to validate / verify
* @param bool $requireProtocol (optional) If is set to true, the protocol is required to be passed in the url.
* Otherwise - not.
* @return bool
*/
public static function isValidUrl($url, $requireProtocol = false)
{
$pattern = self::getUrlPattern($requireProtocol);
return (bool)preg_match($pattern, $url);
}
/**
* Returns information if given phone number is valid
*
* @param string $phoneNumber The phone number to validate / verify
* @return bool
*/
public static function isValidPhoneNumber($phoneNumber)
{
$pattern = self::getPhoneNumberPattern();
return (bool)preg_match($pattern, $phoneNumber);
}
/**
* Returns array values that matches given pattern (or values that keys matches)
*
* @param string $pattern Pattern to match
* @param array $dataArray The array
* @param bool $itsKeyPattern (optional) If is set to true, keys are checks if they match pattern. Otherwise -
* values are checks.
* @return array
*/
public static function getArrayValuesByPattern($pattern, $dataArray, $itsKeyPattern = false)
{
if ($itsKeyPattern) {
$effect = [];
if (!empty($dataArray)) {
$matches = [];
foreach ($dataArray as $key => $value) {
if (preg_match($pattern, $key, $matches)) {
$effect[$key] = $value;
}
}
}
return $effect;
}
return preg_grep($pattern, $dataArray);
}
/**
* Filters array by given expression and column
*
* Expression can be simple compare expression, like ' == 2', or regular expression.
* Returns filtered array.
*
* @param array $array The array that should be filtered
* @param string $arrayColumnKey Column name
* @param string $filterExpression Filter expression, e.g. '== 2' or '!= \'home\''
* @param bool $itsRegularExpression (optional) If is set to true, means that filter expression is a
* regular expression
* @return array
*/
public static function arrayFilter($array, $arrayColumnKey, $filterExpression, $itsRegularExpression = false)
{
$effect = [];
if (!empty($array)) {
$effect = $array;
foreach ($effect as $key => &$item) {
if (isset($item[$arrayColumnKey])) {
$value = $item[$arrayColumnKey];
if ($itsRegularExpression) {
$matches = [];
$pattern = '|' . $filterExpression . '|';
$matchesCount = preg_match($pattern, $value, $matches);
$remove = 0 == $matchesCount;
} else {
if ('' == $value) {
$value = '\'\'';
} elseif (is_string($value)) {
$value = '\'' . $value . '\'';
}
eval('$isTrue = ' . $value . $filterExpression . ';');
/* @var bool $isTrue */
$remove = !$isTrue;
}
if ($remove) {
unset($effect[$key]);
}
}
}
}
return $effect;
}
/**
* Perform regular expression match with many given patterns.
* Returns information if given $subject matches one or all given $patterns.
*
* @param array|string $patterns The patterns to match
* @param string $subject The string to check
* @param bool $mustAllMatch (optional) If is set to true, $subject must match all $patterns. Otherwise -
* not.
* @return bool
*/
public static function pregMultiMatch($patterns, $subject, $mustAllMatch = false)
{
$effect = false;
$patterns = Arrays::makeArray($patterns);
if (!empty($patterns)) {
if ($mustAllMatch) {
$effect = true;
}
foreach ($patterns as $pattern) {
$matches = [];
$matched = (bool)preg_match_all($pattern, $subject, $matches);
if ($mustAllMatch) {
$effect = $effect && $matched;
} else {
if ($matched) {
$effect = $matched;
break;
}
}
}
}
return $effect;
}
/**
* Returns string in human readable style generated from given camel case string / text
*
* @param string $string The string / text to convert
* @param bool $applyUpperCaseFirst (optional) If is set to true, first word / element from the converted
* string is uppercased. Otherwise - not.
* @return string
*/
public static function camelCase2humanReadable($string, $applyUpperCaseFirst = false)
{
$parts = self::getCamelCaseParts($string);
if (!empty($parts)) {
$elements = [];
foreach ($parts as $part) {
$elements[] = strtolower($part);
}
$string = implode(' ', $elements);
if ($applyUpperCaseFirst) {
$string = ucfirst($string);
}
}
return $string;
}
/**
* Returns parts of given camel case string / text
*
* @param string $string The string / text to retrieve parts
* @return array
*/
public static function getCamelCaseParts($string)
{
$pattern = self::getCamelCasePartPattern();
$matches = [];
preg_match_all($pattern, $string, $matches);
return $matches[0];
}
/**
* Returns simple, lowercase string generated from given camel case string / text
*
* @param string $string The string / text to convert
* @param string $separator (optional) Separator used to concatenate parts of the string, e.g. '-' or '_'
* @param bool $applyLowercase (optional) If is set to true, returned string will be lowercased. Otherwise - not.
* @return string
*/
public static function camelCase2simpleLowercase($string, $separator = '', $applyLowercase = true)
{
$parts = self::getCamelCaseParts($string);
if (!empty($parts)) {
$string = implode($separator, $parts);
if ($applyLowercase) {
$string = strtolower($string);
}
}
return $string;
}
/**
* Returns pattern used to validate / verify or get e-mail address
*
* @return string
*/
public static function getEmailPattern()
{
return self::$patterns['email'];
}
/**
* Returns pattern used to validate / verify or get phone number
*
* @return string
*/
public static function getPhoneNumberPattern()
{
return self::$patterns['phone'];
}
/**
* Returns pattern used to validate / verify or get camel case parts of string
*
* @return string
*/
public static function getCamelCasePartPattern()
{
return self::$patterns['camelCasePart'];
}
/**
* Returns pattern used to validate / verify or get url address
*
* @param bool $requireProtocol (optional) If is set to true, the protocol is required to be passed in the url.
* Otherwise - not.
* @return string
*/
public static function getUrlPattern($requireProtocol = false)
{
$urlProtocol = self::$patterns['urlProtocol'];
$urlDomain = self::$patterns['urlDomain'];
$protocolPatternPart = '?';
if ($requireProtocol) {
$protocolPatternPart = '';
}
return sprintf('%s%s%s', $urlProtocol, $protocolPatternPart, $urlDomain);
}
/**
* Returns information if given path is sub-path of another path, e.g. path file is owned by path of directory
*
* @param string $subPath Path to verify, probably sub-path
* @param string $path Main / parent path
* @return bool
*/
public static function isSubPathOf($subPath, $path)
{
/*
* Empty path?
* Nothing to do
*/
if (empty($path) || empty($subPath)) {
return false;
}
/*
* I have to escape all slashes (directory separators): "/" -> "\/"
*/
$prepared = preg_quote($path, '/');
/*
* Slash at the ending is optional
*/
if (self::endsWith($path, '/')) {
$prepared .= '?';
}
$pattern = sprintf('/^%s.*/', $prepared);
return (bool)preg_match($pattern, $subPath);
}
/**
* Returns pattern used to validate / verify letter or digit
*
* @return string
*/
public static function getLetterOrDigitPattern()
{
return self::$patterns['letterOrDigit'];
}
/**
* Returns information if given character is a letter or digit
*
* @param string $char Character to check
* @return bool
*/
public static function isLetterOrDigit($char)
{
$pattern = self::getLetterOrDigitPattern();
return is_scalar($char) && (bool)preg_match($pattern, $char);
}
/**
* Returns information if the string starts with given beginning / characters
*
* @param string $string String to check
* @param string $beginning The beginning of string, one or more characters
* @return bool
*/
public static function startsWith($string, $beginning)
{
if (!empty($string) && !empty($beginning)) {
if (1 == strlen($beginning) && !self::isLetterOrDigit($beginning)) {
$beginning = '\\' . $beginning;
}
$pattern = sprintf('|^%s|', $beginning);
return (bool)preg_match($pattern, $string);
}
return false;
}
/**
* Returns information if the string ends with given ending / characters
*
* @param string $string String to check
* @param string $ending The ending of string, one or more characters
* @return bool
*/
public static function endsWith($string, $ending)
{
if (1 == strlen($ending) && !self::isLetterOrDigit($ending)) {
$ending = '\\' . $ending;
}
return (bool)preg_match('|' . $ending . '$|', $string);
}
/**
* Returns information if the string starts with directory's separator
*
* @param string $string String that may contain a directory's separator at the start / beginning
* @param string $separator (optional) The directory's separator, e.g. "/". If is empty (not provided), system's
* separator is used.
* @return bool
*/
public static function startsWithDirectorySeparator($string, $separator = '')
{
if (empty($separator)) {
$separator = DIRECTORY_SEPARATOR;
}
return self::startsWith($string, $separator);
}
/**
* Returns information if the string ends with directory's separator
*
* @param string $text String that may contain a directory's separator at the end
* @param string $separator (optional) The directory's separator, e.g. "/". If is empty (not provided), system's
* separator is used.
* @return string
*/
public static function endsWithDirectorySeparator($text, $separator = '')
{
if (empty($separator)) {
$separator = DIRECTORY_SEPARATOR;
}
return self::endsWith($text, $separator);
}
/**
* Returns information if uri contains parameter
*
* @param string $uri Uri string (e.g. $_SERVER['REQUEST_URI'])
* @param string $parameterName Uri parameter name
* @return bool
*/
public static function isSetUriParameter($uri, $parameterName)
{
return (bool)preg_match('|[?&]{1}' . $parameterName . '=|', $uri); // e.g. ?name=phil&type=4 -> '$type='
}
/**
* Returns pattern used to validate / verify html entity
*
* @return string
*/
public static function getHtmlEntityPattern()
{
return self::$patterns['htmlEntity'];
}
/**
* Returns information if the string contains html entities
*
* @param string $string String to check
* @return bool
*/
public static function containsEntities($string)
{
$pattern = self::getHtmlEntityPattern();
return (bool)preg_match_all($pattern, $string);
}
/**
* Returns information if one string contains another string
*
* @param string $haystack The string to search in
* @param string $needle The string to be search for
* @return bool
*/
public static function contains($haystack, $needle)
{
if (1 == strlen($needle) && !self::isLetterOrDigit($needle)) {
$needle = '\\' . $needle;
}
return (bool)preg_match('|.*' . $needle . '.*|', $haystack);
}
/**
* Returns pattern used to validate / verify name of file
*
* @return string
*/
public static function getFileNamePattern()
{
return self::$patterns['fileName'];
}
/**
* Returns information if given name of file is a really name of file.
* Verifies if given name contains a dot and an extension, e.g. "My File 001.jpg".
*
* @param string $fileName Name of file to check. It may be path of file also.
* @return bool
*/
public static function isFileName($fileName)
{
$pattern = self::getFileNamePattern();
return (bool)preg_match($pattern, $fileName);
}
/**
* Returns pattern used to validate / verify if value is quoted (by apostrophes or quotation marks)
*
* @return string
*/
public static function getIsQuotedPattern()
{
return self::$patterns['isQuoted'];
}
/**
* Returns information if given value is quoted (by apostrophes or quotation marks)
*
* @param mixed $value The value to check
* @return bool
*/
public static function isQuoted($value)
{
$pattern = self::getIsQuotedPattern();
return is_scalar($value) && (bool)preg_match($pattern, $value);
}
/**
* Returns pattern used to validate / verify if given path is a Windows-based path, e.g. "C:\path\to\file.jpg"
*
* @return string
*/
public static function getWindowsBasedPathPattern()
{
return self::$patterns['windowsBasedPath'];
}
/**
* Returns information if given path is a Windows-based path, e.g. "C:\path\to\file.jpg"
*
* @param string $path The path to verify
* @return bool
*/
public static function isWindowsBasedPath($path)
{
$pattern = self::getWindowsBasedPathPattern();
return (bool)preg_match($pattern, $path);
}
/**
* Returns information if given NIP number is valid
*
* @param string $nip A given NIP number
* @return bool
*
* @see https://pl.wikipedia.org/wiki/NIP#Znaczenie_numeru
*/
public static function isValidNip($nip)
{
$nip = preg_replace('/[^0-9]/', '', $nip);
$invalidNips = [
'1234567890',
'0000000000',
];
if (!preg_match('/^[0-9]{10}$/', $nip) || in_array($nip, $invalidNips)) {
return false;
}
$sum = 0;
$weights = [
6,
5,
7,
2,
3,
4,
5,
6,
7,
];
for ($i = 0; $i < 9; ++$i) {
$sum += $weights[$i] * $nip[$i];
}
$modulo = $sum % 11;
$numberControl = (10 == $modulo) ? 0 : $modulo;
return $numberControl == $nip[9];
}
/**
* Returns pattern used to validate / verify if given value is money-related value
*
* @return string
*/
public static function getMoneyPattern()
{
return self::$patterns['money'];
}
/**
* Returns information if given value is valid money-related value
*
* @param mixed $value Value to verify
* @return bool
*/
public static function isValidMoneyValue($value)
{
$pattern = self::getMoneyPattern();
return (bool)preg_match($pattern, $value);
}
/**
* Returns valid given hexadecimal value of color.
* If the value is invalid, throws an exception or returns false.
*
* @param string $color Color to verify
* @param bool $throwException (optional) If is set to true, throws an exception if given color is invalid
* (default behaviour). Otherwise - not.
* @return string|bool
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*/
public static function getValidColorHexValue($color, $throwException = true)
{
$color = Miscellaneous::replace($color, '/#/', '');
$length = strlen($color);
if (3 === $length) {
$color = Miscellaneous::replace($color, '/(.)(.)(.)/', '$1$1$2$2$3$3');
} else {
if (6 !== $length) {
if ($throwException) {
throw new IncorrectColorHexLengthException($color);
}
return false;
}
}
$pattern = self::$patterns['color'];
$match = (bool)preg_match($pattern, $color);
if (!$match) {
if ($throwException) {
throw new InvalidColorHexValueException($color);
}
return false;
}
return strtolower($color);
}
}

View File

@@ -16,6 +16,8 @@ namespace Meritoo\LimeSurvey\ApiClient\Base\Result;
*/ */
abstract class BaseItem abstract class BaseItem
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem';
/** /**
* Class constructor * Class constructor
* *

View File

@@ -0,0 +1,81 @@
<?php
namespace Meritoo\LimeSurvey\ApiClient\Base\Result;
/**
* Base class for participant of survey.
* Used as a foundation for short or full participant's data.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class BaseParticipant extends BaseItem
{
/**
* ID of the participant
*
* @var int
*/
protected $id;
/**
* First name of the participant
*
* @var string
*/
protected $firstName;
/**
* Last name of the participant
*
* @var string
*/
protected $lastName;
/**
* E-mail of the participant
*
* @var string
*/
protected $email;
/**
* Returns ID of the participant
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Returns first name of the participant
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Returns last name of the participant
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Returns e-mail of the participant
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
}

View File

@@ -1,35 +1,24 @@
<?php <?php
/** namespace Meritoo\LimeSurvey\ApiClient\Base\Result;
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Collection;
use Meritoo\Common\Collection\Collection; use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Method\DisabledMethodException; use Meritoo\Common\Exception\Method\DisabledMethodException;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
/** /**
* Collection of participants (of surveys). * Base class for participants' collection
* All participants grouped per survey.
*
* It's a collection of participants' collections.
* The survey ID is used as an index per each collection of participants, so they are grouped by survey.
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
*/ */
class Participants extends Collection abstract class BaseParticipantsCollection extends Collection
{ {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function add($element, $index = null) public function add($element, $index = null)
{ {
throw new DisabledMethodException(__METHOD__, 'addParticipants'); throw new DisabledMethodException(__METHOD__, 'addParticipant');
} }
/** /**
@@ -51,7 +40,7 @@ class Participants extends Collection
/** /**
* Adds participants of given survey * Adds participants of given survey
* *
* @param Collection $participants Participants to add. Collection of ParticipantShort classes. * @param Collection $participants Participants to add. Collection of ParticipantShort or Participant instances.
* @param int $surveyId ID of survey * @param int $surveyId ID of survey
* @return $this * @return $this
*/ */
@@ -72,35 +61,6 @@ class Participants extends Collection
return $this; return $this;
} }
/**
* Adds participant of given survey
*
* @param ParticipantShort $participant Participant to add
* @param int $surveyId ID of survey
* @return $this
*/
public function addParticipant(ParticipantShort $participant, $surveyId)
{
$this
->getBySurvey($surveyId)
->add($participant);
return $this;
}
/**
* Returns information if there are participants of given survey
*
* @param int $surveyId ID of survey
* @return bool
*/
public function hasParticipantsOfSurvey($surveyId)
{
return false === $this
->getBySurvey($surveyId)
->isEmpty();
}
/** /**
* Returns participants of given survey * Returns participants of given survey
* *
@@ -123,23 +83,54 @@ class Participants extends Collection
return $this[$surveyId]; return $this[$surveyId];
} }
/**
* Returns information if there are participants of given survey
*
* @param int $surveyId ID of survey
* @return bool
*/
public function hasParticipantsOfSurvey($surveyId)
{
return false === $this
->getBySurvey($surveyId)
->isEmpty();
}
/**
* Adds participant of given survey
*
* @param BaseParticipant $participant Participant to add
* @param int $surveyId ID of survey
* @return $this
*/
public function addParticipant(BaseParticipant $participant, $surveyId)
{
$this
->getBySurvey($surveyId)
->add($participant);
return $this;
}
/** /**
* Returns participant of given survey * Returns participant of given survey
* *
* @param int $surveyId ID of survey * @param int $surveyId ID of survey
* @param string $participantEmail E-mail of searched participant * @param string $participantEmail E-mail of searched participant
* @return ParticipantShort|null * @return BaseParticipant|null
*/ */
public function getParticipantOfSurvey($surveyId, $participantEmail) public function getParticipantOfSurvey($surveyId, $participantEmail)
{ {
/* @var Collection $participants */
$participants = $this->getBySurvey($surveyId); $participants = $this->getBySurvey($surveyId);
/*
* No participants?
* Nothing to do
*/
if ($participants->isEmpty()) { if ($participants->isEmpty()) {
return null; return null;
} }
/* @var ParticipantShort $participant */
foreach ($participants as $participant) { foreach ($participants as $participant) {
if ($participant->getEmail() == $participantEmail) { if ($participant->getEmail() == $participantEmail) {
return $participant; return $participant;

View File

@@ -24,6 +24,8 @@ use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
*/ */
class Client class Client
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Client\Client';
/** /**
* Configuration used while connecting to LimeSurvey's API * Configuration used while connecting to LimeSurvey's API
* *

View File

@@ -19,6 +19,8 @@ use Meritoo\Common\Utilities\Regex;
*/ */
class ConnectionConfiguration class ConnectionConfiguration
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration';
/** /**
* Base url. * Base url.
* Protocol & domain. * Protocol & domain.

View File

@@ -16,6 +16,8 @@ namespace Meritoo\LimeSurvey\ApiClient\Exception;
*/ */
class CannotProcessDataException extends \Exception class CannotProcessDataException extends \Exception
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException';
/** /**
* Reason why data cannot be processed, e.g. "Invalid user name or password" * Reason why data cannot be processed, e.g. "Invalid user name or password"
* *

View File

@@ -18,6 +18,8 @@ use Exception;
*/ */
class CreateSessionKeyFailedException extends Exception class CreateSessionKeyFailedException extends Exception
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\CreateSessionKeyFailedException';
/** /**
* Class constructor * Class constructor
* *

View File

@@ -19,6 +19,8 @@ use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
*/ */
class IncorrectClassOfResultItemException extends \Exception class IncorrectClassOfResultItemException extends \Exception
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\IncorrectClassOfResultItemException';
/** /**
* Class constructor * Class constructor
* *
@@ -29,7 +31,7 @@ class IncorrectClassOfResultItemException extends \Exception
$template = 'Class %s used to create instance of one item of the result should extend %s, but it does not. Did' $template = 'Class %s used to create instance of one item of the result should extend %s, but it does not. Did'
. ' you forget to use proper base class?'; . ' you forget to use proper base class?';
$message = sprintf($template, $className, BaseItem::class); $message = sprintf($template, $className, BaseItem::className);
parent::__construct($message); parent::__construct($message);
} }
} }

View File

@@ -19,6 +19,8 @@ use Meritoo\Common\Utilities\Arrays;
*/ */
class InvalidResultOfMethodRunException extends Exception class InvalidResultOfMethodRunException extends Exception
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\InvalidResultOfMethodRunException';
/** /**
* Class constructor * Class constructor
* *

View File

@@ -16,6 +16,8 @@ namespace Meritoo\LimeSurvey\ApiClient\Exception;
*/ */
class MissingParticipantOfSurveyException extends \Exception class MissingParticipantOfSurveyException extends \Exception
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException';
/** /**
* Class constructor * Class constructor
* *

View File

@@ -0,0 +1,33 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Exception;
/**
* An exception used when survey's summary is missing
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class MissingSurveySummaryException extends \Exception
{
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\MissingSurveySummaryException';
/**
* Class constructor
*
* @param int $surveyId ID of survey
*/
public function __construct($surveyId)
{
$template = 'Summary of survey with ID %d is missing. Does the survey exist?';
$message = sprintf($template, $surveyId);
parent::__construct($message);
}
}

View File

@@ -20,6 +20,8 @@ use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
*/ */
class UnknownInstanceOfResultItem extends Exception class UnknownInstanceOfResultItem extends Exception
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\UnknownInstanceOfResultItem';
/** /**
* Class constructor * Class constructor
* *
@@ -31,7 +33,7 @@ class UnknownInstanceOfResultItem extends Exception
$template = 'Class name used to create instance of one item used by result the of \'%s\' LimeSurvey API\'s' $template = 'Class name used to create instance of one item used by result the of \'%s\' LimeSurvey API\'s'
. ' method is unknown. Proper class is not mapped in %s::%s() method. Did you forget about this?'; . ' method is unknown. Proper class is not mapped in %s::%s() method. Did you forget about this?';
$message = sprintf($template, $method, ResultProcessor::class, 'getItemClassName'); $message = sprintf($template, $method, ResultProcessor::className, 'getItemClassName');
parent::__construct($message); parent::__construct($message);
} }
} }

View File

@@ -19,6 +19,8 @@ use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
*/ */
class UnknownMethodException extends UnknownTypeException class UnknownMethodException extends UnknownTypeException
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException';
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@@ -17,6 +17,8 @@ use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
*/ */
class JsonRpcClientManager class JsonRpcClientManager
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager';
/** /**
* Configuration used while connecting to LimeSurvey's API * Configuration used while connecting to LimeSurvey's API
* *

View File

@@ -13,6 +13,8 @@ use Meritoo\LimeSurvey\ApiClient\Type\SystemMethodType;
*/ */
class SessionManager class SessionManager
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Manager\SessionManager';
/** /**
* The session key. * The session key.
* Used to authenticate user while connecting to LimeSurvey's API. * Used to authenticate user while connecting to LimeSurvey's API.

View File

@@ -0,0 +1,26 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Collection;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipantsCollection;
/**
* Collection of participants' short data.
* All participants grouped per survey.
*
* It's a collection of participants' collections.
* The survey ID is used as an index per each collection of participants, so they are grouped by survey.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Participants extends BaseParticipantsCollection
{
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants';
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Collection;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipantsCollection;
/**
* Collection of participants' full data.
* All participants grouped per survey.
*
* It's a collection of participants' collections.
* The survey ID is used as an index per each collection of participants, so they are grouped by survey.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class ParticipantsDetails extends BaseParticipantsCollection
{
/**
* Returns information if survey with given ID has participant with given e-mail address
*
* @param int $surveyId ID of survey
* @param string $participantEmail E-mail of searched participant
* @return bool
*/
public function hasParticipantOfSurvey($surveyId, $participantEmail)
{
return null !== $this->getParticipantOfSurvey($surveyId, $participantEmail);
}
}

View File

@@ -19,6 +19,8 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
*/ */
class Surveys extends Collection class Surveys extends Collection
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys';
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@@ -0,0 +1,118 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Collection;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Method\DisabledMethodException;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
/**
* Collection of surveys' summaries (the SurveySummary class instances)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveysSummaries extends Collection
{
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Collection\SurveysSummaries';
/**
* {@inheritdoc}
*/
public function add($element, $index = null)
{
throw new DisabledMethodException(__METHOD__, 'addSurveySummary');
}
/**
* {@inheritdoc}
*/
public function addMultiple($elements, $useIndexes = false)
{
throw new DisabledMethodException(__METHOD__, 'addSurveysSummaries');
}
/**
* {@inheritdoc}
*/
public function has($element)
{
throw new DisabledMethodException(__METHOD__, 'hasSurveySummary');
}
/**
* Adds survey's summary
*
* @param SurveySummary $summary Survey's summary
* @param int $surveyId ID of survey
* @return $this
*/
public function addSurveySummary(SurveySummary $summary, $surveyId)
{
$this[$surveyId] = $summary;
return $this;
}
/**
* Adds surveys' summaries
*
* @param array $summaries Surveys' summaries to add
* @return $this
*/
public function addSurveysSummaries(array $summaries)
{
/*
* No summaries?
* Nothing to do
*/
if (empty($summaries)) {
return $this;
}
foreach ($summaries as $surveyId => $summary) {
$this->addSurveySummary($summary, $surveyId);
}
return $this;
}
/**
* Returns information if there is summary of survey with given ID
*
* @param int $surveyId ID of survey
* @return bool
*/
public function hasSurveySummary($surveyId)
{
/*
* There are no surveys' summaries or there is no summary of survey with given ID?
*/
if ($this->isEmpty() || !isset($this[$surveyId])) {
return false;
}
return true;
}
/**
* Returns summary of survey with given ID
*
* @param int $surveyId ID of survey
* @return SurveySummary|null
*/
public function getSurveySummary($surveyId)
{
if ($this->hasSurveySummary($surveyId)) {
return $this[$surveyId];
}
return null;
}
}

View File

@@ -10,7 +10,7 @@ namespace Meritoo\LimeSurvey\ApiClient\Result\Item;
use DateTime; use DateTime;
use Meritoo\Common\Utilities\Date; use Meritoo\Common\Utilities\Date;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipant;
/** /**
* One item of the result/data: full data of one participant * One item of the result/data: full data of one participant
@@ -18,14 +18,9 @@ use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
*/ */
class Participant extends BaseItem class Participant extends BaseParticipant
{ {
/** const className = 'Meritoo\LimeSurvey\ApiClient\Result\Item\Participant';
* ID of the participant
*
* @var int
*/
private $id;
/** /**
* Another ID of the participant? * Another ID of the participant?
@@ -42,27 +37,6 @@ class Participant extends BaseItem
*/ */
private $mpId; private $mpId;
/**
* First name of the participant
*
* @var string
*/
private $firstName;
/**
* Last name of the participant
*
* @var string
*/
private $lastName;
/**
* E-mail of the participant
*
* @var string
*/
private $email;
/** /**
* Status of the e-mail * Status of the e-mail
* *
@@ -199,7 +173,12 @@ class Participant extends BaseItem
break; break;
case 'completed': case 'completed':
$this->completed = 'Y' === trim(strtoupper($value)); if ('N' === trim(strtoupper($value))) {
$this->completed = false;
break;
}
$this->completed = Date::isValidDate($value, true);
break; break;
case 'usesleft': case 'usesleft':
@@ -211,7 +190,7 @@ class Participant extends BaseItem
break; break;
} }
$this->validFrom = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->validFrom = Date::getDateTime($value, true);
break; break;
case 'validuntil': case 'validuntil':
@@ -219,21 +198,11 @@ class Participant extends BaseItem
break; break;
} }
$this->validUntil = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->validUntil = Date::getDateTime($value, true);
break; break;
} }
} }
/**
* Returns ID of the participant
*
* @return int
*/
public function getId()
{
return $this->id;
}
/** /**
* Returns another ID of the participant? * Returns another ID of the participant?
* Don't know where it is used. * Don't know where it is used.
@@ -255,36 +224,6 @@ class Participant extends BaseItem
return $this->mpId; return $this->mpId;
} }
/**
* Returns first name of the participant
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Returns last name of the participant
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Returns e-mail of the participant
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/** /**
* Returns status of the e-mail * Returns status of the e-mail
* *

View File

@@ -8,7 +8,7 @@
namespace Meritoo\LimeSurvey\ApiClient\Result\Item; namespace Meritoo\LimeSurvey\ApiClient\Result\Item;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipant;
/** /**
* One item of the result/data: short data of one participant * One item of the result/data: short data of one participant
@@ -16,35 +16,9 @@ use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
*/ */
class ParticipantShort extends BaseItem class ParticipantShort extends BaseParticipant
{ {
/** const className = 'Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort';
* ID of the participant
*
* @var int
*/
private $id;
/**
* First name of the participant
*
* @var string
*/
private $firstName;
/**
* Last name of the participant
*
* @var string
*/
private $lastName;
/**
* E-mail of the participant
*
* @var string
*/
private $email;
/** /**
* {@inheritdoc} * {@inheritdoc}
@@ -64,46 +38,6 @@ class ParticipantShort extends BaseItem
} }
} }
/**
* Returns ID of the participant
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Returns first name of the participant
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Returns last name of the participant
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Returns e-mail of the participant
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/** /**
* Returns short data of participant created from full data of participant * Returns short data of participant created from full data of participant
* *

View File

@@ -16,6 +16,8 @@ namespace Meritoo\LimeSurvey\ApiClient\Result\Item;
*/ */
class Question extends QuestionShort class Question extends QuestionShort
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Item\Question';
/** /**
* Available answers * Available answers
* *

View File

@@ -18,6 +18,8 @@ use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
*/ */
class QuestionShort extends BaseItem class QuestionShort extends BaseItem
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Item\QuestionShort';
/** /**
* ID of the question * ID of the question
* *

View File

@@ -20,6 +20,8 @@ use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
*/ */
class Survey extends BaseItem class Survey extends BaseItem
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Item\Survey';
/** /**
* ID of the survey * ID of the survey
* *
@@ -74,7 +76,7 @@ class Survey extends BaseItem
break; break;
} }
$this->startsAt = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->startsAt = Date::getDateTime($value, true);
break; break;
case 'expires': case 'expires':
@@ -82,7 +84,7 @@ class Survey extends BaseItem
break; break;
} }
$this->expiresAt = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->expiresAt = Date::getDateTime($value, true);
break; break;
case 'active': case 'active':

View File

@@ -0,0 +1,198 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Item;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
/**
* One item of the result/data: survey's summary (contains aggregated data)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveySummary extends BaseItem
{
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary';
/**
* Count/Amount of tokens
*
* @var int
*/
private $tokenCount;
/**
* Count/Amount of invalid tokens
*
* @var int
*/
private $tokenInvalidCount;
/**
* Count/Amount of sent tokens
*
* @var int
*/
private $tokenSentCount;
/**
* Count/Amount of opted out tokens
*
* @var int
*/
private $tokenOptedOutCount;
/**
* Count/Amount of completed tokens
*
* @var int
*/
private $tokenCompletedCount;
/**
* Count/Amount of complete responses
*
* @var int
*/
private $completeResponsesCount;
/**
* Count/Amount of incomplete responses
*
* @var int
*/
private $incompleteResponsesCount;
/**
* Count/Amount of full responses
*
* @var int
*/
private $fullResponsesCount;
/**
* {@inheritdoc}
*/
public function setValue($property, $value)
{
switch ($property) {
case 'token_count':
$this->tokenCount = (int)$value;
break;
case 'token_invalid':
$this->tokenInvalidCount = (int)$value;
break;
case 'token_sent':
$this->tokenSentCount = (int)$value;
break;
case 'token_opted_out':
$this->tokenOptedOutCount = (int)$value;
break;
case 'token_completed':
$this->tokenCompletedCount = (int)$value;
break;
case 'completed_responses':
$this->completeResponsesCount = (int)$value;
break;
case 'incomplete_responses':
$this->incompleteResponsesCount = (int)$value;
break;
case 'full_responses':
$this->fullResponsesCount = (int)$value;
break;
}
}
/**
* Returns count/amount of tokens
*
* @return int
*/
public function getTokenCount()
{
return $this->tokenCount;
}
/**
* Returns count/amount of invalid tokens
*
* @return int
*/
public function getTokenInvalidCount()
{
return $this->tokenInvalidCount;
}
/**
* Returns count/amount of sent tokens
*
* @return int
*/
public function getTokenSentCount()
{
return $this->tokenSentCount;
}
/**
* Returns count/amount of opted out tokens
*
* @return int
*/
public function getTokenOptedOutCount()
{
return $this->tokenOptedOutCount;
}
/**
* Returns count/amount of completed tokens
*
* @return int
*/
public function getTokenCompletedCount()
{
return $this->tokenCompletedCount;
}
/**
* Returns count/amount of complete responses
*
* @return int
*/
public function getCompleteResponsesCount()
{
return $this->completeResponsesCount;
}
/**
* Returns count/amount of incomplete responses
*
* @return int
*/
public function getIncompleteResponsesCount()
{
return $this->incompleteResponsesCount;
}
/**
* Returns count/amount of full responses
*
* @return int
*/
public function getFullResponsesCount()
{
return $this->fullResponsesCount;
}
}

View File

@@ -17,6 +17,7 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Question; use Meritoo\LimeSurvey\ApiClient\Result\Item\Question;
use Meritoo\LimeSurvey\ApiClient\Result\Item\QuestionShort; use Meritoo\LimeSurvey\ApiClient\Result\Item\QuestionShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
/** /**
@@ -27,6 +28,8 @@ use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
*/ */
class ResultProcessor class ResultProcessor
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor';
/** /**
* Returns processed data based on the raw data returned by the LimeSurvey's API * Returns processed data based on the raw data returned by the LimeSurvey's API
* *
@@ -88,23 +91,27 @@ class ResultProcessor
switch ($method) { switch ($method) {
case MethodType::ADD_PARTICIPANTS: case MethodType::ADD_PARTICIPANTS:
case MethodType::GET_PARTICIPANT_PROPERTIES: case MethodType::GET_PARTICIPANT_PROPERTIES:
$className = Participant::class; $className = Participant::className;
break; break;
case MethodType::GET_QUESTION_PROPERTIES: case MethodType::GET_QUESTION_PROPERTIES:
$className = Question::class; $className = Question::className;
break;
case MethodType::GET_SUMMARY:
$className = SurveySummary::className;
break; break;
case MethodType::LIST_PARTICIPANTS: case MethodType::LIST_PARTICIPANTS:
$className = ParticipantShort::class; $className = ParticipantShort::className;
break; break;
case MethodType::LIST_QUESTIONS: case MethodType::LIST_QUESTIONS:
$className = QuestionShort::class; $className = QuestionShort::className;
break; break;
case MethodType::LIST_SURVEYS: case MethodType::LIST_SURVEYS:
$className = Survey::class; $className = Survey::className;
break; break;
/* /*
@@ -119,7 +126,7 @@ class ResultProcessor
throw new UnknownInstanceOfResultItem($method); throw new UnknownInstanceOfResultItem($method);
} }
if (Reflection::isChildOfClass($className, BaseItem::class)) { if (Reflection::isChildOfClass($className, BaseItem::className)) {
return $className; return $className;
} }

View File

@@ -22,6 +22,8 @@ use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
*/ */
class Result class Result
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Result\Result';
/** /**
* Name of called method while talking to the LimeSurvey's API. One of the MethodType class constants. * Name of called method while talking to the LimeSurvey's API. One of the MethodType class constants.
* *

View File

@@ -0,0 +1,152 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Service;
use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\ParticipantsDetails;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
/**
* Service that serves participants
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class ParticipantService
{
const className = 'Meritoo\LimeSurvey\ApiClient\Service\ParticipantService';
/**
* Client of the LimeSurvey's API
*
* @var Client
*/
private $client;
/**
* Collection of participants' full data.
* All participants grouped per survey.
*
* @var ParticipantsDetails
*/
private $participantsDetails;
/**
* Class constructor
*
* @param Client $client Client of the LimeSurvey's API
* @param ParticipantsDetails $participantsDetails (optional) Collection of participants' full data. All
* participants grouped per survey.
*/
public function __construct(
Client $client,
ParticipantsDetails $participantsDetails = null
) {
if (null === $participantsDetails) {
$participantsDetails = new ParticipantsDetails();
}
$this->client = $client;
$this->participantsDetails = $participantsDetails;
}
/**
* Returns client of the LimeSurvey's API
*
* @return Client
*/
public function getClient()
{
return $this->client;
}
/**
* Returns information if given survey has participant with given e-mail
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return bool
*/
public function hasParticipant($surveyId, $email)
{
return null !== $this->getParticipantDetails($surveyId, $email);
}
/**
* Returns full data of participant with given e-mail (participant of given survey)
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return Participant|null
*
* @throws CannotProcessDataException
*/
public function getParticipantDetails($surveyId, $email)
{
if (!$this->participantsDetails->hasParticipantOfSurvey($surveyId, $email)) {
$participant = null;
$arguments = [
$surveyId,
[
'email' => $email,
],
];
try {
/* @var Participant $participant */
$participant = $this
->client
->run(MethodType::GET_PARTICIPANT_PROPERTIES, $arguments)
->getData();
} catch (CannotProcessDataException $exception) {
/*
* Oops, something is broken, because the reason is different than "participant was not found"
*/
if (ReasonType::NO_PARTICIPANT_PROPERTIES !== $exception->getReason()) {
throw $exception;
}
}
if (null !== $participant) {
$this->participantsDetails->addParticipant($participant, $surveyId);
}
}
$participant = $this
->participantsDetails
->getParticipantOfSurvey($surveyId, $email);
return $participant;
}
/**
* Returns information if participant with given e-mail has filled given survey
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return bool
*
* @throws MissingParticipantOfSurveyException
*/
public function hasParticipantFilledSurvey($surveyId, $email)
{
if ($this->hasParticipant($surveyId, $email)) {
return true === $this
->getParticipantDetails($surveyId, $email)
->isCompleted();
}
throw new MissingParticipantOfSurveyException($surveyId, $email);
}
}

View File

@@ -0,0 +1,400 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Service;
use Meritoo\Common\Collection\Collection;
use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingSurveySummaryException;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\SurveysSummaries;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
/**
* Service that serves surveys and participants of surveys
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveyService
{
const className = 'Meritoo\LimeSurvey\ApiClient\Service\SurveyService';
/**
* Client of the LimeSurvey's API
*
* @var Client
*/
private $client;
/**
* All surveys.
* Collection of surveys (the Survey class instances).
*
* @var Surveys
*/
private $allSurveys;
/**
* Collection of participants' short data.
* All participants grouped per survey.
*
* @var Participants
*/
private $allParticipants;
/**
* Collection of surveys' summaries (the SurveySummary class instances)
*
* @var SurveysSummaries
*/
private $surveySummaries;
/**
* Template of the url used to start survey
*
* Example:
* - url: https://your.limesurvey.instance/12345?token=q1w2e3r4t5y6
* - LimeSurvey frontend: https://your.limesurvey.instance
* - survey ID: 12345
* - token: q1w2e3r4t5y6
*
* @var string
*/
private $startSurveyUrlTemplate = '%s/%d?token=%s';
/**
* Class constructor
*
* @param Client $client Client of the LimeSurvey's API
* @param Surveys $allSurveys (optional) All surveys. Collection of surveys (the Survey class
* instances).
* @param Participants $allParticipants (optional) Collection of participants' short data. All participants
* grouped per survey.
* @param SurveysSummaries $surveysSummaries (optional) Collection of surveys' summaries (the SurveySummary class
* instances)
*/
public function __construct(
Client $client,
Surveys $allSurveys = null,
Participants $allParticipants = null,
SurveysSummaries $surveysSummaries = null
) {
if (null === $allSurveys) {
$allSurveys = new Surveys();
}
if (null === $allParticipants) {
$allParticipants = new Participants();
}
if (null === $surveysSummaries) {
$surveysSummaries = new SurveysSummaries();
}
$this->client = $client;
$this->allSurveys = $allSurveys;
$this->allParticipants = $allParticipants;
$this->surveySummaries = $surveysSummaries;
}
/**
* Returns client of the LimeSurvey's API
*
* @return Client
*/
public function getClient()
{
return $this->client;
}
/**
* Returns all surveys
*
* @param bool $onlyActive (optional) If is set to true, active surveys are returned only. Otherwise - all (default
* behaviour).
* @return Surveys
*
* @throws CannotProcessDataException
*/
public function getAllSurveys($onlyActive = false)
{
if ($this->allSurveys->isEmpty()) {
$surveys = new Surveys();
try {
$surveys = $this
->client
->run(MethodType::LIST_SURVEYS)
->getData();
} catch (CannotProcessDataException $exception) {
$reason = $exception->getReason();
/*
* Reason of the exception is different than "Oops, there is no surveys. Everything else is fine."?
* Let's throw the exception
*/
if (ReasonType::NO_SURVEYS_FOUND !== $reason) {
throw $exception;
}
}
if (null !== $surveys && $surveys instanceof Collection) {
$this->allSurveys = new Surveys($surveys->toArray());
}
}
return $this->allSurveys->getAll($onlyActive);
}
/**
* Returns information if survey with given ID exists
*
* @param int $surveyId ID of survey to verify
* @param bool $shouldBeActive (optional) If is set to true, survey should be active. If it's not, it shouldn't
* be returned, even if exists. Otherwise - it doesn't matter (default behaviour).
* @return bool
*/
public function isExistingSurvey($surveyId, $shouldBeActive = false)
{
$allSurveys = $this->getAllSurveys($shouldBeActive);
/*
* No surveys?
* Nothing to do
*/
if ($allSurveys->isEmpty()) {
return false;
}
$surveyId = (int)$surveyId;
/* @var Survey $survey */
foreach ($allSurveys as $survey) {
if ($survey->getId() == $surveyId) {
return true;
}
}
return false;
}
/**
* Returns url used to start survey for given survey and participant's token
*
* @param int $surveyId ID of survey to start
* @param string $participantToken Token of participant who would like to start survey
* @return string
*/
public function getStartSurveyUrlByToken($surveyId, $participantToken)
{
$baseUrl = $this
->client
->getConfiguration()
->getBaseUrl();
return sprintf($this->startSurveyUrlTemplate, $baseUrl, $surveyId, $participantToken);
}
/**
* Returns url used to start survey for given survey and participant
*
* @param int $surveyId ID of survey to start
* @param Participant $participant Participant who would like to start survey
* @return string
*/
public function getStartSurveyUrl($surveyId, Participant $participant)
{
return $this->getStartSurveyUrlByToken($surveyId, $participant->getToken());
}
/**
* Returns participants of given survey
*
* @param int $surveyId ID of survey
* @param bool $onlyCompleted (optional) If is set to true, participants who completed survey are returned only.
* Otherwise - all (default behaviour).
* @return Collection
*
* @throws CannotProcessDataException
*/
public function getSurveyParticipants($surveyId, $onlyCompleted = false)
{
$hasSurvey = $this
->allParticipants
->hasParticipantsOfSurvey($surveyId);
if (!$hasSurvey) {
$offset = 0;
$limit = $this->getSurveyTokenCount($surveyId);
$includeUnused = !$onlyCompleted;
$arguments = [
$surveyId,
$offset,
$limit,
$includeUnused,
];
try {
$participants = $this
->client
->run(MethodType::LIST_PARTICIPANTS, $arguments)
->getData();
} catch (CannotProcessDataException $exception) {
/*
* Oops, something is broken, because the reason is different than "there are no participants"
*/
if (ReasonType::NO_PARTICIPANTS_FOUND !== $exception->getReason()) {
throw $exception;
}
$participants = new Collection();
}
$this
->allParticipants
->addParticipants($participants, $surveyId);
}
return $this
->allParticipants
->getBySurvey($surveyId);
}
/**
* Adds participant with given data to survey with given ID
*
* @param int $surveyId ID of survey
* @param string $firstName First name of the participant to add
* @param string $lastName Last ame of the participant to add
* @param string $email E-mail address of the participant to add
* @return Participant
*/
public function addParticipant($surveyId, $firstName, $lastName, $email)
{
$participantsData = [
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
];
$arguments = [
$surveyId,
$participantsData,
];
$participantCollection = $this
->client
->run(MethodType::ADD_PARTICIPANTS, $arguments)
->getData();
/* @var Participant $addedParticipant */
$addedParticipant = $participantCollection->getFirst();
$participants = new Collection([
ParticipantShort::fromParticipant($addedParticipant),
]);
$this
->allParticipants
->addParticipants($participants, $surveyId);
return $participantCollection->getFirst();
}
/**
* Returns short data of one participant with given e-mail (participant of given survey)
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return ParticipantShort|null
*/
public function getParticipant($surveyId, $email)
{
/*
* I have to get all participants of survey to avoid problem when participants exist but are not loaded
*/
$this->getSurveyParticipants($surveyId);
$participant = $this
->allParticipants
->getParticipantOfSurvey($surveyId, $email);
/* @var ParticipantShort $participant */
return $participant;
}
/**
* Returns count/amount of tokens of survey with given ID
*
* @param int $surveyId ID of survey
* @return int
*
* @throws MissingSurveySummaryException
*/
public function getSurveyTokenCount($surveyId)
{
$surveySummary = $this
->surveySummaries
->getSurveySummary($surveyId);
/*
* Unknown survey's summary?
* Let's fetch it
*/
if (null === $surveySummary) {
$surveySummary = $this->getSurveySummary($surveyId);
}
/*
* Oops, survey's summary is missing
*/
if (null === $surveySummary) {
throw new MissingSurveySummaryException($surveyId);
}
return $surveySummary->getTokenCount();
}
/**
* Returns summary of survey with given ID
*
* @param int $surveyId ID of survey
* @return SurveySummary|null
*/
private function getSurveySummary($surveyId)
{
$arguments = [
$surveyId,
];
/* @var SurveySummary $surveySummary */
$surveySummary = $this
->client
->run(MethodType::GET_SUMMARY, $arguments)
->getData();
if (null !== $surveySummary) {
$this
->surveySummaries
->addSurveySummary($surveySummary, $surveyId);
}
return $surveySummary;
}
}

View File

@@ -19,6 +19,8 @@ use Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException;
*/ */
class MethodType extends BaseType class MethodType extends BaseType
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Type\MethodType';
/** /**
* Add participants to the tokens collection of the survey * Add participants to the tokens collection of the survey
* *
@@ -58,6 +60,13 @@ class MethodType extends BaseType
*/ */
const GET_QUESTION_PROPERTIES = 'get_question_properties'; const GET_QUESTION_PROPERTIES = 'get_question_properties';
/**
* Get survey summary, regarding token usage and survey participation
*
* @var string
*/
const GET_SUMMARY = 'get_summary';
/** /**
* Return the IDs and properties of token/participants of a survey * Return the IDs and properties of token/participants of a survey
* *

View File

@@ -12,6 +12,8 @@ use Meritoo\Common\Type\Base\BaseType;
*/ */
class ReasonType extends BaseType class ReasonType extends BaseType
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Type\ReasonType';
/** /**
* Reason of exception when there is no survey with given ID * Reason of exception when there is no survey with given ID
* *
@@ -26,6 +28,13 @@ class ReasonType extends BaseType
*/ */
const NO_PARTICIPANTS_FOUND = 'No survey participants found.'; const NO_PARTICIPANTS_FOUND = 'No survey participants found.';
/**
* Reason of exception when there is no participant's properties/details
*
* @var string
*/
const NO_PARTICIPANT_PROPERTIES = 'Error: No results were found based on your attributes.';
/** /**
* Reason of exception when there is no surveys * Reason of exception when there is no surveys
* *

View File

@@ -18,6 +18,8 @@ use Meritoo\Common\Type\Base\BaseType;
*/ */
class SystemMethodType extends BaseType class SystemMethodType extends BaseType
{ {
const className = 'Meritoo\LimeSurvey\ApiClient\Type\SystemMethodType';
/** /**
* Create and return a session key * Create and return a session key
* *

View File

@@ -1,255 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Service;
use Meritoo\Common\Collection\Collection;
use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
/**
* Service that serves participants
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class ParticipantService
{
/**
* Client of the LimeSurvey's API
*
* @var Client
*/
private $client;
/**
* Collection of participants (of surveys).
* All participants grouped per survey.
*
* @var Participants
*/
private $allParticipants;
/**
* Class constructor
*
* @param Client $client Client of the LimeSurvey's API
* @param Participants $allParticipants (optional) Collection of participants (of surveys). All participants
* grouped per survey.
*/
public function __construct(Client $client, Participants $allParticipants = null)
{
if (null === $allParticipants) {
$allParticipants = new Participants();
}
$this->client = $client;
$this->allParticipants = $allParticipants;
}
/**
* Returns client of the LimeSurvey's API
*
* @return Client
*/
public function getClient()
{
return $this->client;
}
/**
* Returns participants of given survey
*
* @param int $surveyId ID of survey
* @return Collection
*
* @throws CannotProcessDataException
*/
public function getSurveyParticipants($surveyId)
{
$hasSurvey = $this
->allParticipants
->hasParticipantsOfSurvey($surveyId);
if (!$hasSurvey) {
$arguments = [
$surveyId,
];
try {
$participants = $this
->client
->run(MethodType::LIST_PARTICIPANTS, $arguments)
->getData();
} catch (CannotProcessDataException $exception) {
$reason = $exception->getReason();
/*
* Reason of the exception is different than "Oops, there is no participants. Everything else is fine."?
* Let's throw the exception
*/
if (ReasonType::NO_PARTICIPANTS_FOUND !== $reason) {
throw $exception;
}
$participants = new Collection();
}
$this
->allParticipants
->addParticipants($participants, $surveyId);
}
return $this
->allParticipants
->getBySurvey($surveyId);
}
/**
* Returns information if given survey has participant with given e-mail
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return bool
*/
public function hasParticipant($surveyId, $email)
{
/*
* I have to get all participants of survey to avoid problem when participants exist but are not loaded
*/
$this->getSurveyParticipants($surveyId);
return null !== $this
->allParticipants
->getParticipantOfSurvey($surveyId, $email);
}
/**
* Adds participant with given data to survey with given ID
*
* @param int $surveyId ID of survey
* @param string $firstName First name of the participant to add
* @param string $lastName Last ame of the participant to add
* @param string $email E-mail address of the participant to add
* @return Participant
*/
public function addParticipant($surveyId, $firstName, $lastName, $email)
{
$participantsData = [
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
];
$arguments = [
$surveyId,
$participantsData,
];
$participantCollection = $this
->client
->run(MethodType::ADD_PARTICIPANTS, $arguments)
->getData();
/* @var Participant $addedParticipant */
$addedParticipant = $participantCollection->getFirst();
$participants = new Collection([
ParticipantShort::fromParticipant($addedParticipant),
]);
$this
->allParticipants
->addParticipants($participants, $surveyId);
return $participantCollection->getFirst();
}
/**
* Returns short data of one participant with given e-mail of given survey
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return ParticipantShort|null
*/
public function getParticipant($surveyId, $email)
{
/*
* I have to get all participants of survey to avoid problem when participants exist but are not loaded
*/
$this->getSurveyParticipants($surveyId);
return $this
->allParticipants
->getParticipantOfSurvey($surveyId, $email);
}
/**
* Returns full data of participant with given e-mail of given survey
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return Participant|null
*/
public function getParticipantDetails($surveyId, $email)
{
$arguments = [
$surveyId,
[
'email' => $email,
],
];
$participant = $this
->client
->run(MethodType::GET_PARTICIPANT_PROPERTIES, $arguments)
->getData();
/* @var Participant $participant */
return $participant;
}
/**
* Returns information if participant with given e-mail has filled given survey
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return bool
*
* @throws MissingParticipantOfSurveyException
*/
public function hasParticipantFilledSurvey($surveyId, $email)
{
if ($this->hasParticipant($surveyId, $email)) {
$arguments = [
$surveyId,
[
'email' => $email,
],
];
/* @var Participant $participant */
$participant = $this
->client
->run(MethodType::GET_PARTICIPANT_PROPERTIES, $arguments)
->getData();
return true === $participant->isCompleted();
}
throw new MissingParticipantOfSurveyException($surveyId, $email);
}
}

View File

@@ -1,168 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Service;
use Meritoo\Common\Collection\Collection;
use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
/**
* Service that serves surveys
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveyService
{
/**
* Client of the LimeSurvey's API
*
* @var Client
*/
private $client;
/**
* All surveys.
* Collection of surveys (the Survey class instances).
*
* @var Surveys
*/
private $allSurveys;
/**
* Template of the url used to start survey
*
* Example:
* - url: https://your.limesurvey.instance/12345?token=q1w2e3r4t5y6
* - LimeSurvey frontend: https://your.limesurvey.instance
* - survey ID: 12345
* - token: q1w2e3r4t5y6
*
* @var string
*/
private $startSurveyUrlTemplate = '%s/%d?token=%s';
/**
* Class constructor
*
* @param Client $client Client of the LimeSurvey's API
* @param Surveys $allSurveys (optional) All surveys. Collection of surveys (the Survey class instances).
*/
public function __construct(Client $client, Surveys $allSurveys = null)
{
if (null === $allSurveys) {
$allSurveys = new Surveys();
}
$this->client = $client;
$this->allSurveys = $allSurveys;
}
/**
* Returns client of the LimeSurvey's API
*
* @return Client
*/
public function getClient()
{
return $this->client;
}
/**
* Returns all surveys
*
* @param bool $onlyActive (optional) If is set to true, active surveys are returned only. Otherwise - all.
* @return Surveys
*
* @throws CannotProcessDataException
*/
public function getAllSurveys($onlyActive = false)
{
if ($this->allSurveys->isEmpty()) {
$surveys = new Surveys();
try {
$surveys = $this
->client
->run(MethodType::LIST_SURVEYS)
->getData();
} catch (CannotProcessDataException $exception) {
$reason = $exception->getReason();
/*
* Reason of the exception is different than "Oops, there is no surveys. Everything else is fine."?
* Let's throw the exception
*/
if (ReasonType::NO_SURVEYS_FOUND !== $reason) {
throw $exception;
}
}
if (null !== $surveys && $surveys instanceof Collection) {
$this->allSurveys = new Surveys($surveys->toArray());
}
}
return $this->allSurveys->getAll($onlyActive);
}
/**
* Returns information if survey with given ID exists
*
* @param int $surveyId ID of survey to verify
* @param bool $shouldBeActive (optional) If is set to true, survey should be active. If it's not, it shouldn't
* be returned, even if exists. Otherwise - it doesn't matter.
* @return bool
*/
public function isExistingSurvey($surveyId, $shouldBeActive = false)
{
$allSurveys = $this->getAllSurveys($shouldBeActive);
/*
* No surveys?
* Nothing to do
*/
if ($allSurveys->isEmpty()) {
return false;
}
$surveyId = (int)$surveyId;
/* @var Survey $survey */
foreach ($allSurveys as $survey) {
if ($survey->getId() == $surveyId) {
return true;
}
}
return false;
}
/**
* Returns url used to start survey for given survey and participant
*
* @param int $surveyId ID of survey to start
* @param Participant $participant Participant who would like to start survey
* @return string
*/
public function getStartSurveyUrl($surveyId, Participant $participant)
{
$baseUrl = $this
->client
->getConfiguration()
->getBaseUrl();
return sprintf($this->startSurveyUrlTemplate, $baseUrl, $surveyId, $participant->getToken());
}
}

View File

@@ -22,11 +22,11 @@ class BaseItemTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(BaseItem::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(BaseItem::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testSetValuesVisibilityAndArguments() public function testSetValuesVisibilityAndArguments()
{ {
static::assertMethodVisibilityAndArguments(BaseItem::class, 'setValues', OopVisibilityType::IS_PRIVATE, 1, 1); static::assertMethodVisibilityAndArguments(BaseItem::className, 'setValues', OopVisibilityType::IS_PRIVATE, 1, 1);
} }
} }

View File

@@ -8,15 +8,12 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Client; namespace Meritoo\LimeSurvey\Test\ApiClient\Client;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Client\Client; use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration; use Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration;
use Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException;
use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager; use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager;
use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager; use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager;
use Meritoo\LimeSurvey\ApiClient\Result\Result;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
/** /**
@@ -36,7 +33,7 @@ class ClientTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(Client::class, OopVisibilityType::IS_PUBLIC, 3, 1); static::assertConstructorVisibilityAndArguments(Client::className, OopVisibilityType::IS_PUBLIC, 3, 1);
} }
/** /**
@@ -45,7 +42,7 @@ class ClientTest extends BaseTestCase
*/ */
public function testRunWithIncorrectMethod($incorrectMethod) public function testRunWithIncorrectMethod($incorrectMethod)
{ {
$this->expectException(UnknownMethodException::class); $this->setExpectedException('Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException');
$client = new Client($this->configuration); $client = new Client($this->configuration);
$client->run($incorrectMethod); $client->run($incorrectMethod);
@@ -61,8 +58,8 @@ class ClientTest extends BaseTestCase
*/ */
public function testRun($method, $arguments, $debugMode, $expectedRawData) public function testRun($method, $arguments, $debugMode, $expectedRawData)
{ {
$sessionManager = $this->createMock(SessionManager::class); $sessionManager = $this->createMock(SessionManager::className);
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->createMock(JsonRpcClientManager::className);
$rpcClientManager $rpcClientManager
->expects(static::any()) ->expects(static::any())
@@ -78,7 +75,7 @@ class ClientTest extends BaseTestCase
); );
$client = new Client($configuration, $rpcClientManager, $sessionManager); $client = new Client($configuration, $rpcClientManager, $sessionManager);
static::assertInstanceOf(Result::class, $client->run($method, $arguments)); static::assertInstanceOf('Meritoo\LimeSurvey\ApiClient\Result\Result', $client->run($method, $arguments));
} }
public function testGetConfiguration() public function testGetConfiguration()
@@ -89,21 +86,29 @@ class ClientTest extends BaseTestCase
public function testGetRpcClientManagerVisibilityAndArguments() public function testGetRpcClientManagerVisibilityAndArguments()
{ {
static::assertMethodVisibilityAndArguments(Client::class, 'getRpcClientManager', OopVisibilityType::IS_PRIVATE); static::assertMethodVisibilityAndArguments(Client::className, 'getRpcClientManager', OopVisibilityType::IS_PRIVATE);
} }
public function testGetSessionManagerVisibilityAndArguments() public function testGetSessionManagerVisibilityAndArguments()
{ {
static::assertMethodVisibilityAndArguments(Client::class, 'getRpcClientManager', OopVisibilityType::IS_PRIVATE); static::assertMethodVisibilityAndArguments(Client::className, 'getRpcClientManager', OopVisibilityType::IS_PRIVATE);
} }
/** /**
* Provides incorrect name of method * Provides incorrect name of method
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideIncorrectMethod() public function provideIncorrectMethod()
{ {
return [
['lorem'],
['ipsum'],
[''],
];
/*
yield[ yield[
'lorem', 'lorem',
]; ];
@@ -115,15 +120,39 @@ class ClientTest extends BaseTestCase
yield[ yield[
'', '',
]; ];
*/
} }
/** /**
* Provides correct name of method * Provides correct name of method
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideMethod() public function provideMethod()
{ {
return [
[
MethodType::GET_PARTICIPANT_PROPERTIES,
[],
true,
[],
],
[
MethodType::LIST_SURVEYS,
[],
false,
[],
],
[
MethodType::LIST_PARTICIPANTS,
[],
false,
null,
],
];
/*
yield[ yield[
MethodType::GET_PARTICIPANT_PROPERTIES, MethodType::GET_PARTICIPANT_PROPERTIES,
[], [],
@@ -144,6 +173,7 @@ class ClientTest extends BaseTestCase
false, false,
null, null,
]; ];
*/
/* /*
* todo: Use/Verify other types of methods * todo: Use/Verify other types of methods

View File

@@ -8,7 +8,6 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Configuration; namespace Meritoo\LimeSurvey\Test\ApiClient\Configuration;
use Generator;
use Meritoo\Common\Exception\Regex\InvalidUrlException; use Meritoo\Common\Exception\Regex\InvalidUrlException;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
@@ -38,7 +37,7 @@ class ConnectionConfigurationTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(ConnectionConfiguration::class, OopVisibilityType::IS_PUBLIC, 5, 3); static::assertConstructorVisibilityAndArguments(ConnectionConfiguration::className, OopVisibilityType::IS_PUBLIC, 5, 3);
} }
/** /**
@@ -47,7 +46,7 @@ class ConnectionConfigurationTest extends BaseTestCase
*/ */
public function testConstructorWithEmptyBaseUrl($emptyBaseUrl) public function testConstructorWithEmptyBaseUrl($emptyBaseUrl)
{ {
$this->expectException(InvalidUrlException::class); $this->setExpectedException(InvalidUrlException::className);
new ConnectionConfiguration($emptyBaseUrl, '', ''); new ConnectionConfiguration($emptyBaseUrl, '', '');
} }
@@ -57,7 +56,7 @@ class ConnectionConfigurationTest extends BaseTestCase
*/ */
public function testConstructorWithInvalidBaseUrl($invalidBaseUrl) public function testConstructorWithInvalidBaseUrl($invalidBaseUrl)
{ {
$this->expectException(InvalidUrlException::class); $this->setExpectedException(InvalidUrlException::className);
new ConnectionConfiguration($invalidBaseUrl, '', ''); new ConnectionConfiguration($invalidBaseUrl, '', '');
} }
@@ -94,10 +93,17 @@ class ConnectionConfigurationTest extends BaseTestCase
/** /**
* Provides empty base url * Provides empty base url
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideEmptyBaseUrl() public function provideEmptyBaseUrl()
{ {
return [
[''],
[null],
];
/*
yield[ yield[
'', '',
]; ];
@@ -105,15 +111,24 @@ class ConnectionConfigurationTest extends BaseTestCase
yield[ yield[
null, null,
]; ];
*/
} }
/** /**
* Provides invalid base url * Provides invalid base url
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideInvalidBaseUrl() public function provideInvalidBaseUrl()
{ {
return [
['lorem'],
['ipsum'],
['htp:/dolor.com'],
];
/*
yield[ yield[
'lorem', 'lorem',
]; ];
@@ -125,6 +140,7 @@ class ConnectionConfigurationTest extends BaseTestCase
yield[ yield[
'htp:/dolor.com', 'htp:/dolor.com',
]; ];
*/
} }
/** /**

View File

@@ -8,7 +8,6 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception; namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
@@ -23,7 +22,7 @@ class CannotProcessDataExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(CannotProcessDataException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(CannotProcessDataException::className, OopVisibilityType::IS_PUBLIC, 1, 1);
} }
/** /**
@@ -41,12 +40,25 @@ class CannotProcessDataExceptionTest extends BaseTestCase
/** /**
* Provides reason why data cannot be processed * Provides reason why data cannot be processed
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideReason() public function provideReason()
{ {
$template = 'Raw data returned by the LimeSurvey\'s API cannot be processed. Reason: \'%s\'.'; $template = 'Raw data returned by the LimeSurvey\'s API cannot be processed. Reason: \'%s\'.';
return [
[
'unknown',
sprintf($template, 'unknown'),
],
[
'Invalid user name or password',
sprintf($template, 'Invalid user name or password'),
],
];
/*
yield[ yield[
'unknown', 'unknown',
sprintf($template, 'unknown'), sprintf($template, 'unknown'),
@@ -56,5 +68,6 @@ class CannotProcessDataExceptionTest extends BaseTestCase
'Invalid user name or password', 'Invalid user name or password',
sprintf($template, 'Invalid user name or password'), sprintf($template, 'Invalid user name or password'),
]; ];
*/
} }
} }

View File

@@ -8,7 +8,6 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception; namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\CreateSessionKeyFailedException; use Meritoo\LimeSurvey\ApiClient\Exception\CreateSessionKeyFailedException;
@@ -23,7 +22,7 @@ class CreateSessionKeyFailedExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(CreateSessionKeyFailedException::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(CreateSessionKeyFailedException::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
/** /**
@@ -41,13 +40,26 @@ class CreateSessionKeyFailedExceptionTest extends BaseTestCase
/** /**
* Provides reason of failure * Provides reason of failure
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideReason() public function provideReason()
{ {
$shortMessage = 'Create of the session key has failed'; $shortMessage = 'Create of the session key has failed';
$longMessageTemplate = sprintf('%s. Reason: \'%s\'.', $shortMessage, '%s'); $longMessageTemplate = sprintf('%s. Reason: \'%s\'.', $shortMessage, '%s');
return [
[
'',
$shortMessage,
],
[
'Invalid user name or password',
sprintf($longMessageTemplate, 'Invalid user name or password'),
],
];
/*
yield[ yield[
'', '',
$shortMessage, $shortMessage,
@@ -57,5 +69,6 @@ class CreateSessionKeyFailedExceptionTest extends BaseTestCase
'Invalid user name or password', 'Invalid user name or password',
sprintf($longMessageTemplate, 'Invalid user name or password'), sprintf($longMessageTemplate, 'Invalid user name or password'),
]; ];
*/
} }
} }

View File

@@ -8,12 +8,9 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception; namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
use Meritoo\LimeSurvey\ApiClient\Exception\IncorrectClassOfResultItemException; use Meritoo\LimeSurvey\ApiClient\Exception\IncorrectClassOfResultItemException;
use stdClass;
/** /**
* Test case of an exception used while class used to create instance of one item of the result is incorrect * Test case of an exception used while class used to create instance of one item of the result is incorrect
@@ -25,7 +22,7 @@ class IncorrectClassOfResultItemExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(IncorrectClassOfResultItemException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(IncorrectClassOfResultItemException::className, OopVisibilityType::IS_PUBLIC, 1, 1);
} }
/** /**
@@ -43,16 +40,26 @@ class IncorrectClassOfResultItemExceptionTest extends BaseTestCase
/** /**
* Provides incorrect class name used to create instance of one item * Provides incorrect class name used to create instance of one item
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideIncorrectClassName() public function provideIncorrectClassName()
{ {
$template = 'Class %s used to create instance of one item of the result should extend %s, but it does not. Did' $template = 'Class %s used to create instance of one item of the result should extend %s, but it does not. Did'
. ' you forget to use proper base class?'; . ' you forget to use proper base class?';
return [
[
'\stdClass',
sprintf($template, '\stdClass', 'Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem'),
],
];
/*
yield[ yield[
stdClass::class, stdClass::class,
sprintf($template, stdClass::class, BaseItem::class), sprintf($template, stdClass::class, BaseItem::class),
]; ];
*/
} }
} }

View File

@@ -9,7 +9,6 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception; namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Exception; use Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\InvalidResultOfMethodRunException; use Meritoo\LimeSurvey\ApiClient\Exception\InvalidResultOfMethodRunException;
@@ -25,7 +24,7 @@ class InvalidResultOfMethodRunExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(InvalidResultOfMethodRunException::class, OopVisibilityType::IS_PUBLIC, 3, 2); static::assertConstructorVisibilityAndArguments(InvalidResultOfMethodRunException::className, OopVisibilityType::IS_PUBLIC, 3, 2);
} }
/** /**
@@ -45,7 +44,8 @@ class InvalidResultOfMethodRunExceptionTest extends BaseTestCase
/** /**
* Provides previous exception, name and arguments of called method * Provides previous exception, name and arguments of called method
* *
* @return Generator * @return array
* //return Generator
*/ */
public function providePreviousExceptionAndMethod() public function providePreviousExceptionAndMethod()
{ {
@@ -54,6 +54,26 @@ class InvalidResultOfMethodRunExceptionTest extends BaseTestCase
. "- method: %s,\n" . "- method: %s,\n"
. '- arguments: %s.'; . '- arguments: %s.';
return [
[
new Exception('Lorem ipsum'),
MethodType::ADD_RESPONSE,
[],
sprintf($template, 'Lorem ipsum', MethodType::ADD_RESPONSE, '(no arguments)'),
],
[
new Exception('Dolor sit amet'),
MethodType::LIST_SURVEYS,
[
'fist_name' => 'John',
'last_name' => 'Scott',
'email' => 'john@scott.com',
],
sprintf($template, 'Dolor sit amet', MethodType::LIST_SURVEYS, 'fist_name="John", last_name="Scott", email="john@scott.com"'),
],
];
/*
yield[ yield[
new Exception('Lorem ipsum'), new Exception('Lorem ipsum'),
MethodType::ADD_RESPONSE, MethodType::ADD_RESPONSE,
@@ -71,5 +91,6 @@ class InvalidResultOfMethodRunExceptionTest extends BaseTestCase
], ],
sprintf($template, 'Dolor sit amet', MethodType::LIST_SURVEYS, 'fist_name="John", last_name="Scott", email="john@scott.com"'), sprintf($template, 'Dolor sit amet', MethodType::LIST_SURVEYS, 'fist_name="John", last_name="Scott", email="john@scott.com"'),
]; ];
*/
} }
} }

View File

@@ -22,7 +22,7 @@ class MissingParticipantOfSurveyExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(MissingParticipantOfSurveyException::class, OopVisibilityType::IS_PUBLIC, 2, 2); static::assertConstructorVisibilityAndArguments(MissingParticipantOfSurveyException::className, OopVisibilityType::IS_PUBLIC, 2, 2);
} }
/** /**
@@ -41,12 +41,27 @@ class MissingParticipantOfSurveyExceptionTest extends BaseTestCase
/** /**
* Provides ID of survey and e-mail address of the participant * Provides ID of survey and e-mail address of the participant
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideSurveyIdAndEmail() public function provideSurveyIdAndEmail()
{ {
$template = 'Participant with e-mail %s of survey with ID %s is missing. Maybe was not added to the survey?'; $template = 'Participant with e-mail %s of survey with ID %s is missing. Maybe was not added to the survey?';
return [
[
1,
'lorem@ipsum.com',
sprintf($template, 'lorem@ipsum.com', 1),
],
[
1234,
'another@email.comm',
sprintf($template, 'another@email.comm', 1234),
],
];
/*
yield[ yield[
1, 1,
'lorem@ipsum.com', 'lorem@ipsum.com',
@@ -58,5 +73,6 @@ class MissingParticipantOfSurveyExceptionTest extends BaseTestCase
'another@email.comm', 'another@email.comm',
sprintf($template, 'another@email.comm', 1234), sprintf($template, 'another@email.comm', 1234),
]; ];
*/
} }
} }

View File

@@ -0,0 +1,73 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingSurveySummaryException;
/**
* Test case of an exception used when survey's summary is missing
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class MissingSurveySummaryExceptionTest extends BaseTestCase
{
public function testConstructorVisibilityAndArguments()
{
static::assertConstructorVisibilityAndArguments(MissingSurveySummaryException::className, OopVisibilityType::IS_PUBLIC, 1, 1);
}
/**
* @param int $surveyId ID of survey
* @param string $expectedMessage Expected exception's message
*
* @dataProvider provideSurveyId
*/
public function testConstructorMessage($surveyId, $expectedMessage)
{
$exception = new MissingSurveySummaryException($surveyId);
static::assertEquals($expectedMessage, $exception->getMessage());
}
/**
* Provides ID of survey
*
* @return array
* //return Generator
*/
public function provideSurveyId()
{
$template = 'Summary of survey with ID %d is missing. Does the survey exist?';
return [
[
1,
sprintf($template, 1),
],
[
'123',
sprintf($template, '123'),
],
];
/*
yield[
1,
sprintf($template, 1),
];
yield[
'123',
sprintf($template, '123'),
];
*/
}
}

View File

@@ -8,11 +8,9 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception; namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\UnknownInstanceOfResultItem; use Meritoo\LimeSurvey\ApiClient\Exception\UnknownInstanceOfResultItem;
use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
/** /**
@@ -26,7 +24,7 @@ class UnknownInstanceOfResultItemTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(UnknownInstanceOfResultItem::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(UnknownInstanceOfResultItem::className, OopVisibilityType::IS_PUBLIC, 1, 1);
} }
/** /**
@@ -45,13 +43,26 @@ class UnknownInstanceOfResultItemTest extends BaseTestCase
/** /**
* Provides name of called method * Provides name of called method
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideMethodName() public function provideMethodName()
{ {
$template = 'Class name used to create instance of one item used by result the of \'%s\' LimeSurvey API\'s' $template = 'Class name used to create instance of one item used by result the of \'%s\' LimeSurvey API\'s'
. ' method is unknown. Proper class is not mapped in %s::%s() method. Did you forget about this?'; . ' method is unknown. Proper class is not mapped in %s::%s() method. Did you forget about this?';
return [
[
MethodType::LIST_SURVEYS,
sprintf($template, MethodType::LIST_SURVEYS, 'Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor', 'getItemClassName'),
],
[
MethodType::ADD_PARTICIPANTS,
sprintf($template, MethodType::ADD_PARTICIPANTS, 'Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor', 'getItemClassName'),
],
];
/*
yield[ yield[
MethodType::LIST_SURVEYS, MethodType::LIST_SURVEYS,
sprintf($template, MethodType::LIST_SURVEYS, ResultProcessor::class, 'getItemClassName'), sprintf($template, MethodType::LIST_SURVEYS, ResultProcessor::class, 'getItemClassName'),
@@ -61,5 +72,6 @@ class UnknownInstanceOfResultItemTest extends BaseTestCase
MethodType::ADD_PARTICIPANTS, MethodType::ADD_PARTICIPANTS,
sprintf($template, MethodType::ADD_PARTICIPANTS, ResultProcessor::class, 'getItemClassName'), sprintf($template, MethodType::ADD_PARTICIPANTS, ResultProcessor::class, 'getItemClassName'),
]; ];
*/
} }
} }

View File

@@ -8,7 +8,6 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception; namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException; use Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException;
@@ -24,7 +23,7 @@ class UnknownMethodExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(UnknownMethodException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(UnknownMethodException::className, OopVisibilityType::IS_PUBLIC, 1, 1);
} }
/** /**
@@ -42,7 +41,8 @@ class UnknownMethodExceptionTest extends BaseTestCase
/** /**
* Provides name of called method * Provides name of called method
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideUnknownType() public function provideUnknownType()
{ {
@@ -51,6 +51,18 @@ class UnknownMethodExceptionTest extends BaseTestCase
$template = 'The \'%s\' type of name of method used while talking to the LimeSurvey\'s API is unknown. Probably' $template = 'The \'%s\' type of name of method used while talking to the LimeSurvey\'s API is unknown. Probably'
. ' doesn\'t exist or there is a typo. You should use one of these types: %s.'; . ' doesn\'t exist or there is a typo. You should use one of these types: %s.';
return [
[
MethodType::ADD_PARTICIPANTS,
sprintf($template, MethodType::ADD_PARTICIPANTS, $allMethods),
],
[
MethodType::ADD_PARTICIPANTS,
sprintf($template, MethodType::ADD_PARTICIPANTS, $allMethods),
],
];
/*
yield[ yield[
MethodType::ADD_PARTICIPANTS, MethodType::ADD_PARTICIPANTS,
sprintf($template, MethodType::ADD_PARTICIPANTS, $allMethods), sprintf($template, MethodType::ADD_PARTICIPANTS, $allMethods),
@@ -60,5 +72,6 @@ class UnknownMethodExceptionTest extends BaseTestCase
MethodType::ADD_PARTICIPANTS, MethodType::ADD_PARTICIPANTS,
sprintf($template, MethodType::ADD_PARTICIPANTS, $allMethods), sprintf($template, MethodType::ADD_PARTICIPANTS, $allMethods),
]; ];
*/
} }
} }

View File

@@ -8,7 +8,6 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Manager; namespace Meritoo\LimeSurvey\Test\ApiClient\Manager;
use JsonRPC\Client as RpcClient;
use JsonRPC\Exception\InvalidJsonFormatException; use JsonRPC\Exception\InvalidJsonFormatException;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
@@ -35,15 +34,15 @@ class JsonRpcClientManagerTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(JsonRpcClientManager::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(JsonRpcClientManager::className, OopVisibilityType::IS_PUBLIC, 1, 1);
} }
public function testRunMethodWithEmptyArrayReturned() public function testRunMethodWithEmptyArrayReturned()
{ {
$rpcClient = $this->createMock(RpcClient::class); $rpcClient = $this->createMock('\JsonRPC\Client');
$manager = $this $manager = $this
->getMockBuilder(JsonRpcClientManager::class) ->getMockBuilder(JsonRpcClientManager::className)
->setConstructorArgs([ ->setConstructorArgs([
$this->configuration, $this->configuration,
]) ])
@@ -68,8 +67,8 @@ class JsonRpcClientManagerTest extends BaseTestCase
public function testRunMethodWithRawDataReturned() public function testRunMethodWithRawDataReturned()
{ {
$rpcClient = $this->createMock(RpcClient::class); $rpcClient = $this->createMock('\JsonRPC\Client');
$manager = $this->createPartialMock(JsonRpcClientManager::class, ['getRpcClient']); $manager = $this->getMock(JsonRpcClientManager::className, ['getRpcClient'], [], '', false);
$rpcClient $rpcClient
->expects(static::once()) ->expects(static::once())
@@ -87,10 +86,10 @@ class JsonRpcClientManagerTest extends BaseTestCase
public function testRunMethodWithException() public function testRunMethodWithException()
{ {
$this->expectException(InvalidResultOfMethodRunException::class); $this->setExpectedException(InvalidResultOfMethodRunException::className);
$manager = $this->createPartialMock(JsonRpcClientManager::class, ['getRpcClient']); $manager = $this->getMock(JsonRpcClientManager::className, ['getRpcClient'], [], '', false);
$rpcClient = $this->createMock(RpcClient::class); $rpcClient = $this->createMock('\JsonRPC\Client');
$rpcClient $rpcClient
->expects(self::once()) ->expects(self::once())
@@ -108,7 +107,7 @@ class JsonRpcClientManagerTest extends BaseTestCase
public function testGetRpcClientVisibilityAndArguments() public function testGetRpcClientVisibilityAndArguments()
{ {
static::assertMethodVisibilityAndArguments(JsonRpcClientManager::class, 'getRpcClient', OopVisibilityType::IS_PROTECTED); static::assertMethodVisibilityAndArguments(JsonRpcClientManager::className, 'getRpcClient', OopVisibilityType::IS_PROTECTED);
} }
/** /**

View File

@@ -24,15 +24,15 @@ class SessionManagerTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(SessionManager::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(SessionManager::className, OopVisibilityType::IS_PUBLIC, 1, 1);
} }
public function testGetSessionKeyWhenFailedWithoutReason() public function testGetSessionKeyWhenFailedWithoutReason()
{ {
$this->expectException(CreateSessionKeyFailedException::class); $this->setExpectedException(CreateSessionKeyFailedException::className, 'Create of the session key has failed');
$this->expectExceptionMessage('Create of the session key has failed'); //$this->expectExceptionMessage('Create of the session key has failed');
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->createMock(JsonRpcClientManager::className);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())
@@ -46,10 +46,10 @@ class SessionManagerTest extends BaseTestCase
{ {
$reason = 'Invalid credentials'; $reason = 'Invalid credentials';
$this->expectException(CreateSessionKeyFailedException::class); $this->setExpectedException(CreateSessionKeyFailedException::className, sprintf('Create of the session key has failed. Reason: \'%s\'.', $reason));
$this->expectExceptionMessage(sprintf('Create of the session key has failed. Reason: \'%s\'.', $reason)); //$this->expectExceptionMessage(sprintf('Create of the session key has failed. Reason: \'%s\'.', $reason));
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->createMock(JsonRpcClientManager::className);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())
@@ -63,7 +63,7 @@ class SessionManagerTest extends BaseTestCase
public function testGetSessionKey() public function testGetSessionKey()
{ {
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->createMock(JsonRpcClientManager::className);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())
@@ -76,7 +76,7 @@ class SessionManagerTest extends BaseTestCase
public function testReleaseSessionKey() public function testReleaseSessionKey()
{ {
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->createMock(JsonRpcClientManager::className);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())
@@ -84,6 +84,6 @@ class SessionManagerTest extends BaseTestCase
->willReturn([]); ->willReturn([]);
$sessionManager = new SessionManager($clientManager); $sessionManager = new SessionManager($clientManager);
static::assertInstanceOf(SessionManager::class, $sessionManager->releaseSessionKey()); static::assertInstanceOf(SessionManager::className, $sessionManager->releaseSessionKey());
} }
} }

View File

@@ -17,7 +17,7 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort; use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
/** /**
* Test case of the collection of participants (of surveys) * Test case of the collection of participants' short data
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
@@ -25,7 +25,7 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
class ParticipantsTest extends BaseTestCase class ParticipantsTest extends BaseTestCase
{ {
/** /**
* An empty collection of participants (of surveys) * An empty collection of participants' short data
* *
* @var Participants * @var Participants
*/ */
@@ -47,24 +47,24 @@ class ParticipantsTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(Participants::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(Participants::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testAdd() public function testAdd()
{ {
$this->expectException(DisabledMethodException::class); $this->setExpectedException(DisabledMethodException::className);
(new Participants())->add(''); (new Participants())->add('');
} }
public function testAddMultiple() public function testAddMultiple()
{ {
$this->expectException(DisabledMethodException::class); $this->setExpectedException(DisabledMethodException::className);
(new Participants())->addMultiple([]); (new Participants())->addMultiple([]);
} }
public function testHas() public function testHas()
{ {
$this->expectException(DisabledMethodException::class); $this->setExpectedException(DisabledMethodException::className);
(new Participants())->has(new Participant()); (new Participants())->has(new Participant());
} }

View File

@@ -0,0 +1,194 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Collection;
use Meritoo\Common\Exception\Method\DisabledMethodException;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\SurveysSummaries;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
/**
* Test case of the collection of surveys' summaries (the SurveySummary class instances)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveysSummariesTest extends BaseTestCase
{
/**
* Empty collection of surveys' summaries
*
* @var SurveysSummaries
*/
private $emptySurveysSummaries;
/**
* Non-empty collection of surveys' summaries
*
* @var SurveysSummaries
*/
private $nonEmptySurveysSummaries;
public function testConstructorVisibilityAndArguments()
{
static::assertConstructorVisibilityAndArguments(SurveysSummaries::className, OopVisibilityType::IS_PUBLIC, 1, 0);
}
public function testAdd()
{
$this->setExpectedException(DisabledMethodException::className);
(new SurveysSummaries())->add('');
}
public function testAddMultiple()
{
$this->setExpectedException(DisabledMethodException::className);
(new SurveysSummaries())->addMultiple([]);
}
public function testHas()
{
$this->setExpectedException(DisabledMethodException::className);
(new SurveysSummaries())->has(new SurveySummary());
}
/**
* @param array $summaries Surveys' summaries to add
* @dataProvider provideSurveysSummaries
*/
public function testAddSurveysSummaries(array $summaries)
{
$existingSummariesCount = $this->nonEmptySurveysSummaries->count();
$this->emptySurveysSummaries->addSurveysSummaries($summaries);
$this->nonEmptySurveysSummaries->addSurveysSummaries($summaries);
static::assertCount(count($summaries), $this->emptySurveysSummaries);
static::assertCount(count($summaries) + $existingSummariesCount, $this->nonEmptySurveysSummaries);
}
public function testHasSurveySummaryUsingNonExistingSurvey()
{
static::assertFalse($this->emptySurveysSummaries->hasSurveySummary(1));
static::assertFalse($this->emptySurveysSummaries->hasSurveySummary(2));
static::assertFalse($this->nonEmptySurveysSummaries->hasSurveySummary(3));
static::assertFalse($this->nonEmptySurveysSummaries->hasSurveySummary(4));
}
public function testHasSurveySummaryUsingExistingSurvey()
{
static::assertTrue($this->nonEmptySurveysSummaries->hasSurveySummary(1));
static::assertTrue($this->nonEmptySurveysSummaries->hasSurveySummary(2));
}
public function testGetSurveySummaryUsingNonExistingSurvey()
{
static::assertNull($this->emptySurveysSummaries->getSurveySummary(1));
static::assertNull($this->emptySurveysSummaries->getSurveySummary(2));
static::assertNull($this->nonEmptySurveysSummaries->getSurveySummary(3));
static::assertNull($this->nonEmptySurveysSummaries->getSurveySummary(4));
}
public function testGetSurveySummaryUsingExistingSurvey()
{
$surveySummary1 = $this->nonEmptySurveysSummaries->getSurveySummary(1);
$surveySummary2 = $this->nonEmptySurveysSummaries->getSurveySummary(2);
static::assertInstanceOf(SurveySummary::className, $surveySummary1);
static::assertInstanceOf(SurveySummary::className, $surveySummary2);
static::assertEquals(0, $surveySummary1->getTokenCount());
static::assertEquals(5, $surveySummary2->getTokenCount());
static::assertEquals(0, $surveySummary1->getFullResponsesCount());
static::assertEquals(3, $surveySummary2->getFullResponsesCount());
}
/**
* Provides surveys' summaries
*
* @return array
* //return Generator
*/
public function provideSurveysSummaries()
{
return [
[
[],
],
[
[
123 => new SurveySummary(),
],
],
[
[
100 => new SurveySummary(),
500 => new SurveySummary(),
800 => new SurveySummary(),
],
],
];
/*
yield[
[],
];
yield[
[
123 => new SurveySummary(),
],
];
yield[
[
100 => new SurveySummary(),
500 => new SurveySummary(),
800 => new SurveySummary(),
],
];
*/
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->emptySurveysSummaries = new SurveysSummaries();
$this->nonEmptySurveysSummaries = new SurveysSummaries([
1 => new SurveySummary([
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
]),
2 => new SurveySummary([
'token_count' => '5',
'token_invalid' => '2',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '2',
'completed_responses' => '1',
'incomplete_responses' => '2',
'full_responses' => '3',
]),
]);
}
}

View File

@@ -37,7 +37,7 @@ class SurveysTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(Surveys::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(Surveys::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testAddWithoutIndex() public function testAddWithoutIndex()

View File

@@ -46,7 +46,7 @@ class ParticipantShortTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(ParticipantShort::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(ParticipantShort::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testCreateOfTheParticipant() public function testCreateOfTheParticipant()
@@ -127,12 +127,24 @@ class ParticipantShortTest extends BaseTestCase
static::assertEquals($participant2->getEmail(), $participantShort2->getEmail()); static::assertEquals($participant2->getEmail(), $participantShort2->getEmail());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new ParticipantShort($this->rawData[0]);
$this->participant2ndInstance = new ParticipantShort($this->rawData[1]);
}
/** /**
* Returns raw data of participants * Returns raw data of participants
* *
* @return array * @return array
*/ */
public static function getParticipantsRawData() private static function getParticipantsRawData()
{ {
return [ return [
[ [
@@ -153,16 +165,4 @@ class ParticipantShortTest extends BaseTestCase
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new ParticipantShort($this->rawData[0]);
$this->participant2ndInstance = new ParticipantShort($this->rawData[1]);
}
} }

View File

@@ -14,6 +14,7 @@ use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
/** /**
* Test case of the one item of the result/data: full data of participant * Test case of the one item of the result/data: full data of participant
@@ -46,7 +47,7 @@ class ParticipantTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(Participant::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(Participant::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testCreateOfTheParticipant() public function testCreateOfTheParticipant()
@@ -54,7 +55,7 @@ class ParticipantTest extends BaseTestCase
$processor = new ResultProcessor(); $processor = new ResultProcessor();
$processed = $processor->process(MethodType::GET_PARTICIPANT_PROPERTIES, $this->rawData[0]); $processed = $processor->process(MethodType::GET_PARTICIPANT_PROPERTIES, $this->rawData[0]);
static::assertInstanceOf(Participant::class, $processed); static::assertInstanceOf(Participant::className, $processed);
} }
public function testGetId() public function testGetId()
@@ -159,12 +160,24 @@ class ParticipantTest extends BaseTestCase
static::assertNull($this->participant2ndInstance->getValidUntil()); static::assertNull($this->participant2ndInstance->getValidUntil());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new Participant($this->rawData[0]);
$this->participant2ndInstance = new Participant($this->rawData[1]);
}
/** /**
* Returns raw data of participants * Returns raw data of participants
* *
* @return array * @return array
*/ */
public static function getParticipantsRawData() private static function getParticipantsRawData()
{ {
return [ return [
[ [
@@ -184,7 +197,7 @@ class ParticipantTest extends BaseTestCase
'completed' => 'N', 'completed' => 'N',
'usesleft' => 10, 'usesleft' => 10,
'validfrom' => null, 'validfrom' => null,
'validuntil' => (new DateTime())->format('Y-m-d H:i:s'), 'validuntil' => DateUtility::getDateTime(),
], ],
[ [
'tid' => '456', 'tid' => '456',
@@ -200,23 +213,11 @@ class ParticipantTest extends BaseTestCase
'sent' => 'Y', 'sent' => 'Y',
'remindersent' => 'N', 'remindersent' => 'N',
'remindercount' => 1, 'remindercount' => 1,
'completed' => 'Y', 'completed' => DateUtility::getDateTime(false),
'usesleft' => 5, 'usesleft' => 5,
'validfrom' => (new DateTime())->format('Y-m-d H:i:s'), 'validfrom' => DateUtility::getDateTime(),
'validuntil' => null, 'validuntil' => null,
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new Participant($this->rawData[0]);
$this->participant2ndInstance = new Participant($this->rawData[1]);
}
} }

View File

@@ -45,7 +45,7 @@ class QuestionShortTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(QuestionShort::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(QuestionShort::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testCreateOfTheQuestionShort() public function testCreateOfTheQuestionShort()
@@ -158,12 +158,24 @@ class QuestionShortTest extends BaseTestCase
static::assertEquals('HR', $this->question2ndInstance->getModuleName()); static::assertEquals('HR', $this->question2ndInstance->getModuleName());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new QuestionShort($this->rawData[0]);
$this->question2ndInstance = new QuestionShort($this->rawData[1]);
}
/** /**
* Returns raw data of questions * Returns raw data of questions
* *
* @return array * @return array
*/ */
public static function getQuestionsRawData() private static function getQuestionsRawData()
{ {
return [ return [
[ [
@@ -214,16 +226,4 @@ class QuestionShortTest extends BaseTestCase
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new QuestionShort($this->rawData[0]);
$this->question2ndInstance = new QuestionShort($this->rawData[1]);
}
} }

View File

@@ -45,7 +45,7 @@ class QuestionTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(Question::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(Question::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testCreateOfTheQuestionShort() public function testCreateOfTheQuestionShort()
@@ -53,7 +53,7 @@ class QuestionTest extends BaseTestCase
$processor = new ResultProcessor(); $processor = new ResultProcessor();
$processed = $processor->process(MethodType::GET_QUESTION_PROPERTIES, $this->rawData); $processed = $processor->process(MethodType::GET_QUESTION_PROPERTIES, $this->rawData);
static::assertInstanceOf(Question::class, $processed); static::assertInstanceOf(Question::className, $processed);
} }
public function testGetId() public function testGetId()
@@ -194,12 +194,24 @@ class QuestionTest extends BaseTestCase
static::assertNull($this->question2ndInstance->getDefaultValue()); static::assertNull($this->question2ndInstance->getDefaultValue());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new Question($this->rawData[0]);
$this->question2ndInstance = new Question($this->rawData[1]);
}
/** /**
* Returns raw data of questions * Returns raw data of questions
* *
* @return array * @return array
*/ */
public static function getQuestionsRawData() private static function getQuestionsRawData()
{ {
return [ return [
[ [
@@ -276,16 +288,4 @@ class QuestionTest extends BaseTestCase
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new Question($this->rawData[0]);
$this->question2ndInstance = new Question($this->rawData[1]);
}
} }

View File

@@ -0,0 +1,138 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Item;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
/**
* Test case of the one item of the result/data: survey's summary (contains aggregated data)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveySummaryTest extends BaseTestCase
{
public function testConstructorVisibilityAndArguments()
{
static::assertConstructorVisibilityAndArguments(SurveySummary::className, OopVisibilityType::IS_PUBLIC, 1, 0);
}
/**
* @param array $rawData Raw data of survey's summary
* @dataProvider provideRawData
*/
public function testCreateOfTheSurveySummary(array $rawData)
{
$processor = new ResultProcessor();
$processed = $processor->process(MethodType::GET_SUMMARY, $rawData);
/* @var SurveySummary $processed */
static::assertEquals($rawData['token_count'], $processed->getTokenCount());
static::assertEquals($rawData['token_invalid'], $processed->getTokenInvalidCount());
static::assertEquals($rawData['token_sent'], $processed->getTokenSentCount());
static::assertEquals($rawData['token_opted_out'], $processed->getTokenOptedOutCount());
static::assertEquals($rawData['token_completed'], $processed->getTokenCompletedCount());
static::assertEquals($rawData['completed_responses'], $processed->getCompleteResponsesCount());
static::assertEquals($rawData['incomplete_responses'], $processed->getIncompleteResponsesCount());
static::assertEquals($rawData['full_responses'], $processed->getFullResponsesCount());
}
/**
* Provides raw data of survey's summary
*
* @return array
* //return Generator
*/
public function provideRawData()
{
return [
[
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
],
[
[
'token_count' => '28',
'token_invalid' => '0',
'token_sent' => '5',
'token_opted_out' => '0',
'token_completed' => '6',
'completed_responses' => '6',
'incomplete_responses' => '10',
'full_responses' => '16',
],
],
[
[
'token_count' => '28',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '2',
'completed_responses' => '2',
'incomplete_responses' => '12',
'full_responses' => '14',
],
],
];
/*
yield[
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
];
yield[
[
'token_count' => '28',
'token_invalid' => '0',
'token_sent' => '5',
'token_opted_out' => '0',
'token_completed' => '6',
'completed_responses' => '6',
'incomplete_responses' => '10',
'full_responses' => '16',
],
];
yield[
[
'token_count' => '28',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '2',
'completed_responses' => '2',
'incomplete_responses' => '12',
'full_responses' => '14',
],
];
*/
}
}

View File

@@ -14,6 +14,7 @@ use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
/** /**
* Test case of the one item of the result/data: survey * Test case of the one item of the result/data: survey
@@ -46,7 +47,7 @@ class SurveyTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(Survey::class, OopVisibilityType::IS_PUBLIC, 1, 0); static::assertConstructorVisibilityAndArguments(Survey::className, OopVisibilityType::IS_PUBLIC, 1, 0);
} }
public function testCreateOfTheSurvey() public function testCreateOfTheSurvey()
@@ -99,13 +100,13 @@ class SurveyTest extends BaseTestCase
'sid' => '123', 'sid' => '123',
'surveyls_title' => 'Test', 'surveyls_title' => 'Test',
'startdate' => null, 'startdate' => null,
'expires' => (new DateTime())->format('Y-m-d H:i:s'), 'expires' => DateUtility::getDateTime(),
'active' => 'N', 'active' => 'N',
], ],
[ [
'sid' => '456', 'sid' => '456',
'surveyls_title' => 'Another Test', 'surveyls_title' => 'Another Test',
'startdate' => (new DateTime())->format('Y-m-d H:i:s'), 'startdate' => DateUtility::getDateTime(),
'expires' => null, 'expires' => null,
'active' => 'Y', 'active' => 'Y',
], ],

View File

@@ -27,7 +27,7 @@ class ResultProcessorTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertHasNoConstructor(ResultProcessor::class); static::assertHasNoConstructor(ResultProcessor::className);
} }
public function testProcessWithEmptyRawData() public function testProcessWithEmptyRawData()
@@ -72,17 +72,17 @@ class ResultProcessorTest extends BaseTestCase
static::assertNotEmpty($processed); static::assertNotEmpty($processed);
static::assertFalse(is_array($processed)); static::assertFalse(is_array($processed));
static::assertInstanceOf(BaseItem::class, $processed); static::assertInstanceOf(BaseItem::className, $processed);
} }
public function testGetItemClassNameVisibilityAndArguments() public function testGetItemClassNameVisibilityAndArguments()
{ {
static::assertMethodVisibilityAndArguments(ResultProcessor::class, 'getItemClassName', OopVisibilityType::IS_PRIVATE, 1, 1); static::assertMethodVisibilityAndArguments(ResultProcessor::className, 'getItemClassName', OopVisibilityType::IS_PRIVATE, 1, 1);
} }
public function testRunWithUnknownResultClass() public function testRunWithUnknownResultClass()
{ {
$this->expectException(UnknownInstanceOfResultItem::class); $this->setExpectedException(UnknownInstanceOfResultItem::className);
$rawData = [ $rawData = [
'lorem' => 'ipsum', 'lorem' => 'ipsum',

View File

@@ -8,13 +8,13 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Result; namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Result;
use DateTime;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Result\Result; use Meritoo\LimeSurvey\ApiClient\Result\Result;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
/** /**
@@ -87,7 +87,7 @@ class ResultTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(Result::class, OopVisibilityType::IS_PUBLIC, 2, 2); static::assertConstructorVisibilityAndArguments(Result::className, OopVisibilityType::IS_PUBLIC, 2, 2);
} }
public function testIsEmpty() public function testIsEmpty()
@@ -108,7 +108,7 @@ class ResultTest extends BaseTestCase
static::assertCount(count($this->emptyData), $emptyData); static::assertCount(count($this->emptyData), $emptyData);
static::assertCount(count($this->iterableData), $iterableData); static::assertCount(count($this->iterableData), $iterableData);
static::assertInstanceOf(BaseItem::class, $notIterableData); static::assertInstanceOf(BaseItem::className, $notIterableData);
} }
public function testGetDataUsingRawData() public function testGetDataUsingRawData()
@@ -128,18 +128,18 @@ class ResultTest extends BaseTestCase
public function testGetDataUsingProcessedDataWhoCannotBeProcessed() public function testGetDataUsingProcessedDataWhoCannotBeProcessed()
{ {
$this->expectException(CannotProcessDataException::class); $this->setExpectedException(CannotProcessDataException::className);
$this->statusInsteadDataResult->getData(); $this->statusInsteadDataResult->getData();
} }
public function testGetProcessedDataVisibilityAndArguments() public function testGetProcessedDataVisibilityAndArguments()
{ {
static::assertMethodVisibilityAndArguments(Result::class, 'getProcessedData', OopVisibilityType::IS_PRIVATE, 1, 1); static::assertMethodVisibilityAndArguments(Result::className, 'getProcessedData', OopVisibilityType::IS_PRIVATE, 1, 1);
} }
public function testGetResultProcessorVisibilityAndArguments() public function testGetResultProcessorVisibilityAndArguments()
{ {
static::assertMethodVisibilityAndArguments(Result::class, 'getResultProcessor', OopVisibilityType::IS_PRIVATE); static::assertMethodVisibilityAndArguments(Result::className, 'getResultProcessor', OopVisibilityType::IS_PRIVATE);
} }
public function testGetStatusWhenIsNotProvided() public function testGetStatusWhenIsNotProvided()
@@ -179,7 +179,7 @@ class ResultTest extends BaseTestCase
[ [
'sid' => '456', 'sid' => '456',
'surveyls_title' => 'Another Test', 'surveyls_title' => 'Another Test',
'startdate' => (new DateTime())->format('Y-m-d H:i:s'), 'startdate' => DateUtility::getDateTime(),
'expires' => null, 'expires' => null,
'active' => 'Y', 'active' => 'Y',
], ],
@@ -218,6 +218,6 @@ class ResultTest extends BaseTestCase
*/ */
private function getResultMock($constructorArguments) private function getResultMock($constructorArguments)
{ {
return $this->getMockForAbstractClass(Result::class, $constructorArguments); return $this->getMockForAbstractClass(Result::className, $constructorArguments);
} }
} }

View File

@@ -18,11 +18,11 @@ use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException; use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException;
use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager; use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager;
use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager; use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants; use Meritoo\LimeSurvey\ApiClient\Result\Collection\ParticipantsDetails;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Service\ParticipantService; use Meritoo\LimeSurvey\ApiClient\Service\ParticipantService;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
/** /**
@@ -33,6 +33,13 @@ use PHPUnit_Framework_MockObject_MockObject;
*/ */
class ParticipantServiceTest extends BaseTestCase class ParticipantServiceTest extends BaseTestCase
{ {
/**
* Raw data of participants
*
* @var array
*/
private $participantsRawData;
/** /**
* Service that serves participants. * Service that serves participants.
* Without participants. * Without participants.
@@ -51,7 +58,7 @@ class ParticipantServiceTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(ParticipantService::class, OopVisibilityType::IS_PUBLIC, 2, 1); static::assertConstructorVisibilityAndArguments(ParticipantService::className, OopVisibilityType::IS_PUBLIC, 2, 1);
} }
public function testGetClient() public function testGetClient()
@@ -62,8 +69,8 @@ class ParticipantServiceTest extends BaseTestCase
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager); $this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertInstanceOf(Client::class, $this->serviceWithoutParticipants->getClient()); static::assertInstanceOf(Client::className, $this->serviceWithoutParticipants->getClient());
static::assertInstanceOf(Client::class, $this->serviceWithParticipants->getClient()); static::assertInstanceOf(Client::className, $this->serviceWithParticipants->getClient());
$connectionConfiguration = $this->getConnectionConfiguration(); $connectionConfiguration = $this->getConnectionConfiguration();
$client = new Client($connectionConfiguration); $client = new Client($connectionConfiguration);
@@ -72,124 +79,46 @@ class ParticipantServiceTest extends BaseTestCase
static::assertEquals($client, $participantService->getClient()); static::assertEquals($client, $participantService->getClient());
} }
public function testGetSurveyParticipants() public function testHasParticipantUsingServiceWithoutParticipants()
{ {
$rpcClientManager = $this->getJsonRpcClientManager(3); $rpcClientManager = $this->getJsonRpcClientManager(2);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager); $this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(1)); static::assertFalse($this->serviceWithoutParticipants->hasParticipant(1, 'john@scott.com'));
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(2)); static::assertFalse($this->serviceWithoutParticipants->hasParticipant(2, 'john@scott.com'));
static::assertCount(2, $this->serviceWithParticipants->getSurveyParticipants(1));
static::assertCount(1, $this->serviceWithParticipants->getSurveyParticipants(2));
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
}
public function testGetSurveyParticipantsWithImportantException()
{
$this->expectException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$this->serviceWithParticipants->getSurveyParticipants(3);
}
public function testGetSurveyParticipantsWithNoParticipantsException()
{
$exception = new CannotProcessDataException(ReasonType::NO_PARTICIPANTS_FOUND);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
} }
public function testHasParticipant() public function testHasParticipant()
{ {
$rpcClientManager = $this->getJsonRpcClientManager(3); $runMethodCallResults = [
[
null,
],
[
null,
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertFalse($this->serviceWithoutParticipants->hasParticipant(1, 'john@scott.com'));
static::assertFalse($this->serviceWithoutParticipants->hasParticipant(2, 'john@scott.com'));
static::assertTrue($this->serviceWithParticipants->hasParticipant(1, 'john@scott.com')); static::assertTrue($this->serviceWithParticipants->hasParticipant(1, 'john@scott.com'));
static::assertFalse($this->serviceWithParticipants->hasParticipant(2, 'john@scott.com')); static::assertFalse($this->serviceWithParticipants->hasParticipant(2, 'john@scott.com'));
static::assertFalse($this->serviceWithParticipants->hasParticipant(3, 'john@scott.com')); static::assertFalse($this->serviceWithParticipants->hasParticipant(3, 'john@scott.com'));
} }
public function testAddParticipantForNotExistingSurvey() public function testGetParticipantDetailsWithException()
{ {
$this->expectException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID); $exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID);
$this->setExpectedException(CannotProcessDataException::className, $exception->getMessage());
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception); $rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$surveyId = 1; $this->serviceWithParticipants->getParticipantDetails(1, 'lorem@ipsum.com');
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
$this->serviceWithParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
}
public function testAddParticipant()
{
$surveyId = 1;
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$runMethodCallCount = 1;
$runMethodCallResults = [
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
];
$rpcClientManager = $this->getJsonRpcClientManager($runMethodCallCount, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$result = $this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
static::assertInstanceOf(Participant::class, $result);
static::assertEquals($firstName, $result->getFirstName());
static::assertEquals($lastName, $result->getLastName());
static::assertEquals($email, $result->getEmail());
}
public function testGetParticipant()
{
$rpcClientManager = $this->getJsonRpcClientManager(1);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertNull($this->serviceWithoutParticipants->getParticipant(1, 'john@scott.com'));
$participant = $this->serviceWithParticipants->getParticipant(1, 'john@scott.com');
static::assertInstanceOf(ParticipantShort::class, $participant);
static::assertEquals('John', $participant->getFirstName());
static::assertEquals('Scott', $participant->getLastName());
static::assertEquals('john@scott.com', $participant->getEmail());
} }
public function testGetParticipantDetails() public function testGetParticipantDetails()
@@ -199,37 +128,35 @@ class ParticipantServiceTest extends BaseTestCase
$rpcClientManager = $this->getJsonRpcClientManager(1); $rpcClientManager = $this->getJsonRpcClientManager(1);
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager); $this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$runMethodCallResults = [ $rpcClientManager = $this->getJsonRpcClientManager(0);
'tid' => 1,
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
'token' => uniqid(),
'sent' => 'N',
'completed' => 'N',
];
$rpcClientManager = $this->getJsonRpcClientManager(1, $runMethodCallResults);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertNull($this->serviceWithoutParticipants->getParticipantDetails(1, 'john@scott.com')); $participant1 = $this->serviceWithoutParticipants->getParticipantDetails(1, 'john@scott.com');
$participant = $this->serviceWithParticipants->getParticipantDetails(1, 'john@scott.com'); $participant2 = $this->serviceWithParticipants->getParticipantDetails(1, 'john@scott.com');
static::assertInstanceOf(Participant::class, $participant); $rawData = $this->participantsRawData[0];
static::assertEquals($runMethodCallResults['tid'], $participant->getId()); $id = $rawData['tid'];
static::assertEquals($runMethodCallResults['firstname'], $participant->getFirstName()); $firstName = $rawData['firstname'];
static::assertEquals($runMethodCallResults['lastname'], $participant->getLastName()); $lastName = $rawData['lastname'];
static::assertEquals($runMethodCallResults['email'], $participant->getEmail()); $email = $rawData['email'];
static::assertEquals($runMethodCallResults['token'], $participant->getToken()); $token = $rawData['token'];
static::assertFalse($participant->isSent());
static::assertFalse($participant->isCompleted()); static::assertNull($participant1);
static::assertNull($participant->isBlacklisted()); static::assertInstanceOf(Participant::className, $participant2);
static::assertNull($participant->getValidFrom()); static::assertEquals($id, $participant2->getId());
static::assertEquals($firstName, $participant2->getFirstName());
static::assertEquals($lastName, $participant2->getLastName());
static::assertEquals($email, $participant2->getEmail());
static::assertEquals($token, $participant2->getToken());
static::assertTrue($participant2->isSent());
static::assertTrue($participant2->isCompleted());
static::assertFalse($participant2->isBlacklisted());
static::assertNull($participant2->getValidFrom());
} }
public function testHasParticipantFilledSurveyWithException() public function testHasParticipantFilledSurveyWithoutParticipants()
{ {
$this->expectException(MissingParticipantOfSurveyException::class); $this->setExpectedException(MissingParticipantOfSurveyException::className);
$rpcClientManager = $this->getJsonRpcClientManager(1); $rpcClientManager = $this->getJsonRpcClientManager(1);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
@@ -240,14 +167,7 @@ class ParticipantServiceTest extends BaseTestCase
public function testHasParticipantFilledSurveyUsingExistingParticipant() public function testHasParticipantFilledSurveyUsingExistingParticipant()
{ {
$runMethodCallResults = [ $rpcClientManager = $this->getJsonRpcClientManager(0);
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
'completed' => 'Y',
];
$rpcClientManager = $this->getJsonRpcClientManager(1, $runMethodCallResults);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
@@ -256,7 +176,7 @@ class ParticipantServiceTest extends BaseTestCase
public function testHasParticipantFilledSurveyUsingNotExistingParticipant() public function testHasParticipantFilledSurveyUsingNotExistingParticipant()
{ {
$this->expectException(MissingParticipantOfSurveyException::class); $this->setExpectedException(MissingParticipantOfSurveyException::className);
$rpcClientManager = $this->getJsonRpcClientManager(1); $rpcClientManager = $this->getJsonRpcClientManager(1);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
@@ -265,6 +185,55 @@ class ParticipantServiceTest extends BaseTestCase
$this->serviceWithParticipants->hasParticipantFilledSurvey(3, 'mary@jane.com'); $this->serviceWithParticipants->hasParticipantFilledSurvey(3, 'mary@jane.com');
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->participantsRawData = [
[
'tid' => 1,
'participant_id' => null,
'mpid' => null,
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
'emailstatus' => 'OK',
'token' => uniqid(),
'language' => 'pl',
'blacklisted' => 'N',
'sent' => 'Y',
'remindersent' => 'N',
'remindercount' => 0,
'completed' => DateUtility::getDateTime(),
'usesleft' => 10,
'validfrom' => null,
'validuntil' => DateUtility::getDateTime(),
],
[
'tid' => 2,
'participant_id' => null,
'mpid' => null,
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
'emailstatus' => 'OK',
'token' => uniqid(),
'language' => 'pl',
'blacklisted' => 'N',
'sent' => 'Y',
'remindersent' => 'N',
'remindercount' => 0,
'completed' => 'N',
'usesleft' => 10,
'validfrom' => null,
'validuntil' => DateUtility::getDateTime(),
],
];
}
/** /**
* Returns configuration used while connecting to LimeSurvey's API * Returns configuration used while connecting to LimeSurvey's API
* *
@@ -282,7 +251,7 @@ class ParticipantServiceTest extends BaseTestCase
*/ */
private function getSessionManager() private function getSessionManager()
{ {
return $this->createMock(SessionManager::class); return $this->createMock(SessionManager::className);
} }
/** /**
@@ -294,12 +263,24 @@ class ParticipantServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = []) private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = [])
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->createMock(JsonRpcClientManager::className);
$rpcClientManager $mocker = $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
->method('runMethod') ->method('runMethod');
->will(static::returnValue($runMethodCallResults));
if (!empty($runMethodCallResults)) {
$function = [
$mocker,
'willReturnOnConsecutiveCalls',
];
/*
* I have to use the call_user_func_array() function to pass elements of $runMethodCallResults array as
* arguments of the willReturnOnConsecutiveCalls() method
*/
call_user_func_array($function, $runMethodCallResults);
}
return $rpcClientManager; return $rpcClientManager;
} }
@@ -314,7 +295,7 @@ class ParticipantServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception) private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception)
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->createMock(JsonRpcClientManager::className);
$rpcClientManager $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
@@ -348,30 +329,16 @@ class ParticipantServiceTest extends BaseTestCase
$configuration = $this->getConnectionConfiguration(); $configuration = $this->getConnectionConfiguration();
$client = new Client($configuration, $rpcClientManager, $sessionManager); $client = new Client($configuration, $rpcClientManager, $sessionManager);
$allParticipants = new Participants([ $participantsDetails = new ParticipantsDetails([
1 => new Collection([ 1 => new Collection([
new ParticipantShort([ new Participant($this->participantsRawData[0]),
'tid' => 1, new Participant($this->participantsRawData[1]),
'participant_info' => [
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
],
]),
new ParticipantShort([
'tid' => 2,
'participant_info' => [
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
],
]),
]), ]),
2 => new Collection([ 2 => new Collection([
new ParticipantShort(), new Participant(),
]), ]),
]); ]);
$this->serviceWithParticipants = new ParticipantService($client, $allParticipants); $this->serviceWithParticipants = new ParticipantService($client, $participantsDetails);
} }
} }

View File

@@ -9,22 +9,26 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Service; namespace Meritoo\LimeSurvey\Test\ApiClient\Service;
use Exception; use Exception;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Client\Client; use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration; use Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingSurveySummaryException;
use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager; use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager;
use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager; use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys; use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Service\SurveyService; use Meritoo\LimeSurvey\ApiClient\Service\SurveyService;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
/** /**
* Test case of the service that serves surveys * Test case of the service that serves surveys and participants of surveys
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
@@ -32,7 +36,7 @@ use PHPUnit_Framework_MockObject_MockObject;
class SurveyServiceTest extends BaseTestCase class SurveyServiceTest extends BaseTestCase
{ {
/** /**
* Service that serves surveys. * Service that serves surveys and participants of surveys.
* Without surveys. * Without surveys.
* *
* @var SurveyService * @var SurveyService
@@ -40,13 +44,29 @@ class SurveyServiceTest extends BaseTestCase
private $serviceWithoutSurveys; private $serviceWithoutSurveys;
/** /**
* Service that serves surveys. * Service that serves surveys and participants of surveys.
* With surveys. * With surveys.
* *
* @var SurveyService * @var SurveyService
*/ */
private $serviceWithSurveys; private $serviceWithSurveys;
/**
* Service that serves surveys and participants of surveys.
* Without participants.
*
* @var SurveyService
*/
private $serviceWithoutParticipants;
/**
* Service that serves surveys and participants of surveys.
* With participants.
*
* @var SurveyService
*/
private $serviceWithParticipants;
/** /**
* Base url of LimeSurvey's instance. * Base url of LimeSurvey's instance.
* Used to prepare configuration of connection. * Used to prepare configuration of connection.
@@ -57,7 +77,7 @@ class SurveyServiceTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(SurveyService::class, OopVisibilityType::IS_PUBLIC, 2, 1); static::assertConstructorVisibilityAndArguments(SurveyService::className, OopVisibilityType::IS_PUBLIC, 4, 1);
} }
public function testGetClient() public function testGetClient()
@@ -68,8 +88,8 @@ class SurveyServiceTest extends BaseTestCase
$this->createServiceWithoutSurveys($rpcClientManager, $sessionManager); $this->createServiceWithoutSurveys($rpcClientManager, $sessionManager);
$this->createServiceWithSurveys($rpcClientManager, $sessionManager); $this->createServiceWithSurveys($rpcClientManager, $sessionManager);
static::assertInstanceOf(Client::class, $this->serviceWithoutSurveys->getClient()); static::assertInstanceOf(Client::className, $this->serviceWithoutSurveys->getClient());
static::assertInstanceOf(Client::class, $this->serviceWithSurveys->getClient()); static::assertInstanceOf(Client::className, $this->serviceWithSurveys->getClient());
$connectionConfiguration = $this->getConnectionConfiguration(); $connectionConfiguration = $this->getConnectionConfiguration();
$client = new Client($connectionConfiguration); $client = new Client($connectionConfiguration);
@@ -78,9 +98,9 @@ class SurveyServiceTest extends BaseTestCase
static::assertEquals($client, $surveyService->getClient()); static::assertEquals($client, $surveyService->getClient());
} }
public function testGetAllSurveysWithImportantException() public function testGetAllSurveysWithNoTableException()
{ {
$this->expectException(CannotProcessDataException::class); $this->setExpectedException(CannotProcessDataException::className);
$exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE); $exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception); $rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
@@ -161,6 +181,22 @@ class SurveyServiceTest extends BaseTestCase
static::assertFalse($this->serviceWithSurveys->isExistingSurvey(4, true)); static::assertFalse($this->serviceWithSurveys->isExistingSurvey(4, true));
} }
public function testGetStartSurveyUrlByToken()
{
$rpcClientManager = $this->getJsonRpcClientManager(0);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutSurveys($rpcClientManager, $sessionManager);
$this->createServiceWithSurveys($rpcClientManager, $sessionManager);
$surveyId = 123;
$token = uniqid();
$expectedUrl = sprintf('%s/%d?token=%s', $this->connectionBaseUrl, $surveyId, $token);
static::assertEquals($expectedUrl, $this->serviceWithoutSurveys->getStartSurveyUrlByToken($surveyId, $token));
static::assertEquals($expectedUrl, $this->serviceWithSurveys->getStartSurveyUrlByToken($surveyId, $token));
}
public function testGetStartSurveyUrl() public function testGetStartSurveyUrl()
{ {
$rpcClientManager = $this->getJsonRpcClientManager(0); $rpcClientManager = $this->getJsonRpcClientManager(0);
@@ -185,6 +221,262 @@ class SurveyServiceTest extends BaseTestCase
static::assertEquals($expectedUrl, $this->serviceWithSurveys->getStartSurveyUrl($surveyId, $participant)); static::assertEquals($expectedUrl, $this->serviceWithSurveys->getStartSurveyUrl($surveyId, $participant));
} }
public function testGetSurveyParticipantsWithNotExistingSurveyException()
{
$exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID);
$this->setExpectedException(CannotProcessDataException::className, $exception->getMessage());
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
[
'status' => ReasonType::NOT_EXISTING_SURVEY_ID,
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$this->serviceWithParticipants->getSurveyParticipants(3);
}
public function testGetSurveyParticipantsWithNoParticipantsFoundException()
{
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
[
'status' => ReasonType::NO_PARTICIPANTS_FOUND,
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$participants = $this->serviceWithParticipants->getSurveyParticipants(3);
static::assertInstanceOf(Collection::className, $participants);
static::assertCount(0, $participants);
}
public function testGetSurveyParticipants()
{
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
null,
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
null,
[
'token_count' => '2',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
];
$rpcClientManager = $this->getJsonRpcClientManager(6, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(1));
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(2));
static::assertCount(2, $this->serviceWithParticipants->getSurveyParticipants(1));
static::assertCount(1, $this->serviceWithParticipants->getSurveyParticipants(2));
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
}
public function testGetSurveyParticipantsWithNoTableException()
{
$this->setExpectedException(CannotProcessDataException::className);
$exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$this->serviceWithParticipants->getSurveyParticipants(3);
}
public function testGetSurveyParticipantsWithNoParticipantsException()
{
$this->setExpectedException(CannotProcessDataException::className);
$exception = new CannotProcessDataException(ReasonType::NO_PARTICIPANTS_FOUND);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
}
public function testAddParticipantForNotExistingSurvey()
{
$this->setExpectedException(CannotProcessDataException::className);
$exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$surveyId = 1;
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
$this->serviceWithParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
}
public function testAddParticipant()
{
$surveyId = 1;
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$runMethodCallCount = 1;
$runMethodCallResults = [
[
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
],
];
$rpcClientManager = $this->getJsonRpcClientManager($runMethodCallCount, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$result = $this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
static::assertInstanceOf(Participant::className, $result);
static::assertEquals($firstName, $result->getFirstName());
static::assertEquals($lastName, $result->getLastName());
static::assertEquals($email, $result->getEmail());
}
public function testGetParticipant()
{
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
null,
[
[
'tid' => 1,
'participant_info' => [
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
],
],
[
'tid' => 2,
'participant_info' => [
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
],
],
],
[
'token_count' => '2',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$participant1 = $this->serviceWithoutParticipants->getParticipant(1, 'john@scott.com');
$participant2 = $this->serviceWithParticipants->getParticipant(1, 'john@scott.com');
static::assertNull($participant1);
static::assertInstanceOf(ParticipantShort::className, $participant2);
static::assertEquals('John', $participant2->getFirstName());
static::assertEquals('Scott', $participant2->getLastName());
static::assertEquals('john@scott.com', $participant2->getEmail());
}
public function testGetSurveyTokenCountWithException()
{
$this->setExpectedException(MissingSurveySummaryException::className);
$runMethodCallResults = [
null,
];
$rpcClientManager = $this->getJsonRpcClientManager(1, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutSurveys($rpcClientManager, $sessionManager);
$this->serviceWithoutSurveys->getSurveyTokenCount(1);
}
/** /**
* Returns configuration used while connecting to LimeSurvey's API * Returns configuration used while connecting to LimeSurvey's API
* *
@@ -202,7 +494,7 @@ class SurveyServiceTest extends BaseTestCase
*/ */
private function getSessionManager() private function getSessionManager()
{ {
return $this->createMock(SessionManager::class); return $this->createMock(SessionManager::className);
} }
/** /**
@@ -214,12 +506,24 @@ class SurveyServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = []) private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = [])
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->createMock(JsonRpcClientManager::className);
$rpcClientManager $mocker = $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
->method('runMethod') ->method('runMethod');
->will(static::returnValue($runMethodCallResults));
if (!empty($runMethodCallResults)) {
$function = [
$mocker,
'willReturnOnConsecutiveCalls',
];
/*
* I have to use the call_user_func_array() function to pass elements of $runMethodCallResults array as
* arguments of the willReturnOnConsecutiveCalls() method
*/
call_user_func_array($function, $runMethodCallResults);
}
return $rpcClientManager; return $rpcClientManager;
} }
@@ -234,7 +538,7 @@ class SurveyServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception) private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception)
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->createMock(JsonRpcClientManager::className);
$rpcClientManager $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
@@ -287,4 +591,55 @@ class SurveyServiceTest extends BaseTestCase
$this->serviceWithSurveys = new SurveyService($client, $allSurveys); $this->serviceWithSurveys = new SurveyService($client, $allSurveys);
} }
/**
* Creates instance of the tested service without participants
*
* @param PHPUnit_Framework_MockObject_MockObject $rpcClientManager Manager of the JsonRPC client used while connecting to LimeSurvey's API
* @param PHPUnit_Framework_MockObject_MockObject $sessionManager Manager of session started while connecting to LimeSurvey's API
*/
private function createServiceWithoutParticipants(PHPUnit_Framework_MockObject_MockObject $rpcClientManager, PHPUnit_Framework_MockObject_MockObject $sessionManager)
{
$configuration = $this->getConnectionConfiguration();
$client = new Client($configuration, $rpcClientManager, $sessionManager);
$this->serviceWithoutParticipants = new SurveyService($client);
}
/**
* Creates instance of the tested service with participants
*
* @param PHPUnit_Framework_MockObject_MockObject $rpcClientManager Manager of the JsonRPC client used while connecting to LimeSurvey's API
* @param PHPUnit_Framework_MockObject_MockObject $sessionManager Manager of session started while connecting to LimeSurvey's API
*/
private function createServiceWithParticipants(PHPUnit_Framework_MockObject_MockObject $rpcClientManager, PHPUnit_Framework_MockObject_MockObject $sessionManager)
{
$configuration = $this->getConnectionConfiguration();
$client = new Client($configuration, $rpcClientManager, $sessionManager);
$allParticipants = new Participants([
1 => new Collection([
new ParticipantShort([
'tid' => 1,
'participant_info' => [
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
],
]),
new ParticipantShort([
'tid' => 2,
'participant_info' => [
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
],
]),
]),
2 => new Collection([
new ParticipantShort(),
]),
]);
$this->serviceWithParticipants = new SurveyService($client, null, $allParticipants);
}
} }

View File

@@ -8,7 +8,6 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Type; namespace Meritoo\LimeSurvey\Test\ApiClient\Type;
use Generator;
use Meritoo\Common\Test\Base\BaseTypeTestCase; use Meritoo\Common\Test\Base\BaseTypeTestCase;
use Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException; use Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
@@ -24,7 +23,7 @@ class MethodTypeTest extends BaseTypeTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertHasNoConstructor(MethodType::class); static::assertHasNoConstructor(MethodType::className);
} }
/** /**
@@ -33,7 +32,7 @@ class MethodTypeTest extends BaseTypeTestCase
*/ */
public function testGetValidatedMethodWithIncorrectMethod($incorrectMethod) public function testGetValidatedMethodWithIncorrectMethod($incorrectMethod)
{ {
$this->expectException(UnknownMethodException::class); $this->setExpectedException(UnknownMethodException::className);
MethodType::getValidatedMethod($incorrectMethod); MethodType::getValidatedMethod($incorrectMethod);
} }
@@ -52,7 +51,7 @@ class MethodTypeTest extends BaseTypeTestCase
*/ */
public function testIsResultIterableWithIncorrectMethod($incorrectMethod) public function testIsResultIterableWithIncorrectMethod($incorrectMethod)
{ {
$this->expectException(UnknownMethodException::class); $this->setExpectedException(UnknownMethodException::className);
MethodType::isResultIterable($incorrectMethod); MethodType::isResultIterable($incorrectMethod);
} }
@@ -70,10 +69,33 @@ class MethodTypeTest extends BaseTypeTestCase
/** /**
* Provides correct type of method * Provides correct type of method
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideMethod() public function provideMethod()
{ {
return [
[
MethodType::ADD_RESPONSE,
],
[
MethodType::EXPORT_STATISTICS,
],
[
MethodType::GET_PARTICIPANT_PROPERTIES,
],
[
MethodType::LIST_SURVEYS,
],
[
SystemMethodType::GET_SESSION_KEY,
],
[
SystemMethodType::RELEASE_SESSION_KEY,
],
];
/*
yield[ yield[
MethodType::ADD_RESPONSE, MethodType::ADD_RESPONSE,
]; ];
@@ -97,15 +119,36 @@ class MethodTypeTest extends BaseTypeTestCase
yield[ yield[
SystemMethodType::RELEASE_SESSION_KEY, SystemMethodType::RELEASE_SESSION_KEY,
]; ];
*/
} }
/** /**
* Provides incorrect type of method * Provides incorrect type of method
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideIncorrectMethod() public function provideIncorrectMethod()
{ {
return [
[
'',
],
[
null,
],
[
true,
],
[
false,
],
[
'lorem',
],
];
/*
yield[ yield[
'', '',
]; ];
@@ -125,15 +168,45 @@ class MethodTypeTest extends BaseTypeTestCase
yield[ yield[
'lorem', 'lorem',
]; ];
*/
} }
/** /**
* Provides type of method who result provided by the API is iterable and information if it's iterable * Provides type of method who result provided by the API is iterable and information if it's iterable
* *
* @return Generator * @return array
* //return Generator
*/ */
public function provideIterableType() public function provideIterableType()
{ {
return [
[
MethodType::ADD_RESPONSE,
false,
],
[
MethodType::GET_PARTICIPANT_PROPERTIES,
false,
],
[
MethodType::LIST_PARTICIPANTS,
true,
],
[
MethodType::LIST_QUESTIONS,
true,
],
[
MethodType::LIST_SURVEYS,
true,
],
[
MethodType::LIST_USERS,
true,
],
];
/*
yield[ yield[
MethodType::ADD_RESPONSE, MethodType::ADD_RESPONSE,
false, false,
@@ -163,6 +236,7 @@ class MethodTypeTest extends BaseTypeTestCase
MethodType::LIST_USERS, MethodType::LIST_USERS,
true, true,
]; ];
*/
} }
/** /**
@@ -176,6 +250,7 @@ class MethodTypeTest extends BaseTypeTestCase
'EXPORT_STATISTICS' => MethodType::EXPORT_STATISTICS, 'EXPORT_STATISTICS' => MethodType::EXPORT_STATISTICS,
'GET_PARTICIPANT_PROPERTIES' => MethodType::GET_PARTICIPANT_PROPERTIES, 'GET_PARTICIPANT_PROPERTIES' => MethodType::GET_PARTICIPANT_PROPERTIES,
'GET_QUESTION_PROPERTIES' => MethodType::GET_QUESTION_PROPERTIES, 'GET_QUESTION_PROPERTIES' => MethodType::GET_QUESTION_PROPERTIES,
'GET_SUMMARY' => MethodType::GET_SUMMARY,
'LIST_PARTICIPANTS' => MethodType::LIST_PARTICIPANTS, 'LIST_PARTICIPANTS' => MethodType::LIST_PARTICIPANTS,
'LIST_QUESTIONS' => MethodType::LIST_QUESTIONS, 'LIST_QUESTIONS' => MethodType::LIST_QUESTIONS,
'LIST_SURVEYS' => MethodType::LIST_SURVEYS, 'LIST_SURVEYS' => MethodType::LIST_SURVEYS,
@@ -196,6 +271,26 @@ class MethodTypeTest extends BaseTypeTestCase
*/ */
public function provideTypeToVerify() public function provideTypeToVerify()
{ {
return [
[
'',
false,
],
[
'lorem',
false,
],
[
MethodType::ADD_RESPONSE,
true,
],
[
MethodType::GET_PARTICIPANT_PROPERTIES,
true,
],
];
/*
yield[ yield[
'', '',
false, false,
@@ -215,5 +310,6 @@ class MethodTypeTest extends BaseTypeTestCase
MethodType::GET_PARTICIPANT_PROPERTIES, MethodType::GET_PARTICIPANT_PROPERTIES,
true, true,
]; ];
*/
} }
} }

View File

@@ -21,7 +21,7 @@ class ReasonTypeTest extends BaseTypeTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertHasNoConstructor(ReasonType::class); static::assertHasNoConstructor(ReasonType::className);
} }
/** /**
@@ -32,6 +32,7 @@ class ReasonTypeTest extends BaseTypeTestCase
return [ return [
'NOT_EXISTING_SURVEY_ID' => ReasonType::NOT_EXISTING_SURVEY_ID, 'NOT_EXISTING_SURVEY_ID' => ReasonType::NOT_EXISTING_SURVEY_ID,
'NO_PARTICIPANTS_FOUND' => ReasonType::NO_PARTICIPANTS_FOUND, 'NO_PARTICIPANTS_FOUND' => ReasonType::NO_PARTICIPANTS_FOUND,
'NO_PARTICIPANT_PROPERTIES' => ReasonType::NO_PARTICIPANT_PROPERTIES,
'NO_SURVEYS_FOUND' => ReasonType::NO_SURVEYS_FOUND, 'NO_SURVEYS_FOUND' => ReasonType::NO_SURVEYS_FOUND,
'NO_TOKEN_TABLE' => ReasonType::NO_TOKEN_TABLE, 'NO_TOKEN_TABLE' => ReasonType::NO_TOKEN_TABLE,
]; ];
@@ -50,6 +51,34 @@ class ReasonTypeTest extends BaseTypeTestCase
*/ */
public function provideTypeToVerify() public function provideTypeToVerify()
{ {
return [
[
'',
false,
],
[
'lorem',
false,
],
[
ReasonType::NOT_EXISTING_SURVEY_ID,
true,
],
[
ReasonType::NO_PARTICIPANTS_FOUND,
true,
],
[
ReasonType::NO_SURVEYS_FOUND,
true,
],
[
ReasonType::NO_TOKEN_TABLE,
true,
],
];
/*
yield[ yield[
'', '',
false, false,
@@ -79,5 +108,6 @@ class ReasonTypeTest extends BaseTypeTestCase
ReasonType::NO_TOKEN_TABLE, ReasonType::NO_TOKEN_TABLE,
true, true,
]; ];
*/
} }
} }

View File

@@ -21,7 +21,7 @@ class SystemMethodTypeTest extends BaseTypeTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertHasNoConstructor(SystemMethodType::class); static::assertHasNoConstructor(SystemMethodType::className);
} }
/** /**
@@ -48,6 +48,26 @@ class SystemMethodTypeTest extends BaseTypeTestCase
*/ */
public function provideTypeToVerify() public function provideTypeToVerify()
{ {
return [
[
'',
false,
],
[
'lorem',
false,
],
[
SystemMethodType::GET_SESSION_KEY,
true,
],
[
SystemMethodType::RELEASE_SESSION_KEY,
true,
],
];
/*
yield[ yield[
'', '',
false, false,
@@ -67,5 +87,6 @@ class SystemMethodTypeTest extends BaseTypeTestCase
SystemMethodType::RELEASE_SESSION_KEY, SystemMethodType::RELEASE_SESSION_KEY,
true, true,
]; ];
*/
} }
} }

View File

@@ -0,0 +1,38 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Utilities;
use DateTime;
/**
* Date-related utility
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DateUtility
{
/**
* Returns date formatted with long or medium format
*
* @param bool $useLongFormat (optional) If is set to true, long format will be used (default behaviour).
* Otherwise - medium format.
* @return string
*/
public static function getDateTime($useLongFormat = true)
{
$format = 'Y-m-d H:i';
if ($useLongFormat) {
$format = 'Y-m-d H:i:s';
}
return (new DateTime())->format($format);
}
}