ldc-crm-client/src/Models/Question.php

309 lines
9.4 KiB
PHP
Raw Normal View History

2021-08-11 17:26:30 +02:00
<?php
namespace LDC\LDCCRM\Models;
use LDC\LDCCRM\Enums\QuestionType;
use LDC\LDCCRM\Utils;
use TypeError;
/**
* This class represents a question
* It has some static methods to retrieve questions and answers
*
* @property string $id The question id
* @property string $question The actual question as a string
* @property \LDC\LDCCRM\Enums\QuestionType $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>
2021-08-11 17:26:30 +02:00
*/
class Question extends CrmClientModel
{
/**
* The question id
*
* Required
* Field Type bigInt
*
* @var integer
2021-08-11 17:26:30 +02:00
*/
private $id;
/**
* The actual question as a string
*
* Required
* Max length 255
* Field Type varchar
*
* @var string
*/
private $question = null;
/**
* The question type
*
* Validate: in QuestionType::toValues()
*
* Required
* Field Type tinyInteger
*
* @var \LDC\LDCCRM\Enums\QuestionType
*/
private $type = null;
/**
* The question answers
*
* \LDC\LDCCRM\Models\Answer
*
* @var array
2021-08-11 17:26:30 +02:00
*/
private $answers = [];
/**
* The crm customer fields
*
* @var array
*/
protected $modelFields = [
'id', 'question', 'type', 'answers'
];
/**
* Validation rules
*
* @var array
*/
protected static $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.
*/
2021-08-11 17:26:30 +02:00
public function __construct(array $properties = [])
{
parent::__construct();
$this->fill($properties);
return $this;
}
/**
* General accessor
*
* @param string $field
* @return mixed
*/
2021-08-11 17:26:30 +02:00
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.
2021-08-11 17:26:30 +02:00
*
* @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.
2021-08-11 17:26:30 +02:00
*/
public function __set(string $field, $value): void
2021-08-11 17:26:30 +02:00
{
if ($field === 'type') {
$value = (\is_object($value) and
2021-08-11 17:26:30 +02:00
get_class($value) === QuestionType::class) ? $value->value : $value;
}
parent::__set($field, $value);
2021-08-11 17:26:30 +02:00
}
/**
* Fill values into model using validation rules.
2021-08-11 17:26:30 +02:00
*
* @param array $properties
* @return void
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
2021-08-11 17:26:30 +02:00
*/
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 $e) {
// * Cast anyway
2021-08-11 17:26:30 +02:00
$properties['type'] = (int)$properties['type'];
}
}
parent::fill($properties);
}
/**
* Validate all model properties
*
* @param array $ignore
2021-08-11 17:26:30 +02:00
* @return array the validated values
* @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
2021-08-11 17:26:30 +02:00
*/
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 $e) {
// Use this to throw validation error.
$this->validateValue('type', Utils::getRawProperty($this, 'type'));
2021-08-11 17:26:30 +02:00
}
$out['type'] = Utils::getRawProperty($this, 'type');
2021-08-11 17:26:30 +02:00
}
return array_merge($out, parent::validateAllValues(array_merge(['type'], $ignore)));
}
// * PUBLIC METHODS
2021-08-11 17:26:30 +02:00
/**
* 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
2021-08-11 17:26:30 +02:00
*/
public static function all(): array
{
static::setUpApiInterface();
2021-08-11 17:26:30 +02:00
$request = Utils::getResquest('apiV2.questions.index');
$response = static::$apiInterface->call($request);
2021-12-06 00:16:13 +01:00
$out = [];
2021-08-11 17:26:30 +02:00
foreach ($response->data as $question) {
2021-12-06 00:16:13 +01:00
$answers = \array_map(function ($answer) {
2021-08-11 17:26:30 +02:00
return new Answer($answer);
}, $question['answers']);
$question['answers'] = $answers;
2021-12-06 00:16:13 +01:00
$out[] = new self($question);
2021-08-11 17:26:30 +02:00
}
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
2021-08-11 17:26:30 +02:00
*/
public static function allWithCustomerAnswers(Customer $customer): array
{
self::assertValidHascode($customer->hashcode);
static::setUpApiInterface();
2021-08-11 17:26:30 +02:00
$request = Utils::getResquest('apiV2.questions.indexWithResponse', [
'serviceCustomer' => $customer->hashcode
2021-08-11 17:26:30 +02:00
]);
$response = static::$apiInterface->call($request);
2021-12-06 00:16:13 +01:00
$out = [];
2021-08-11 17:26:30 +02:00
foreach ($response->data as $question) {
2021-12-06 00:16:13 +01:00
$answers = \array_map(function ($answer) {
2021-08-11 17:26:30 +02:00
return new Answer($answer);
}, $question['answers']);
$customerAnswers = \array_map(function ($answer) {
return new Answer($answer);
}, $question['customerAnswers']);
unset($question['customerAnswers']);
$question['answers'] = $answers;
2021-12-06 00:16:13 +01:00
$out[] = [
2021-08-11 17:26:30 +02:00
'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
2021-08-11 17:26:30 +02:00
*/
public static function unansweredBy(Customer $customer): array
{
self::assertValidHascode($customer->hashcode);
static::setUpApiInterface();
2021-08-11 17:26:30 +02:00
$request = Utils::getResquest(
'apiV2.questions.unAnsweredBy',
['serviceCustomer' => $customer->hashcode]
2021-08-11 17:26:30 +02:00
);
$response = static::$apiInterface->call($request);
2021-12-06 00:16:13 +01:00
$out = [];
2021-08-11 17:26:30 +02:00
foreach ($response->data as $question) {
2021-12-06 00:16:13 +01:00
$answers = \array_map(function ($answer) {
2021-08-11 17:26:30 +02:00
return new Answer($answer);
}, $question['answers']);
$question['answers'] = $answers;
2021-12-06 00:16:13 +01:00
$out[] = new self($question);
2021-08-11 17:26:30 +02:00
}
return $out;
}
2021-08-16 13:22:34 +02:00
/**
* Serialize this object to an array
*
* @return array
*/
public function jsonSerialize()
{
return [
'id' => $this->id,
'question' => $this->question,
'type' => $this->type,
'answers' => $this->answers
];
}
2021-08-11 17:26:30 +02:00
}