310 lines
9.5 KiB
PHP
310 lines
9.5 KiB
PHP
<?php
|
|
|
|
namespace LDC\LDCCRM\Models;
|
|
|
|
use LDC\LDCCRM\Enums\QuestionType;
|
|
use LDC\LDCCRM\Utils;
|
|
|
|
/**
|
|
* This class represents a question
|
|
* It has some static methods to retrieve questions and answers
|
|
*
|
|
* @property string $id The question id
|
|
* @property string|null $question The actual question as a string
|
|
* @property \LDC\LDCCRM\Enums\QuestionType|null $type
|
|
* The question type to display,
|
|
* it also hints wether it can accept one or multiple responses,
|
|
* so only checkbox allows multiple responses
|
|
* @property \LDC\LDCCRM\Models\Answer[] $answers An array with answers
|
|
*
|
|
* @category Api Models
|
|
* @package LDCCrmClient
|
|
* @subpackage models
|
|
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
|
|
*/
|
|
class Question extends ClientModel
|
|
{
|
|
/**
|
|
* The question id
|
|
*
|
|
* Required
|
|
* Field Type bigInt
|
|
*
|
|
* @var integer
|
|
*/
|
|
private int $id;
|
|
|
|
/**
|
|
* The actual question as a string
|
|
*
|
|
* Required
|
|
* Max length 255
|
|
* Field Type varchar
|
|
*
|
|
* @var string|null
|
|
*/
|
|
private ?string $question = null;
|
|
|
|
/**
|
|
* The question type
|
|
*
|
|
* Validate: in QuestionType::toValues()
|
|
*
|
|
* Required
|
|
* Field Type tinyInteger
|
|
*
|
|
* @var \LDC\LDCCRM\Enums\QuestionType|null
|
|
*/
|
|
private ?int $type = null;
|
|
|
|
/**
|
|
* The question answers
|
|
*
|
|
* \LDC\LDCCRM\Models\Answer
|
|
*
|
|
* @var array
|
|
*/
|
|
private array $answers = [];
|
|
|
|
/**
|
|
* The crm customer fields
|
|
*
|
|
* @var array
|
|
*/
|
|
protected array $modelFields = [
|
|
'id',
|
|
'question',
|
|
'type',
|
|
'answers',
|
|
];
|
|
|
|
/**
|
|
* Validation rules
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static array $validation = [
|
|
'id' => 'required|int',
|
|
'question' => 'required|string|max:255',
|
|
'type' => ['required'],
|
|
'answers' => 'required|array'
|
|
];
|
|
|
|
/**
|
|
* Question
|
|
*
|
|
* @param array $properties
|
|
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
|
|
*/
|
|
public function __construct(array $properties = [])
|
|
{
|
|
parent::__construct();
|
|
$this->fill($properties);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* General accessor
|
|
*
|
|
* @param string $field
|
|
* @return mixed
|
|
*/
|
|
public function __get(string $field)
|
|
{
|
|
$props = \array_diff(
|
|
$this->modelFields,
|
|
$this->invisibleFields
|
|
);
|
|
if (in_array($field, $props)) {
|
|
if ($field === 'type' and !\is_object($this->{$field})) {
|
|
return QuestionType::make($this->{$field});
|
|
}
|
|
}
|
|
return parent::__get($field);
|
|
}
|
|
|
|
/**
|
|
* Set prop on the model.
|
|
*
|
|
* @param string $field
|
|
* @param mixed $value
|
|
* @return void
|
|
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
|
|
* @throws \LDC\LDCCRM\Exceptions\AccessError If trying to set a value on a unknown property.
|
|
*/
|
|
public function __set(string $field, mixed $value): void
|
|
{
|
|
if ($field === 'type') {
|
|
$value = (\is_object($value) and
|
|
get_class($value) === QuestionType::class) ? $value->value() : $value;
|
|
}
|
|
parent::__set($field, $value);
|
|
}
|
|
|
|
/**
|
|
* Fill values into model using validation rules.
|
|
*
|
|
* @param array $properties
|
|
* @return void
|
|
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
|
|
*/
|
|
public function fill(array $properties)
|
|
{
|
|
if (isset($properties['type'])) {
|
|
try {
|
|
$properties['type'] = (\is_object($properties['type']) and
|
|
get_class($properties['type']) === QuestionType::class) ?
|
|
$properties['type']->value : (ctype_digit($properties['type']) ?
|
|
(int)$properties['type'] : $properties['type']);
|
|
} catch (\TypeError | \BadMethodCallException) {
|
|
// * Cast anyway
|
|
$properties['type'] = (int)$properties['type'];
|
|
}
|
|
}
|
|
parent::fill($properties);
|
|
}
|
|
|
|
/**
|
|
* Validate all model properties
|
|
*
|
|
* @param array $ignore
|
|
* @return array the validated values
|
|
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
|
|
*/
|
|
protected function validateAllValues(array $ignore = []): array
|
|
{
|
|
$out = [];
|
|
if (!\in_array('type', $ignore)) {
|
|
try {
|
|
$this->validateValue('type', QuestionType::make(Utils::getRawProperty($this, 'type')));
|
|
} catch (\TypeError | \BadMethodCallException) {
|
|
// Use this to throw validation error.
|
|
$this->validateValue('type', Utils::getRawProperty($this, 'type'));
|
|
}
|
|
$out['type'] = Utils::getRawProperty($this, 'type');
|
|
}
|
|
return array_merge($out, parent::validateAllValues(array_merge(['type'], $ignore)));
|
|
}
|
|
|
|
// * PUBLIC METHODS
|
|
|
|
/**
|
|
* Get all questions only
|
|
*
|
|
* @return array of \LDC\LDCCRM\Models\Question
|
|
* @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
|
|
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
|
|
* @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
|
*/
|
|
public static function all(): array
|
|
{
|
|
static::setUpApiInterface();
|
|
$request = Utils::getResquest('apiV4.questions.index');
|
|
|
|
$response = static::$apiInterface->call($request);
|
|
$out = [];
|
|
foreach ($response->data as $question) {
|
|
$answers = \array_map(function ($answer) {
|
|
return new Answer($answer);
|
|
}, $question['answers']);
|
|
$question['answers'] = $answers;
|
|
$out[] = new self($question);
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
/**
|
|
* Get all the questions with customer answers
|
|
*
|
|
* @param \LDC\LDCCRM\Models\Customer $customer
|
|
* @return array
|
|
*
|
|
* [
|
|
* 0 => [
|
|
* 'question' => \LDC\LDCCRM\Models\Question,
|
|
* 'customerAnswers' => \LDC\LDCCRM\Models\Answer[]
|
|
* ]
|
|
* ]
|
|
*
|
|
* with \LDC\LDCCRM\Models\Question[]
|
|
* and the customer \LDC\LDCCRM\Models\Answer[]
|
|
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a customer's hashcode could not be validated.
|
|
* @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
|
|
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
|
|
* Possibles are : - modelNotFound, If the customer could not be found(CRM side).
|
|
* @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
|
*/
|
|
public static function allWithCustomerAnswers(Customer $customer): array
|
|
{
|
|
self::assertValidHascode($customer->hashcode);
|
|
static::setUpApiInterface();
|
|
$request = Utils::getResquest('apiV4.questions.indexWithResponse', [
|
|
'serviceCustomer' => $customer->hashcode
|
|
]);
|
|
|
|
$response = static::$apiInterface->call($request);
|
|
$out = [];
|
|
foreach ($response->data as $question) {
|
|
$answers = \array_map(function ($answer) {
|
|
return new Answer($answer);
|
|
}, $question['answers']);
|
|
$customerAnswers = \array_map(function ($answer) {
|
|
return new Answer($answer);
|
|
}, $question['customerAnswers']);
|
|
unset($question['customerAnswers']);
|
|
$question['answers'] = $answers;
|
|
$out[] = [
|
|
'question' => new self($question),
|
|
'customerAnswers' => $customerAnswers,
|
|
];
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
/**
|
|
* Get unanswered question for a specific customer
|
|
*
|
|
* @param \LDC\LDCCRM\Models\Customer $customer
|
|
* @return array of \LDC\LDCCRM\Models\Question
|
|
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a customer's hashcode could not be validated.
|
|
* @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
|
|
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
|
|
* Possibles are : - modelNotFound, If the customer could not be found(CRM side).
|
|
* @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
|
*/
|
|
public static function unansweredBy(Customer $customer): array
|
|
{
|
|
self::assertValidHascode($customer->hashcode);
|
|
static::setUpApiInterface();
|
|
$request = Utils::getResquest(
|
|
'apiV4.questions.unAnsweredBy',
|
|
['serviceCustomer' => $customer->hashcode]
|
|
);
|
|
|
|
$response = static::$apiInterface->call($request);
|
|
$out = [];
|
|
foreach ($response->data as $question) {
|
|
$answers = \array_map(function ($answer) {
|
|
return new Answer($answer);
|
|
}, $question['answers']);
|
|
$question['answers'] = $answers;
|
|
$out[] = new self($question);
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
/**
|
|
* Serialize this object to an array
|
|
*
|
|
* @return array
|
|
*/
|
|
public function jsonSerialize()
|
|
{
|
|
return [
|
|
'id' => $this->id,
|
|
'question' => $this->question,
|
|
'type' => $this->type,
|
|
'answers' => $this->answers
|
|
];
|
|
}
|
|
}
|