Skip to content

Instantly share code, notes, and snippets.

@eldadfux
Created January 14, 2020 11:43
Show Gist options
  • Select an option

  • Save eldadfux/fabcd5259dcaec9d2e9fb5e8bc757767 to your computer and use it in GitHub Desktop.

Select an option

Save eldadfux/fabcd5259dcaec9d2e9fb5e8bc757767 to your computer and use it in GitHub Desktop.

Revisions

  1. eldadfux created this gist Jan 14, 2020.
    398 changes: 398 additions & 0 deletions data.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,398 @@
    <?php

    class Client
    {
    const METHOD_GET = 'GET';
    const METHOD_POST = 'POST';
    const METHOD_PUT = 'PUT';
    const METHOD_PATCH = 'PATCH';
    const METHOD_DELETE = 'DELETE';
    const METHOD_HEAD = 'HEAD';
    const METHOD_OPTIONS = 'OPTIONS';
    const METHOD_CONNECT = 'CONNECT';
    const METHOD_TRACE = 'TRACE';

    /**
    * Is Self Signed Certificates Allowed?
    *
    * @var bool
    */
    protected $selfSigned = false;

    /**
    * Service host name
    *
    * @var string
    */
    protected $endpoint = 'http://localhost/v1';

    /**
    * Global Headers
    *
    * @var array
    */
    protected $headers = [
    'content-type' => '',
    'x-sdk-version' => 'appwrite:php:v1.0.7',
    ];

    /**
    * SDK constructor.
    */
    public function __construct()
    {
    }

    /**
    * Set Project
    *
    * Your Appwrite project ID. You can find your project ID in your Appwrite console project settings.
    *
    * @param string $value
    *
    * @return self $this
    */
    public function setProject(string $value): self
    {
    $this->addHeader('X-Appwrite-Project', $value);

    return $this;
    }

    /**
    * @param bool $status true
    * @return self $this
    */
    public function setSelfSigned(bool $status = true): self
    {
    $this->selfSigned = $status;

    return $this;
    }

    /**
    * @param mixed $endpoint
    * @return self $this
    */
    public function setEndpoint($endpoint): self
    {
    $this->endpoint = $endpoint;

    return $this;
    }

    /**
    * @param string $key
    * @param string $value
    *
    * @return self $this
    */
    public function addHeader(string $key, string $value): self
    {
    $this->headers[strtolower($key)] = strtolower($value);

    return $this;
    }

    /**
    * Call
    *
    * Make an API call
    *
    * @param string $method
    * @param string $path
    * @param array $params
    * @param array $headers
    * @return array|string
    * @throws Exception
    */
    public function call(string $method, string $path = '', array $headers = [], array $params = [])
    {
    $headers = array_merge($this->headers, $headers);
    $ch = curl_init($this->endpoint . $path . (($method == self::METHOD_GET && !empty($params)) ? '?' . http_build_query($params) : ''));
    $responseHeaders = [];
    $responseStatus = -1;
    $responseType = '';
    $responseBody = '';

    switch ($headers['content-type']) {
    case 'application/json':
    $query = json_encode($params);
    break;

    case 'multipart/form-data':
    $query = $this->flatten($params);
    break;

    default:
    $query = http_build_query($params);
    break;
    }

    foreach ($headers as $i => $header) {
    $headers[] = $i . ':' . $header;
    unset($headers[$i]);
    }

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36');
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) {
    $len = strlen($header);
    $header = explode(':', $header, 2);

    if (count($header) < 2) { // ignore invalid headers
    return $len;
    }

    $responseHeaders[strtolower(trim($header[0]))] = trim($header[1]);

    return $len;
    });

    if ($method != self::METHOD_GET) {
    curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
    }

    // Allow self signed certificates
    if ($this->selfSigned) {
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    }

    $responseBody = curl_exec($ch);
    $responseType = (isset($responseHeaders['content-type'])) ? $responseHeaders['content-type'] : '';
    $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    switch (substr($responseType, 0, strpos($responseType, ';'))) {
    case 'application/json':
    $json = json_decode($responseBody, true);

    if($json === null) {
    throw new Exception('Failed to parse response: '.$responseBody);
    }

    $responseBody = $json;
    $json = null;
    break;
    }

    if ((curl_errno($ch)/* || 200 != $responseStatus*/)) {
    throw new Exception(curl_error($ch) . ' with status code ' . $responseStatus, $responseStatus);
    }

    curl_close($ch);

    $responseHeaders['status-code'] = $responseStatus;

    if($responseStatus === 500) {
    echo 'Server error(!): '.json_encode($responseBody)."\n";
    }

    return [
    'headers' => $responseHeaders,
    'body' => $responseBody
    ];
    }

    /**
    * Parse Cookie String
    *
    * @param string $cookie
    * @return array
    */
    public function parseCookie(string $cookie): array
    {
    $cookies = [];

    parse_str(strtr($cookie, array('&' => '%26', '+' => '%2B', ';' => '&')), $cookies);

    return $cookies;
    }

    /**
    * Flatten params array to PHP multiple format
    *
    * @param array $data
    * @param string $prefix
    * @return array
    */
    protected function flatten(array $data, string $prefix = ''): array
    {
    $output = [];

    foreach ($data as $key => $value) {
    $finalKey = $prefix ? "{$prefix}[{$key}]" : $key;

    if (is_array($value)) {
    $output += $this->flatten($value, $finalKey); // @todo: handle name collision here if needed
    } else {
    $output[$finalKey] = $value;
    }
    }

    return $output;
    }
    }

    $client = new Client();
    $projectID = '';
    $apiKey = '';

    $actors = $client->call(Client::METHOD_POST, '/database', array_merge([
    'content-type' => 'application/json',
    'x-appwrite-project' => $projectID,
    'x-appwrite-key' => $apiKey
    ]), [
    'name' => 'Actors Z',
    'read' => ['*'],
    'write' => ['role:1', 'role:2'],
    'rules' => [
    [
    'label' => 'First Name',
    'key' => 'firstName',
    'type' => 'text',
    'default' => '',
    'required' => true,
    'array' => false
    ],
    [
    'label' => 'Last Name',
    'key' => 'lastName',
    'type' => 'text',
    'default' => '',
    'required' => true,
    'array' => false
    ],
    ],
    ]);

    $movies = $client->call(Client::METHOD_POST, '/database', array_merge([
    'content-type' => 'application/json',
    'x-appwrite-project' => $projectID,
    'x-appwrite-key' => $apiKey
    ]), [
    'name' => 'Movies Z',
    'read' => ['*'],
    'write' => ['role:1', 'role:2'],
    'rules' => [
    [
    'label' => 'Name',
    'key' => 'name',
    'type' => 'text',
    'default' => '',
    'required' => true,
    'array' => false
    ],
    [
    'label' => 'Release Year',
    'key' => 'releaseYear',
    'type' => 'numeric',
    'default' => 0,
    'required' => false,
    'array' => false
    ],
    [
    'label' => 'Actors',
    'key' => 'actors',
    'type' => 'document',
    'default' => [],
    'required' => false,
    'array' => true,
    'list' => [$actors['body']['$uid']],
    ],
    ],
    ]);

    $document1 = $client->call(Client::METHOD_POST, '/database/' . $movies['body']['$uid'] . '/documents', [
    'content-type' => 'application/json',
    'x-appwrite-project' => $projectID,
    'x-appwrite-key' => $apiKey
    ], [
    'data' => [
    'name' => 'Captain America',
    'releaseYear' => 1944,
    'actors' => [
    [
    '$collection' => $actors['body']['$uid'],
    '$permissions' => ['read' => [], 'write' => []],
    'firstName' => 'Chris',
    'lastName' => 'Evans',
    ],
    [
    '$collection' => $actors['body']['$uid'],
    '$permissions' => ['read' => [], 'write' => []],
    'firstName' => 'Samuel',
    'lastName' => 'Jackson',
    ],
    ]
    ],
    ]);

    $document2 = $client->call(Client::METHOD_POST, '/database/' . $movies['body']['$uid'] . '/documents', [
    'content-type' => 'application/json',
    'x-appwrite-project' => $projectID,
    'x-appwrite-key' => $apiKey
    ], [
    'data' => [
    'name' => 'Spider-Man: Far From Home',
    'releaseYear' => 2019,
    'actors' => [
    [
    '$collection' => $actors['body']['$uid'],
    '$permissions' => ['read' => [], 'write' => []],
    'firstName' => 'Tom',
    'lastName' => 'Holland',
    ],
    [
    '$collection' => $actors['body']['$uid'],
    '$permissions' => ['read' => [], 'write' => []],
    'firstName' => 'Zendaya',
    'lastName' => 'Maree Stoermer',
    ],
    [
    '$collection' => $actors['body']['$uid'],
    '$permissions' => ['read' => [], 'write' => []],
    'firstName' => 'Samuel',
    'lastName' => 'Jackson',
    ],
    ]
    ],
    ]);

    $document3 = $client->call(Client::METHOD_POST, '/database/' . $movies['body']['$uid'] . '/documents', [
    'content-type' => 'application/json',
    'x-appwrite-project' => $projectID,
    'x-appwrite-key' => $apiKey
    ], [
    'data' => [
    'name' => 'Spider-Man: Homecoming',
    'releaseYear' => 2017,
    'actors' => [
    [
    '$collection' => $actors['body']['$uid'],
    '$permissions' => ['read' => [], 'write' => []],
    'firstName' => 'Tom',
    'lastName' => 'Holland',
    ],
    [
    '$collection' => $actors['body']['$uid'],
    '$permissions' => ['read' => [], 'write' => []],
    'firstName' => 'Zendaya',
    'lastName' => 'Maree Stoermer',
    ],
    ],
    ],
    ]);

    $document4 = $client->call(Client::METHOD_POST, '/database/' . $movies['body']['$uid'] . '/documents', [
    'content-type' => 'application/json',
    'x-appwrite-project' => $projectID,
    'x-appwrite-key' => $apiKey
    ], [
    'data' => [
    'releaseYear' => 2020, // Missing title, expect an 400 error
    ],
    ]);