Compare commits
16 Commits
899b034013
...
main
Author | SHA1 | Date | |
---|---|---|---|
6346aae533
|
|||
d6c646e45c
|
|||
d7030d3dd4
|
|||
2ab290c712
|
|||
b18e2ceea2
|
|||
56078fabad
|
|||
5d009163f0
|
|||
4ceeba7f4b
|
|||
7f0f8ac95b
|
|||
848c1ae91e
|
|||
3cc7c812e8
|
|||
77ae2cc627
|
|||
62820fd272
|
|||
2f5aa63306
|
|||
7f16b67d02
|
|||
4a3bbeec79
|
@ -1,8 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"com.thorlaksson.phpcs.formatOnSave" : true,
|
||||||
"com.thorlaksson.phpcs.runOnChange" : "onSave",
|
"com.thorlaksson.phpcs.runOnChange" : "onSave",
|
||||||
"com.thorlaksson.phpcs.standard" : "phpcs.xml",
|
"com.thorlaksson.phpcs.standard" : "phpcs.xml",
|
||||||
"editor.default_syntax" : "php",
|
"editor.default_syntax" : "php",
|
||||||
"php.validate" : "onSave",
|
"php.validate" : "onSave",
|
||||||
|
"prettier.format-on-save" : "Disable",
|
||||||
|
"prettier.format-on-save.ignore-remote" : "Disable",
|
||||||
|
"prettier.format-on-save.ignore-without-config" : "Disable",
|
||||||
"workspace.color" : 1,
|
"workspace.color" : 1,
|
||||||
"workspace.name" : "APnutI"
|
"workspace.name" : "APnutI"
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"ignoredFilePatterns" : [
|
"ignoredFilePatterns" : [
|
||||||
"logs"
|
"logs"
|
||||||
],
|
],
|
||||||
"remotePath" : "\/var\/www\/html\/Dragonpolls\/vendor\/hutattedonmyarm\/apnuti",
|
"remotePath" : "\/var\/www\/dragonpolls\/vendor\/hutattedonmyarm\/apnuti",
|
||||||
"server" : "Phlaym",
|
"server" : "Rabenberger Photos",
|
||||||
"usesPublishing" : true
|
"usesPublishing" : true
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
"keywords": ["pnut", "api"],
|
"keywords": ["pnut", "api"],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"monolog/monolog": "^2.0",
|
"monolog/monolog": "^3.0",
|
||||||
"psr/log": "^1.1",
|
"psr/log": "^2.0 || ^3.0",
|
||||||
"php": "^7.4|^8.0",
|
"php": "^8.3",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
|
83
composer.lock
generated
83
composer.lock
generated
@ -4,63 +4,70 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "3c041ce633113232f43e991a77d802f9",
|
"content-hash": "fd959c4dda47577b06ccb0f69ab89de8",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "2.2.0",
|
"version": "3.9.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Seldaek/monolog.git",
|
"url": "https://github.com/Seldaek/monolog.git",
|
||||||
"reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084"
|
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/1cb1cde8e8dd0f70cc0fe51354a59acad9302084",
|
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6",
|
||||||
"reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084",
|
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.2",
|
"php": ">=8.1",
|
||||||
"psr/log": "^1.0.1"
|
"psr/log": "^2.0 || ^3.0"
|
||||||
},
|
},
|
||||||
"provide": {
|
"provide": {
|
||||||
"psr/log-implementation": "1.0.0"
|
"psr/log-implementation": "3.0.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
|
"aws/aws-sdk-php": "^3.0",
|
||||||
"doctrine/couchdb": "~1.0@dev",
|
"doctrine/couchdb": "~1.0@dev",
|
||||||
"elasticsearch/elasticsearch": "^7",
|
"elasticsearch/elasticsearch": "^7 || ^8",
|
||||||
"graylog2/gelf-php": "^1.4.2",
|
"ext-json": "*",
|
||||||
|
"graylog2/gelf-php": "^1.4.2 || ^2.0",
|
||||||
|
"guzzlehttp/guzzle": "^7.4.5",
|
||||||
|
"guzzlehttp/psr7": "^2.2",
|
||||||
"mongodb/mongodb": "^1.8",
|
"mongodb/mongodb": "^1.8",
|
||||||
"php-amqplib/php-amqplib": "~2.4",
|
"php-amqplib/php-amqplib": "~2.4 || ^3",
|
||||||
"php-console/php-console": "^3.1.3",
|
"php-console/php-console": "^3.1.8",
|
||||||
"phpspec/prophecy": "^1.6.1",
|
"phpstan/phpstan": "^2",
|
||||||
"phpstan/phpstan": "^0.12.59",
|
"phpstan/phpstan-deprecation-rules": "^2",
|
||||||
"phpunit/phpunit": "^8.5",
|
"phpstan/phpstan-strict-rules": "^2",
|
||||||
"predis/predis": "^1.1",
|
"phpunit/phpunit": "^10.5.17 || ^11.0.7",
|
||||||
"rollbar/rollbar": "^1.3",
|
"predis/predis": "^1.1 || ^2",
|
||||||
"ruflin/elastica": ">=0.90 <7.0.1",
|
"rollbar/rollbar": "^4.0",
|
||||||
"swiftmailer/swiftmailer": "^5.3|^6.0"
|
"ruflin/elastica": "^7 || ^8",
|
||||||
|
"symfony/mailer": "^5.4 || ^6",
|
||||||
|
"symfony/mime": "^5.4 || ^6"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
||||||
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
||||||
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
|
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
|
||||||
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
||||||
|
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
|
||||||
"ext-mbstring": "Allow to work properly with unicode symbols",
|
"ext-mbstring": "Allow to work properly with unicode symbols",
|
||||||
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
|
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
|
||||||
|
"ext-openssl": "Required to send log messages using SSL",
|
||||||
|
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
|
||||||
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||||
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
|
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
|
||||||
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
|
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
|
||||||
"php-console/php-console": "Allow sending log messages to Google Chrome",
|
|
||||||
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
||||||
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
|
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "2.x-dev"
|
"dev-main": "3.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@ -88,7 +95,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/Seldaek/monolog/issues",
|
"issues": "https://github.com/Seldaek/monolog/issues",
|
||||||
"source": "https://github.com/Seldaek/monolog/tree/2.2.0"
|
"source": "https://github.com/Seldaek/monolog/tree/3.9.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -100,34 +107,34 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-14T13:15:25+00:00"
|
"time": "2025-03-24T10:02:05+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/log",
|
"name": "psr/log",
|
||||||
"version": "1.1.3",
|
"version": "3.0.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/php-fig/log.git",
|
"url": "https://github.com/php-fig/log.git",
|
||||||
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
|
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
|
"url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||||
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
|
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.0"
|
"php": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.1.x-dev"
|
"dev-master": "3.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Psr\\Log\\": "Psr/Log/"
|
"Psr\\Log\\": "src"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
@ -137,7 +144,7 @@
|
|||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "PHP-FIG",
|
"name": "PHP-FIG",
|
||||||
"homepage": "http://www.php-fig.org/"
|
"homepage": "https://www.php-fig.org/"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Common interface for logging libraries",
|
"description": "Common interface for logging libraries",
|
||||||
@ -148,24 +155,24 @@
|
|||||||
"psr-3"
|
"psr-3"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/php-fig/log/tree/1.1.3"
|
"source": "https://github.com/php-fig/log/tree/3.0.2"
|
||||||
},
|
},
|
||||||
"time": "2020-03-23T09:12:05+00:00"
|
"time": "2024-09-11T13:17:53+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": [],
|
"stability-flags": {},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^7.4|^8.0",
|
"php": "^8.3",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-mbstring": "*"
|
"ext-mbstring": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.0.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
<property name="eolChar" value="\n"/>
|
<property name="eolChar" value="\n"/>
|
||||||
</properties>
|
</properties>
|
||||||
</rule>
|
</rule>
|
||||||
<arg name="tab-width" value="2"/>
|
<arg name="tab-width" value="4"/>
|
||||||
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="indent" value="2"/>
|
<property name="indent" value="4"/>
|
||||||
</properties>
|
</properties>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
292
src/APnutI.php
292
src/APnutI.php
@ -7,7 +7,6 @@ use APnutI\Entities\Poll;
|
|||||||
use APnutI\Entities\User;
|
use APnutI\Entities\User;
|
||||||
use APnutI\Entities\Channel;
|
use APnutI\Entities\Channel;
|
||||||
use APnutI\Exceptions\PnutException;
|
use APnutI\Exceptions\PnutException;
|
||||||
use APnutI\Exceptions\NotFoundException;
|
|
||||||
use APnutI\Exceptions\NotAuthorizedException;
|
use APnutI\Exceptions\NotAuthorizedException;
|
||||||
use APnutI\Exceptions\HttpPnutException;
|
use APnutI\Exceptions\HttpPnutException;
|
||||||
use APnutI\Exceptions\HttpPnutRedirectException;
|
use APnutI\Exceptions\HttpPnutRedirectException;
|
||||||
@ -15,8 +14,12 @@ use APnutI\Exceptions\NotSupportedPollException;
|
|||||||
use APnutI\Exceptions\HttpPnutForbiddenException;
|
use APnutI\Exceptions\HttpPnutForbiddenException;
|
||||||
use APnutI\Exceptions\PollAccessRestrictedException;
|
use APnutI\Exceptions\PollAccessRestrictedException;
|
||||||
use APnutI\Meta;
|
use APnutI\Meta;
|
||||||
|
use APnutI\Logger\LevelNamePaddingProcessor;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use Monolog\Handler\RotatingFileHandler;
|
use Monolog\Handler\RotatingFileHandler;
|
||||||
|
use Monolog\Handler\StreamHandler;
|
||||||
|
use Monolog\Handler\SyslogHandler;
|
||||||
|
use Monolog\Formatter\LineFormatter;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Psr\Log\NullLogger;
|
use Psr\Log\NullLogger;
|
||||||
|
|
||||||
@ -26,7 +29,7 @@ class APnutI
|
|||||||
protected string $auth_url = 'https://pnut.io/oauth/authenticate';
|
protected string $auth_url = 'https://pnut.io/oauth/authenticate';
|
||||||
protected string $client_secret;
|
protected string $client_secret;
|
||||||
protected string $client_id;
|
protected string $client_id;
|
||||||
protected string $scope = "";
|
protected string $scope = '';
|
||||||
protected string $redirect_uri;
|
protected string $redirect_uri;
|
||||||
protected int $rate_limit = 40;
|
protected int $rate_limit = 40;
|
||||||
protected int $rate_limit_remaining = 40;
|
protected int $rate_limit_remaining = 40;
|
||||||
@ -79,19 +82,45 @@ class APnutI
|
|||||||
?string $app_name = null,
|
?string $app_name = null,
|
||||||
?string $redirect_uri = null,
|
?string $redirect_uri = null,
|
||||||
?string $log_path = null,
|
?string $log_path = null,
|
||||||
$log_level = null
|
string|int|null $log_level = null,
|
||||||
|
bool $use_rotating_file_handler = true,
|
||||||
|
bool $use_stream_handler = false,
|
||||||
|
bool $use_syslog_handler = false,
|
||||||
) {
|
) {
|
||||||
|
if (!empty($app_name)) {
|
||||||
|
$this->app_name = $app_name;
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($log_level)) {
|
if (empty($log_level)) {
|
||||||
$log_level = Logger::INFO;
|
$log_level = Logger::INFO;
|
||||||
} elseif (is_string($log_level)) {
|
} elseif (is_string($log_level)) {
|
||||||
$log_level = constant('Monolog\Logger::' . $log_level);
|
$log_level = constant('Monolog\Logger::' . $log_level);
|
||||||
}
|
}
|
||||||
$this->logger = empty($log_path) ? new NullLogger() : new Logger($this->app_name);
|
$this->logger = empty($log_path)
|
||||||
|
? new NullLogger()
|
||||||
|
: new Logger($this->app_name);
|
||||||
$this->token_session_key = $this->app_name . 'access_token';
|
$this->token_session_key = $this->app_name . 'access_token';
|
||||||
$this->token_redirect_after_auth = $this->app_name
|
$this->token_redirect_after_auth = $this->app_name . 'redirect_after_auth';
|
||||||
.'redirect_after_auth';
|
|
||||||
|
$this->logger->pushProcessor(new LevelNamePaddingProcessor());
|
||||||
|
$formatter = new LineFormatter("[%datetime%] %channel%.%extra.level_padded%: %message% %context% %extra%\n");
|
||||||
|
|
||||||
|
if ($use_rotating_file_handler) {
|
||||||
$handler = new RotatingFileHandler($log_path, 5, $log_level, true);
|
$handler = new RotatingFileHandler($log_path, 5, $log_level, true);
|
||||||
|
$handler->setFormatter($formatter);
|
||||||
$this->logger->pushHandler($handler);
|
$this->logger->pushHandler($handler);
|
||||||
|
}
|
||||||
|
if ($use_stream_handler) {
|
||||||
|
$handler = new StreamHandler($log_path, $log_level, true);
|
||||||
|
$handler->setFormatter($formatter);
|
||||||
|
$this->logger->pushHandler($handler);
|
||||||
|
}
|
||||||
|
if ($use_syslog_handler) {
|
||||||
|
$handler = new SyslogHandler($this->app_name, \LOG_USER, $log_level, true);
|
||||||
|
$handler->setFormatter($formatter);
|
||||||
|
$this->logger->pushHandler($handler);
|
||||||
|
}
|
||||||
|
|
||||||
$this->server_token = null;
|
$this->server_token = null;
|
||||||
$this->logger->debug('__construct API');
|
$this->logger->debug('__construct API');
|
||||||
if (isset($_SESSION[$this->token_session_key])) {
|
if (isset($_SESSION[$this->token_session_key])) {
|
||||||
@ -112,9 +141,6 @@ class APnutI
|
|||||||
if (!empty($redirect_uri)) {
|
if (!empty($redirect_uri)) {
|
||||||
$this->redirect_uri = $redirect_uri;
|
$this->redirect_uri = $redirect_uri;
|
||||||
}
|
}
|
||||||
if (!empty($app_name)) {
|
|
||||||
$this->app_name = $app_name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,9 +197,7 @@ class APnutI
|
|||||||
$this->logger->debug(
|
$this->logger->debug(
|
||||||
'Is redirect. Headers: ' . json_encode($this->headers)
|
'Is redirect. Headers: ' . json_encode($this->headers)
|
||||||
);
|
);
|
||||||
$this->logger->debug(
|
$this->logger->debug('Is redirect. Target: ' . $v);
|
||||||
'Is redirect. Target: '. $v
|
|
||||||
);
|
|
||||||
$this->redirect_target = $v;
|
$this->redirect_target = $v;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -188,7 +212,6 @@ class APnutI
|
|||||||
string $content_type = 'application/x-www-form-urlencoded',
|
string $content_type = 'application/x-www-form-urlencoded',
|
||||||
bool $follow_redirect = true
|
bool $follow_redirect = true
|
||||||
): array {
|
): array {
|
||||||
|
|
||||||
$this->redirect_target = null;
|
$this->redirect_target = null;
|
||||||
$this->meta = null;
|
$this->meta = null;
|
||||||
$method = strtoupper($method);
|
$method = strtoupper($method);
|
||||||
@ -201,26 +224,29 @@ class APnutI
|
|||||||
// if they passed an array, build a list of parameters from it
|
// if they passed an array, build a list of parameters from it
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
if (is_array($parameters) && $method !== 'POST-RAW') {
|
if (is_array($parameters) && $method !== 'POST-RAW') {
|
||||||
$parameters = $content_type === 'application/json' ? json_encode($parameters) : http_build_query($parameters);
|
$parameters =
|
||||||
|
$content_type === 'application/json'
|
||||||
|
? json_encode($parameters)
|
||||||
|
: http_build_query($parameters);
|
||||||
}
|
}
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
|
||||||
$headers[] = "Content-Type: ".$content_type;
|
$headers[] = 'Content-Type: ' . $content_type;
|
||||||
}
|
}
|
||||||
if ($method !== 'POST' && $method !== 'POST-RAW') {
|
if ($method !== 'POST' && $method !== 'POST-RAW') {
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||||
}
|
}
|
||||||
if ($method === 'GET' && isset($parameters['access_token'])) {
|
if ($method === 'GET' && isset($parameters['access_token'])) {
|
||||||
$this->logger->info("Using provided token for auth");
|
$this->logger->info('Using provided token for auth');
|
||||||
$headers[] = 'Authorization: Bearer '.$params['access_token'];
|
$headers[] = 'Authorization: Bearer ' . $parameters['access_token'];
|
||||||
} elseif (!empty($this->access_token)) {
|
} elseif (!empty($this->access_token)) {
|
||||||
$this->logger->info("Using access token for auth");
|
$this->logger->info('Using access token for auth');
|
||||||
$headers[] = 'Authorization: Bearer ' . $this->access_token;
|
$headers[] = 'Authorization: Bearer ' . $this->access_token;
|
||||||
} elseif (!empty($this->server_token)) {
|
} elseif (!empty($this->server_token)) {
|
||||||
$use_server_token = true;
|
$use_server_token = true;
|
||||||
$this->logger->info("Using server token for auth");
|
$this->logger->info('Using server token for auth');
|
||||||
$headers[] = 'Authorization: Bearer ' . $this->server_token;
|
$headers[] = 'Authorization: Bearer ' . $this->server_token;
|
||||||
} else {
|
} else {
|
||||||
$this->logger->info("Using no auth");
|
$this->logger->info('Using no auth');
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
@ -231,15 +257,18 @@ class APnutI
|
|||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
$request = curl_getinfo($ch, CURLINFO_HEADER_OUT);
|
$request = curl_getinfo($ch, CURLINFO_HEADER_OUT);
|
||||||
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
$effectiveURL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
$this->logger->debug("{$method} Request to {$url}. Received status: {$http_status}. Response: {$response}");
|
$this->logger->debug(
|
||||||
|
"{$method} Request to {$url}. Received status: {$http_status}. Response: {$response}"
|
||||||
|
);
|
||||||
if ($http_status === 0) {
|
if ($http_status === 0) {
|
||||||
throw new \Exception('Unable to connect to Pnut ' . $url);
|
throw new \Exception('Unable to connect to Pnut ' . $url);
|
||||||
}
|
}
|
||||||
if ($request === false) {
|
if ($request === false) {
|
||||||
if (!curl_getinfo($ch, CURLINFO_SSL_VERIFYRESULT)) {
|
if (!curl_getinfo($ch, CURLINFO_SSL_VERIFYRESULT)) {
|
||||||
throw new \Exception('SSL verification failed, connection terminated: ' . $url);
|
throw new \Exception(
|
||||||
|
'SSL verification failed, connection terminated: ' . $url
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty($response)) {
|
if (!empty($response)) {
|
||||||
@ -281,13 +310,19 @@ class APnutI
|
|||||||
// look for errors
|
// look for errors
|
||||||
if (isset($response['error'])) {
|
if (isset($response['error'])) {
|
||||||
if (is_array($response['error'])) {
|
if (is_array($response['error'])) {
|
||||||
throw new PnutException($response['error']['message'], $response['error']['code']);
|
throw new PnutException(
|
||||||
|
$response['error']['message'],
|
||||||
|
$response['error']['code']
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new PnutException($response['error']);
|
throw new PnutException($response['error']);
|
||||||
}
|
}
|
||||||
// look for response migration errors
|
// look for response migration errors
|
||||||
} elseif (isset($response['meta'], $response['meta']['error_message'])) {
|
} elseif (isset($response['meta'], $response['meta']['error_message'])) {
|
||||||
throw new PnutException($response['meta']['error_message'], $response['meta']['code']);
|
throw new PnutException(
|
||||||
|
$response['meta']['error_message'],
|
||||||
|
$response['meta']['code']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,7 +335,11 @@ class APnutI
|
|||||||
} elseif (!empty($this->redirect_target)) {
|
} elseif (!empty($this->redirect_target)) {
|
||||||
return [$this->redirect_target];
|
return [$this->redirect_target];
|
||||||
} else {
|
} else {
|
||||||
throw new PnutException("No response ".json_encode($response).", http status: ${http_status}");
|
throw new PnutException(
|
||||||
|
'No response ' .
|
||||||
|
json_encode($response) .
|
||||||
|
", http status: {$http_status}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,10 +352,8 @@ class APnutI
|
|||||||
return $this->makeRequest($method, $end_point, $parameters, $content_type);
|
return $this->makeRequest($method, $end_point, $parameters, $content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postJson(
|
public function postJson(string $end_point, array $parameters): array
|
||||||
string $end_point,
|
{
|
||||||
array $parameters
|
|
||||||
): array {
|
|
||||||
return $this->post($end_point, $parameters, 'application/json');
|
return $this->post($end_point, $parameters, 'application/json');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,35 +369,50 @@ class APnutI
|
|||||||
$end_point .= $separator . http_build_query($parameters);
|
$end_point .= $separator . http_build_query($parameters);
|
||||||
$parameters = [];
|
$parameters = [];
|
||||||
}
|
}
|
||||||
return $this->makeRequest('get', $end_point, $parameters, $content_type, $follow_redirect);
|
return $this->makeRequest(
|
||||||
|
'get',
|
||||||
|
$end_point,
|
||||||
|
$parameters,
|
||||||
|
$content_type,
|
||||||
|
$follow_redirect
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAuthURL()
|
public function getAuthURL($append_redirect_query_string = null)
|
||||||
{
|
{
|
||||||
$url = $this->auth_url
|
$redirect_uri = $this->redirect_uri;
|
||||||
. '?client_id='
|
if (!empty($append_redirect_query_string)) {
|
||||||
. $this->client_id
|
$redirect_uri .= $append_redirect_query_string;
|
||||||
. '&redirect_uri='
|
}
|
||||||
. urlencode($this->redirect_uri)
|
$url =
|
||||||
. '&scope='.$this->needed_scope
|
$this->auth_url .
|
||||||
. '&response_type=code';
|
'?client_id=' .
|
||||||
|
$this->client_id .
|
||||||
|
'&redirect_uri=' .
|
||||||
|
urlencode($redirect_uri) .
|
||||||
|
'&scope=' .
|
||||||
|
$this->needed_scope .
|
||||||
|
'&response_type=code';
|
||||||
$this->logger->debug('Auth URL: ' . $url);
|
$this->logger->debug('Auth URL: ' . $url);
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Ping server and validate token
|
//TODO: Ping server and validate token
|
||||||
public function isAuthenticated(bool $allow_server_token = false, bool $skip_verify_token = false): bool
|
public function isAuthenticated(
|
||||||
{
|
bool $allow_server_token = false,
|
||||||
$is_authenticated = ($allow_server_token && !empty($this->server_token))
|
bool $skip_verify_token = false
|
||||||
|| isset($this->access_token);
|
): bool {
|
||||||
$log_str = $is_authenticated
|
$is_authenticated =
|
||||||
? 'Authenticated'
|
($allow_server_token && !empty($this->server_token)) ||
|
||||||
: 'Not authenticated';
|
isset($this->access_token);
|
||||||
|
$log_str = $is_authenticated ? 'Authenticated' : 'Not authenticated';
|
||||||
$this->logger->info(
|
$this->logger->info(
|
||||||
"Checking auth status for app: {$this->app_name}: {$log_str}"
|
"Checking auth status for app: {$this->app_name}: {$log_str}"
|
||||||
);
|
);
|
||||||
if (isset($_SERVER['HTTP_REFERER'])) {
|
if (isset($_SERVER['HTTP_REFERER'])) {
|
||||||
$this->logger->info('Referrer: '.($_SERVER['HTTP_REFERER'] ?? 'Unknown'));
|
$this->logger->info(
|
||||||
|
'Referrer: ' . ($_SERVER['HTTP_REFERER'] ?? 'Unknown')
|
||||||
|
);
|
||||||
$_SESSION[$this->token_redirect_after_auth] = $_SERVER['HTTP_REFERER'];
|
$_SESSION[$this->token_redirect_after_auth] = $_SERVER['HTTP_REFERER'];
|
||||||
}
|
}
|
||||||
return $is_authenticated;
|
return $is_authenticated;
|
||||||
@ -374,7 +426,7 @@ class APnutI
|
|||||||
'client_secret' => $this->client_secret,
|
'client_secret' => $this->client_secret,
|
||||||
'code' => $auth_code,
|
'code' => $auth_code,
|
||||||
'redirect_uri' => $this->redirect_uri,
|
'redirect_uri' => $this->redirect_uri,
|
||||||
'grant_type'=> 'authorization_code'
|
'grant_type' => 'authorization_code',
|
||||||
];
|
];
|
||||||
$resp = $this->post(
|
$resp = $this->post(
|
||||||
'/oauth/access_token',
|
'/oauth/access_token',
|
||||||
@ -383,7 +435,7 @@ class APnutI
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (empty($resp['access_token'])) {
|
if (empty($resp['access_token'])) {
|
||||||
$this->logger->error("No access token ".json_encode($resp));
|
$this->logger->error('No access token ' . json_encode($resp));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
$this->logger->debug('Received access token ' . $resp['access_token']);
|
$this->logger->debug('Received access token ' . $resp['access_token']);
|
||||||
@ -454,14 +506,12 @@ class APnutI
|
|||||||
foreach ($posts as $post) {
|
foreach ($posts as $post) {
|
||||||
$post_obj[] = new Post($post, $this);
|
$post_obj[] = new Post($post, $this);
|
||||||
}
|
}
|
||||||
} while ($this->meta != null
|
} while ($this->meta != null && $this->meta->more && (count($post_obj) < $count || $count !== 0));
|
||||||
&& $this->meta->more
|
|
||||||
&& (count($post_obj) < $count || $count !== 0));
|
|
||||||
return $post_obj;
|
return $post_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Maybe support additional polls?
|
// TODO Maybe support additional polls?
|
||||||
public function getPollsFromUser(int $user_id, array $params = []): array
|
public function getPollsFromUser(int|string $user_id, array $params = []): array
|
||||||
{
|
{
|
||||||
$parameters = [
|
$parameters = [
|
||||||
'raw_types' => 'io.pnut.core.poll-notice',
|
'raw_types' => 'io.pnut.core.poll-notice',
|
||||||
@ -472,21 +522,28 @@ class APnutI
|
|||||||
'include_html' => false,
|
'include_html' => false,
|
||||||
'include_mention_posts' => false,
|
'include_mention_posts' => false,
|
||||||
'include_copy_mentions' => false,
|
'include_copy_mentions' => false,
|
||||||
'include_post_raw' => true
|
'include_post_raw' => true,
|
||||||
];
|
];
|
||||||
foreach ($params as $param => $value) {
|
foreach ($params as $param => $value) {
|
||||||
$parameters[$param] = $value;
|
$parameters[$param] = $value;
|
||||||
}
|
}
|
||||||
$response = $this->get('posts/search', $parameters);
|
$response = $this->get('/posts/search', $parameters);
|
||||||
if (count($response) === 0) {
|
if (count($response) === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
$polls = [];
|
$polls = [];
|
||||||
|
$this->logger->debug('Parsing ' . count($response) . ' results');
|
||||||
foreach ($response as $post) {
|
foreach ($response as $post) {
|
||||||
if (!empty($post['raw'])) {
|
if (!empty($post['raw'])) {
|
||||||
foreach ($post['raw'] as $raw) {
|
foreach ($post['raw'] as $raw_type => $raw) {
|
||||||
if (Poll::$notice_type === $raw['type']) {
|
if ($raw_type === Poll::$notice_type) {
|
||||||
$polls[] = $this->getPoll($raw['value']['poll_id']);
|
try {
|
||||||
|
$this->logger->debug('Parsing poll from raw', $raw);
|
||||||
|
$polls[] = new Poll($post, $this);
|
||||||
|
} catch (NotSupportedPollException) {
|
||||||
|
$this->logger->warning('Parsing poll from raw failed. Loading from poll id');
|
||||||
|
$polls[] = $this->getPoll($raw[Poll::$notice_type]['poll_id']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -503,16 +560,18 @@ class APnutI
|
|||||||
$this->logger->error('Poll not supported: ' . json_encode($res));
|
$this->logger->error('Poll not supported: ' . json_encode($res));
|
||||||
throw $e;
|
throw $e;
|
||||||
} catch (HttpPnutForbiddenException $fe) {
|
} catch (HttpPnutForbiddenException $fe) {
|
||||||
$this->logger->error('Poll token required and not provided!');
|
$this->logger->error('Poll token required and not provided!', ['ex' => $fe]);
|
||||||
throw new PollAccessRestrictedException();
|
throw new PollAccessRestrictedException();
|
||||||
} catch (NotAuthorizedException $nauth) {
|
} catch (NotAuthorizedException $nauth) {
|
||||||
$this->logger->error('Not authorized when fetching poll');
|
$this->logger->error('Not authorized when fetching poll', ['ex' => $nauth]);
|
||||||
throw new PollAccessRestrictedException();
|
throw new PollAccessRestrictedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPollFromToken(int $poll_id, ?string $poll_token = null): Poll
|
public function getPollFromToken(
|
||||||
{
|
int $poll_id,
|
||||||
|
?string $poll_token = null
|
||||||
|
): Poll {
|
||||||
$poll_token_query = empty($poll_token) ? '' : '?poll_token=' . $poll_token;
|
$poll_token_query = empty($poll_token) ? '' : '?poll_token=' . $poll_token;
|
||||||
return $this->getPollFromEndpoint('/polls/' . $poll_id . $poll_token_query);
|
return $this->getPollFromEndpoint('/polls/' . $poll_id . $poll_token_query);
|
||||||
}
|
}
|
||||||
@ -524,7 +583,8 @@ class APnutI
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug('Poll token provided');
|
$this->logger->debug('Poll token provided');
|
||||||
$re = '/((http(s)?:\/\/)?((posts)|(beta))\.pnut\.io\/(@.*\/)?)?(?(1)|^)(?<postid>\d+)/';
|
$re =
|
||||||
|
'/((http(s)?:\/\/)?((posts)|(beta))\.pnut\.io\/(@.*\/)?)?(?(1)|^)(?<postid>\d+)/$';
|
||||||
preg_match($re, $poll_token, $matches);
|
preg_match($re, $poll_token, $matches);
|
||||||
if (!empty($matches['postid'])) {
|
if (!empty($matches['postid'])) {
|
||||||
$this->logger->debug('Poll token is post ' . $matches['postid']);
|
$this->logger->debug('Poll token is post ' . $matches['postid']);
|
||||||
@ -533,9 +593,9 @@ class APnutI
|
|||||||
'include_raw' => true,
|
'include_raw' => true,
|
||||||
'include_counts' => false,
|
'include_counts' => false,
|
||||||
'include_html' => false,
|
'include_html' => false,
|
||||||
'include_post_raw' => true
|
'include_post_raw' => true,
|
||||||
];
|
];
|
||||||
return $this->getPollFromEndpoint('/posts/' . $post_id, $arg);
|
return $this->getPollFromEndpoint('/posts/' . $post_id, $args);
|
||||||
} else {
|
} else {
|
||||||
$this->logger->debug('Poll token seems to be an actual poll token');
|
$this->logger->debug('Poll token seems to be an actual poll token');
|
||||||
return $this->getPollFromToken($poll_id, $poll_token);
|
return $this->getPollFromToken($poll_id, $poll_token);
|
||||||
@ -553,13 +613,16 @@ class APnutI
|
|||||||
$poll_types = Poll::$poll_types;
|
$poll_types = Poll::$poll_types;
|
||||||
$poll_types[] = Poll::$notice_type;
|
$poll_types[] = Poll::$notice_type;
|
||||||
$poll_types_param = implode(',', $poll_types);
|
$poll_types_param = implode(',', $poll_types);
|
||||||
$this->logger->info('No list of polls provided, using post search for poll types: '.$poll_types_param);
|
$this->logger->info(
|
||||||
|
'No list of polls provided, using post search for poll types: ' .
|
||||||
|
$poll_types_param
|
||||||
|
);
|
||||||
$endpoint = '/posts/search?raw_types=' . $poll_types_param;
|
$endpoint = '/posts/search?raw_types=' . $poll_types_param;
|
||||||
$params = [
|
$params = [
|
||||||
'include_raw' => true,
|
'include_raw' => true,
|
||||||
'include_counts' => false,
|
'include_counts' => false,
|
||||||
'include_html' => false,
|
'include_html' => false,
|
||||||
'include_post_raw' => true
|
'include_post_raw' => true,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -573,19 +636,22 @@ class APnutI
|
|||||||
} catch (NotSupportedPollException $e) {
|
} catch (NotSupportedPollException $e) {
|
||||||
$this->logger->error('Poll not supported: ' . json_encode($res));
|
$this->logger->error('Poll not supported: ' . json_encode($res));
|
||||||
throw $e;
|
throw $e;
|
||||||
} catch (HttpPnutForbiddenException $fe) {
|
} catch (HttpPnutForbiddenException) {
|
||||||
$this->logger->error('Poll token required and not provided!');
|
$this->logger->error('Poll token required and not provided!');
|
||||||
throw new PollAccessRestrictedException();
|
throw new PollAccessRestrictedException();
|
||||||
} catch (NotAuthorizedException $nauth) {
|
} catch (NotAuthorizedException) {
|
||||||
$this->logger->error('Not authorized when fetching poll');
|
$this->logger->error('Not authorized when fetching poll');
|
||||||
throw new PollAccessRestrictedException();
|
throw new PollAccessRestrictedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function voteInPoll(int $poll_id, array $options, ?string $poll_token): Poll
|
public function voteInPoll(
|
||||||
{
|
int $poll_id,
|
||||||
|
array $options,
|
||||||
|
?string $poll_token
|
||||||
|
): Poll {
|
||||||
$params = [
|
$params = [
|
||||||
'positions' => $options
|
'positions' => $options,
|
||||||
];
|
];
|
||||||
if (!empty($poll_token)) {
|
if (!empty($poll_token)) {
|
||||||
$params['poll_token'] = $poll_token;
|
$params['poll_token'] = $poll_token;
|
||||||
@ -607,7 +673,8 @@ class APnutI
|
|||||||
return $this->current_user;
|
return $this->current_user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUser(int $user_id, array $args = [])
|
// User ID or user name
|
||||||
|
public function getUser(int|string $user_id, array $args = [])
|
||||||
{
|
{
|
||||||
return new User($this->get('/users/' . $user_id, $args), $this);
|
return new User($this->get('/users/' . $user_id, $args), $this);
|
||||||
}
|
}
|
||||||
@ -617,7 +684,7 @@ class APnutI
|
|||||||
if (!empty($this->access_token)) {
|
if (!empty($this->access_token)) {
|
||||||
#$this->logger->info("AT:".$this->access_token);
|
#$this->logger->info("AT:".$this->access_token);
|
||||||
} else {
|
} else {
|
||||||
$this->logger->info("No AT");
|
$this->logger->info('No AT');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove in production again
|
// Remove in production again
|
||||||
@ -625,7 +692,7 @@ class APnutI
|
|||||||
$p = new Post($this->get('/posts/' . $post_id, $args), $this);
|
$p = new Post($this->get('/posts/' . $post_id, $args), $this);
|
||||||
$this->logger->debug(json_encode($p));
|
$this->logger->debug(json_encode($p));
|
||||||
return $p;
|
return $p;
|
||||||
} catch (NotAuthorizedException $nae) {
|
} catch (NotAuthorizedException) {
|
||||||
$this->logger->warning(
|
$this->logger->warning(
|
||||||
'NotAuthorizedException when getting post, trying without access token'
|
'NotAuthorizedException when getting post, trying without access token'
|
||||||
);
|
);
|
||||||
@ -641,21 +708,28 @@ class APnutI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAvatar(int $user_id, array $args = []): string
|
public function getAvatar(int|string $user_id, array $args = []): string
|
||||||
{
|
{
|
||||||
//get returns an array with the url at idx 0
|
//get returns an array with the url at idx 0
|
||||||
$r = null;
|
$r = null;
|
||||||
try {
|
try {
|
||||||
$r = $this->get('/users/'.$user_id.'/avatar', $args, 'application/json', false);
|
$r = $this->get(
|
||||||
|
'/users/' . $user_id . '/avatar',
|
||||||
|
$args,
|
||||||
|
'application/json',
|
||||||
|
false
|
||||||
|
);
|
||||||
} catch (HttpPnutRedirectException $re) {
|
} catch (HttpPnutRedirectException $re) {
|
||||||
return $re->response;
|
return $re->response;
|
||||||
}
|
}
|
||||||
$this->logger->error('Could not fetch avatar: No redirection! ' . json_encode($r));
|
$this->logger->error(
|
||||||
|
'Could not fetch avatar: No redirection! ' . json_encode($r)
|
||||||
|
);
|
||||||
throw new PnutException('Could not fetch avatar: No redirection!');
|
throw new PnutException('Could not fetch avatar: No redirection!');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAvatarUrl(
|
public function getAvatarUrl(
|
||||||
int $user_id,
|
int|string $user_id,
|
||||||
?int $width = null,
|
?int $width = null,
|
||||||
?int $height = null
|
?int $height = null
|
||||||
): string {
|
): string {
|
||||||
@ -705,7 +779,7 @@ class APnutI
|
|||||||
bool $auto_crop = false,
|
bool $auto_crop = false,
|
||||||
array $raw = []
|
array $raw = []
|
||||||
): Post {
|
): Post {
|
||||||
return createPost($text, $reply_to, $is_nsfw, $auto_crop, $raw);
|
return $this->createPost($text, $reply_to, $is_nsfw, $auto_crop, $raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createPost(
|
public function createPost(
|
||||||
@ -724,7 +798,10 @@ class APnutI
|
|||||||
if (!empty($raw)) {
|
if (!empty($raw)) {
|
||||||
$parameters['raw'] = $parameters;
|
$parameters['raw'] = $parameters;
|
||||||
}
|
}
|
||||||
return new Post($this->post('/posts', $parameters, 'application/json'), $this);
|
return new Post(
|
||||||
|
$this->post('/posts', $parameters, 'application/json'),
|
||||||
|
$this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createPostWithParameters(
|
public function createPostWithParameters(
|
||||||
@ -739,20 +816,28 @@ class APnutI
|
|||||||
$parameters = array_merge($parameters, $params);
|
$parameters = array_merge($parameters, $params);
|
||||||
$this->logger->debug('Post with params');
|
$this->logger->debug('Post with params');
|
||||||
$this->logger->debug(json_encode($parameters));
|
$this->logger->debug(json_encode($parameters));
|
||||||
return new Post($this->post('/posts', $parameters, 'application/json'), $this);
|
return new Post(
|
||||||
|
$this->post('/posts', $parameters, 'application/json'),
|
||||||
|
$this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChannel(int $channel_id): Channel
|
public function getChannel(int $channel_id): Channel
|
||||||
{
|
{
|
||||||
# Always include channel raw, it contains the channel name
|
# Always include channel raw, it contains the channel name
|
||||||
$parameters = [
|
$parameters = [
|
||||||
'include_channel_raw' => true
|
'include_channel_raw' => true,
|
||||||
];
|
];
|
||||||
return new Channel($this->get('/channels/'.$channel_id, $parameters), $this);
|
return new Channel(
|
||||||
|
$this->get('/channels/' . $channel_id, $parameters),
|
||||||
|
$this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscribedChannels(bool $include_pms = true, bool $include_channels = true): array
|
public function getSubscribedChannels(
|
||||||
{
|
bool $include_pms = true,
|
||||||
|
bool $include_channels = true
|
||||||
|
): array {
|
||||||
# Always include channel raw, it contains the channel name
|
# Always include channel raw, it contains the channel name
|
||||||
$channel_types = [];
|
$channel_types = [];
|
||||||
if ($include_pms) {
|
if ($include_pms) {
|
||||||
@ -764,7 +849,7 @@ class APnutI
|
|||||||
|
|
||||||
$parameters = [
|
$parameters = [
|
||||||
'include_channel_raw' => true,
|
'include_channel_raw' => true,
|
||||||
'channel_types' => implode(',', $channel_types)
|
'channel_types' => implode(',', $channel_types),
|
||||||
];
|
];
|
||||||
$channels = [];
|
$channels = [];
|
||||||
$resp = $this->get('/users/me/channels/subscribed', $parameters);
|
$resp = $this->get('/users/me/channels/subscribed', $parameters);
|
||||||
@ -780,19 +865,28 @@ class APnutI
|
|||||||
self::$POST_MAX_LENGTH = $config['post']['max_length'];
|
self::$POST_MAX_LENGTH = $config['post']['max_length'];
|
||||||
//self::$POST_MAX_LENGTH_REPOST = $config['post']['repost_max_length'];
|
//self::$POST_MAX_LENGTH_REPOST = $config['post']['repost_max_length'];
|
||||||
self::$POST_MAX_LENGTH_REPOST = self::$POST_MAX_LENGTH;
|
self::$POST_MAX_LENGTH_REPOST = self::$POST_MAX_LENGTH;
|
||||||
self::$POST_SECONDS_BETWEEN_DUPLICATES = $config['post']['seconds_between_duplicates'];
|
self::$POST_SECONDS_BETWEEN_DUPLICATES =
|
||||||
|
$config['post']['seconds_between_duplicates'];
|
||||||
self::$MESSAGE_MAX_LENGTH = $config['message']['max_length'];
|
self::$MESSAGE_MAX_LENGTH = $config['message']['max_length'];
|
||||||
self::$RAW_MAX_LENGTH = $config['raw']['max_length'];
|
self::$RAW_MAX_LENGTH = $config['raw']['max_length'];
|
||||||
self::$USER_DESCRIPTION_MAX_LENGTH = $config['user']['description_max_length'];
|
self::$USER_DESCRIPTION_MAX_LENGTH =
|
||||||
|
$config['user']['description_max_length'];
|
||||||
self::$USER_USERNAME_MAX_LENGTH = $config['user']['username_max_length'];
|
self::$USER_USERNAME_MAX_LENGTH = $config['user']['username_max_length'];
|
||||||
$this->logger->info('-----------Pnut API config-----------');
|
$this->logger->info('-----------Pnut API config-----------');
|
||||||
$this->logger->info('');
|
$this->logger->info('');
|
||||||
$this->logger->info("Max post length: ".self::$POST_MAX_LENGTH);
|
$this->logger->info('Max post length: ' . self::$POST_MAX_LENGTH);
|
||||||
$this->logger->info("Max repost length: ".self::$POST_MAX_LENGTH_REPOST);
|
$this->logger->info('Max repost length: ' . self::$POST_MAX_LENGTH_REPOST);
|
||||||
$this->logger->info("Seconds between post duplicates: ".self::$POST_SECONDS_BETWEEN_DUPLICATES);
|
$this->logger->info(
|
||||||
$this->logger->info("Max raw length: ".self::$RAW_MAX_LENGTH);
|
'Seconds between post duplicates: ' .
|
||||||
$this->logger->info("Max user description length: ".self::$USER_DESCRIPTION_MAX_LENGTH);
|
self::$POST_SECONDS_BETWEEN_DUPLICATES
|
||||||
$this->logger->info("Max username length: ".self::$USER_USERNAME_MAX_LENGTH);
|
);
|
||||||
|
$this->logger->info('Max raw length: ' . self::$RAW_MAX_LENGTH);
|
||||||
|
$this->logger->info(
|
||||||
|
'Max user description length: ' . self::$USER_DESCRIPTION_MAX_LENGTH
|
||||||
|
);
|
||||||
|
$this->logger->info(
|
||||||
|
'Max username length: ' . self::$USER_USERNAME_MAX_LENGTH
|
||||||
|
);
|
||||||
$this->logger->info('--------------------------------------');
|
$this->logger->info('--------------------------------------');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +902,7 @@ class APnutI
|
|||||||
{
|
{
|
||||||
$token = $this->getServerToken();
|
$token = $this->getServerToken();
|
||||||
$this->server_token = $token;
|
$this->server_token = $token;
|
||||||
$this->logger->info("ST:".$this->server_token);
|
$this->logger->info('ST:' . $this->server_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getServerToken(): string
|
protected function getServerToken(): string
|
||||||
@ -817,14 +911,16 @@ class APnutI
|
|||||||
$params = [
|
$params = [
|
||||||
'client_id' => $this->client_id,
|
'client_id' => $this->client_id,
|
||||||
'client_secret' => $this->client_secret,
|
'client_secret' => $this->client_secret,
|
||||||
'grant_type' => 'client_credentials'
|
'grant_type' => 'client_credentials',
|
||||||
];
|
];
|
||||||
$resp = $this->post('/oauth/access_token', $params);
|
$resp = $this->post('/oauth/access_token', $params);
|
||||||
if (!empty($resp['access_token'])) {
|
if (!empty($resp['access_token'])) {
|
||||||
$this->logger->info(json_encode($resp));
|
$this->logger->info(json_encode($resp));
|
||||||
return $resp['access_token'];
|
return $resp['access_token'];
|
||||||
} else {
|
} else {
|
||||||
throw new PnutException("Error retrieving app access token: ".json_encode($resp));
|
throw new PnutException(
|
||||||
|
'Error retrieving app access token: ' . json_encode($resp)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace APnutI\Entities;
|
namespace APnutI\Entities;
|
||||||
|
|
||||||
use APnutI\Entities\PollOption;
|
use APnutI\Entities\PollOption;
|
||||||
@ -17,7 +18,7 @@ class Poll
|
|||||||
public bool $is_public = false;
|
public bool $is_public = false;
|
||||||
public array $options = [];
|
public array $options = [];
|
||||||
public ?string $token = null;
|
public ?string $token = null;
|
||||||
public string $prompt = "";
|
public string $prompt = '';
|
||||||
public ?User $user = null;
|
public ?User $user = null;
|
||||||
public ?Source $source = null;
|
public ?Source $source = null;
|
||||||
public string $type;
|
public string $type;
|
||||||
@ -30,7 +31,7 @@ class Poll
|
|||||||
'net.unsweets.beta',
|
'net.unsweets.beta',
|
||||||
'io.pnut.core.poll',
|
'io.pnut.core.poll',
|
||||||
'io.broadsword.poll',
|
'io.broadsword.poll',
|
||||||
'nl.chimpnut.quizbot.attachment.poll'
|
'nl.chimpnut.quizbot.attachment.poll',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(array $data, APnutI $api)
|
public function __construct(array $data, APnutI $api)
|
||||||
@ -38,7 +39,9 @@ class Poll
|
|||||||
$this->api = $api;
|
$this->api = $api;
|
||||||
$this->options = [];
|
$this->options = [];
|
||||||
$type = '';
|
$type = '';
|
||||||
if (array_key_exists('type', $data) && $data['type'] === Poll::$notice_type) {
|
if (array_key_exists('type', $data) &&
|
||||||
|
$data['type'] === Poll::$notice_type
|
||||||
|
) {
|
||||||
$val = $data['value'];
|
$val = $data['value'];
|
||||||
$this->closed_at = new \DateTime($val['closed_at']);
|
$this->closed_at = new \DateTime($val['closed_at']);
|
||||||
foreach ($val['options'] as $option) {
|
foreach ($val['options'] as $option) {
|
||||||
@ -47,9 +50,13 @@ class Poll
|
|||||||
$this->id = (int) $val['poll_id'];
|
$this->id = (int) $val['poll_id'];
|
||||||
$this->token = $val['poll_token'];
|
$this->token = $val['poll_token'];
|
||||||
$this->prompt = $val['prompt'];
|
$this->prompt = $val['prompt'];
|
||||||
} elseif (array_key_exists('type', $data) &&in_array($data['type'], Poll::$poll_types)) {
|
} elseif (array_key_exists('type', $data) &&
|
||||||
|
in_array($data['type'], Poll::$poll_types)
|
||||||
|
) {
|
||||||
$this->parsePoll($data);
|
$this->parsePoll($data);
|
||||||
} elseif (array_key_exists('type', $data) &&strpos($data['type'], '.poll') !== false) {
|
} elseif (array_key_exists('type', $data) &&
|
||||||
|
strpos($data['type'], '.poll') !== false
|
||||||
|
) {
|
||||||
// Try parsing unknown types if they *might* be a poll
|
// Try parsing unknown types if they *might* be a poll
|
||||||
try {
|
try {
|
||||||
$this->parsePoll($data);
|
$this->parsePoll($data);
|
||||||
@ -61,10 +68,12 @@ class Poll
|
|||||||
count($data['raw'][Poll::$notice_type]) > 0
|
count($data['raw'][Poll::$notice_type]) > 0
|
||||||
) {
|
) {
|
||||||
$poll_data = $data['raw'][Poll::$notice_type][0];
|
$poll_data = $data['raw'][Poll::$notice_type][0];
|
||||||
if (!empty($data['source'])) { #Source is attached to post, not to poll raw
|
if (!empty($data['source'])) {
|
||||||
|
#Source is attached to post, not to poll raw
|
||||||
$poll_data['source'] = $data['source'];
|
$poll_data['source'] = $data['source'];
|
||||||
}
|
}
|
||||||
if (!empty($data['user'])) { #User is attached to post, not to poll raw
|
if (!empty($data['user'])) {
|
||||||
|
#User is attached to post, not to poll raw
|
||||||
$poll_data['user'] = $data['user'];
|
$poll_data['user'] = $data['user'];
|
||||||
}
|
}
|
||||||
$type = Poll::$notice_type;
|
$type = Poll::$notice_type;
|
||||||
@ -80,9 +89,15 @@ class Poll
|
|||||||
$this->created_at = new \DateTime($data['created_at']);
|
$this->created_at = new \DateTime($data['created_at']);
|
||||||
$this->closed_at = new \DateTime($data['closed_at']);
|
$this->closed_at = new \DateTime($data['closed_at']);
|
||||||
$this->id = (int) $data['id'];
|
$this->id = (int) $data['id'];
|
||||||
$this->is_anonymous = array_key_exists('is_anonymous', $data) ? (bool)$data['is_anonymous'] : false;
|
$this->is_anonymous = array_key_exists('is_anonymous', $data)
|
||||||
$this->max_options = array_key_exists('max_options', $data) ? (int)$data['max_options'] : 1;
|
? (bool) $data['is_anonymous']
|
||||||
$this->is_public = array_key_exists('is_public', $data) ? (bool)$data['is_public'] : false;
|
: false;
|
||||||
|
$this->max_options = array_key_exists('max_options', $data)
|
||||||
|
? (int) $data['max_options']
|
||||||
|
: 1;
|
||||||
|
$this->is_public = array_key_exists('is_public', $data)
|
||||||
|
? (bool) $data['is_public']
|
||||||
|
: false;
|
||||||
foreach ($data['options'] as $option) {
|
foreach ($data['options'] as $option) {
|
||||||
$this->options[] = new PollOption($option);
|
$this->options[] = new PollOption($option);
|
||||||
}
|
}
|
||||||
@ -171,12 +186,9 @@ class Poll
|
|||||||
bool $is_public
|
bool $is_public
|
||||||
): Poll {
|
): Poll {
|
||||||
$options = array_filter($options);
|
$options = array_filter($options);
|
||||||
$options = array_map(
|
$options = array_map(function ($v) {
|
||||||
function ($v) {
|
|
||||||
return ['text' => $v];
|
return ['text' => $v];
|
||||||
},
|
}, $options);
|
||||||
$options
|
|
||||||
);
|
|
||||||
$params = [
|
$params = [
|
||||||
'duration' => $duration_minutes,
|
'duration' => $duration_minutes,
|
||||||
'options' => array_filter($options), #filters empty options
|
'options' => array_filter($options), #filters empty options
|
||||||
@ -184,7 +196,7 @@ class Poll
|
|||||||
'type' => 'io.pnut.core.poll',
|
'type' => 'io.pnut.core.poll',
|
||||||
'is_anonymous' => $is_anonymous,
|
'is_anonymous' => $is_anonymous,
|
||||||
'is_public' => $is_public,
|
'is_public' => $is_public,
|
||||||
'max_options' => $max_options
|
'max_options' => $max_options,
|
||||||
];
|
];
|
||||||
$api->logger->debug('Creating poll');
|
$api->logger->debug('Creating poll');
|
||||||
$api->logger->debug(json_encode($params));
|
$api->logger->debug(json_encode($params));
|
||||||
@ -200,10 +212,10 @@ class Poll
|
|||||||
[
|
[
|
||||||
'+io.pnut.core.poll' => [
|
'+io.pnut.core.poll' => [
|
||||||
'poll_id' => $poll_id,
|
'poll_id' => $poll_id,
|
||||||
'poll_token' => $poll_token
|
'poll_token' => $poll_token,
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,10 +227,10 @@ class Poll
|
|||||||
} else {
|
} else {
|
||||||
$str = 'Unknown user';
|
$str = 'Unknown user';
|
||||||
}
|
}
|
||||||
return $str
|
return $str .
|
||||||
. " asked: '"
|
" asked: '" .
|
||||||
. $this->prompt
|
$this->prompt .
|
||||||
. "', closed at "
|
"', closed at " .
|
||||||
. $this->closed_at->format('Y-m-d H:i:s T');
|
$this->closed_at->format('Y-m-d H:i:s T');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,17 @@ class User
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPresenceString()
|
||||||
|
{
|
||||||
|
if ($this->presence === true) {
|
||||||
|
return "online";
|
||||||
|
} elseif ($this->presence === false) {
|
||||||
|
return "offline";
|
||||||
|
} else {
|
||||||
|
return "presence unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getAvatarUrl(
|
public function getAvatarUrl(
|
||||||
?int $width = null,
|
?int $width = null,
|
||||||
?int $height = null
|
?int $height = null
|
||||||
|
17
src/Logger/LevelNamePaddingProcessor.php
Normal file
17
src/Logger/LevelNamePaddingProcessor.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace APnutI\Logger;
|
||||||
|
|
||||||
|
use Monolog\Processor\ProcessorInterface;
|
||||||
|
use Monolog\LogRecord;
|
||||||
|
|
||||||
|
// See: https://stackoverflow.com/a/78901964
|
||||||
|
class LevelNamePaddingProcessor implements ProcessorInterface
|
||||||
|
{
|
||||||
|
public function __invoke(LogRecord $record): LogRecord
|
||||||
|
{
|
||||||
|
$record->extra['level_padded'] = str_pad($record->level->getName(), 5, ' ', STR_PAD_RIGHT);
|
||||||
|
|
||||||
|
return $record;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user