283 lines
7.9 KiB
PHP
283 lines
7.9 KiB
PHP
|
|
<?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
|
||
|
|
*/
|
||
|
|
class Question extends CrmClientModel
|
||
|
|
{
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Is true if this model was not filled from crm
|
||
|
|
*
|
||
|
|
* @var boolean
|
||
|
|
*/
|
||
|
|
private $isNew = true;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The question id
|
||
|
|
*
|
||
|
|
* Required
|
||
|
|
* Field Type bigInt
|
||
|
|
*
|
||
|
|
* @var int
|
||
|
|
*/
|
||
|
|
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
|
||
|
|
*
|
||
|
|
* @var \LDC\LDCCRM\Models\Answer[]
|
||
|
|
*/
|
||
|
|
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'
|
||
|
|
];
|
||
|
|
|
||
|
|
public function __construct(array $properties = [])
|
||
|
|
{
|
||
|
|
parent::__construct();
|
||
|
|
if (count(self::$validation['type']) < 2) {
|
||
|
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||
|
|
self::$validation['type'][] = function ($attribute, $value, $fail) {
|
||
|
|
if (!is_object($value) or !\in_array($value, QuestionType::toArray())) {
|
||
|
|
$type = \gettype($value);
|
||
|
|
$fail("Question type ($type)$value is not in QuestionType enum list");
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
$this->fill($properties);
|
||
|
|
return $this;
|
||
|
|
}
|
||
|
|
|
||
|
|
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
|
||
|
|
*
|
||
|
|
* @param string $field
|
||
|
|
* @param mixed $value
|
||
|
|
* @throws TypeError if the field has an incorrect value
|
||
|
|
* @return mixed|null The input value or null is this prop does not exists
|
||
|
|
*/
|
||
|
|
public function __set(string $field, $value)
|
||
|
|
{
|
||
|
|
$out = parent::__set($field, $value);
|
||
|
|
if (in_array($field, $this->modelFields)) {
|
||
|
|
$this->updatedValues[$field] = (\is_object($value) and
|
||
|
|
get_class($value) === QuestionType::class) ? $value->value : $value;
|
||
|
|
$this->setRawProperty($this, $field, $this->updatedValues[$field]);
|
||
|
|
}
|
||
|
|
return $out;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Fill data into this model
|
||
|
|
* using validation rules
|
||
|
|
*
|
||
|
|
* @param array $properties
|
||
|
|
* @return void
|
||
|
|
* @throws TypeError if any valid is not validated
|
||
|
|
*/
|
||
|
|
public function fill(array $properties)
|
||
|
|
{
|
||
|
|
if (isset($properties['type'])) {
|
||
|
|
try {
|
||
|
|
$properties['type'] = (\is_int($properties['type']) or \ctype_digit($properties['type'])) ?
|
||
|
|
QuestionType::make((int)$properties['type']) : $properties['type'];
|
||
|
|
} catch (TypeError $e) {
|
||
|
|
// cast anyway
|
||
|
|
$properties['type'] = (int)$properties['type'];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
parent::fill($properties);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Validate all model properties
|
||
|
|
*
|
||
|
|
* @return array the validated values
|
||
|
|
*/
|
||
|
|
protected function validateAllValues(array $ignore = []): array
|
||
|
|
{
|
||
|
|
$out = [];
|
||
|
|
if (!\in_array('type', $ignore)) {
|
||
|
|
try {
|
||
|
|
$this->validateValue('type', QuestionType::make(self::getRawProperty($this, 'type')));
|
||
|
|
} catch (TypeError $e) {
|
||
|
|
// this to throw validation error if failure way
|
||
|
|
$this->validateValue('type', self::getRawProperty($this, 'type'));
|
||
|
|
}
|
||
|
|
$out['type'] = self::getRawProperty($this, 'type');
|
||
|
|
}
|
||
|
|
return array_merge($out, parent::validateAllValues(array_merge(['type'], $ignore)));
|
||
|
|
}
|
||
|
|
|
||
|
|
// PUBLIC METHODS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all questions only
|
||
|
|
*
|
||
|
|
* @param string $hashcode
|
||
|
|
* @return array
|
||
|
|
*
|
||
|
|
* with \LDC\LDCCRM\Models\Question[]
|
||
|
|
*/
|
||
|
|
public static function all(): array
|
||
|
|
{
|
||
|
|
static::setUpApiInterface(); // set apiInterface
|
||
|
|
$request = Utils::getResquest('apiV2.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[]
|
||
|
|
*/
|
||
|
|
public static function allWithCustomerAnswers(Customer $customer): array
|
||
|
|
{
|
||
|
|
static::setUpApiInterface(); // set apiInterface
|
||
|
|
$request = Utils::getResquest('apiV2.questions.indexWithResponse', [
|
||
|
|
'customer' => $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 \LDC\LDCCRM\Models\Question[]
|
||
|
|
*/
|
||
|
|
public static function unansweredBy(Customer $customer): array
|
||
|
|
{
|
||
|
|
self::assertValidHascode($customer->hashcode);
|
||
|
|
static::setUpApiInterface(); // set apiInterface
|
||
|
|
$request = Utils::getResquest(
|
||
|
|
'apiV2.questions.unAnsweredBy',
|
||
|
|
['customer' => $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;
|
||
|
|
}
|
||
|
|
}
|