Skip to content

Commit 3ce0d8b

Browse files
committed
added initial meta views
1 parent 834b01b commit 3ce0d8b

File tree

3 files changed

+271
-0
lines changed

3 files changed

+271
-0
lines changed

app/commands/MetaTester.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace App\Console;
4+
5+
use App\Helpers\Notifications\ReviewsEmailsSender;
6+
use App\Model\Repository\AssignmentSolutions;
7+
use App\Model\Entity\Group;
8+
use App\Model\Entity\User;
9+
use Symfony\Component\Console\Command\Command;
10+
use Symfony\Component\Console\Input\InputArgument;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
use DateTime;
14+
15+
///TODO: this command is debug only, delete it
16+
class MetaTester extends Command
17+
{
18+
protected static $defaultName = 'meta:test';
19+
20+
protected function configure()
21+
{
22+
$this->setName(self::$defaultName)->setDescription(
23+
'Test the meta views.'
24+
);
25+
}
26+
27+
protected function execute(InputInterface $input, OutputInterface $output)
28+
{
29+
$this->test("a");
30+
return Command::SUCCESS;
31+
}
32+
33+
function test(string $arg) {
34+
$view = new \App\Model\View\TestView();
35+
$view->endpoint([
36+
"id" => "0",
37+
"organizational" => false,
38+
], "0001", true);
39+
#$view->get_user_info(0);
40+
}
41+
}

app/config/config.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ services:
318318
- App\Console\AsyncJobsUpkeep(%async.upkeep%)
319319
- App\Console\GeneralStatsNotification
320320
- App\Console\ExportDatabase
321+
- App\Console\MetaTester
321322
- App\Console\GenerateSwagger
322323
- App\Console\SwaggerAnnotator
323324
- App\Console\CleanupLocalizedTexts

