Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
66.67% covered (warning)
66.67%
6 / 9
CRAP
82.05% covered (warning)
82.05%
64 / 78
Question
0.00% covered (danger)
0.00%
0 / 1
66.67% covered (warning)
66.67%
6 / 9
28.61
82.05% covered (warning)
82.05%
64 / 78
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 __get
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
7 / 7
 __set
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 5
 fill
0.00% covered (danger)
0.00%
0 / 1
6.40
77.78% covered (warning)
77.78%
7 / 9
 validateAllValues
0.00% covered (danger)
0.00%
0 / 1
12
0.00% covered (danger)
0.00%
0 / 7
 all
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
11 / 11
 allWithCustomerAnswers
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
19 / 19
 unansweredBy
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
13 / 13
 jsonSerialize
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
4 / 4
1<?php
2
3namespace LDC\LDCCRM\Models;
4
5use LDC\LDCCRM\Enums\QuestionType;
6use LDC\LDCCRM\Utils;
7use TypeError;
8
9/**
10 * This class represents a question
11 * It has some static methods to retrieve questions and answers
12 *
13 * @property string $id The question id
14 * @property string $question The actual question as a string
15 * @property \LDC\LDCCRM\Enums\QuestionType $type
16 * The question type to display,
17 * it also hints wether it can accept one or multiple responses,
18 * so only checkbox allows multiple responses
19 * @property \LDC\LDCCRM\Models\Answer[] $answers An array with answers
20 *
21 * @category Api Models
22 * @package LDCCrmClient
23 * @subpackage models
24 * @author Jérémy Munsch <jeremy.munsch@ldc.fr>
25 */
26class Question extends CrmClientModel
27{
28    /**
29     * The question id
30     *
31     * Required
32     * Field Type bigInt
33     *
34     * @var integer
35     */
36    private $id;
37
38    /**
39     * The actual question as a string
40     *
41     * Required
42     * Max length 255
43     * Field Type varchar
44     *
45     * @var string
46     */
47    private $question = null;
48
49    /**
50     * The question type
51     *
52     * Validate: in QuestionType::toValues()
53     *
54     * Required
55     * Field Type tinyInteger
56     *
57     * @var \LDC\LDCCRM\Enums\QuestionType
58     */
59    private $type = null;
60
61    /**
62     * The question answers
63     *
64     * \LDC\LDCCRM\Models\Answer
65     *
66     * @var array
67     */
68    private $answers = [];
69
70    /**
71     * The crm customer fields
72     *
73     * @var array
74     */
75    protected $modelFields = [
76        'id', 'question', 'type', 'answers'
77    ];
78
79    /**
80     * Validation rules
81     *
82     * @var array
83     */
84    protected static $validation = [
85        'id' => 'required|int',
86        'question' => 'required|string|max:255',
87        'type' => ['required'],
88        'answers' => 'required|array'
89    ];
90
91    /**
92     * Question
93     *
94     * @param array $properties
95     * @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
96     */
97    public function __construct(array $properties = [])
98    {
99        parent::__construct();
100        $this->fill($properties);
101        return $this;
102    }
103
104    /**
105     * General accessor
106     *
107     * @param string $field
108     * @return mixed
109     */
110    public function __get(string $field)
111    {
112        $props = \array_diff(
113            $this->modelFields,
114            $this->invisibleFields
115        );
116        if (in_array($field, $props)) {
117            if ($field === 'type' and !\is_object($this->{$field})) {
118                return QuestionType::make($this->{$field});
119            }
120        }
121        return parent::__get($field);
122    }
123
124    /**
125     * Set prop on the model.
126     *
127     * @param string $field
128     * @param mixed  $value
129     * @return void
130     * @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
131     * @throws \LDC\LDCCRM\Exceptions\AccessError If trying to set a value on a unknown property.
132     */
133    public function __set(string $field, $value): void
134    {
135        if ($field === 'type') {
136            $value = (\is_object($value) and
137                get_class($value) === QuestionType::class) ? $value->value : $value;
138        }
139        parent::__set($field, $value);
140    }
141
142    /**
143     * Fill values into model using validation rules.
144     *
145     * @param array $properties
146     * @return void
147     * @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
148     */
149    public function fill(array $properties)
150    {
151        if (isset($properties['type'])) {
152            try {
153                $properties['type'] = (\is_object($properties['type']) and
154                    get_class($properties['type']) === QuestionType::class) ?
155                    $properties['type']->value : (ctype_digit($properties['type']) ?
156                        (int)$properties['type'] : $properties['type']);
157            } catch (TypeError | \BadMethodCallException $e) {
158                // * Cast anyway
159                $properties['type'] = (int)$properties['type'];
160            }
161        }
162        parent::fill($properties);
163    }
164
165    /**
166     * Validate all model properties
167     *
168     * @param array $ignore
169     * @return array the validated values
170     * @throws \LDC\LDCCRM\Exceptions\ValidationException If a field could not be validated.
171     */
172    protected function validateAllValues(array $ignore = []): array
173    {
174        $out = [];
175        if (!\in_array('type', $ignore)) {
176            try {
177                $this->validateValue('type', QuestionType::make(Utils::getRawProperty($this, 'type')));
178            } catch (TypeError | \BadMethodCallException $e) {
179                // Use this to throw validation error.
180                $this->validateValue('type', Utils::getRawProperty($this, 'type'));
181            }
182            $out['type'] = Utils::getRawProperty($this, 'type');
183        }
184        return array_merge($out, parent::validateAllValues(array_merge(['type'], $ignore)));
185    }
186
187    // * PUBLIC METHODS
188
189    /**
190     * Get all questions only
191     *
192     * @return array of \LDC\LDCCRM\Models\Question
193     * @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
194     * @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
195     * @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
196     */
197    public static function all(): array
198    {
199        static::setUpApiInterface();
200        $request = Utils::getResquest('apiV2.questions.index');
201
202        $response = static::$apiInterface->call($request);
203        $out      = [];
204        foreach ($response->data as $question) {
205            $answers             = \array_map(function ($answer) {
206                return new Answer($answer);
207            }, $question['answers']);
208            $question['answers'] = $answers;
209            $out[]               = new self($question);
210        }
211        return $out;
212    }
213
214    /**
215     * Get all the questions with customer answers
216     *
217     * @param \LDC\LDCCRM\Models\Customer $customer
218     * @return array
219     *
220     *   [
221     *        0 => [
222     *             'question' => \LDC\LDCCRM\Models\Question,
223     *             'customerAnswers' => \LDC\LDCCRM\Models\Answer[]
224     *        ]
225     *   ]
226     *
227     * with \LDC\LDCCRM\Models\Question[]
228     * and the customer \LDC\LDCCRM\Models\Answer[]
229     * @throws \LDC\LDCCRM\Exceptions\ValidationException If a customer's hashcode could not be validated.
230     * @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
231     * @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
232     * Possibles are : - modelNotFound, If the customer could not be found(CRM side).
233     * @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
234     */
235    public static function allWithCustomerAnswers(Customer $customer): array
236    {
237        self::assertValidHascode($customer->hashcode);
238        static::setUpApiInterface();
239        $request = Utils::getResquest('apiV2.questions.indexWithResponse', [
240            'serviceCustomer' => $customer->hashcode
241        ]);
242
243        $response = static::$apiInterface->call($request);
244        $out      = [];
245        foreach ($response->data as $question) {
246            $answers         = \array_map(function ($answer) {
247                return new Answer($answer);
248            }, $question['answers']);
249            $customerAnswers = \array_map(function ($answer) {
250                return new Answer($answer);
251            }, $question['customerAnswers']);
252            unset($question['customerAnswers']);
253            $question['answers'] = $answers;
254            $out[]               = [
255                'question' => new self($question),
256                'customerAnswers' => $customerAnswers,
257            ];
258        }
259        return $out;
260    }
261
262    /**
263     * Get unanswered question for a specific customer
264     *
265     * @param \LDC\LDCCRM\Models\Customer $customer
266     * @return array of \LDC\LDCCRM\Models\Question
267     * @throws \LDC\LDCCRM\Exceptions\ValidationException If a customer's hashcode could not be validated.
268     * @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
269     * @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
270     * Possibles are : - modelNotFound, If the customer could not be found(CRM side).
271     * @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
272     */
273    public static function unansweredBy(Customer $customer): array
274    {
275        self::assertValidHascode($customer->hashcode);
276        static::setUpApiInterface();
277        $request = Utils::getResquest(
278            'apiV2.questions.unAnsweredBy',
279            ['serviceCustomer' => $customer->hashcode]
280        );
281
282        $response = static::$apiInterface->call($request);
283        $out      = [];
284        foreach ($response->data as $question) {
285            $answers             = \array_map(function ($answer) {
286                return new Answer($answer);
287            }, $question['answers']);
288            $question['answers'] = $answers;
289            $out[]               = new self($question);
290        }
291        return $out;
292    }
293
294    /**
295     * Serialize this object to an array
296     *
297     * @return array
298     */
299    public function jsonSerialize()
300    {
301        return [
302            'id' => $this->id,
303            'question' => $this->question,
304            'type' => $this->type,
305            'answers' => $this->answers
306        ];
307    }
308}