wikimedia/mediawiki-extensions-Wikibase

View on GitHub
lib/packages/wikibase/internal-serialization/src/Deserializers/LegacySnakDeserializer.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php

namespace Wikibase\InternalSerialization\Deserializers;

use DataValues\DataValue;
use DataValues\UnDeserializableValue;
use Deserializers\Deserializer;
use Deserializers\Exceptions\DeserializationException;
use LogicException;
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
use Wikibase\DataModel\Snak\PropertyValueSnak;
use Wikibase\DataModel\Snak\Snak;

/**
 * @license GPL-2.0-or-later
 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 */
class LegacySnakDeserializer implements Deserializer {

    /**
     * @var Deserializer
     */
    private $dataValueDeserializer;

    public function __construct( Deserializer $dataValueDeserializer ) {
        $this->dataValueDeserializer = $dataValueDeserializer;
    }

    /**
     * @param array $serialization
     *
     * @return Snak
     * @throws DeserializationException
     * @throws LogicException
     */
    public function deserialize( $serialization ) {
        $this->assertStructureIsValid( $serialization );

        switch ( $serialization[0] ) {
            case 'novalue':
                return new PropertyNoValueSnak( $serialization[1] );
            case 'somevalue':
                return new PropertySomeValueSnak( $serialization[1] );
            case 'value':
                return $this->deserializeValueSnak( $serialization );
                // @codeCoverageIgnoreStart
            default:
                throw new LogicException();
        }
        // @codeCoverageIgnoreEnd
    }

    private function deserializeValueSnak( array $serialization ) {
        try {
            $dataValue = $this->dataValueDeserializer->deserialize(
                [
                    'type' => $serialization[2],
                    'value' => $serialization[3],
                ]
            );
        } catch ( DeserializationException $ex ) {
            $dataValue = new UnDeserializableValue( $serialization[3], $serialization[2], $ex->getMessage() );
        }

        /**
         * @var DataValue $dataValue
         */
        return new PropertyValueSnak( $serialization[1], $dataValue );
    }

    private function assertStructureIsValid( $serialization ) {
        if ( !is_array( $serialization ) || $serialization === [] ) {
            throw new DeserializationException( 'Serialization should be a non-empty array' );
        }

        if ( $serialization[0] === 'value' ) {
            $this->assertIsValueSnak( $serialization );
        } else {
            $this->assertIsNonValueSnak( $serialization );
        }

        $this->assertIsPropertyId( $serialization[1] );
    }

    private function assertIsValueSnak( array $serialization ) {
        if ( count( $serialization ) != 4 ) {
            throw new DeserializationException( 'Value snaks need to have 4 elements' );
        }
    }

    private function assertIsNonValueSnak( array $serialization ) {
        if ( count( $serialization ) != 2 ) {
            throw new DeserializationException( 'Non-value snaks need to have 2 elements' );
        }

        if ( !in_array( $serialization[0], [ 'novalue', 'somevalue' ] ) ) {
            throw new DeserializationException( 'Unknown snak type' );
        }
    }

    private function assertIsPropertyId( $idSerialization ) {
        if ( !is_int( $idSerialization ) || $idSerialization < 1 ) {
            throw new DeserializationException( 'Property id needs to be an int bigger than 0' );
        }
    }

}