First release
This commit is contained in:
commit
b48881a8a4
74
README.md
Normal file
74
README.md
Normal file
@ -0,0 +1,74 @@
|
||||
# Vdm Openai (1.0.0)
|
||||
|
||||
VDM OpenAi Library
|
||||
|
||||
## Details
|
||||
|
||||
- Packager: [OctoPower v2.0](https://git.vdm.dev/octoleo/octopower)
|
||||
- Author: [Llewellyn van der Merwe](https://io.vdm.dev)
|
||||
- Creation Date: June 2024
|
||||
|
||||
### Installation via Composer
|
||||
|
||||
Setup this registry in your `~/.composer/config.json` file:
|
||||
```
|
||||
{
|
||||
"repositories": [{
|
||||
"type": "composer",
|
||||
"url": "https://git.vdm.dev/api/packages/joomla/composer"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
To install the package using Composer, run the following command:
|
||||
```
|
||||
composer require vdm/openai:1.0.0
|
||||
```
|
||||
|
||||
## Joomla Framework Dependencies
|
||||
|
||||
>We have added the following framework classes to the required list of this Composer package.
|
||||
|
||||
- Joomla/DI "^3.0"
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Factory](src/VastDevelopmentMethod/Openai/Joomla/Openai/Factory.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Abstraction\Factory](src/VastDevelopmentMethod/Openai/Joomla/Abstraction/Factory.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Interfaces\FactoryInterface](src/VastDevelopmentMethod/Openai/Joomla/Interfaces/FactoryInterface.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Service\Api](src/VastDevelopmentMethod/Openai/Joomla/Openai/Service/Api.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Audio](src/VastDevelopmentMethod/Openai/Joomla/Openai/Audio.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api](src/VastDevelopmentMethod/Openai/Joomla/Openai/Abstraction/Api.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Service\Utilities](src/VastDevelopmentMethod/Openai/Joomla/Openai/Service/Utilities.php)
|
||||
- Joomla/Filter "^3.0"
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\StringHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/StringHelper.php)
|
||||
- Joomla/Input "^3.0"
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/Component/Helper.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/String/NamespaceHelper.php)
|
||||
- Joomla/Registry "^3.0"
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Http](src/VastDevelopmentMethod/Openai/Joomla/Openai/Utilities/Http.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/Component/Helper.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/String/NamespaceHelper.php)
|
||||
- Joomla/Uri "^3.0"
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Uri](src/VastDevelopmentMethod/Openai/Joomla/Openai/Utilities/Uri.php)
|
||||
|
||||
|
||||
## Joomla CMS Dependencies
|
||||
|
||||
- Joomla\CMS\Component\ComponentHelper
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/Component/Helper.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/String/NamespaceHelper.php)
|
||||
- Joomla\CMS\Factory
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/Component/Helper.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/String/NamespaceHelper.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\GetHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/GetHelper.php)
|
||||
- Joomla\CMS\Http\Http
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Http](src/VastDevelopmentMethod/Openai/Joomla/Openai/Utilities/Http.php)
|
||||
- Joomla\CMS\Http\Response
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Response](src/VastDevelopmentMethod/Openai/Joomla/Openai/Utilities/Response.php)
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\JsonHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/JsonHelper.php)
|
||||
- Joomla\CMS\Language\Language
|
||||
- [VastDevelopmentMethod\Openai\Joomla\Utilities\StringHelper](src/VastDevelopmentMethod/Openai/Joomla/Utilities/StringHelper.php)
|
||||
|
||||
|
||||
### License
|
||||
> GNU General Public License version 2 or later
|
||||
|
32
composer.json
Normal file
32
composer.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "vdm/openai",
|
||||
"type": "library",
|
||||
"description": "VDM OpenAi Library",
|
||||
"homepage": "https://git.vdm.dev/joomla/vdm-openai",
|
||||
"license": "GNU General Public License version 2 or later",
|
||||
"require": {
|
||||
"php": "^8.1.0",
|
||||
"Joomla/DI": "^3.0",
|
||||
"Joomla/Filter": "^3.0",
|
||||
"Joomla/Input": "^3.0",
|
||||
"Joomla/Registry": "^3.0",
|
||||
"Joomla/Uri": "^3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"VastDevelopmentMethod\\Openai\\": "src/VastDevelopmentMethod/Openai"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"VDM",
|
||||
"OpenAi",
|
||||
"SuperPower"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Llewellyn van der Merwe",
|
||||
"email": "joomla@vdm.io",
|
||||
"homepage": "https://io.vdm.dev"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Abstraction;
|
||||
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Interfaces\FactoryInterface;
|
||||
|
||||
|
||||
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||
**
|
||||
** In realms of code where purists frown, the anti-pattern wears a crown,
|
||||
** A paradox of chaos bright, where complex paths lose all its slight.
|
||||
** For in its tangled, wild embrace, lies raw creativity's face,
|
||||
** No rigid forms, no strict decree, just boundless, daring artistry.
|
||||
** In flaws, we find the freedom's key, where messy code and brilliance spree,
|
||||
** A dance of thought, unchained, unbound, in anti-pattern, beauty's found.
|
||||
**
|
||||
** Perfect Paradox and True Nature of the Anti-Pattern by ChatGPT
|
||||
**
|
||||
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||
**
|
||||
** @since 0.0.0
|
||||
**/
|
||||
abstract class Factory implements FactoryInterface
|
||||
{
|
||||
/**
|
||||
* Global Package Container
|
||||
*
|
||||
* @var Container|null
|
||||
* @since 0.0.0
|
||||
**/
|
||||
protected static ?Container $container = null;
|
||||
|
||||
/**
|
||||
* Get any class from the package container
|
||||
*
|
||||
* @param string $key The container class key
|
||||
*
|
||||
* @return Mixed
|
||||
* @since 0.0.0
|
||||
*/
|
||||
public static function _($key)
|
||||
{
|
||||
return static::getContainer()->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the global package container
|
||||
*
|
||||
* @return Container
|
||||
* @since 0.0.0
|
||||
*/
|
||||
public static function getContainer(): Container
|
||||
{
|
||||
if (!static::$container)
|
||||
{
|
||||
static::$container = static::createContainer();
|
||||
}
|
||||
|
||||
return static::$container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a container object
|
||||
*
|
||||
* @return Container
|
||||
* @since 0.0.0
|
||||
*/
|
||||
abstract protected static function createContainer(): Container;
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Interfaces;
|
||||
|
||||
|
||||
use Joomla\DI\Container;
|
||||
|
||||
|
||||
/**
|
||||
* The Container Factory Interface
|
||||
*
|
||||
* @since 0.0.0
|
||||
*/
|
||||
interface FactoryInterface
|
||||
{
|
||||
/**
|
||||
* Get any class from the container
|
||||
*
|
||||
* @param string $key The container class key
|
||||
*
|
||||
* @return Mixed
|
||||
* @since 0.0.0
|
||||
*/
|
||||
public static function _(string $key);
|
||||
|
||||
/**
|
||||
* Get the global container
|
||||
*
|
||||
* @return Container
|
||||
* @since 0.0.0
|
||||
*/
|
||||
public static function getContainer(): Container;
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Http;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Uri;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Response;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Api
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
abstract class Api
|
||||
{
|
||||
/**
|
||||
* The Http class
|
||||
*
|
||||
* @var Http
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected Http $http;
|
||||
|
||||
/**
|
||||
* The Uri class
|
||||
*
|
||||
* @var Uri
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected Uri $uri;
|
||||
|
||||
/**
|
||||
* The Response class
|
||||
*
|
||||
* @var Response
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected Response $response;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Http $http The http class.
|
||||
* @param Uri $uri The uri class.
|
||||
* @param Response $response The response class.
|
||||
*
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function __construct(Http $http, Uri $uri, Response $response)
|
||||
{
|
||||
$this->http = $http;
|
||||
$this->uri = $uri;
|
||||
$this->response = $response;
|
||||
}
|
||||
}
|
||||
|
138
src/VastDevelopmentMethod/Openai/Joomla/Openai/Audio.php
Normal file
138
src/VastDevelopmentMethod/Openai/Joomla/Openai/Audio.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Audio
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Audio extends Api
|
||||
{
|
||||
/**
|
||||
* Transcribes audio into the input language.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/audio/create
|
||||
*
|
||||
* @param string $file The audio file to transcribe. Formats: mp3, mp4, mpeg, mpga, m4a, wav, or webm (required).
|
||||
* @param string|null $prompt An optional text to guide the model's style (optional).
|
||||
* @param string|null $responseFormat The format of the transcript output. Options: json, text, srt, verbose_json, or vtt (optional).
|
||||
* @param float|null $temperature The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic (optional).
|
||||
* @param string|null $language The language of the input audio (optional).
|
||||
* @param string $model ID of the model to use. Only "whisper-1" is currently available.
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function transcribe(
|
||||
string $file,
|
||||
?string $prompt = null,
|
||||
?string $responseFormat = null,
|
||||
?float $temperature = null,
|
||||
?string $language = null,
|
||||
string $model = 'whisper-1'
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/audio/transcriptions";
|
||||
|
||||
// Set the request data.
|
||||
$data = new \stdClass();
|
||||
$data->file = $file;
|
||||
|
||||
if ($prompt !== null)
|
||||
{
|
||||
$data->prompt = $prompt;
|
||||
}
|
||||
|
||||
if ($responseFormat !== null)
|
||||
{
|
||||
$data->response_format = $responseFormat;
|
||||
}
|
||||
|
||||
if ($temperature !== null)
|
||||
{
|
||||
$data->temperature = $temperature;
|
||||
}
|
||||
|
||||
if ($language !== null)
|
||||
{
|
||||
$data->language = $language;
|
||||
}
|
||||
|
||||
$data->model = $model;
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data), ['Content-Type' => 'multipart/form-data']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate an audio file into English.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/audio/create
|
||||
*
|
||||
* @param string $file The the audio file. Formats: mp3, mp4, mpeg, mpga, m4a, wav, or webm (required).
|
||||
* @param string|null $prompt An optional text to guide the model's style or continue a previous audio segment. The prompt should be in English (optional).
|
||||
* @param string|null $responseFormat The format of the transcript output. Options: json, text, srt, verbose_json, or vtt (optional).
|
||||
* @param float|null $temperature The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic (optional).
|
||||
* @param string $model ID of the model to use. Only "whisper-1" is currently available.
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function translation(
|
||||
string $file,
|
||||
?string $prompt = null,
|
||||
?string $responseFormat = null,
|
||||
?float $temperature = null,
|
||||
string $model = 'whisper-1'
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/audio/translations";
|
||||
|
||||
// Set the data.
|
||||
$data = new \stdClass();
|
||||
$data->file = $file;
|
||||
|
||||
if ($prompt !== null)
|
||||
{
|
||||
$data->prompt = $prompt;
|
||||
}
|
||||
|
||||
if ($responseFormat !== null)
|
||||
{
|
||||
$data->response_format = $responseFormat;
|
||||
}
|
||||
|
||||
if ($temperature !== null)
|
||||
{
|
||||
$data->temperature = $temperature;
|
||||
}
|
||||
|
||||
$data->model = $model;
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data), ['Content-Type' => 'multipart/form-data']
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
142
src/VastDevelopmentMethod/Openai/Joomla/Openai/Chat.php
Normal file
142
src/VastDevelopmentMethod/Openai/Joomla/Openai/Chat.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Chat
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Chat extends Api
|
||||
{
|
||||
/**
|
||||
* Create a chat completion with the OpenAI API.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/chat/create
|
||||
*
|
||||
* @param string $model The model to use for completion.
|
||||
* @param array $messages A list of messages describing the conversation so far.
|
||||
*
|
||||
* Each item in the array is an object with the following:
|
||||
* - role (string) Required
|
||||
* The role of the author of this message.
|
||||
* One of system, user, or assistant.
|
||||
* - content (string) Required
|
||||
* The contents of the message.
|
||||
* - name (string) Optional
|
||||
* The name of the author of this message.
|
||||
* May contain a-z, A-Z, 0-9, and underscores,
|
||||
* with a maximum length of 64 characters.
|
||||
*
|
||||
* @param int|null $maxTokens Maximum number of tokens to generate (optional).
|
||||
* @param float|null $temperature The sampling temperature to use (optional).
|
||||
* @param float|null $topP The nucleus sampling parameter (optional).
|
||||
* @param int|null $n The number of chat completion choices to generate (optional).
|
||||
* @param bool|null $stream Partial message deltas (optional).
|
||||
* @param mixed|null $stop Sequences where the API will stop generating tokens (optional).
|
||||
* @param float|null $presencePenalty Penalty for new tokens based on whether they appear in the text (optional).
|
||||
* @param float|null $frequencyPenalty Penalty for new tokens based on their frequency in the text (optional).
|
||||
* @param array|null $logitBias Modify the likelihood of specified tokens appearing (optional).
|
||||
* @param string|null $user A unique identifier representing the end-user (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function create(
|
||||
string $model,
|
||||
array $messages,
|
||||
?int $maxTokens = null,
|
||||
?float $temperature = null,
|
||||
?float $topP = null,
|
||||
?int $n = null,
|
||||
?bool $stream = null,
|
||||
$stop = null,
|
||||
?float $presencePenalty = null,
|
||||
?float $frequencyPenalty = null,
|
||||
?array $logitBias = null,
|
||||
?string $user = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/chat/completions";
|
||||
|
||||
// Set the request data.
|
||||
$data = new \stdClass();
|
||||
$data->model = $model;
|
||||
$data->messages = $messages;
|
||||
|
||||
if ($maxTokens !== null)
|
||||
{
|
||||
$data->max_tokens = $maxTokens;
|
||||
}
|
||||
|
||||
if ($temperature !== null)
|
||||
{
|
||||
$data->temperature = $temperature;
|
||||
}
|
||||
|
||||
if ($topP !== null)
|
||||
{
|
||||
$data->top_p = $topP;
|
||||
}
|
||||
|
||||
if ($n !== null)
|
||||
{
|
||||
$data->n = $n;
|
||||
}
|
||||
|
||||
if ($stream !== null)
|
||||
{
|
||||
$data->stream = $stream;
|
||||
}
|
||||
|
||||
if ($stop !== null)
|
||||
{
|
||||
$data->stop = $stop;
|
||||
}
|
||||
|
||||
if ($presencePenalty !== null)
|
||||
{
|
||||
$data->presence_penalty = $presencePenalty;
|
||||
}
|
||||
|
||||
if ($frequencyPenalty !== null)
|
||||
{
|
||||
$data->frequency_penalty = $frequencyPenalty;
|
||||
}
|
||||
|
||||
if ($logitBias !== null)
|
||||
{
|
||||
$data->logit_bias = new \stdClass();
|
||||
foreach ($logitBias as $key => $val)
|
||||
{
|
||||
$data->logit_bias->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if ($user !== null)
|
||||
{
|
||||
$data->user = $user;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
158
src/VastDevelopmentMethod/Openai/Joomla/Openai/Completions.php
Normal file
158
src/VastDevelopmentMethod/Openai/Joomla/Openai/Completions.php
Normal file
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Completions
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Completions extends Api
|
||||
{
|
||||
/**
|
||||
* Create a completion using the OpenAI API.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/completions
|
||||
*
|
||||
* @param string $model The ID of the model to use.
|
||||
* @param string|array $prompt The prompt(s) to generate completions for.
|
||||
* @param int|null $maxTokens The maximum number of tokens to generate (optional).
|
||||
* @param float|null $temperature The sampling temperature to use (optional).
|
||||
* @param string $suffix The suffix that comes after a completion of inserted text. (optional).
|
||||
* @param float|null $topP The top_p value for nucleus sampling (optional).
|
||||
* @param int|null $n How many completions to generate (optional).
|
||||
* @param bool|null $stream Whether to stream back partial progress (optional).
|
||||
* @param int|null $logprobs Include the log probabilities on the most likely tokens (optional).
|
||||
* @param bool|null $echo Echo back the prompt in addition to the completion (optional).
|
||||
* @param string|null $stop Up to 4 sequences where the API will stop generating (optional).
|
||||
* @param float|null $presencePenalty The presence penalty to use (optional).
|
||||
* @param float|null $frequencyPenalty The frequency penalty to use (optional).
|
||||
* @param int|null $bestOf Generates best_of completions server-side (optional).
|
||||
* @param array|null $logitBias Modify the likelihood of specified tokens (optional).
|
||||
* @param string|null $user A unique identifier representing your end-user (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function create(
|
||||
string $model,
|
||||
$prompt,
|
||||
?int $maxTokens = null,
|
||||
?string $suffix = null,
|
||||
?float $temperature = null,
|
||||
?float $topP = null,
|
||||
?int $n = null,
|
||||
?bool $stream = null,
|
||||
?int $logprobs = null,
|
||||
?bool $echo = null,
|
||||
$stop = null,
|
||||
?float $presencePenalty = null,
|
||||
?float $frequencyPenalty = null,
|
||||
?int $bestOf = null,
|
||||
?array $logitBias = null,
|
||||
?string $user = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/completions";
|
||||
|
||||
// Set the completion data.
|
||||
$data = new \stdClass();
|
||||
$data->model = $model;
|
||||
$data->prompt = $prompt;
|
||||
|
||||
if ($maxTokens !== null)
|
||||
{
|
||||
$data->max_tokens = $maxTokens;
|
||||
}
|
||||
|
||||
if ($temperature !== null)
|
||||
{
|
||||
$data->temperature = $temperature;
|
||||
}
|
||||
|
||||
if ($suffix !== null)
|
||||
{
|
||||
$data->suffix = $suffix;
|
||||
}
|
||||
|
||||
if ($topP !== null)
|
||||
{
|
||||
$data->top_p = $topP;
|
||||
}
|
||||
|
||||
if ($n !== null)
|
||||
{
|
||||
$data->n = $n;
|
||||
}
|
||||
|
||||
if ($stream !== null)
|
||||
{
|
||||
$data->stream = $stream;
|
||||
}
|
||||
|
||||
if ($logprobs !== null)
|
||||
{
|
||||
$data->logprobs = $logprobs;
|
||||
}
|
||||
|
||||
if ($echo !== null)
|
||||
{
|
||||
$data->echo = $echo;
|
||||
}
|
||||
|
||||
if ($stop !== null)
|
||||
{
|
||||
$data->stop = $stop;
|
||||
}
|
||||
|
||||
if ($presencePenalty !== null)
|
||||
{
|
||||
$data->presence_penalty = $presencePenalty;
|
||||
}
|
||||
|
||||
if ($frequencyPenalty !== null)
|
||||
{
|
||||
$data->frequency_penalty = $frequencyPenalty;
|
||||
}
|
||||
|
||||
if ($bestOf !== null)
|
||||
{
|
||||
$data->best_of = $bestOf;
|
||||
}
|
||||
|
||||
if ($logitBias !== null)
|
||||
{
|
||||
$data->logit_bias = new \stdClass();
|
||||
foreach ($logitBias as $key => $val)
|
||||
{
|
||||
$data->logit_bias->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if ($user !== null)
|
||||
{
|
||||
$data->user = $user;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
84
src/VastDevelopmentMethod/Openai/Joomla/Openai/Edits.php
Normal file
84
src/VastDevelopmentMethod/Openai/Joomla/Openai/Edits.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Edits
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Edits extends Api
|
||||
{
|
||||
/**
|
||||
* Create a new edit using OpenAI Edit API.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/edits
|
||||
*
|
||||
* @param string $model The model to use.
|
||||
* @param string $instruction The instruction for the edit.
|
||||
* @param string|null $input The input text (optional).
|
||||
* @param int|null $n How many edits to generate (optional).
|
||||
* @param float|null $temperature The sampling temperature (optional).
|
||||
* @param float|null $topP Nucleus sampling parameter (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function create(
|
||||
string $model,
|
||||
string $instruction,
|
||||
?string $input = null,
|
||||
?int $n = null,
|
||||
?float $temperature = null,
|
||||
?float $topP = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/edits";
|
||||
|
||||
// Set the data.
|
||||
$data = new \stdClass();
|
||||
$data->model = $model;
|
||||
$data->instruction = $instruction;
|
||||
|
||||
if ($input !== null)
|
||||
{
|
||||
$data->input = $input;
|
||||
}
|
||||
|
||||
if ($n !== null)
|
||||
{
|
||||
$data->n = $n;
|
||||
}
|
||||
|
||||
if ($temperature !== null)
|
||||
{
|
||||
$data->temperature = $temperature;
|
||||
}
|
||||
|
||||
if ($topP !== null)
|
||||
{
|
||||
$data->top_p = $topP;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Embeddings
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Embeddings extends Api
|
||||
{
|
||||
/**
|
||||
* Create an embedding of a given input.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/embeddings
|
||||
*
|
||||
* @param string $model The ID of the model to use.
|
||||
* @param mixed $input The input text to get embeddings for, encoded as a string or array of tokens.
|
||||
* @param string|null $user A unique identifier representing your end-user (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function create(
|
||||
string $model,
|
||||
$input,
|
||||
?string $user = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/embeddings";
|
||||
|
||||
// Set the request data.
|
||||
$data = new \stdClass();
|
||||
$data->model = $model;
|
||||
$data->input = $input;
|
||||
|
||||
if ($user !== null)
|
||||
{
|
||||
$data->user = $user;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
42
src/VastDevelopmentMethod/Openai/Joomla/Openai/Factory.php
Normal file
42
src/VastDevelopmentMethod/Openai/Joomla/Openai/Factory.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Service\Api;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Service\Utilities;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Interfaces\FactoryInterface;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Abstraction\Factory as ExtendingFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Openai Factory
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
abstract class Factory extends ExtendingFactory implements FactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a container object
|
||||
*
|
||||
* @return Container
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected static function createContainer(): Container
|
||||
{
|
||||
return (new Container())
|
||||
->registerServiceProvider(new Utilities())
|
||||
->registerServiceProvider(new Api());
|
||||
}
|
||||
}
|
||||
|
140
src/VastDevelopmentMethod/Openai/Joomla/Openai/Files.php
Normal file
140
src/VastDevelopmentMethod/Openai/Joomla/Openai/Files.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Files
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Files extends Api
|
||||
{
|
||||
/**
|
||||
* Fetches a list of files belonging to the user's organization.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/files/list
|
||||
*
|
||||
* @return object|null The response from the OpenAI API, or null if an error occurred.
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function list(): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/files";
|
||||
|
||||
// Prepare the URI.
|
||||
$uri = $this->uri->get($path);
|
||||
|
||||
// Send the GET request.
|
||||
return $this->response->get(
|
||||
$this->http->get($uri)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a file that contains document(s) to be used across various endpoints/features.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/files/upload
|
||||
*
|
||||
* @param string $file The file to upload.
|
||||
* @param string $purpose The intended purpose of the uploaded documents.
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function upload(string $file, string $purpose): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/files";
|
||||
|
||||
// Set the request data.
|
||||
$data = new \stdClass();
|
||||
$data->file = $file;
|
||||
$data->purpose = $purpose;
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about a specific file.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/files/retrieve
|
||||
*
|
||||
* @param string $fileID The file id to retrieve info
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function info(string $fileID): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/files/{$fileID}";
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->get(
|
||||
$this->uri->get($path)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a specific file content.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/files/retrieve-content
|
||||
*
|
||||
* @param string $fileID The file id to retrieve content
|
||||
*
|
||||
* @return mixed
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function content(string $fileID)
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/files/{$fileID}/content";
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->get(
|
||||
$this->uri->get($path)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/files/delete
|
||||
*
|
||||
* @param string $fileID The file id to delete
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function delete(string $fileID): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/files/{$fileID}";
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->delete(
|
||||
$this->uri->get($path)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
50
src/VastDevelopmentMethod/Openai/Joomla/Openai/FineTunes.php
Normal file
50
src/VastDevelopmentMethod/Openai/Joomla/Openai/FineTunes.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Fine Tunes
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class FineTunes extends Api
|
||||
{
|
||||
/**
|
||||
* List your organization's fine-tuning jobs
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/fine-tunes/list
|
||||
*
|
||||
* @return object|null The response from the OpenAI API, or null if an error occurred.
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function list(): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/fine-tunes";
|
||||
|
||||
// Prepare the URI.
|
||||
$uri = $this->uri->get($path);
|
||||
|
||||
// Send the GET request.
|
||||
return $this->response->get(
|
||||
$this->http->get($uri)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* More to follow: https://platform.openai.com/docs/api-reference/fine-tunes
|
||||
**/
|
||||
}
|
||||
|
203
src/VastDevelopmentMethod/Openai/Joomla/Openai/Images.php
Normal file
203
src/VastDevelopmentMethod/Openai/Joomla/Openai/Images.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Images
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Images extends Api
|
||||
{
|
||||
/**
|
||||
* Generate an image given a text prompt.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/images/create
|
||||
*
|
||||
* @param string $prompt The text description of the desired image(s).
|
||||
* @param string|null $size The size of the generated images (optional).
|
||||
* @param string|null $responseFormat The format in which the images are returned (optional).
|
||||
* @param int|null $n The number of images to generate (optional).
|
||||
* @param string|null $user A unique identifier representing the end-user (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function generate(
|
||||
string $prompt,
|
||||
?string $size = null,
|
||||
?string $responseFormat = null,
|
||||
?int $n = null,
|
||||
?string $user = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/images/generations";
|
||||
|
||||
// Set the request data.
|
||||
$data = new \stdClass();
|
||||
$data->prompt = $prompt;
|
||||
|
||||
if ($size !== null)
|
||||
{
|
||||
$data->size = $size;
|
||||
}
|
||||
|
||||
if ($responseFormat !== null)
|
||||
{
|
||||
$data->response_format = $responseFormat;
|
||||
}
|
||||
|
||||
if ($n !== null)
|
||||
{
|
||||
$data->n = $n;
|
||||
}
|
||||
|
||||
if ($user !== null)
|
||||
{
|
||||
$data->user = $user;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an image edit with extended options.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/images/create-edit
|
||||
*
|
||||
* @param string $image The original image to edit. Must be a valid PNG file, less than 4MB, and square.
|
||||
* @param string|null $mask An additional image for editing (optional).
|
||||
* @param string $prompt A text description of the desired image(s).
|
||||
* @param string|null $size The size of the generated images (optional).
|
||||
* @param string|null $responseFormat The format in which the images are returned (optional).
|
||||
* @param int|null $n The number of images to generate (optional).
|
||||
* @param string|null $user A unique identifier representing your end-user (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function edit(
|
||||
string $image,
|
||||
string $prompt,
|
||||
?string $mask = null,
|
||||
?string $size = null,
|
||||
?string $responseFormat = null,
|
||||
?int $n = null,
|
||||
?string $user = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/images/edits";
|
||||
|
||||
// Set the image edit data.
|
||||
$data = new \stdClass();
|
||||
$data->image = $image;
|
||||
$data->prompt = $prompt;
|
||||
|
||||
if ($mask !== null)
|
||||
{
|
||||
$data->mask = $mask;
|
||||
}
|
||||
|
||||
if ($size !== null)
|
||||
{
|
||||
$data->size = $size;
|
||||
}
|
||||
|
||||
if ($responseFormat !== null)
|
||||
{
|
||||
$data->response_format = $responseFormat;
|
||||
}
|
||||
|
||||
if ($n !== null)
|
||||
{
|
||||
$data->n = $n;
|
||||
}
|
||||
|
||||
if ($user !== null)
|
||||
{
|
||||
$data->user = $user;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a variation of a given image.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/images/create-variation
|
||||
*
|
||||
* @param string $image The image to use as the basis for the variation(s).
|
||||
* @param string|null $size The size of the generated images (optional).
|
||||
* @param string|null $responseFormat The format in which the generated images are returned (optional).
|
||||
* @param int|null $n The number of images to generate (optional).
|
||||
* @param string|null $user A unique identifier representing your end-user (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function variation(
|
||||
string $image,
|
||||
?string $size = null,
|
||||
?string $responseFormat = null,
|
||||
?int $n = null,
|
||||
?string $user = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/images/variations";
|
||||
|
||||
// Set the image variation data.
|
||||
$data = new \stdClass();
|
||||
$data->image = $image;
|
||||
|
||||
if ($size !== null)
|
||||
{
|
||||
$data->size = $size;
|
||||
}
|
||||
|
||||
if ($responseFormat !== null)
|
||||
{
|
||||
$data->response_format = $responseFormat;
|
||||
}
|
||||
|
||||
if ($n !== null)
|
||||
{
|
||||
$data->n = $n;
|
||||
}
|
||||
|
||||
if ($user !== null)
|
||||
{
|
||||
$data->user = $user;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
44
src/VastDevelopmentMethod/Openai/Joomla/Openai/Models.php
Normal file
44
src/VastDevelopmentMethod/Openai/Joomla/Openai/Models.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Models
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Models extends Api
|
||||
{
|
||||
/**
|
||||
* List the available models from OpenAI API.
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function list(): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/models";
|
||||
|
||||
// Send the get request.
|
||||
return $this->response->get(
|
||||
$this->http->get(
|
||||
$this->uri->get($path)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
60
src/VastDevelopmentMethod/Openai/Joomla/Openai/Moderate.php
Normal file
60
src/VastDevelopmentMethod/Openai/Joomla/Openai/Moderate.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Abstraction\Api;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Moderate
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Moderate extends Api
|
||||
{
|
||||
/**
|
||||
* Classify if text violates OpenAI's Content Policy.
|
||||
* API Ref: https://platform.openai.com/docs/api-reference/moderations/create
|
||||
*
|
||||
* @param string|array $input The input text to classify.
|
||||
* @param string|null $model The moderation model (optional).
|
||||
*
|
||||
* @return object|null
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function text(
|
||||
$input,
|
||||
?string $model = null
|
||||
): ?object
|
||||
{
|
||||
// Build the request path.
|
||||
$path = "/moderations";
|
||||
|
||||
// Set the moderation data.
|
||||
$data = new \stdClass();
|
||||
$data->input = $input;
|
||||
|
||||
if ($model !== null)
|
||||
{
|
||||
$data->model = $model;
|
||||
}
|
||||
|
||||
// Send the post request.
|
||||
return $this->response->get(
|
||||
$this->http->post(
|
||||
$this->uri->get($path), json_encode($data)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
247
src/VastDevelopmentMethod/Openai/Joomla/Openai/Service/Api.php
Normal file
247
src/VastDevelopmentMethod/Openai/Joomla/Openai/Service/Api.php
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai\Service;
|
||||
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Audio;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Chat;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Completions;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Edits;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Embeddings;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Files;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\FineTunes;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Images;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Models;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Moderate;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Api Service
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Api implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->alias(Audio::class, 'Openai.Audio')
|
||||
->share('Openai.Audio', [$this, 'getAudio'], true);
|
||||
|
||||
$container->alias(Chat::class, 'Openai.Chat')
|
||||
->share('Openai.Chat', [$this, 'getChat'], true);
|
||||
|
||||
$container->alias(Completions::class, 'Openai.Completions')
|
||||
->share('Openai.Completions', [$this, 'getCompletions'], true);
|
||||
|
||||
$container->alias(Edits::class, 'Openai.Edits')
|
||||
->share('Openai.Edits', [$this, 'getEdits'], true);
|
||||
|
||||
$container->alias(Embeddings::class, 'Openai.Embeddings')
|
||||
->share('Openai.Embeddings', [$this, 'getEmbeddings'], true);
|
||||
|
||||
$container->alias(Files::class, 'Openai.Files')
|
||||
->share('Openai.Files', [$this, 'getFiles'], true);
|
||||
|
||||
$container->alias(FineTunes::class, 'Openai.FineTunes')
|
||||
->share('Openai.FineTunes', [$this, 'getFineTunes'], true);
|
||||
|
||||
$container->alias(Images::class, 'Openai.Images')
|
||||
->share('Openai.Images', [$this, 'getImages'], true);
|
||||
|
||||
$container->alias(Models::class, 'Openai.Models')
|
||||
->share('Openai.Models', [$this, 'getModels'], true);
|
||||
|
||||
$container->alias(Moderate::class, 'Openai.Moderate')
|
||||
->share('Openai.Moderate', [$this, 'getModerate'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Audio class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Audio
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getAudio(Container $container): Audio
|
||||
{
|
||||
return new Audio(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Chat class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Chat
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getChat(Container $container): Chat
|
||||
{
|
||||
return new Chat(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Completions class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Completions
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getCompletions(Container $container): Completions
|
||||
{
|
||||
return new Completions(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Edits class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Edits
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getEdits(Container $container): Edits
|
||||
{
|
||||
return new Edits(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Embeddings class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Embeddings
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getEmbeddings(Container $container): Embeddings
|
||||
{
|
||||
return new Embeddings(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Files class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Files
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getFiles(Container $container): Files
|
||||
{
|
||||
return new Files(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the FineTunes class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return FineTunes
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getFineTunes(Container $container): FineTunes
|
||||
{
|
||||
return new FineTunes(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Images class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Images
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getImages(Container $container): Images
|
||||
{
|
||||
return new Images(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Models class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Models
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getModels(Container $container): Models
|
||||
{
|
||||
return new Models(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Moderate class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Moderate
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getModerate(Container $container): Moderate
|
||||
{
|
||||
return new Moderate(
|
||||
$container->get('Openai.Utilities.Http'),
|
||||
$container->get('Openai.Utilities.Uri'),
|
||||
$container->get('Openai.Utilities.Response')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai\Service;
|
||||
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Uri;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Response;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Openai\Utilities\Http;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Utilities\Component\Helper;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Utilities Service
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Utilities implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->alias(Uri::class, 'Openai.Utilities.Uri')
|
||||
->share('Openai.Utilities.Uri', [$this, 'getUri'], true);
|
||||
|
||||
$container->alias(Response::class, 'Openai.Utilities.Response')
|
||||
->share('Openai.Utilities.Response', [$this, 'getResponse'], true);
|
||||
|
||||
$container->alias(Http::class, 'Openai.Utilities.Http')
|
||||
->share('Openai.Utilities.Http', [$this, 'getHttp'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Uri class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Uri
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getUri(Container $container): Uri
|
||||
{
|
||||
return new Uri();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Response class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Response
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getResponse(Container $container): Response
|
||||
{
|
||||
return new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Http class
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Http
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getHttp(Container $container): Http
|
||||
{
|
||||
$openai_token = null;
|
||||
$openai_org_token = null;
|
||||
if (Helper::getParams()->get('enable_open_ai') == 1)
|
||||
{
|
||||
$openai_token = Helper::getParams()->get('openai_token');
|
||||
if (Helper::getParams()->get('enable_open_ai_org') == 1)
|
||||
{
|
||||
$openai_org_token = Helper::getParams()->get('openai_org_token');
|
||||
}
|
||||
|
||||
if ($openai_token === 'secret')
|
||||
{
|
||||
$openai_token = null;
|
||||
}
|
||||
|
||||
if ($openai_org_token === 'secret')
|
||||
{
|
||||
$openai_org_token = null;
|
||||
}
|
||||
}
|
||||
|
||||
return new Http(
|
||||
$openai_token,
|
||||
$openai_org_token
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai\Utilities;
|
||||
|
||||
|
||||
use Joomla\CMS\Http\Http as JoomlaHttp;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Http
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
final class Http extends JoomlaHttp
|
||||
{
|
||||
/**
|
||||
* The default Header
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $defaultHeaders = ['Content-Type' => 'application/json'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string|null $token The Openai API token.
|
||||
* @param string|null $orgToken The Openai API Organization token.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @throws \InvalidArgumentException
|
||||
**/
|
||||
public function __construct(?string $token, ?string $orgToken = null)
|
||||
{
|
||||
// add the token if given
|
||||
if (is_string($token))
|
||||
{
|
||||
$this->defaultHeaders['Authorization'] = 'Bearer ' . $token;
|
||||
}
|
||||
|
||||
// add the organization token if given
|
||||
if (is_string($orgToken))
|
||||
{
|
||||
$this->defaultHeaders['OpenAI-Organization'] = $orgToken;
|
||||
}
|
||||
|
||||
// setup config
|
||||
$config = [
|
||||
'userAgent' => 'JoomlaOpenai/3.0',
|
||||
'headers' => $this->defaultHeaders
|
||||
];
|
||||
|
||||
$options = new Registry($config);
|
||||
|
||||
// run parent constructor
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the Tokens.
|
||||
*
|
||||
* @param string|null $token The Openai API token.
|
||||
* @param string|null $orgToken The Openai API Organization token.
|
||||
*
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function setTokens(?string $token = null, ?string $orgToken = null)
|
||||
{
|
||||
// get the current headers
|
||||
$this->defaultHeaders = (array) $this->getOption('headers',
|
||||
$this->defaultHeaders
|
||||
);
|
||||
|
||||
// add the token if given
|
||||
if (is_string($token))
|
||||
{
|
||||
$this->defaultHeaders['Authorization'] = 'Bearer ' . $token;
|
||||
}
|
||||
|
||||
// add the organization token if given
|
||||
if (is_string($orgToken))
|
||||
{
|
||||
$this->defaultHeaders['OpenAI-Organization'] = $orgToken;
|
||||
}
|
||||
|
||||
$this->setOption('headers', $this->defaultHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the User Token.
|
||||
*
|
||||
* @param string $token The API token.
|
||||
*
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function setToken(string $token)
|
||||
{
|
||||
// get the current headers
|
||||
$this->defaultHeaders = (array) $this->getOption('headers',
|
||||
$this->defaultHeaders
|
||||
);
|
||||
|
||||
// add the token
|
||||
$this->defaultHeaders['Authorization'] = 'Bearer ' . $token;
|
||||
|
||||
$this->setOption('headers', $this->defaultHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the Organization Token.
|
||||
*
|
||||
* @param string $token The Organization API token.
|
||||
*
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function setOrgToken(string $token)
|
||||
{
|
||||
// get the current headers
|
||||
$this->defaultHeaders = (array) $this->getOption('headers',
|
||||
$this->defaultHeader
|
||||
);
|
||||
|
||||
// add the token
|
||||
$this->defaultHeaders['OpenAI-Organization'] = $token;
|
||||
|
||||
$this->setOption('headers', $this->defaultHeaders);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai\Utilities;
|
||||
|
||||
|
||||
use Joomla\CMS\Http\Response as JoomlaResponse;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Utilities\JsonHelper;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Utilities\StringHelper;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Response
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
final class Response
|
||||
{
|
||||
/**
|
||||
* Process the response and decode it.
|
||||
*
|
||||
* @param JoomlaResponse $response The response.
|
||||
* @param integer $expectedCode The expected "good" code.
|
||||
* @param mixed $default The default if body not have length
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @throws \DomainException
|
||||
**/
|
||||
public function get($response, int $expectedCode = 200, $default = null)
|
||||
{
|
||||
// Validate the response code.
|
||||
if ($response->code != $expectedCode)
|
||||
{
|
||||
// Decode the error response and throw an exception.
|
||||
$message = $this->error($response);
|
||||
|
||||
// Throw an exception with the OpenAI error message and code.
|
||||
throw new \DomainException($message, $response->code);
|
||||
}
|
||||
|
||||
return $this->body($response, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the response and decode it. (when we have multiple success codes)
|
||||
*
|
||||
* @param JoomlaResponse $response The response.
|
||||
* @param array [$expectedCode => $default] The expected "good" code. and The default if body not have length
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @throws \DomainException
|
||||
**/
|
||||
public function get_($response, array $validate = [200 => null])
|
||||
{
|
||||
// Validate the response code.
|
||||
if (!isset($validate[$response->code]))
|
||||
{
|
||||
// Decode the error response and throw an exception.
|
||||
$message = $this->error($response);
|
||||
|
||||
// Throw an exception with the OpenAI error message and code.
|
||||
throw new \DomainException($message, $response->code);
|
||||
|
||||
}
|
||||
|
||||
return $this->body($response, $validate[$response->code]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the body from the response
|
||||
*
|
||||
* @param JoomlaResponse $response The response.
|
||||
* @param mixed $default The default if body not have length
|
||||
*
|
||||
* @return mixed
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected function body($response, $default = null)
|
||||
{
|
||||
$body = $response->body ?? null;
|
||||
// check that we have a body
|
||||
if (StringHelper::check($body))
|
||||
{
|
||||
if (JsonHelper::check($body))
|
||||
{
|
||||
$body = json_decode((string) $body);
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error message from the OpenAI API response
|
||||
*
|
||||
* @param JoomlaResponse $response The response.
|
||||
*
|
||||
* @return string
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected function error($response): string
|
||||
{
|
||||
// do we have a json string
|
||||
if (isset($response->body) && JsonHelper::check($response->body))
|
||||
{
|
||||
$error = json_decode($response->body);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'Invalid or empty response body.';
|
||||
}
|
||||
|
||||
// check if OpenAI returned an error object
|
||||
if (isset($error->error))
|
||||
{
|
||||
// error object found, extract message and code
|
||||
$errorMessage = isset($error->error->message) ? $error->error->message : 'Unknown error.';
|
||||
$errorCode = isset($error->error->code) ? $error->error->code : 'Unknown error code.';
|
||||
|
||||
// return formatted error message
|
||||
return 'OpenAI Error: ' . $errorMessage . ' Code: ' . $errorCode;
|
||||
}
|
||||
|
||||
return 'No error information found in response.';
|
||||
}
|
||||
}
|
||||
|
115
src/VastDevelopmentMethod/Openai/Joomla/Openai/Utilities/Uri.php
Normal file
115
src/VastDevelopmentMethod/Openai/Joomla/Openai/Utilities/Uri.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 4th September, 2022
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Openai\Utilities;
|
||||
|
||||
|
||||
use Joomla\Uri\Uri as JoomlaUri;
|
||||
|
||||
|
||||
/**
|
||||
* The Openai Uri
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
final class Uri
|
||||
{
|
||||
/**
|
||||
* The api version
|
||||
*
|
||||
* @var string
|
||||
* @since 3.2.0
|
||||
*/
|
||||
private string $version;
|
||||
|
||||
/**
|
||||
* The api URL
|
||||
*
|
||||
* @var string
|
||||
* @since 3.2.0
|
||||
*/
|
||||
private string $url;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $url URL to the openai system
|
||||
* example: https://api.openai.com
|
||||
* @param string $version Version to the openai system
|
||||
*
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function __construct(
|
||||
string $url = 'https://api.openai.com',
|
||||
string $version = 'v1')
|
||||
{
|
||||
// set the API details
|
||||
$this->setUrl($url);
|
||||
$this->setVersion($version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to build and return a full request URL for the request. This method will
|
||||
* add appropriate pagination details if necessary and also prepend the API url
|
||||
* to have a complete URL for the request.
|
||||
*
|
||||
* @param string $path URL to inflect
|
||||
*
|
||||
* @return JoomlaUri
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function get(string $path): JoomlaUri
|
||||
{
|
||||
// Get a new Uri object focusing the api url and given path.
|
||||
$uri = new JoomlaUri($this->api() . $path);
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full API URL
|
||||
*
|
||||
* @return string
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public function api(): string
|
||||
{
|
||||
return $this->url . '/' . $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URL of the API
|
||||
*
|
||||
* @param string $url URL to your openai system
|
||||
* example: https://api.openai.com
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
**/
|
||||
private function setUrl(string $url)
|
||||
{
|
||||
return $this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version of the API
|
||||
*
|
||||
* @param string $version version to your openai API
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
**/
|
||||
private function setVersion($version)
|
||||
{
|
||||
return $this->version = $version;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 3rd September, 2020
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Utilities;
|
||||
|
||||
|
||||
/**
|
||||
* Some array tricks helper
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
abstract class ArrayHelper
|
||||
{
|
||||
/**
|
||||
* Check if have an array with a length
|
||||
*
|
||||
* @input array The array to check
|
||||
*
|
||||
* @returns int|false number of items in array on success
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function check($array, $removeEmptyString = false)
|
||||
{
|
||||
if (is_array($array) && ($nr = count((array) $array)) > 0)
|
||||
{
|
||||
// also make sure the empty strings are removed
|
||||
if ($removeEmptyString)
|
||||
{
|
||||
$array = array_filter($array);
|
||||
|
||||
if ($array === [])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return count($array);
|
||||
}
|
||||
|
||||
return $nr;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge an array of array's
|
||||
*
|
||||
* @input array The arrays you would like to merge
|
||||
*
|
||||
* @returns array|null merged array on success
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function merge($arrays): ?array
|
||||
{
|
||||
if(self::check($arrays))
|
||||
{
|
||||
$merged = [];
|
||||
foreach ($arrays as $array)
|
||||
{
|
||||
if (self::check($array))
|
||||
{
|
||||
$merged = array_merge($merged, $array);
|
||||
}
|
||||
}
|
||||
return $merged;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if arrays intersect
|
||||
*
|
||||
* @input array The first array
|
||||
* @input array The second array
|
||||
*
|
||||
* @returns bool true if intersect else false
|
||||
*
|
||||
* @since 3.1.1
|
||||
*/
|
||||
public static function intersect($a_array, $b_array): bool
|
||||
{
|
||||
// flip the second array
|
||||
$b_array = array_flip($b_array);
|
||||
|
||||
// loop the first array
|
||||
foreach ($a_array as $v)
|
||||
{
|
||||
if (isset($b_array[$v]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,296 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 3rd September, 2020
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Utilities\Component;
|
||||
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Registry\Registry;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Utilities\String\NamespaceHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Some component helper
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
abstract class Helper
|
||||
{
|
||||
/**
|
||||
* The current option
|
||||
*
|
||||
* @var string|null
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static ?string $option = null;
|
||||
|
||||
/**
|
||||
* The component manifest list cache
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static array $manifest = [];
|
||||
|
||||
/**
|
||||
* The component params list cache
|
||||
*
|
||||
* @var Registry[]
|
||||
* @since 3.0.11
|
||||
*/
|
||||
protected static array $params = [];
|
||||
|
||||
/**
|
||||
* Gets the parameter object for the component
|
||||
*
|
||||
* @param string|null $option The option for the component.
|
||||
*
|
||||
* @return Registry A Registry object.
|
||||
* @see Registry
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getParams(?string $option = null): Registry
|
||||
{
|
||||
// check that we have an option
|
||||
if (empty($option))
|
||||
{
|
||||
$option = self::getOption();
|
||||
}
|
||||
|
||||
// get global value
|
||||
if (!isset(self::$params[$option]) || !self::$params[$option] instanceof Registry)
|
||||
{
|
||||
self::$params[$option] = ComponentHelper::getParams($option);
|
||||
}
|
||||
|
||||
return self::$params[$option];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the component option
|
||||
*
|
||||
* @param string|null $option The option
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function setOption(?string $option): void
|
||||
{
|
||||
self::$option = $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component option
|
||||
*
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return string|null A component option
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getOption(?string $default = 'empty'): ?string
|
||||
{
|
||||
if (empty(self::$option))
|
||||
{
|
||||
// get the option from the url input
|
||||
self::$option = (new Input)->getString('option', null);
|
||||
}
|
||||
|
||||
if (empty(self::$option))
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Check if the getInput method exists in the application object
|
||||
if (method_exists($app, 'getInput'))
|
||||
{
|
||||
// get the option from the application
|
||||
self::$option = $app->getInput()->getCmd('option', $default);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the default value if getInput method does not exist
|
||||
self::$option = $default;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component code name
|
||||
*
|
||||
* @param string|null $option The option for the component.
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return string|null A component code name
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getCode(?string $option = null, ?string $default = null): ?string
|
||||
{
|
||||
// check that we have an option
|
||||
if (empty($option))
|
||||
{
|
||||
$option = self::getOption();
|
||||
}
|
||||
// option with com_
|
||||
if (is_string($option) && strpos($option, 'com_') === 0)
|
||||
{
|
||||
return strtolower(trim(substr($option, 4)));
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component abstract helper class
|
||||
*
|
||||
* @param string|null $option The option for the component.
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return string|null A component helper name
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function get(?string $option = null, ?string $default = null): ?string
|
||||
{
|
||||
// check that we have an option
|
||||
// and get the code name from it
|
||||
if (($code_name = self::getCode($option, null)) !== null)
|
||||
{
|
||||
// we build the helper class name
|
||||
$helper_name = '\\' . \ucfirst($code_name) . 'Helper';
|
||||
|
||||
// check if class exist
|
||||
if (class_exists($helper_name))
|
||||
{
|
||||
return $helper_name;
|
||||
}
|
||||
|
||||
// try loading namespace
|
||||
if (($namespace = self::getNamespace($option)) !== null)
|
||||
{
|
||||
$name = \ucfirst($code_name) . 'Helper';
|
||||
$namespace_helper = '\\' . $namespace . '\Administrator\Helper\\' . NamespaceHelper::safeSegment($name); // TODO target site or admin locations not just admin...
|
||||
if (class_exists($namespace_helper))
|
||||
{
|
||||
return $namespace_helper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component namespace if set
|
||||
*
|
||||
* @param string|null $option The option for the component.
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return string|null A component namespace
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getNamespace(?string $option = null): ?string
|
||||
{
|
||||
$manifest = self::getManifest($option);
|
||||
|
||||
return $manifest->namespace ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component abstract helper class
|
||||
*
|
||||
* @param string|null $option The option for the component.
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return object|null A component helper name
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getManifest(?string $option = null): ?object
|
||||
{
|
||||
if ($option === null
|
||||
&& ($option = self::getOption($option)) === null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// get global manifest_cache values
|
||||
if (!isset(self::$manifest[$option]))
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select($db->quoteName('manifest_cache'))
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('type') . ' = ' . $db->quote('component'))
|
||||
->where($db->quoteName('element') . ' LIKE ' . $db->quote($option));
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$manifest = $db->loadResult();
|
||||
self::$manifest[$option] = json_decode($manifest);
|
||||
} catch (\Exception $e) {
|
||||
// Handle the database error appropriately.
|
||||
self::$manifest[$option] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$manifest[$option];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the helper class of this component has a method
|
||||
*
|
||||
* @param string $method The method name to search for
|
||||
* @param string|null $option The option for the component.
|
||||
*
|
||||
* @return bool true if method exist
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function methodExists(string $method, ?string $option = null): bool
|
||||
{
|
||||
// get the helper class
|
||||
return ($helper = self::get($option, null)) !== null &&
|
||||
method_exists($helper, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the helper class of this component has a method, and call it with the arguments
|
||||
*
|
||||
* @param string $method The method name to search for
|
||||
* @param array $arguments The arguments for function.
|
||||
* @param string|null $option The option for the component.
|
||||
*
|
||||
* @return mixed return whatever the method returns or null
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function _(string $method, array $arguments = [], ?string $option = null)
|
||||
{
|
||||
// get the helper class
|
||||
if (($helper = self::get($option, null)) !== null &&
|
||||
method_exists($helper, $method))
|
||||
{
|
||||
// we know this is not ideal...
|
||||
// so we need to move these
|
||||
// functions to their own classes
|
||||
return call_user_func_array([$helper, $method], $arguments);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
258
src/VastDevelopmentMethod/Openai/Joomla/Utilities/GetHelper.php
Normal file
258
src/VastDevelopmentMethod/Openai/Joomla/Utilities/GetHelper.php
Normal file
@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 3rd September, 2020
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Utilities;
|
||||
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Utilities\Component\Helper;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Data\Factory as Data;
|
||||
|
||||
|
||||
/**
|
||||
* Some easy get...
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
abstract class GetHelper
|
||||
{
|
||||
/**
|
||||
* Get a Variable
|
||||
*
|
||||
* @param string|null $table The table from which to get the variable
|
||||
* @param mixed $where The value where
|
||||
* @param string $whereString The target/field string where/name
|
||||
* @param string $what The return field
|
||||
* @param string $operator The operator between $whereString/field and $where/value
|
||||
* @param string $main The component in which the table is found
|
||||
*
|
||||
* @return mixed string/int/float
|
||||
* @since 3.0.9
|
||||
*
|
||||
* @deprecated 5.1 Use Data::_('Load')->table($table)->value(...)
|
||||
*/
|
||||
public static function var(?string $table = null, $where = null,
|
||||
string $whereString = 'user', string $what = 'id',
|
||||
string $operator = '=', ?string $main = null)
|
||||
{
|
||||
if(empty($where))
|
||||
{
|
||||
$where = Factory::getUser()->id;
|
||||
}
|
||||
|
||||
if(empty($main))
|
||||
{
|
||||
$main = Helper::getCode();
|
||||
}
|
||||
|
||||
// Get a db connection.
|
||||
$db = Factory::getDbo();
|
||||
|
||||
// Create a new query object.
|
||||
$query = $db->getQuery(true);
|
||||
$query->select($db->quoteName(array($what)));
|
||||
|
||||
if (empty($table))
|
||||
{
|
||||
$query->from($db->quoteName('#__' . $main));
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->from($db->quoteName('#__' . $main . '_' . $table));
|
||||
}
|
||||
|
||||
if (is_numeric($where))
|
||||
{
|
||||
$query->where($db->quoteName($whereString) . ' ' . $operator . ' ' . (int) $where);
|
||||
}
|
||||
elseif (is_string($where))
|
||||
{
|
||||
$query->where($db->quoteName($whereString) . ' ' . $operator . ' ' . $db->quote((string)$where));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
if ($db->getNumRows())
|
||||
{
|
||||
return $db->loadResult();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of variables
|
||||
*
|
||||
* @param string|null $table The table from which to get the variables
|
||||
* @param mixed $where The value where
|
||||
* @param string $whereString The target/field string where/name
|
||||
* @param string $what The return field
|
||||
* @param string $operator The operator between $whereString/field and $where/value
|
||||
* @param string $main The component in which the table is found
|
||||
* @param bool $unique The switch to return a unique array
|
||||
*
|
||||
* @return array|null
|
||||
* @since 3.0.9
|
||||
*
|
||||
* @deprecated 5.1 Use Data::_('Load')->table($table)->values(...)
|
||||
*/
|
||||
public static function vars(?string $table = null, $where = null,
|
||||
string $whereString = 'user', string $what = 'id', string $operator = 'IN',
|
||||
?string $main = null, bool $unique = true): ?array
|
||||
{
|
||||
if(empty($where))
|
||||
{
|
||||
$where = Factory::getUser()->id;
|
||||
}
|
||||
|
||||
if($main === null)
|
||||
{
|
||||
$main = Helper::getCode();
|
||||
}
|
||||
|
||||
if (!ArrayHelper::check($where) && $where > 0)
|
||||
{
|
||||
$where = [$where];
|
||||
}
|
||||
|
||||
if (ArrayHelper::check($where))
|
||||
{
|
||||
// prep main <-- why? well if $main='' is empty then $table can be categories or users
|
||||
if (StringHelper::check($main))
|
||||
{
|
||||
$main = '_' . ltrim($main, '_');
|
||||
}
|
||||
|
||||
// Get a db connection.
|
||||
$db = Factory::getDbo();
|
||||
|
||||
// Create a new query object.
|
||||
$query = $db->getQuery(true);
|
||||
$query->select($db->quoteName(array($what)));
|
||||
|
||||
if (empty($table))
|
||||
{
|
||||
$query->from($db->quoteName('#__' . $main));
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->from($db->quoteName('#_' . $main . '_' . $table));
|
||||
}
|
||||
|
||||
// add strings to array search
|
||||
if ('IN_STRINGS' === $operator || 'NOT IN_STRINGS' === $operator)
|
||||
{
|
||||
$query->where($db->quoteName($whereString) . ' ' . str_replace('_STRINGS', '', $operator) . ' ("' . implode('","', $where) . '")');
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->where($db->quoteName($whereString) . ' ' . $operator . ' (' . implode(',', $where) . ')');
|
||||
}
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
if ($db->getNumRows())
|
||||
{
|
||||
if ($unique)
|
||||
{
|
||||
return array_unique($db->loadColumn());
|
||||
}
|
||||
return $db->loadColumn();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all strings between two other strings
|
||||
*
|
||||
* @param string $content The content to search
|
||||
* @param string $start The starting value
|
||||
* @param string $end The ending value
|
||||
*
|
||||
* @return array|null On success
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function allBetween(string $content, string $start, string $end): ?array
|
||||
{
|
||||
// reset bucket
|
||||
$bucket = [];
|
||||
for ($i = 0; ; $i++)
|
||||
{
|
||||
// search for string
|
||||
$found = self::between($content, $start, $end);
|
||||
|
||||
if (StringHelper::check($found))
|
||||
{
|
||||
// add to bucket
|
||||
$bucket[] = $found;
|
||||
|
||||
// build removal string
|
||||
$remove = $start . $found . $end;
|
||||
|
||||
// remove from content
|
||||
$content = str_replace($remove, '', $content);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// safety catch
|
||||
if ($i == 500)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// only return unique array of values
|
||||
if (ArrayHelper::check($bucket))
|
||||
{
|
||||
return array_unique($bucket);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a string between two other strings
|
||||
*
|
||||
* @param string $content The content to search
|
||||
* @param string $start The starting value
|
||||
* @param string $end The ending value
|
||||
* @param string $default The default value if none found
|
||||
*
|
||||
* @return string On success / empty string on failure
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function between(string $content, string $start, string $end, string $default = ''): string
|
||||
{
|
||||
$array = explode($start, $content);
|
||||
if (isset($array[1]) && strpos($array[1], $end) !== false)
|
||||
{
|
||||
$array = explode($end, $array[1]);
|
||||
|
||||
// return string found between
|
||||
return $array[0];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
}
|
||||
|
101
src/VastDevelopmentMethod/Openai/Joomla/Utilities/JsonHelper.php
Normal file
101
src/VastDevelopmentMethod/Openai/Joomla/Utilities/JsonHelper.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 3rd September, 2020
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Utilities;
|
||||
|
||||
|
||||
/**
|
||||
* The json checker
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
abstract class JsonHelper
|
||||
{
|
||||
/**
|
||||
* Check if you have a json string
|
||||
*
|
||||
* @input string $string The json string to check
|
||||
*
|
||||
* @returns bool true on success
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function check($string): bool
|
||||
{
|
||||
if (StringHelper::check($string))
|
||||
{
|
||||
json_decode((string) $string);
|
||||
return (json_last_error() === JSON_ERROR_NONE);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a json object to a string
|
||||
*
|
||||
* @input string $value The json string to convert
|
||||
*
|
||||
* @returns a string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function string($value, $separator = ", ", $table = null, $id = 'id', $name = 'name')
|
||||
{
|
||||
// do some table foot work
|
||||
$external = false;
|
||||
if (is_string($table) && strpos((string) $table, '#__') !== false)
|
||||
{
|
||||
$external = true;
|
||||
$table = str_replace('#__', '', (string) $table);
|
||||
}
|
||||
|
||||
// check if string is JSON
|
||||
$result = json_decode((string) $value, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE)
|
||||
{
|
||||
// is JSON
|
||||
if (ArrayHelper::check($result))
|
||||
{
|
||||
if (StringHelper::check($table))
|
||||
{
|
||||
$names = [];
|
||||
foreach ($result as $val)
|
||||
{
|
||||
if ($external)
|
||||
{
|
||||
if ($_name = GetHelper::var(null, $val, $id, $name, '=', $table))
|
||||
{
|
||||
$names[] = $_name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($_name = GetHelper::var($table, $val, $id, $name))
|
||||
{
|
||||
$names[] = $_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ArrayHelper::check($names))
|
||||
{
|
||||
return (string) implode($separator, $names);
|
||||
}
|
||||
}
|
||||
return (string) implode($separator, $result);
|
||||
}
|
||||
return (string) json_decode((string) $value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 3rd September, 2020
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Utilities\String;
|
||||
|
||||
|
||||
use VastDevelopmentMethod\Openai\Joomla\Utilities\StringHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Control the naming of a namespace helper
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
abstract class NamespaceHelper
|
||||
{
|
||||
/**
|
||||
* Making namespace safe
|
||||
*
|
||||
* @param string $string The namespace string you would like to make safe
|
||||
*
|
||||
* @return string on success
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function safe(string $string): string
|
||||
{
|
||||
// Remove leading and trailing backslashes
|
||||
$string = trim($string, '\\');
|
||||
|
||||
// Split the string into namespace segments
|
||||
$segments = explode('\\', $string);
|
||||
|
||||
// make each segment safe
|
||||
$segments = array_map([self::class, 'safeSegment'], $segments);
|
||||
|
||||
// Join the namespace segments back together
|
||||
return implode('\\', $segments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Making one namespace segment safe
|
||||
*
|
||||
* @param string $string The namespace segment string you would like to make safe
|
||||
*
|
||||
* @return string on success
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function safeSegment(string $string): string
|
||||
{
|
||||
// Check if segment starts with a number
|
||||
if (preg_match("/^\d/", $string))
|
||||
{
|
||||
// Extract the starting number(s)
|
||||
preg_match("/^\d+/", $string, $matches);
|
||||
|
||||
if (isset($matches[0]))
|
||||
{
|
||||
$numberWord = StringHelper::numbers($matches[0]);
|
||||
$string = str_replace($matches[0], $numberWord, $string);
|
||||
}
|
||||
}
|
||||
|
||||
// Transliterate string TODO: look again as this makes it lowercase
|
||||
// $segment = StringHelper::transliterate($segment);
|
||||
|
||||
// Make sure segment only contains valid characters
|
||||
return preg_replace("/[^A-Za-z0-9]/", '', $string);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,416 @@
|
||||
<?php
|
||||
/**
|
||||
* @package vdm/openai
|
||||
*
|
||||
* @created 3rd September, 2020
|
||||
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||
* @git VDM OpenAi Library <https://git.vdm.dev/joomla/vdm-openai>
|
||||
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace VastDevelopmentMethod\Openai\Joomla\Utilities;
|
||||
|
||||
|
||||
use Joomla\Filter\InputFilter;
|
||||
use Joomla\CMS\Language\Language;
|
||||
use VastDevelopmentMethod\Openai\Joomla\Utilities\Component\Helper;
|
||||
|
||||
|
||||
/**
|
||||
* Some string tricks
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
abstract class StringHelper
|
||||
{
|
||||
/**
|
||||
* The Main Active Language
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static $langTag;
|
||||
|
||||
/**
|
||||
* Check if we have a string with a length
|
||||
*
|
||||
* @input string $string The string to check
|
||||
*
|
||||
* @returns bool true on success
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function check($string): bool
|
||||
{
|
||||
return is_string($string) && strlen($string) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorten a string
|
||||
*
|
||||
* @input string The sting that you would like to shorten
|
||||
*
|
||||
* @returns string on success
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function shorten($string, $length = 40, $addTip = true)
|
||||
{
|
||||
if (self::check($string))
|
||||
{
|
||||
$initial = strlen((string) $string);
|
||||
$words = preg_split('/([\s\n\r]+)/', (string) $string, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$words_count = count((array)$words);
|
||||
|
||||
$word_length = 0;
|
||||
$last_word = 0;
|
||||
for (; $last_word < $words_count; ++$last_word)
|
||||
{
|
||||
$word_length += strlen($words[$last_word]);
|
||||
if ($word_length > $length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$newString = implode(array_slice($words, 0, $last_word));
|
||||
$final = strlen($newString);
|
||||
if ($initial !== $final && $addTip)
|
||||
{
|
||||
$title = self::shorten($string, 400 , false);
|
||||
return '<span class="hasTip" title="' . $title . '" style="cursor:help">' . trim($newString) . '...</span>';
|
||||
}
|
||||
elseif ($initial !== $final && !$addTip)
|
||||
{
|
||||
return trim($newString) . '...';
|
||||
}
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Making strings safe (various ways)
|
||||
*
|
||||
* @input string The you would like to make safe
|
||||
*
|
||||
* @returns string on success
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function safe($string, $type = 'L', $spacer = '_', $replaceNumbers = true, $keepOnlyCharacters = true)
|
||||
{
|
||||
if ($replaceNumbers === true)
|
||||
{
|
||||
// remove all numbers and replace with English text version (works well only up to millions)
|
||||
$string = self::numbers($string);
|
||||
}
|
||||
// 0nly continue if we have a string
|
||||
if (self::check($string))
|
||||
{
|
||||
// create file name without the extension that is safe
|
||||
if ($type === 'filename')
|
||||
{
|
||||
// make sure VDM is not in the string
|
||||
$string = str_replace('VDM', 'vDm', (string) $string);
|
||||
// Remove anything which isn't a word, whitespace, number
|
||||
// or any of the following caracters -_()
|
||||
// If you don't need to handle multi-byte characters
|
||||
// you can use preg_replace rather than mb_ereg_replace
|
||||
// Thanks @Łukasz Rysiak!
|
||||
// $string = mb_ereg_replace("([^\w\s\d\-_\(\)])", '', $string);
|
||||
$string = preg_replace("([^\w\s\d\-_\(\)])", '', $string);
|
||||
|
||||
// http://stackoverflow.com/a/2021729/1429677
|
||||
return preg_replace('/\s+/', ' ', (string) $string);
|
||||
}
|
||||
// remove all other characters
|
||||
$string = trim((string) $string);
|
||||
$string = preg_replace('/'.$spacer.'+/', ' ', $string);
|
||||
$string = preg_replace('/\s+/', ' ', $string);
|
||||
// Transliterate string
|
||||
$string = self::transliterate($string);
|
||||
// remove all and keep only characters
|
||||
if ($keepOnlyCharacters)
|
||||
{
|
||||
$string = preg_replace("/[^A-Za-z ]/", '', (string) $string);
|
||||
}
|
||||
// keep both numbers and characters
|
||||
else
|
||||
{
|
||||
$string = preg_replace("/[^A-Za-z0-9 ]/", '', (string) $string);
|
||||
}
|
||||
// select final adaptations
|
||||
if ($type === 'L' || $type === 'strtolower')
|
||||
{
|
||||
// replace white space with underscore
|
||||
$string = preg_replace('/\s+/', (string) $spacer, (string) $string);
|
||||
// default is to return lower
|
||||
return strtolower($string);
|
||||
}
|
||||
elseif ($type === 'W')
|
||||
{
|
||||
// return a string with all first letter of each word uppercase(no underscore)
|
||||
return ucwords(strtolower($string));
|
||||
}
|
||||
elseif ($type === 'w' || $type === 'word')
|
||||
{
|
||||
// return a string with all lowercase(no underscore)
|
||||
return strtolower($string);
|
||||
}
|
||||
elseif ($type === 'Ww' || $type === 'Word')
|
||||
{
|
||||
// return a string with first letter of the first word uppercase and all the rest lowercase(no underscore)
|
||||
return ucfirst(strtolower($string));
|
||||
}
|
||||
elseif ($type === 'WW' || $type === 'WORD')
|
||||
{
|
||||
// return a string with all the uppercase(no underscore)
|
||||
return strtoupper($string);
|
||||
}
|
||||
elseif ($type === 'U' || $type === 'strtoupper')
|
||||
{
|
||||
// replace white space with underscore
|
||||
$string = preg_replace('/\s+/', (string) $spacer, $string);
|
||||
// return all upper
|
||||
return strtoupper($string);
|
||||
}
|
||||
elseif ($type === 'F' || $type === 'ucfirst')
|
||||
{
|
||||
// replace white space with underscore
|
||||
$string = preg_replace('/\s+/', (string) $spacer, $string);
|
||||
// return with first character to upper
|
||||
return ucfirst(strtolower($string));
|
||||
}
|
||||
elseif ($type === 'cA' || $type === 'cAmel' || $type === 'camelcase')
|
||||
{
|
||||
// convert all words to first letter uppercase
|
||||
$string = ucwords(strtolower($string));
|
||||
// remove white space
|
||||
$string = preg_replace('/\s+/', '', $string);
|
||||
// now return first letter lowercase
|
||||
return lcfirst($string);
|
||||
}
|
||||
// return string
|
||||
return $string;
|
||||
}
|
||||
// not a string
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert none English strings to code usable string
|
||||
*
|
||||
* @input an string
|
||||
*
|
||||
* @returns a string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function transliterate($string)
|
||||
{
|
||||
// set tag only once
|
||||
if (!self::check(self::$langTag))
|
||||
{
|
||||
// get global value
|
||||
self::$langTag = Helper::getParams()->get('language', 'en-GB');
|
||||
}
|
||||
|
||||
// Transliterate on the language requested
|
||||
$lang = Language::getInstance(self::$langTag);
|
||||
|
||||
return $lang->transliterate($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* make sure a string is HTML save
|
||||
*
|
||||
* @input an html string
|
||||
*
|
||||
* @returns a string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function html($var, $charset = 'UTF-8', $shorten = false, $length = 40, $addTip = true)
|
||||
{
|
||||
if (self::check($var))
|
||||
{
|
||||
$filter = new InputFilter();
|
||||
$string = $filter->clean(
|
||||
html_entity_decode(
|
||||
htmlentities(
|
||||
(string) $var,
|
||||
ENT_COMPAT,
|
||||
$charset
|
||||
)
|
||||
),
|
||||
'HTML'
|
||||
);
|
||||
if ($shorten)
|
||||
{
|
||||
return self::shorten($string, $length, $addTip);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all int in a string to an English word string
|
||||
*
|
||||
* @input an string with numbers
|
||||
*
|
||||
* @returns a string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function numbers($string)
|
||||
{
|
||||
// set numbers array
|
||||
$numbers = [];
|
||||
$search_replace= [];
|
||||
|
||||
// first get all numbers
|
||||
preg_match_all('!\d+!', (string) $string, $numbers);
|
||||
|
||||
// check if we have any numbers
|
||||
if (isset($numbers[0]) && ArrayHelper::check($numbers[0]))
|
||||
{
|
||||
foreach ($numbers[0] as $number)
|
||||
{
|
||||
$search_replace[$number] = self::number((int)$number);
|
||||
}
|
||||
|
||||
// now replace numbers in string
|
||||
$string = str_replace(array_keys($search_replace), array_values($search_replace), (string) $string);
|
||||
|
||||
// check if we missed any, strange if we did.
|
||||
return self::numbers($string);
|
||||
}
|
||||
|
||||
// return the string with no numbers remaining.
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an integer into an English word string
|
||||
* Thanks to Tom Nicholson <http://php.net/manual/en/function.strval.php#41988>
|
||||
*
|
||||
* @input an int
|
||||
* @returns a string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function number($x)
|
||||
{
|
||||
$nwords = array( "zero", "one", "two", "three", "four", "five", "six", "seven",
|
||||
"eight", "nine", "ten", "eleven", "twelve", "thirteen",
|
||||
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
|
||||
"nineteen", "twenty", 30 => "thirty", 40 => "forty",
|
||||
50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty",
|
||||
90 => "ninety" );
|
||||
|
||||
if(!is_numeric($x))
|
||||
{
|
||||
$w = $x;
|
||||
}
|
||||
elseif(fmod($x, 1) != 0)
|
||||
{
|
||||
$w = $x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($x < 0)
|
||||
{
|
||||
$w = 'minus ';
|
||||
$x = -$x;
|
||||
}
|
||||
else
|
||||
{
|
||||
$w = '';
|
||||
// ... now $x is a non-negative integer.
|
||||
}
|
||||
|
||||
if($x < 21) // 0 to 20
|
||||
{
|
||||
$w .= $nwords[$x];
|
||||
}
|
||||
elseif($x < 100) // 21 to 99
|
||||
{
|
||||
$w .= $nwords[10 * floor($x/10)];
|
||||
$r = fmod($x, 10);
|
||||
if($r > 0)
|
||||
{
|
||||
$w .= ' ' . $nwords[$r];
|
||||
}
|
||||
}
|
||||
elseif($x < 1000) // 100 to 999
|
||||
{
|
||||
$w .= $nwords[floor($x/100)] .' hundred';
|
||||
$r = fmod($x, 100);
|
||||
if($r > 0)
|
||||
{
|
||||
$w .= ' and '. self::number($r);
|
||||
}
|
||||
}
|
||||
elseif($x < 1000000) // 1000 to 999999
|
||||
{
|
||||
$w .= self::number(floor($x/1000)) .' thousand';
|
||||
$r = fmod($x, 1000);
|
||||
if($r > 0)
|
||||
{
|
||||
$w .= ' ';
|
||||
if($r < 100)
|
||||
{
|
||||
$w .= 'and ';
|
||||
}
|
||||
$w .= self::number($r);
|
||||
}
|
||||
}
|
||||
else // millions
|
||||
{
|
||||
$w .= self::number(floor($x/1000000)) .' million';
|
||||
$r = fmod($x, 1000000);
|
||||
if($r > 0)
|
||||
{
|
||||
$w .= ' ';
|
||||
if($r < 100)
|
||||
{
|
||||
$w .= 'and ';
|
||||
}
|
||||
$w .= self::number($r);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Random Key
|
||||
*
|
||||
* @input int $size The size of the random string
|
||||
*
|
||||
* @returns a string
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function random(int $size): string
|
||||
{
|
||||
$bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ";
|
||||
$key = [];
|
||||
$bagsize = strlen($bag) - 1;
|
||||
|
||||
for ($i = 0; $i < $size; $i++)
|
||||
{
|
||||
$get = rand(0, $bagsize);
|
||||
$key[] = $bag[$get];
|
||||
}
|
||||
|
||||
return implode($key);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user