Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
FormChangeOpDeserializer
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
4 / 4
9
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
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
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
4
 getLexemeId
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace Wikibase\Lexeme\Presentation\ChangeOp\Deserialization;
4
5use Wikibase\DataModel\Entity\EntityIdParser;
6use Wikibase\DataModel\Entity\EntityIdParsingException;
7use Wikibase\DataModel\Services\Lookup\EntityLookup;
8use Wikibase\Lexeme\DataAccess\ChangeOp\AddFormToLexemeChangeOp;
9use Wikibase\Lexeme\Domain\Model\Lexeme;
10use Wikibase\Lexeme\Domain\Model\LexemeId;
11use Wikibase\Lexeme\MediaWiki\Api\Error\LexemeNotFound;
12use Wikibase\Lexeme\MediaWiki\Api\Error\ParameterIsNotLexemeId;
13use Wikibase\Repo\ChangeOp\ChangeOp;
14use Wikibase\Repo\ChangeOp\ChangeOpDeserializer;
15use Wikibase\Repo\ChangeOp\Deserialization\ChangeOpDeserializationException;
16use Wikibase\Repo\ChangeOp\NullChangeOp;
17
18/**
19 * Deserialize a creation request of a single form on a lexeme
20 *
21 * @see docs/change-op-serialization.wiki for a description of the serialization format.
22 *
23 * @license GPL-2.0-or-later
24 */
25class FormChangeOpDeserializer implements ChangeOpDeserializer {
26
27    /**
28     * In 'data' when creating 'new' => 'form' through wbeditentity
29     */
30    private const PARAM_LEXEME_ID = 'lexemeId';
31
32    /**
33     * @var EntityLookup
34     */
35    private $entityLookup;
36
37    /**
38     * @var EditFormChangeOpDeserializer
39     */
40    private $editFormChangeOpDeserializer;
41
42    /**
43     * @var EntityIdParser
44     */
45    private $entityIdParser;
46
47    /**
48     * @var ValidationContext
49     */
50    private $validationContext;
51
52    public function __construct(
53        EntityLookup $entityLookup,
54        EntityIdParser $idParser,
55        EditFormChangeOpDeserializer $editFormChangeOpDeserializer
56    ) {
57        $this->entityLookup = $entityLookup;
58        $this->entityIdParser = $idParser;
59        $this->editFormChangeOpDeserializer = $editFormChangeOpDeserializer;
60    }
61
62    public function setContext( ValidationContext $context ) {
63        $this->validationContext = $context;
64    }
65
66    /**
67     * @see ChangeOpDeserializer::createEntityChangeOp
68     *
69     * @param array $changeRequest
70     *
71     * @throws ChangeOpDeserializationException
72     *
73     * @return ChangeOp
74     */
75    public function createEntityChangeOp( array $changeRequest ) {
76        $this->editFormChangeOpDeserializer->setContext( $this->validationContext );
77        $editFormChangeOp = $this->editFormChangeOpDeserializer->createEntityChangeOp( $changeRequest );
78
79        // TODO: move to dedicated deserializer
80        if ( array_key_exists( self::PARAM_LEXEME_ID, $changeRequest ) ) {
81            $lexemeId = $this->getLexemeId( $changeRequest[self::PARAM_LEXEME_ID] );
82            $idContext = $this->validationContext->at( self::PARAM_LEXEME_ID );
83
84            if ( $lexemeId === null ) {
85                $idContext->addViolation(
86                    new ParameterIsNotLexemeId( $changeRequest[self::PARAM_LEXEME_ID ] )
87                );
88                return new NullChangeOp();
89            }
90            /** @var Lexeme $lexeme */
91            $lexeme = $this->entityLookup->getEntity( $lexemeId );
92            '@phan-var Lexeme $lexeme';
93            if ( $lexeme === null ) {
94                $idContext->addViolation( new LexemeNotFound( $lexemeId ) );
95                return new NullChangeOp();
96            }
97            // TODO Use ChangeOp that sets summary
98            return new AddFormToLexemeChangeOp(
99                $lexeme,
100                $editFormChangeOp
101            );
102        }
103
104        return $editFormChangeOp;
105    }
106
107    /**
108     * @param string $id
109     * @return LexemeId|null
110     */
111    private function getLexemeId( $id ) {
112        try {
113            $lexemeId = $this->entityIdParser->parse( $id );
114        } catch ( EntityIdParsingException $ex ) {
115            return null;
116        }
117
118        if ( $lexemeId->getEntityType() !== Lexeme::ENTITY_TYPE ) {
119            return null;
120        }
121
122        // @phan-suppress-next-line PhanTypeMismatchReturnSuperType
123        return $lexemeId;
124    }
125
126}