app/model/view/MetaView.php

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
<?php
2+
3+
namespace App\Model\View;
4+
use \App\Console\AnnotationHelper;
5+
6+
7+
// parent class of all meta classes
8+
9+
class MetaView {
10+
function generator($data, string $output_format) {
11+
$backtrace = debug_backtrace()[1];
12+
$class = $backtrace['class'];
13+
$method = $backtrace['function'];
14+
$args = $backtrace['args'];
15+
16+
$formats = AnnotationHelper::extractClassFormats($class);
17+
var_dump($formats);
18+
}
19+
20+
function conforms_to_format($format, $value) {
21+
///TODO
22+
return false;
23+
}
24+
25+
function validate_args_old() {
26+
$backtrace = debug_backtrace()[1];
27+
$className = $backtrace['class'];
28+
$methodName = $backtrace['function'];
29+
$params_to_values = $this->get_param_names_to_values_map($backtrace);
30+
$params_to_format = AnnotationHelper::extractMethodCheckedParams($className, $methodName);
31+
32+
foreach ($params_to_values as $param=>$value) {
33+
$format = $params_to_format[$param];
34+
if (!$this->conforms_to_format($format, $value)) {
35+
///TODO: debug only
36+
echo "Invalid param <$className:$methodName:$param> value <$value>, given format <$format> \n";
37+
}
38+
}
39+
}
40+
41+
/// extracts function params and returns object representations of the formats
42+
function validate_args() {
43+
$backtrace = debug_backtrace()[1];
44+
$className = $backtrace['class'];
45+
$methodName = $backtrace['function'];
46+
$params_to_values = $this->get_param_names_to_values_map($backtrace);
47+
$params_to_format = AnnotationHelper::extractMethodCheckedParams($className, $methodName);
48+
49+
$a = new GroupFormat();
50+
AnnotationHelper::extractClassFormat(get_class($a));
51+
52+
foreach ($params_to_values as $param=>$value) {
53+
$format = $params_to_format[$param];
54+
if (!$this->conforms_to_format($format, $value)) {
55+
///TODO: debug only
56+
echo "Invalid param <$className:$methodName:$param> value <$value>, given format <$format> \n";
57+
}
58+
}
59+
}
60+
61+
function get_param_names_to_values_map($backtrace) {
62+
$className = $backtrace['class'];
63+
$args = $backtrace['args'];
64+
$methodName = $backtrace['function'];
65+
66+
$class = new \ReflectionClass($className);
67+
$method = $class->getMethod($methodName);
68+
$params = array_map(fn($param) => $param->name, $method->getParameters());
69+
70+
$argMap = [];
71+
for ($i = 0; $i < count($params); $i++) {
72+
$argMap[$params[$i]] = $args[$i];
73+
}
74+
return $argMap;
75+
}
76+
}
77+
78+
class GroupFormat {
79+
/**
80+
* @format uuid
81+
*/
82+
public string $id;
83+
/**
84+
* @format uuid
85+
*/
86+
public string $externalId;
87+
/**
88+
* @format bool
89+
* ///REDUNDANT
90+
*/
91+
public bool $organizational;
92+
/**
93+
* @format bool
94+
*/
95+
public bool $exam;
96+
/**
97+
* @format bool
98+
*/
99+
public bool $archived;
100+
/**
101+
* @format bool
102+
*/
103+
public bool $public;
104+
/**
105+
* @format bool
106+
*/
107+
public bool $directlyArchived;
108+
/**
109+
* @format localizedText[]
110+
*/
111+
public array $localizedTexts;
112+
/**
113+
* @format uuid[]
114+
*/
115+
public array $primaryAdminsIds;
116+
/**
117+
* @format uuid?
118+
*/
119+
public string $parentGroupId;
120+
/**
121+
* @format uuid[]
122+
*/
123+
public array $parentGroupsIds;
124+
/**
125+
* @format uuid[]
126+
*/
127+
public array $childGroups;
128+
/**
129+
* @format groupPrivateData
130+
*/
131+
public $privateData;
132+
/**
133+
* @format acl[]
134+
*/
135+
public array $permissionHints;
136+
}
137+
138+
class TestView extends MetaView {
139+
//function endpoint() { generator(["user_info" /* this would generate the whole user_info object */, "messages":{"name", "message"} /* cherry picking */]) }
140+
141+
142+
/// should formats be defined in comments, or in classes?
143+
/// classes: enables autocomplete, enforces structure, creates a ton of data classes, classes are needed for all nested objects
144+
/// comments: no class cluttering, less verbose, no autocomplete, does not enforce structure -> views are created as dictionaries
145+
/**
146+
* @format_def group {
147+
* "id":"format:uuid",
148+
* "externalId":"format:uuid",
149+
* "organizational":"format:bool",
150+
* "exam":"format:bool",
151+
* "archived":"format:bool",
152+
* "public":"format:bool",
153+
* "directlyArchived":"format:bool",
154+
* "localizedTexts":"format:localizedText[]",
155+
* "primaryAdminsIds":"format:uuid[]",
156+
* "parentGroupId":"format:uuid?",
157+
* "parentGroupsIds":"format:uuid[]",
158+
* "childGroups":"format:uuid[]",
159+
* "privateData":"format:groupPrivateData",
160+
* "permissionHints":"format:acl[]"
161+
* }
162+
*/
163+
private $placeholder;
164+
165+
// here the generator takes an input argument that conforms to format:user_info, therefore the generator can extract named parameters out
166+
// of it and pass them to the database methods
167+
///TODO: check whether the parameters can support the below annotations with the current framework
168+
/**
169+
* Summary of endpoint
170+
* @format_def user_info { "name":"format:name", "points":"format:int", "comments":"format:string[]" }
171+
* @checked_param format:user_info user_info
172+
* @checked_param format:uuid user_id
173+
* @checked_param format:bool verbose
174+
*/
175+
private $old;
176+
177+
178+
179+
/**
180+
* @checked_param format:group group
181+
* @checked_param format:uuid user_id
182+
* @checked_param format:bool verbose
183+
*/
184+
function endpoint($group, $user_id, $verbose) {
185+
$this->validate_args();
186+
187+
/*$data = [
188+
"id" => $user_id,
189+
];
190+
$this->generator($data, output_format: "format:group");*/
191+
192+
193+
//$message = $this->get_last_message($user_id);
194+
//$this->generator(output_format: "format:messages[]:text");
195+
}
196+
197+
// the names of the format and the output do not have to be identical, the strings in the desired data format refer the output names
198+
/**
199+
* @input format:user_id user_id // the input has to be invoked with the user_id extracted from format:group
200+
* @format_def message { "id":"format:uuid", "name":"format:name", "text":"format:string", "date":"format:datetime" }
201+
* @generates format:message[] messages
202+
*/
203+
function get_messages($user_id) {
204+
$messages = [];
205+
for ($i = 0; $i < 5; $i++) {
206+
$messages[] = [
207+
"id" => $i,
208+
"name" => "John Doe",
209+
"message" => "hello $i",
210+
"date" => "todo",
211+
];
212+
}
213+
return $messages;
214+
}
215+
216+
function get_last_message($user_id) {
217+
return [
218+
"id" => 5,
219+
"name" => "John Doe",
220+
"message" => "hello 5",
221+
"date" => "todo",
222+
];
223+
}
224+
225+
///TODO: validators should not exist, validation should be automatic (or should they? what about specific domain rules)
226+
// validators should only return a bool and a descriptive error message; whether it is input or output validation should be handled elsewhere (should the output be validated?)
227+
// @format group { ... } // formats should be defined on validators so that they can be easily found, additionally the validators enforce their structure, so it is nice when they are next to each other
228+
function validate_group($group) { }
229+
}

0 commit comments

Comments
 (0)