-
Notifications
You must be signed in to change notification settings - Fork 0
/
GraphModelType.php
112 lines (87 loc) · 3.73 KB
/
GraphModelType.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
namespace app\helpers;
/**
* Class GraphModelType is the base class for all GraphQL models
* @package app\helpers
*/
abstract class GraphModelType {
// Flags
protected $isQuery = false;
protected $isMutation = false;
// Requested attributes for a new query
public $requestedAttributes = [];
/**
* Adds required attribute to request list
* @param $attributeName String Attribute name requested
* @param $attributeType String Attribute type requested
*/
public function requestAttribute($attributeName, $attributeType) {
// If is a query object add attribute request
if($this->isQuery) {
// Check if attribute is a custom type
if(GraphDatabaseAccessLayer::isGraphModelType($attributeType)) {
// Assign empty attribute to continue tree analyzing
if($this->$attributeName == null) {
// Create new custom empty model
$attributeModelName = GraphDatabaseAccessLayer::getModelsPath(true) . $attributeType;
$attributeModel = new $attributeModelName();
$attributeModel->isQuery = true;
$this->$attributeName = [$attributeModel];
// Attach child requested attributes to parent
$this->requestedAttributes[$attributeName] = [
'type' => $attributeType,
'value' => &$attributeModel->requestedAttributes,
];
}
} else {
// Otherwise just add it as simple parameter
$this->requestedAttributes[$attributeName] = [
'type' => $attributeType,
'value' => $attributeName,
];
}
}
}
/**
* Build formatted query ready to be submitted to endpoint
* @param $className String Name of type to fetch fields from
* @param $requestedAttributes array Requested attributes array
* @param $isRoot bool Define if this type is the root of the query. True only for first call of this method
* @return string Query string
*/
private static function buildQuery($className, $requestedAttributes, $isRoot = false) {
$query = '';
// Build requested attributes
foreach ($requestedAttributes as $key => $attribute) {
if(GraphDatabaseAccessLayer::isGraphModelType($attribute['type'])) {
$query .= self::buildQuery($key, $requestedAttributes[$key]['value']) . ',';
} else {
$query .= $key . ',';
}
}
// Encapsulate
$query = "$className{ $query }";
// Return extra parenthesis only if is root
return $isRoot ? "{ $query }" : $query;
}
/**
* @param $className String Name of type to fetch fields from
* @param $callback mixed Callback function to call to build result data
* @return mixed Result data
* @throws GraphDatabaseAccessLayerException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected static function executeQuery($className, $callback) {
// Create new empty entity for provided class and set it as query
$modelName = GraphDatabaseAccessLayer::getModelsPath(true) . $className;
$model = new $modelName();
$model->isQuery = true;
// First execute callback to discover which fields need to be fetched
$callback([$model]);
// Build and execute query
$query = self::buildQuery($className, $model->requestedAttributes, true);
$queryResult = GraphDatabaseAccessLayer::doQuery($query);
// Execute final callback
return $callback($queryResult);
}
}