ApiOperationGenerator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 1
1
<?php
2
namespace keeko\tools\generator\api;
3
4
use gossi\swagger\collections\Paths;
5
use keeko\framework\utils\NameUtils;
6
use keeko\tools\generator\AbstractGenerator;
7
use keeko\tools\generator\Types;
8
use keeko\tools\services\CommandService;
9
use phootwork\lang\Text;
10
11
class ApiOperationGenerator extends AbstractGenerator {
12
13
	private $generators;
14
15
	public function __construct(CommandService $service) {
16
		parent::__construct($service);
17
18
		$this->generators = [
19
			Types::PAGINATE => new ApiPaginateOperationGenerator($service),
20
			Types::CREATE => new ApiCreateOperationGenerator($service),
21
			Types::READ => new ApiReadOperationGenerator($service),
22
			Types::UPDATE => new ApiUpdateOperationGenerator($service),
23
			Types::DELETE => new ApiDeleteOperationGenerator($service)
24
		];
25
	}
26
27
	public function generateOperation(Paths $paths, $actionName) {
28
		$this->logger->notice('Generating Operation for: ' . $actionName);
29
30
		if (Text::create($actionName)->contains('relationship')) {
31
			$this->generateRelationshipOperation($paths, $actionName);
32
		} else {
33
			$this->generateCRUDOperation($paths, $actionName);
34
		}
35
	}
36
37
	protected function generateCRUDOperation(Paths $paths, $actionName) {
38
		$this->logger->notice('Generating CRUD Operation for: ' . $actionName);
39
40
		$action = $this->packageService->getAction($actionName);
41
		$modelName = $this->modelService->getModelNameByAction($action);
0 ignored issues
show
Bug introduced by
It seems like $action defined by $this->packageService->getAction($actionName) on line 40 can be null; however, keeko\tools\services\Mod...:getModelNameByAction() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
42
		$type = $this->packageService->getActionType($actionName, $modelName);
43
44
		if (isset($this->generators[$type])) {
45
			$this->generators[$type]->generate($paths, $actionName);
46
		}
47
	}
48
49
	protected function generateRelationshipOperation(Paths $paths, $actionName) {
50
		$this->logger->notice('Generating Relationship Operation for: ' . $actionName);
51
		$parsed = $this->factory->getActionNameGenerator()->parseRelationship($actionName);
52
		$type = $parsed['type'];
53
		$modelName = $parsed['modelName'];
54
		$model = $this->modelService->getModel($modelName);
55
		$relatedTypeName = NameUtils::dasherize($parsed['relatedName']);
56
		$relationship = $this->modelService->getRelationship($model, $relatedTypeName);
57
58
		if ($relationship === null) {
59
			return;
60
		}
61
62
		// see if either one of them is excluded
63
		$relatedName = $relationship->getRelatedName();
64
		$foreignModelName = $relationship->getForeign()->getOriginCommonName();
65
		$excluded = $this->project->getGeneratorDefinition()->getExcludedApi();
66
		if ($excluded->contains($modelName) || $excluded->contains($foreignModelName)) {
67
			return;
68
		}
69
70
		// continue if neither model nor related model is excluded
71
		$action = $this->packageService->getAction($actionName);
72
		$method = $this->getMethod($type);
0 ignored issues
show
Unused Code introduced by
$method is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
73
		$endpoint = '/' . NameUtils::pluralize(NameUtils::dasherize($modelName)) . '/{id}/relationship/' .
74
			NameUtils::dasherize($relationship->isOneToOne()
75
				? $relatedTypeName
76
				: NameUtils::pluralize($relatedTypeName));
77
78
		$path = $paths->get($endpoint);
79
		$method = $this->getMethod($type);
80
		$operation = $path->getOperation($method);
81
		$operation->setDescription($action->getTitle());
82
		$operation->setOperationId($action->getName());
83
// 		$operation->getTags()->clear();
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
84
// 		$operation->getTags()->add(new Tag($this->package->getKeeko()->getModule()->getSlug()));
85
86
		$params = $operation->getParameters();
87
		$responses = $operation->getResponses();
88
89
		// general model related params
90
		// params
91
		$id = $params->getByName('id');
92
		$id->setIn('path');
93
		$id->setDescription(sprintf('The %s id', $modelName));
94
		$id->setRequired(true);
95
		$id->setType('integer');
96
97
		if ($type == Types::ADD || $type == Types::UPDATE) {
98
			$body = $params->getByName('body');
99
			$body->setName('body');
100
			$body->setIn('body');
101
			$body->setDescription(sprintf('%ss %s', ucfirst($type), $relatedName));
102
			$body->setRequired(true);
103
104
			$props = $body->getSchema()->setType('object')->getProperties();
105
			$data = $props->get('data');
106
107
			if ($relationship->isOneToOne()) {
108
				$data->setRef('#/definitions/ResourceIdentifier');
109
			} else {
110
				$data
111
				->setType('array')
112
				->getItems()->setRef('#/definitions/ResourceIdentifier');
113
			}
114
		}
115
116
		// response
117
		$ok = $responses->get('200');
118
		$ok->setDescription('Retrieve ' . $relatedName . ' from ' . $modelName);
119
		$props = $ok->getSchema()->setType('object')->getProperties();
120
		$links = $props->get('links')->setType('object')->getProperties();
121
		$links->get('self')->setType('string');
122
		if ($relationship->isOneToOne()) {
123
			$links->get('related')->setType('string');
124
		}
125
		$data = $props->get('data');
126
		if ($relationship->isOneToOne()) {
127
			$data->setType('object')->setRef('#/definitions/ResourceIdentifier');
128
		} else {
129
			$data
130
			->setType('array')
131
			->getItems()->setRef('#/definitions/ResourceIdentifier');
132
		}
133
134
		$invalid = $responses->get('400');
135
		$invalid->setDescription('Invalid ID supplied');
136
		$invalid->getSchema()->setRef('#/definitions/Errors');
137
138
		$notfound = $responses->get('404');
139
		$notfound->setDescription(sprintf('No %s found', $modelName));
140
		$notfound->getSchema()->setRef('#/definitions/Errors');
141
	}
142
143
	private function getMethod($type) {
144
		$methods = [
145
			Types::PAGINATE => 'get',
146
			Types::CREATE => 'post',
147
			Types::READ => 'get',
148
			Types::UPDATE => 'patch',
149
			Types::DELETE => 'delete',
150
			Types::ADD => 'post',
151
			Types::REMOVE => 'delete'
152
		];
153
154
		return $methods[$type];
155
	}
156
157
}