Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
79.55% covered (warning)
79.55%
35 / 44
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
EditFormChangeOpDeserializer
79.55% covered (warning)
79.55%
35 / 44
66.67% covered (warning)
66.67%
2 / 3
13.23
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 setContext
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createEntityChangeOp
76.92% covered (warning)
76.92%
30 / 39
0.00% covered (danger)
0.00%
0 / 1
11.23
1<?php
2
3namespace Wikibase\Lexeme\Presentation\ChangeOp\Deserialization;
4
5use ValueValidators\ValueValidator;
6use Wikibase\Lexeme\DataAccess\ChangeOp\ChangeOpFormEdit;
7use Wikibase\Lexeme\DataAccess\ChangeOp\ChangeOpGrammaticalFeatures;
8use Wikibase\Lexeme\MediaWiki\Api\Error\InvalidFormClaims;
9use Wikibase\Lexeme\MediaWiki\Api\Error\InvalidItemId;
10use Wikibase\Lexeme\MediaWiki\Api\Error\JsonFieldHasWrongType;
11use Wikibase\Repo\ChangeOp\ChangeOp;
12use Wikibase\Repo\ChangeOp\ChangeOpDeserializer;
13use Wikibase\Repo\ChangeOp\Deserialization\ChangeOpDeserializationException;
14use Wikibase\Repo\ChangeOp\Deserialization\ClaimsChangeOpDeserializer;
15
16/**
17 * Deserialize a change request on a single form
18 *
19 * @license GPL-2.0-or-later
20 */
21class EditFormChangeOpDeserializer implements ChangeOpDeserializer {
22
23    private const PARAM_REPRESENTATIONS = 'representations';
24
25    private const PARAM_GRAMM_FEAT = 'grammaticalFeatures';
26
27    private const PARAM_STATEMENTS = 'claims';
28
29    /**
30     * @var RepresentationsChangeOpDeserializer
31     */
32    private $representationsChangeOpDeserializer;
33
34    /**
35     * @var ItemIdListDeserializer
36     */
37    private $itemIdListDeserializer;
38
39    /**
40     * @var ValidationContext
41     */
42    private $validationContext;
43
44    /**
45     * @var ClaimsChangeOpDeserializer
46     */
47    private $statementsChangeOpDeserializer;
48
49    /**
50     * @var ValueValidator
51     */
52    private $entityExistsValidator;
53
54    public function __construct(
55        RepresentationsChangeOpDeserializer $representationsChangeOpDeserializer,
56        ItemIdListDeserializer $itemIdListDeserializer,
57        ClaimsChangeOpDeserializer $statementsChangeOpDeserializer,
58        ValueValidator $entityExistsValidator
59    ) {
60        $this->representationsChangeOpDeserializer = $representationsChangeOpDeserializer;
61        $this->itemIdListDeserializer = $itemIdListDeserializer;
62        $this->statementsChangeOpDeserializer = $statementsChangeOpDeserializer;
63        $this->entityExistsValidator = $entityExistsValidator;
64    }
65
66    public function setContext( ValidationContext $context ) {
67        $this->validationContext = $context;
68    }
69
70    /**
71     * @see ChangeOpDeserializer::createEntityChangeOp
72     *
73     * @param array $changeRequest
74     *
75     * @throws ChangeOpDeserializationException
76     *
77     * @return ChangeOp
78     */
79    public function createEntityChangeOp( array $changeRequest ) {
80        $changeOps = [];
81
82        if ( array_key_exists( self::PARAM_REPRESENTATIONS, $changeRequest ) ) {
83            $representations = $changeRequest[self::PARAM_REPRESENTATIONS];
84
85            $representationsContext = $this->validationContext->at( self::PARAM_REPRESENTATIONS );
86
87            if ( !is_array( $representations ) ) {
88                $representationsContext->addViolation(
89                    new JsonFieldHasWrongType( 'array', gettype( $representations ) )
90                );
91            } else {
92                $this->representationsChangeOpDeserializer->setContext( $representationsContext );
93                $changeOps[] =
94                    $this->representationsChangeOpDeserializer->createEntityChangeOp( $representations );
95            }
96        }
97        if ( array_key_exists( self::PARAM_GRAMM_FEAT, $changeRequest ) ) {
98            $grammaticalFeatures = $changeRequest[self::PARAM_GRAMM_FEAT];
99
100            $grammaticalFeatureContext = $this->validationContext->at( self::PARAM_GRAMM_FEAT );
101
102            if ( !is_array( $grammaticalFeatures ) ) {
103                $grammaticalFeatureContext->addViolation(
104                    new JsonFieldHasWrongType( 'array', gettype( $grammaticalFeatures ) )
105                );
106            } else {
107                $itemIds = $this->itemIdListDeserializer->deserialize(
108                    $grammaticalFeatures,
109                    $grammaticalFeatureContext
110                );
111
112                foreach ( $itemIds as $itemId ) {
113                    if ( $this->entityExistsValidator->validate( $itemId )->getErrors() ) {
114                        $grammaticalFeatureContext->addViolation(
115                            new InvalidItemId( $itemId->getSerialization() )
116                        );
117                    }
118                }
119
120                $changeOps[] = new ChangeOpGrammaticalFeatures( $itemIds );
121            }
122        }
123
124        if ( array_key_exists( self::PARAM_STATEMENTS, $changeRequest ) ) {
125            $statementsContext = $this->validationContext->at( self::PARAM_STATEMENTS );
126            $statementsRequest = $changeRequest[self::PARAM_STATEMENTS];
127
128            if ( !is_array( $statementsRequest ) ) {
129                $statementsContext->addViolation(
130                    new JsonFieldHasWrongType( 'array', gettype( $statementsRequest ) )
131                );
132            } else {
133                try {
134                    $changeOps[] = $this->statementsChangeOpDeserializer->createEntityChangeOp( $changeRequest );
135                } catch ( ChangeOpDeserializationException $exception ) {
136                    $statementsContext->addViolation( new InvalidFormClaims() );
137                }
138            }
139        }
140
141        return new ChangeOpFormEdit( $changeOps );
142    }
143
144}