Last active
April 29, 2026 14:45
-
-
Save rudiedirkx/5f3fed826520414ad70586a7543d22a6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require __DIR__ . '/icares-env.php'; // GRAPHQL_ENDPOINT, GRAPHQL_TOKEN | |
| if (isset($_GET['type'], $_POST['q'])) { | |
| echo '<pre>'; | |
| print_r($_POST['q']); | |
| $answers = []; | |
| foreach ($_POST['q'] as $id => $value) { | |
| $answers[] = [ | |
| 'id' => $id, | |
| 'value' => is_array($value) ? implode('', $value) : $value, | |
| ]; | |
| } | |
| // print_r($answers); exit; | |
| echo "\n"; | |
| echo "Invite:\n"; | |
| $testType = $_GET['type']; | |
| var_dump($testType); | |
| [$data, $time] = graphql( | |
| <<<'GRAPHQL' | |
| mutation InviteTest($type: String!) { | |
| invite(test: $type, amount: 1, readable: true) { | |
| type { | |
| type | |
| } | |
| id | |
| } | |
| } | |
| GRAPHQL, | |
| [ | |
| 'type' => $testType . '_test', | |
| ], | |
| ); | |
| print_r($data); | |
| $userTestId = $data['data']['invite'][0]['id']; | |
| var_dump($userTestId); | |
| echo "\n"; | |
| echo "Submit answers:\n"; | |
| [$data, $time] = graphql( | |
| <<<'GRAPHQL' | |
| mutation SaveAnswers($id: Int!, $answers: [SubmitTestAnswerInput!]!) { | |
| submit_test(id: $id, answers: $answers) { | |
| type { | |
| type | |
| } | |
| started_at | |
| finished_at | |
| secret_url | |
| } | |
| } | |
| GRAPHQL, | |
| [ | |
| 'id' => $userTestId, | |
| 'answers' => $answers | |
| ], | |
| ); | |
| print_r($data); | |
| echo "\n"; | |
| echo "Result:\n"; | |
| if (in_array($testType, ['education_choice', 'study_swiper'])) { | |
| [$data, $time] = graphql( | |
| <<<GRAPHQL | |
| query { | |
| education_choice_test(id: $userTestId) { | |
| educations(level: 5, limit: 2) { | |
| total | |
| level { | |
| name | |
| } | |
| nodes { | |
| score | |
| education { | |
| name | |
| } | |
| } | |
| } | |
| } | |
| } | |
| GRAPHQL | |
| ); | |
| print_r($data); | |
| } | |
| elseif (in_array($testType, ['career_choice', 'skills'])) { | |
| [$data, $time] = graphql( | |
| <<<GRAPHQL | |
| query { | |
| career_choice_test(id: $userTestId) { | |
| professions(level: MIDDLE, limit: 2) { | |
| total | |
| country_region { | |
| name | |
| } | |
| nodes { | |
| score | |
| profession { | |
| name | |
| } | |
| } | |
| } | |
| } | |
| } | |
| GRAPHQL | |
| ); | |
| print_r($data); | |
| } | |
| elseif ($testType == 'enneagram') { | |
| [$data, $time] = graphql( | |
| <<<GRAPHQL | |
| query { | |
| enneagram_test(id: $userTestId) { | |
| personality_types { | |
| score | |
| category { | |
| number | |
| name | |
| } | |
| } | |
| professions(level: MIDDLE, limit: 2) { | |
| nodes { | |
| score | |
| profession { | |
| name | |
| } | |
| } | |
| } | |
| } | |
| } | |
| GRAPHQL | |
| ); | |
| print_r($data); | |
| } | |
| else { | |
| echo "!! No result API?\n"; | |
| } | |
| exit; | |
| } | |
| [$form0, $time] = graphql( | |
| <<<GRAPHQL | |
| query { | |
| career_choice_test_form { | |
| ...multiple_choices | |
| } | |
| education_choice_test_form { | |
| ...multiple_choices | |
| } | |
| capaz_study_test_form { | |
| __typename | |
| test_type { | |
| name | |
| } | |
| answers { | |
| __typename | |
| value | |
| answer | |
| } | |
| questions { | |
| __typename | |
| id | |
| question | |
| } | |
| } | |
| enneagram_test_form { | |
| __typename | |
| test_type { | |
| name | |
| } | |
| answers { | |
| __typename | |
| index | |
| answer | |
| } | |
| questions { | |
| __typename | |
| id | |
| options { | |
| __typename | |
| value | |
| label | |
| } | |
| } | |
| } | |
| cube8_blackboard_test_form { | |
| ...solo_cube8 | |
| } | |
| cube8_notice_board_test_form { | |
| ...solo_cube8 | |
| } | |
| cube8_photo_test_form { | |
| test_type { | |
| name | |
| } | |
| has_genders | |
| questions { | |
| id | |
| value | |
| question | |
| answers { | |
| value | |
| gender | |
| url | |
| title | |
| } | |
| } | |
| } | |
| skills_swiper_test_form { | |
| ...swipertest | |
| } | |
| study_swiper_test_form { | |
| ...swipertest | |
| } | |
| skills_test_form { | |
| test_type { | |
| name | |
| } | |
| answers { | |
| value | |
| answer | |
| } | |
| subcategories { | |
| machine_name | |
| name | |
| description | |
| group_answerable | |
| questions { | |
| id | |
| question | |
| definition | |
| description | |
| professions_table { | |
| text | |
| html | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment multiple_choices on MultipleStaticChoiceTestForm { | |
| __typename | |
| test_type { | |
| name | |
| } | |
| answers { | |
| __typename | |
| value | |
| answer | |
| } | |
| questions { | |
| __typename | |
| id | |
| question | |
| } | |
| } | |
| fragment solo_cube8 on Cube8OnlySortTestForm { | |
| test_type { | |
| type | |
| name | |
| } | |
| has_genders | |
| question { | |
| id | |
| question | |
| help | |
| } | |
| answers { | |
| gender | |
| value | |
| title | |
| description | |
| } | |
| } | |
| fragment swipertest on SwiperTestForm { | |
| test_type { | |
| type | |
| name | |
| } | |
| answers { | |
| value | |
| answer | |
| } | |
| questions { | |
| id | |
| image | |
| question | |
| help | |
| } | |
| } | |
| GRAPHQL | |
| ); | |
| $forms1 = [ | |
| 'career_choice' => $form0['data']['career_choice_test_form'], | |
| 'education_choice' => $form0['data']['education_choice_test_form'], | |
| ]; | |
| $form2 = $form0['data']['enneagram_test_form']; | |
| $form3 = $form0['data']['capaz_study_test_form']; | |
| $forms4 = [ | |
| 'cube8_blackboard' => $form0['data']['cube8_blackboard_test_form'], | |
| 'cube8_notice_board' => $form0['data']['cube8_notice_board_test_form'], | |
| ]; | |
| $form5 = $form0['data']['cube8_photo_test_form']; | |
| $forms6 = [ | |
| 'study_swiper' => $form0['data']['study_swiper_test_form'], | |
| 'skills_swiper' => $form0['data']['skills_swiper_test_form'], | |
| ]; | |
| $form7 = $form0['data']['skills_test_form']; | |
| ?> | |
| <title>Icares live testdata demo</title> | |
| <h1>Icares live testdata demo</h1> | |
| <? foreach ($forms1 as $type => $form): ?> | |
| <details> | |
| <summary><?= e($form['test_type']['name']) ?> - <?= count($form['questions']) ?> questions</summary> | |
| <form method="post" action="?type=<?= $type ?>"> | |
| <? foreach ($form['questions'] as $question): ?> | |
| <p><?= e($question['question']) ?></p> | |
| <p> | |
| <input type="range" name="q[<?= e($question['id']) ?>]" min="1" max="<?= count($form['answers']) ?>" value="1"> | |
| <span><?= e($form['answers'][0]['answer']) ?></span> | |
| </p> | |
| <? endforeach ?> | |
| <p><button>Submit data, get result</button></p> | |
| </form> | |
| </details> | |
| <script> | |
| window.addEventListener('load', function(e) { | |
| const labels = <?= json_encode(array_column($form['answers'], 'answer', 'value')) ?>; | |
| document.querySelectorAll('form[action*="<?= $type ?>"] input[type="range"]').forEach(el => el.addEventListener('input', function(e) { | |
| this.nextElementSibling.textContent = labels[this.value] || '?'; | |
| })); | |
| }); | |
| </script> | |
| <? endforeach ?> | |
| <details> | |
| <summary><?= e($form3['test_type']['name']) ?> - <?= count($form3['questions']) ?> questions</summary> | |
| <form method="post" action="?type=capaz_study"> | |
| <? foreach ($form3['questions'] as $question): ?> | |
| <p><?= e($question['question']) ?></p> | |
| <ul> | |
| <? foreach ($form3['answers'] as $answer): ?> | |
| <li> | |
| <label> | |
| <input type="radio" name="q[<?= e($question['id']) ?>]" value="<?= e($answer['value']) ?>"> | |
| <?= e($answer['answer']) ?> | |
| </label> | |
| </li> | |
| <? endforeach ?> | |
| </ul> | |
| <? endforeach ?> | |
| <p><button>Submit data, get result</button></p> | |
| </form> | |
| </details> | |
| <details> | |
| <summary><?= e($form2['test_type']['name']) ?> - <?= count($form2['questions']) ?> questions</summary> | |
| <form method="post" action="?type=enneagram"> | |
| <? $answers = array_column($form2['answers'], 'answer', 'index') ?> | |
| <? foreach ($form2['questions'] as $question): ?> | |
| <p>Sort from 'most like me' to 'least like me':</p> | |
| <ul> | |
| <? foreach (['123', '132', '213', '231', '312', '321'] as $order): ?> | |
| <? $options = array_map(fn($n) => $question['options'][$n-1], str_split($order)) ?> | |
| <li> | |
| <label> | |
| <input type="radio" name="q[<?= e($question['id']) ?>]" value="<?= e(strrev(implode('', array_column($options, 'value')))) ?>"> | |
| 👍 | |
| <?= e(implode(' > ', array_map(fn(array $option) => $option['label'] . ' (' . $option['value'] . ')', $options))) ?> | |
| 👎 | |
| </label> | |
| </li> | |
| <? endforeach ?> | |
| </ul> | |
| <? endforeach ?> | |
| <p><button>Submit data, get result</button></p> | |
| </form> | |
| </details> | |
| <? foreach ($forms4 as $type => $form): ?> | |
| <details> | |
| <? $gender = !$form['has_genders'] ? '' : (rand(0, 1) ? 'MALE' : 'FEMALE') ?> | |
| <summary><?= e($form['test_type']['name']) ?><?= $gender ? ' - ' . $gender : '' ?></summary> | |
| <p>Sort from 'like' (top) to 'not like' (bottom). Click to select a row, click again to move it there.</p> | |
| <form method="post" action="?type=<?= $type ?>"> | |
| <? $answers = array_filter($form['answers'], fn(array $answer) => !$answer['gender'] || $answer['gender'] == $gender) ?> | |
| <? $question = $form['question'] ?> | |
| <ol class="click-sort"> | |
| <? foreach ($answers as $answer): ?> | |
| <li> | |
| <input type="hidden" name="q[<?= e($question['id']) ?>][]" value="<?= e($answer['value']) ?>"> | |
| <b><?= e(str_replace("\n", ' / ', $answer['title'])) ?></b><br> | |
| <?= nl2br(e($answer['description'])) ?> | |
| </li> | |
| <? endforeach ?> | |
| </ol> | |
| <p><button>Submit data, get result</button></p> | |
| </form> | |
| </details> | |
| <? endforeach ?> | |
| <style> | |
| li.sorting { | |
| background-color: yellow; | |
| } | |
| </style> | |
| <script> | |
| window.addEventListener('load', () => document.querySelectorAll('.click-sort > li').forEach(el => el.addEventListener('click', function(e) { | |
| const ol = this.parentNode; | |
| const source = ol.querySelector('.sorting'); | |
| if (source) { | |
| ol.insertBefore(source, this); | |
| setTimeout(() => source.classList.remove('sorting'), 500); | |
| } | |
| else { | |
| this.classList.add('sorting'); | |
| } | |
| }))); | |
| </script> | |
| <details> | |
| <? $gender = rand(0, 1) ? 'MALE' : 'FEMALE' ?> | |
| <summary><?= e($form5['test_type']['name']) ?> - <?= strtoupper($gender) ?></summary> | |
| <form method="post" action="?type=cube8_photo"> | |
| <? foreach ($form5['questions'] as $question): ?> | |
| <? if ($question['value']): ?> | |
| <p>Which image looks most interesting? (See tooltips)</p> | |
| <p data-copy-photo-from="<?= e($question['value']) ?>"> | |
| <? foreach ($question['answers'] as $answer): | |
| if ($answer['gender'] != $gender) continue; | |
| ?> | |
| <label> | |
| <input type="radio" name="q[<?= e($question['id']) ?>]" value="<?= e($answer['value']) ?>" style="visibility: hidden"> | |
| <img src="<?= e($answer['url']) ?>" width="200" title="<?= e($answer['title']) ?>"> | |
| </label> | |
| <? endforeach ?> | |
| </p> | |
| <? else: ?> | |
| <p>Sort your images from interesting (first) to boring (last). Click to select a row, click again to move it there.</p> | |
| <ol class="click-sort"> | |
| <? foreach (array_filter($form5['questions'], fn($q) => $q['value']) as $q): ?> | |
| <li> | |
| <input type="hidden" name="q[<?= e($question['id']) ?>][]" value="<?= e($q['value']) ?>"> | |
| <img src="" width="200" data-copy-photo-to="<?= e($q['value']) ?>"> | |
| </li> | |
| <? endforeach ?> | |
| </ol> | |
| <? endif ?> | |
| <? endforeach ?> | |
| <p><button>Submit data, get result</button></p> | |
| </form> | |
| </details> | |
| <style> | |
| input:checked + img { | |
| outline: solid 10px lime; | |
| } | |
| img[src=""] { | |
| display: none; | |
| } | |
| </style> | |
| <script> | |
| window.addEventListener('load', () => document.querySelectorAll('[data-copy-photo-from]').forEach(el => el.addEventListener('change', function(e) { | |
| const value = this.dataset.copyPhotoFrom; | |
| // console.log(value); | |
| const img = e.target.nextElementSibling; | |
| const src = img.src; | |
| const title = img.title; | |
| // console.log(src); | |
| const to = document.querySelector(`img[data-copy-photo-to="${value}"]`); | |
| // console.log(to); | |
| to.src = src; | |
| to.title = title; | |
| }))); | |
| </script> | |
| <? foreach ($forms6 as $type => $form): ?> | |
| <details> | |
| <summary><?= e($form['test_type']['name']) ?> - <?= count($form['questions']) ?> questions</summary> | |
| <!-- <p>Sort from 'like' (top) to 'not like' (bottom). Click to select a row, click again to move it there.</p> --> | |
| <form method="post" action="?type=<?= $type ?>" class="swiper"> | |
| <? foreach ($form['questions'] as $question): ?> | |
| <div class="question"> | |
| <div><img src="<?= e($question['image']) ?>" style="width: 200px; height: 200px" /></div> | |
| <div class="answers"> | |
| <? foreach ($form['answers'] as $answer): ?> | |
| <label> | |
| <input type="radio" name="q[<?= e($question['id']) ?>]" value="<?= e($answer['value']) ?>" /> | |
| <?= e($answer['answer']) ?> | |
| </label> | |
| <? endforeach ?> | |
| </div> | |
| </div> | |
| <? endforeach ?> | |
| <div class="answered-all" style="margin: 1rem 0; text-align: center; font-weight: bold; font-size: 20px">You swiped all! You're done. Now submit.</div> | |
| <p><button>Submit data, get result</button></p> | |
| </form> | |
| </details> | |
| <? endforeach ?> | |
| <style> | |
| form.swiper .question { | |
| display: none; | |
| text-align: center; | |
| } | |
| form.swiper:not(:has(input:checked)) > .question:first-child, | |
| form.swiper > .question:has(input:checked) + .question:not(:has(input:checked)) { | |
| display: block; | |
| } | |
| form.swiper .question:not(:has(input:checked)) ~ .answered-all { | |
| display: none; | |
| } | |
| form.swiper .answers { | |
| margin-top: 1rem; | |
| zoom: 1.5; | |
| } | |
| </style> | |
| <details> | |
| <summary><?= e($form7['test_type']['name']) ?> - <?= array_sum(array_map(fn($cat) => count($cat['questions']), $form7['subcategories'])) ?> questions in <?= count($form7['subcategories']) ?> categories</summary> | |
| <form method="post" action="?type=skills"> | |
| <? $answers = array_column($form7['answers'], 'answer', 'value') ?> | |
| <? $answersOptions = implode('', array_map(fn($answer) => sprintf('<option value="%d">%s</option>', $answer['value'], e($answer['answer'])), $form7['answers'])) ?> | |
| <? foreach ($form7['subcategories'] as $cat): ?> | |
| <p> | |
| <?= e($cat['name']) ?> | |
| <? if ($cat['group_answerable']): ?> | |
| <select data-group-answer="<?= e($cat['machine_name']) ?>"> | |
| <option value="">-- group answer</option> | |
| <?= $answersOptions ?> | |
| </select> | |
| <? endif ?> | |
| </p> | |
| <ul class="skills-cat-<?= e($cat['machine_name']) ?>"> | |
| <? foreach ($cat['questions'] as $question): ?> | |
| <li> | |
| <?= e($question['question']) ?> | |
| | |
| <select name="q[<?= e($question['id']) ?>]" required> | |
| <option value="">-- specific answer</option> | |
| <?= $answersOptions ?> | |
| </select> | |
| </li> | |
| <? endforeach ?> | |
| </ul> | |
| <? endforeach ?> | |
| <p><button>Submit data, get result</button></p> | |
| </form> | |
| </details> | |
| <script> | |
| window.addEventListener('load', () => document.querySelectorAll('select[data-group-answer]').forEach(el => el.addEventListener('change', function(e) { | |
| const cat = this.dataset.groupAnswer; | |
| const answer = this.value; | |
| document.querySelectorAll(`ul.skills-cat-${cat} select`).forEach(el => el.value = answer); | |
| }))); | |
| </script> | |
| <br> | |
| <details> | |
| <summary>Forms API response (<?= round($time, 1) ?> ms)</summary> | |
| <pre><?= e(json_encode($form0, JSON_PRETTY_PRINT)) ?></pre> | |
| </details> | |
| <?php | |
| function e(?string $text) { | |
| return htmlspecialchars($text ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); | |
| } | |
| function graphql(string $query, array $variables = []) : array { | |
| $t = hrtime(true); | |
| $ch = curl_init(GRAPHQL_ENDPOINT); | |
| curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
| curl_setopt($ch, CURLOPT_POST, true); | |
| curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ | |
| 'query' => $query, | |
| 'variables' => (object) $variables, | |
| ])); | |
| curl_setopt($ch, CURLOPT_HTTPHEADER, [ | |
| 'Content-Type: application/json', | |
| 'Accept: application/json', | |
| 'Authorization: Bearer ' . GRAPHQL_TOKEN, | |
| ]); | |
| $json = curl_exec($ch); | |
| if (curl_errno($ch)) { | |
| throw new RuntimeException('HTTP ERROR:' . curl_error($ch)); | |
| } | |
| curl_close($ch); | |
| $t = (hrtime(true) - $t) / 1e6; | |
| $data = json_decode($json, true); | |
| if (isset($data['errors'][0]['message'])) { | |
| echo '<pre>'; | |
| print_r($data); | |
| throw new RuntimeException('GRAPHQL ERROR: ' . $data['errors'][0]['message']); | |
| } | |
| if (empty($data['data'])) { | |
| throw new RuntimeException('JSON ERROR:' . $json); | |
| } | |
| return [$data, $t]; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment