• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 10019212347

20 Jul 2024 09:27AM UTC coverage: 64.189% (-0.04%) from 64.225%
10019212347

push

github

soyuka
tests: remove output suffix after reverting

11531 of 17964 relevant lines covered (64.19%)

68.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.23
/src/Metadata/ApiProperty.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\Metadata;
15

16
use Symfony\Component\PropertyInfo\Type;
17

18
/**
19
 * ApiProperty annotation.
20
 *
21
 * @author Kévin Dunglas <dunglas@gmail.com>
22
 */
23
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER | \Attribute::TARGET_CLASS_CONSTANT)]
24
final class ApiProperty
25
{
26
    /**
27
     * @param bool|null               $readableLink            https://api-platform.com/docs/core/serialization/#force-iri-with-relations-of-the-same-type-parentchilds-relations
28
     * @param bool|null               $writableLink            https://api-platform.com/docs/core/serialization/#force-iri-with-relations-of-the-same-type-parentchilds-relations
29
     * @param bool|null               $required                https://api-platform.com/docs/admin/validation/#client-side-validation
30
     * @param bool|null               $identifier              https://api-platform.com/docs/core/identifiers/
31
     * @param mixed                   $example                 https://api-platform.com/docs/core/openapi/#using-the-openapi-and-swagger-contexts
32
     * @param string|null             $deprecationReason       https://api-platform.com/docs/core/deprecations/#deprecating-resource-classes-operations-and-properties
33
     * @param bool|null               $fetchEager              https://api-platform.com/docs/core/performance/#eager-loading
34
     * @param array|null              $jsonldContext           https://api-platform.com/docs/core/extending-jsonld-context/#extending-json-ld-and-hydra-contexts
35
     * @param array|null              $openapiContext          https://api-platform.com/docs/core/openapi/#using-the-openapi-and-swagger-contexts
36
     * @param bool|null               $push                    https://api-platform.com/docs/core/push-relations/
37
     * @param string|\Stringable|null $security                https://api-platform.com/docs/core/security
38
     * @param string|\Stringable|null $securityPostDenormalize https://api-platform.com/docs/core/security/#executing-access-control-rules-after-denormalization
39
     * @param string[]                $types                   the RDF types of this property
40
     * @param string[]                $iris
41
     * @param Type[]                  $builtinTypes
42
     * @param string|null             $uriTemplate             (experimental) whether to return the subRessource collection IRI instead of an iterable of IRI
43
     */
44
    public function __construct(
45
        private ?string $description = null,
46
        private ?bool $readable = null,
47
        private ?bool $writable = null,
48
        private ?bool $readableLink = null,
49
        private ?bool $writableLink = null,
50
        private ?bool $required = null,
51
        private ?bool $identifier = null,
52
        private mixed $default = null,
53
        private mixed $example = null,
54
        /**
55
         * The `deprecationReason` option deprecates the current operation with a deprecation message.
56
         *
57
         * <div data-code-selector>
58
         *
59
         * ```php
60
         * <?php
61
         * // api/src/Entity/Review.php
62
         * use ApiPlatform\Metadata\ApiProperty;
63
         * use ApiPlatform\Metadata\ApiResource;
64
         *
65
         * #[ApiResource]
66
         * class Review
67
         * {
68
         *     #[ApiProperty(deprecationReason: "Use the rating property instead")]
69
         *     public string $letter;
70
         * }
71
         * ```
72
         *
73
         * ```yaml
74
         * # api/config/api_platform/properties.yaml
75
         * properties:
76
         *     App\Entity\Review:
77
         *         letter:
78
         *             deprecationReason: 'Create a Book instead'
79
         * ```
80
         *
81
         * ```xml
82
         * <?xml version="1.0" encoding="UTF-8" ?>
83
         * <!-- api/config/api_platform/properties.xml -->
84
         *
85
         * <properties
86
         *         xmlns="https://api-platform.com/schema/metadata/properties-3.0"
87
         *         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
88
         *         xsi:schemaLocation="https://api-platform.com/schema/metadata/properties-3.0
89
         *         https://api-platform.com/schema/metadata/properties-3.0.xsd">
90
         *     <property resource="App\Entity\Review" name="letter" deprecationReason="Create a Book instead" />
91
         * </properties>
92
         * ```
93
         *
94
         * </div>
95
         *
96
         * - With JSON-lD / Hydra, [an `owl:deprecated` annotation property](https://www.w3.org/TR/owl2-syntax/#Annotation_Properties) will be added to the appropriate data structure
97
         * - With Swagger / OpenAPI, [a `deprecated` property](https://swagger.io/docs/specification/2-0/paths-and-operations/) will be added
98
         * - With GraphQL, the [`isDeprecated` and `deprecationReason` properties](https://facebook.github.io/graphql/June2018/#sec-Deprecation) will be added to the schema
99
         */
100
        private ?string $deprecationReason = null,
101
        private ?bool $fetchable = null,
102
        private ?bool $fetchEager = null,
103
        private ?array $jsonldContext = null,
104
        private ?array $openapiContext = null,
105
        private ?array $jsonSchemaContext = null,
106
        private ?bool $push = null,
107
        /**
108
         * The `security` option defines the access to the current property, on normalization process, based on Symfony Security.
109
         * It receives an `object` variable related to the current object, and a `property` variable related to the current property.
110
         *
111
         * <div data-code-selector>
112
         *
113
         * ```php
114
         * <?php
115
         * // api/src/Entity/Review.php
116
         * use ApiPlatform\Metadata\ApiProperty;
117
         * use ApiPlatform\Metadata\ApiResource;
118
         *
119
         * #[ApiResource]
120
         * class Review
121
         * {
122
         *     #[ApiProperty(security: 'is_granted("ROLE_ADMIN")')]
123
         *     public string $letter;
124
         * }
125
         * ```
126
         *
127
         * ```yaml
128
         * # api/config/api_platform/properties.yaml
129
         * properties:
130
         *     App\Entity\Review:
131
         *         letter:
132
         *             security: 'is_granted("ROLE_ADMIN")'
133
         * ```
134
         *
135
         * ```xml
136
         * <?xml version="1.0" encoding="UTF-8" ?>
137
         * <!-- api/config/api_platform/properties.xml -->
138
         *
139
         * <properties
140
         *         xmlns="https://api-platform.com/schema/metadata/properties-3.0"
141
         *         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
142
         *         xsi:schemaLocation="https://api-platform.com/schema/metadata/properties-3.0
143
         *         https://api-platform.com/schema/metadata/properties-3.0.xsd">
144
         *     <property resource="App\Entity\Review" name="letter" security="is_granted('ROLE_ADMIN')" />
145
         * </properties>
146
         * ```
147
         *
148
         * </div>
149
         */
150
        private string|\Stringable|null $security = null,
151
        /**
152
         * The `securityPostDenormalize` option defines access to the current property after the denormalization process, based on Symfony Security.
153
         * It receives an `object` variable related to the current object, and a `property` variable related to the current property.
154
         *
155
         * <div data-code-selector>
156
         *
157
         * ```php
158
         * <?php
159
         * // api/src/Entity/Review.php
160
         * use ApiPlatform\Metadata\ApiProperty;
161
         * use ApiPlatform\Metadata\ApiResource;
162
         *
163
         * #[ApiResource]
164
         * class Review
165
         * {
166
         *     #[ApiProperty(securityPostDenormalize: 'is_granted("ROLE_ADMIN")')]
167
         *     public string $letter;
168
         * }
169
         * ```
170
         *
171
         * ```yaml
172
         * # api/config/api_platform/properties.yaml
173
         * properties:
174
         *     App\Entity\Review:
175
         *         letter:
176
         *             securityPostDenormalize: 'is_granted("ROLE_ADMIN")'
177
         * ```
178
         *
179
         * ```xml
180
         * <?xml version="1.0" encoding="UTF-8" ?>
181
         * <!-- api/config/api_platform/properties.xml -->
182
         *
183
         * <properties
184
         *         xmlns="https://api-platform.com/schema/metadata/properties-3.0"
185
         *         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
186
         *         xsi:schemaLocation="https://api-platform.com/schema/metadata/properties-3.0
187
         *         https://api-platform.com/schema/metadata/properties-3.0.xsd">
188
         *     <property resource="App\Entity\Review" name="letter" securityPostDenormalize="is_granted('ROLE_ADMIN')" />
189
         * </properties>
190
         * ```
191
         *
192
         * </div>
193
         */
194
        private string|\Stringable|null $securityPostDenormalize = null,
195
        private array|string|null $types = null,
196
        /*
197
         * The related php types.
198
         */
199
        private ?array $builtinTypes = null,
200
        private ?array $schema = null,
201
        private ?bool $initializable = null,
202
        private $iris = null,
203
        private ?bool $genId = null,
204
        private ?string $uriTemplate = null,
205
        private array $extraProperties = [],
206
    ) {
207
        if (\is_string($types)) {
383✔
208
            $this->types = (array) $types;
×
209
        }
210
    }
211

212
    public function getDescription(): ?string
213
    {
214
        return $this->description;
159✔
215
    }
216

217
    public function withDescription(string $description): self
218
    {
219
        $self = clone $this;
111✔
220
        $self->description = $description;
111✔
221

222
        return $self;
111✔
223
    }
224

225
    public function isReadable(): ?bool
226
    {
227
        return $this->readable;
499✔
228
    }
229

230
    public function withReadable(bool $readable): self
231
    {
232
        $self = clone $this;
251✔
233
        $self->readable = $readable;
251✔
234

235
        return $self;
251✔
236
    }
237

238
    public function isWritable(): ?bool
239
    {
240
        return $this->writable;
207✔
241
    }
242

243
    public function withWritable(bool $writable): self
244
    {
245
        $self = clone $this;
231✔
246
        $self->writable = $writable;
231✔
247

248
        return $self;
231✔
249
    }
250

251
    public function isReadableLink(): ?bool
252
    {
253
        return $this->readableLink;
291✔
254
    }
255

256
    public function withReadableLink(bool $readableLink): self
257
    {
258
        $self = clone $this;
104✔
259
        $self->readableLink = $readableLink;
104✔
260

261
        return $self;
104✔
262
    }
263

264
    public function isWritableLink(): ?bool
265
    {
266
        return $this->writableLink;
32✔
267
    }
268

269
    public function withWritableLink(bool $writableLink): self
270
    {
271
        $self = clone $this;
100✔
272
        $self->writableLink = $writableLink;
100✔
273

274
        return $self;
100✔
275
    }
276

277
    public function isRequired(): ?bool
278
    {
279
        return $this->required;
451✔
280
    }
281

282
    public function withRequired(bool $required): self
283
    {
284
        $self = clone $this;
315✔
285
        $self->required = $required;
315✔
286

287
        return $self;
315✔
288
    }
289

290
    public function isIdentifier(): ?bool
291
    {
292
        return $this->identifier;
179✔
293
    }
294

295
    public function withIdentifier(bool $identifier): self
296
    {
297
        $self = clone $this;
75✔
298
        $self->identifier = $identifier;
75✔
299

300
        return $self;
75✔
301
    }
302

303
    public function getDefault()
304
    {
305
        return $this->default;
131✔
306
    }
307

308
    public function withDefault($default): self
309
    {
310
        $self = clone $this;
83✔
311
        $self->default = $default;
83✔
312

313
        return $self;
83✔
314
    }
315

316
    public function getExample(): mixed
317
    {
318
        return $this->example;
131✔
319
    }
320

321
    public function withExample(mixed $example): self
322
    {
323
        $self = clone $this;
8✔
324
        $self->example = $example;
8✔
325

326
        return $self;
8✔
327
    }
328

329
    public function getDeprecationReason(): ?string
330
    {
331
        return $this->deprecationReason;
159✔
332
    }
333

334
    public function withDeprecationReason($deprecationReason): self
335
    {
336
        $self = clone $this;
8✔
337
        $self->deprecationReason = $deprecationReason;
8✔
338

339
        return $self;
8✔
340
    }
341

342
    public function isFetchable(): ?bool
343
    {
344
        return $this->fetchable;
20✔
345
    }
346

347
    public function withFetchable($fetchable): self
348
    {
349
        $self = clone $this;
×
350
        $self->fetchable = $fetchable;
×
351

352
        return $self;
×
353
    }
354

355
    public function getFetchEager(): ?bool
356
    {
357
        return $this->fetchEager;
36✔
358
    }
359

360
    public function withFetchEager($fetchEager): self
361
    {
362
        $self = clone $this;
8✔
363
        $self->fetchEager = $fetchEager;
8✔
364

365
        return $self;
8✔
366
    }
367

368
    public function getJsonldContext(): ?array
369
    {
370
        return $this->jsonldContext;
76✔
371
    }
372

373
    public function withJsonldContext($jsonldContext): self
374
    {
375
        $self = clone $this;
28✔
376
        $self->jsonldContext = $jsonldContext;
28✔
377

378
        return $self;
28✔
379
    }
380

381
    public function getOpenapiContext(): ?array
382
    {
383
        return $this->openapiContext;
155✔
384
    }
385

386
    public function withOpenapiContext($openapiContext): self
387
    {
388
        $self = clone $this;
8✔
389
        $self->openapiContext = $openapiContext;
8✔
390

391
        return $self;
8✔
392
    }
393

394
    public function getJsonSchemaContext(): ?array
395
    {
396
        return $this->jsonSchemaContext;
160✔
397
    }
398

399
    public function withJsonSchemaContext($jsonSchemaContext): self
400
    {
401
        $self = clone $this;
8✔
402
        $self->jsonSchemaContext = $jsonSchemaContext;
8✔
403

404
        return $self;
8✔
405
    }
406

407
    public function getPush(): ?bool
408
    {
409
        return $this->push;
28✔
410
    }
411

412
    public function withPush($push): self
413
    {
414
        $self = clone $this;
12✔
415
        $self->push = $push;
12✔
416

417
        return $self;
12✔
418
    }
419

420
    public function getSecurity(): ?string
421
    {
422
        return $this->security instanceof \Stringable ? (string) $this->security : $this->security;
395✔
423
    }
424

425
    public function withSecurity($security): self
426
    {
427
        $self = clone $this;
8✔
428
        $self->security = $security;
8✔
429

430
        return $self;
8✔
431
    }
432

433
    public function getSecurityPostDenormalize(): ?string
434
    {
435
        return $this->securityPostDenormalize instanceof \Stringable ? (string) $this->securityPostDenormalize : $this->securityPostDenormalize;
36✔
436
    }
437

438
    public function withSecurityPostDenormalize($securityPostDenormalize): self
439
    {
440
        $self = clone $this;
8✔
441
        $self->securityPostDenormalize = $securityPostDenormalize;
8✔
442

443
        return $self;
8✔
444
    }
445

446
    public function getTypes(): ?array
447
    {
448
        return $this->types;
315✔
449
    }
450

451
    /**
452
     * @param string[]|string $types
453
     */
454
    public function withTypes(array|string $types = []): self
455
    {
456
        $self = clone $this;
36✔
457
        $self->types = (array) $types;
36✔
458

459
        return $self;
36✔
460
    }
461

462
    /**
463
     * @return Type[]
464
     */
465
    public function getBuiltinTypes(): ?array
466
    {
467
        return $this->builtinTypes;
787✔
468
    }
469

470
    /**
471
     * @param Type[] $builtinTypes
472
     */
473
    public function withBuiltinTypes(array $builtinTypes = []): self
474
    {
475
        $self = clone $this;
275✔
476
        $self->builtinTypes = $builtinTypes;
275✔
477

478
        return $self;
275✔
479
    }
480

481
    public function getSchema(): ?array
482
    {
483
        return $this->schema;
483✔
484
    }
485

486
    public function withSchema(array $schema = []): self
487
    {
488
        $self = clone $this;
283✔
489
        $self->schema = $schema;
283✔
490

491
        return $self;
283✔
492
    }
493

494
    public function withInitializable(?bool $initializable): self
495
    {
496
        $self = clone $this;
131✔
497
        $self->initializable = $initializable;
131✔
498

499
        return $self;
131✔
500
    }
501

502
    public function isInitializable(): ?bool
503
    {
504
        return $this->initializable;
147✔
505
    }
506

507
    public function getExtraProperties(): ?array
508
    {
509
        return $this->extraProperties;
603✔
510
    }
511

512
    public function withExtraProperties(array $extraProperties = []): self
513
    {
514
        $self = clone $this;
40✔
515
        $self->extraProperties = $extraProperties;
40✔
516

517
        return $self;
40✔
518
    }
519

520
    /**
521
     * Gets IRI of this property.
522
     */
523
    public function getIris()
524
    {
525
        return $this->iris;
76✔
526
    }
527

528
    /**
529
     * Returns a new instance with the given IRI.
530
     *
531
     * @param string|string[] $iris
532
     */
533
    public function withIris(string|array $iris): self
534
    {
535
        $metadata = clone $this;
16✔
536
        $metadata->iris = (array) $iris;
16✔
537

538
        return $metadata;
16✔
539
    }
540

541
    /**
542
     * Whether to generate a skolem iri on anonymous resources.
543
     */
544
    public function getGenId()
545
    {
546
        return $this->genId;
119✔
547
    }
548

549
    public function withGenId(bool $genId): self
550
    {
551
        $metadata = clone $this;
12✔
552
        $metadata->genId = $genId;
12✔
553

554
        return $metadata;
12✔
555
    }
556

557
    /**
558
     * Whether to return the subRessource collection IRI instead of an iterable of IRI.
559
     *
560
     * @experimental
561
     */
562
    public function getUriTemplate(): ?string
563
    {
564
        return $this->uriTemplate;
151✔
565
    }
566

567
    public function withUriTemplate(?string $uriTemplate): self
568
    {
569
        $metadata = clone $this;
8✔
570
        $metadata->uriTemplate = $uriTemplate;
8✔
571

572
        return $metadata;
8✔
573
    }
574
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc