name : UploadContent.php
<?php

namespace Srmklive\Dropbox;

trait UploadContent
{
    /**
     * The file should be uploaded in chunks if it size exceeds the 150 MB threshold
     * or if the resource size could not be determined (eg. a popen() stream).
     *
     * @param string|resource $contents
     *
     * @return bool
     */
    protected function shouldUploadChunk($contents)
    {
        $size = is_string($contents) ? strlen($contents) : fstat($contents)['size'];

        return ($this->isPipe($contents) || ($size === null)) ? true : ($size > $this->maxChunkSize);
    }

    /**
     * Check if the contents is a pipe stream (not seekable, no size defined).
     *
     * @param string|resource $contents
     *
     * @return bool
     */
    protected function isPipe($contents)
    {
        return is_resource($contents) ? (fstat($contents)['mode'] & 010000) != 0 : false;
    }

    /**
     * Upload file split in chunks. This allows uploading large files, since
     * Dropbox API v2 limits the content size to 150MB.
     *
     * The chunk size will affect directly the memory usage, so be careful.
     * Large chunks tends to speed up the upload, while smaller optimizes memory usage.
     *
     * @param string          $path
     * @param string|resource $contents
     * @param string          $mode
     * @param int             $chunkSize
     *
     * @throws \Exception
     *
     * @return array
     */
    public function uploadChunk($path, $contents, $mode = 'add', $chunkSize = null)
    {
        $chunkSize = empty($chunkSize) ? static::MAX_CHUNK_SIZE : $chunkSize;
        $stream = $contents;

        // This method relies on resources, so we need to convert strings to resource
        if (is_string($contents)) {
            $stream = fopen('php://memory', 'r+');
            fwrite($stream, $contents);
            rewind($stream);
        }

        $data = self::readChunk($stream, $chunkSize);
        $cursor = null;

        while (!((strlen($data) < $chunkSize) || feof($stream))) {
            // Start upload session on first iteration, then just append on subsequent iterations
            $cursor = isset($cursor) ? $this->appendContentToUploadSession($data, $cursor) : $this->startUploadSession($data);
            $data = self::readChunk($stream, $chunkSize);
        }

        // If there's no cursor here, our stream is small enough to a single request
        if (!isset($cursor)) {
            $cursor = $this->startUploadSession($data);
            $data = '';
        }

        return $this->finishUploadSession($data, $cursor, $path, $mode);
    }

    /**
     * Upload sessions allow you to upload a single file in one or more requests,
     * for example where the size of the file is greater than 150 MB.
     * This call starts a new upload session with the given data.
     *
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-upload_session-start
     *
     * @param string $contents
     * @param bool   $close
     *
     * @return \Srmklive\Dropbox\DropboxUploadCounter
     */
    public function startUploadSession($contents, $close = false)
    {
        $this->setupRequest(
            compact('close')
        );

        $this->apiEndpoint = 'files/upload_session/start';

        $this->content = $contents;

        $response = json_decode(
            $this->doDropboxApiContentRequest()->getBody(),
            true
        );

        return new DropboxUploadCounter($response['session_id'], strlen($contents));
    }

    /**
     * Append more data to an upload session.
     * When the parameter close is set, this call will close the session.
     * A single request should not upload more than 150 MB.
     *
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-upload_session-append_v2
     *
     * @param string               $contents
     * @param DropboxUploadCounter $cursor
     * @param bool                 $close
     *
     * @return \Srmklive\Dropbox\DropboxUploadCounter
     */
    public function appendContentToUploadSession($contents, DropboxUploadCounter $cursor, $close = false)
    {
        $this->setupRequest(compact('cursor', 'close'));

        $this->apiEndpoint = 'files/upload_session/append_v2';

        $this->content = $contents;

        $this->doDropboxApiContentRequest()->getBody();

        $cursor->offset += strlen($contents);

        return $cursor;
    }

    /**
     * Finish an upload session and save the uploaded data to the given file path.
     * A single request should not upload more than 150 MB.
     *
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-upload_session-finish
     *
     * @param string                                 $contents
     * @param \Srmklive\Dropbox\DropboxUploadCounter $cursor
     * @param string                                 $path
     * @param string|array                           $mode
     * @param bool                                   $autorename
     * @param bool                                   $mute
     *
     * @return array
     */
    public function finishUploadSession($contents, DropboxUploadCounter $cursor, $path, $mode = 'add', $autorename = false, $mute = false)
    {
        $arguments = compact('cursor');
        $arguments['commit'] = compact('path', 'mode', 'autorename', 'mute');

        $this->setupRequest($arguments);

        $this->apiEndpoint = 'files/upload_session/finish';

        $this->content = $contents;

        $response = $this->doDropboxApiContentRequest();

        $metadata = json_decode($response->getBody(), true);

        $metadata['.tag'] = 'file';

        return $metadata;
    }

    /**
     * Sometimes fread() returns less than the request number of bytes (for example, when reading
     * from network streams).  This function repeatedly calls fread until the requested number of
     * bytes have been read or we've reached EOF.
     *
     * @param resource $stream
     * @param int      $chunkSize
     *
     * @throws \Exception
     *
     * @return string
     */
    protected static function readChunk($stream, $chunkSize)
    {
        $chunk = '';
        while (!feof($stream) && $chunkSize > 0) {
            $part = fread($stream, $chunkSize);

            if ($part === false) {
                throw new \Exception('Error reading from $stream.');
            }

            $chunk .= $part;
            $chunkSize -= strlen($part);
        }

        return $chunk;
    }
}

© 2025 UnknownSec
afwwrfwafr45458465
Password