Merge remote-tracking branch 'upstream/develop' into more-q
This commit is contained in:
commit
deb4f8d9ef
|
@ -21,6 +21,9 @@ Excerp from nitters about page.
|
|||
Changelog
|
||||
---------
|
||||
|
||||
* **Version 2.0**
|
||||
* Changes the used hook by the addon, so that attached previews of postings get replaced as well.
|
||||
This means the admins need to reload the addon
|
||||
* **Version 1.1**
|
||||
* Initial localization support with DE translation
|
||||
* Configurable nitter instance address from the admin panel
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 07:44+0100\n"
|
||||
"POT-Creation-Date: 2021-10-01 16:10+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -17,7 +17,7 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: nitter.php:51
|
||||
#: nitter.php:52
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Which nitter server shall be used for the replacements in the post bodies? "
|
||||
|
@ -25,17 +25,17 @@ msgid ""
|
|||
"public Nitter servers."
|
||||
msgstr ""
|
||||
|
||||
#: nitter.php:52
|
||||
#: nitter.php:53
|
||||
msgid "Nitter server"
|
||||
msgstr ""
|
||||
|
||||
#: nitter.php:53
|
||||
#: nitter.php:54
|
||||
msgid "Save Settings"
|
||||
msgstr ""
|
||||
|
||||
#: nitter.php:65
|
||||
#: nitter.php:99
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Links to Twitter in this posting were replaced by links to the Nitter "
|
||||
"instance at %s"
|
||||
"In an attempt to protect your privacy, links to Twitter in this posting were "
|
||||
"replaced by links to the Nitter instance at %s"
|
||||
msgstr ""
|
||||
|
|
|
@ -1,41 +1,50 @@
|
|||
# ADDON nitter
|
||||
# Copyright (C)
|
||||
# Copyright (C)
|
||||
# This file is distributed under the same license as the Friendica nitter addon package.
|
||||
#
|
||||
#
|
||||
#
|
||||
# Translators:
|
||||
# Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2021
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 07:44+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"POT-Creation-Date: 2021-10-01 16:10+0200\n"
|
||||
"PO-Revision-Date: 2021-05-21 12:58+0000\n"
|
||||
"Last-Translator: Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2021\n"
|
||||
"Language-Team: German (https://www.transifex.com/Friendica/teams/12172/de/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: de\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: nitter.php:51
|
||||
#: nitter.php:52
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Which nitter server shall be used for the replacements in the post bodies? "
|
||||
"Use the URL with servername and protocol. See %s for a list of available "
|
||||
"public Nitter servers."
|
||||
msgstr "Welcher Nitter server soll für die Ersetzungen verwendet werden? Gib die URL mit Servername und Protokoll an. Eine Liste von öffentlichen Nitter servern findest du unter %s."
|
||||
msgstr ""
|
||||
"Welcher Nitter server soll für die Ersetzungen verwendet werden? Gib die URL"
|
||||
" mit Servername und Protokoll an. Eine Liste von öffentlichen Nitter servern"
|
||||
" findest du unter %s."
|
||||
|
||||
#: nitter.php:52
|
||||
#: nitter.php:53
|
||||
msgid "Nitter server"
|
||||
msgstr "Nitter Server"
|
||||
|
||||
#: nitter.php:53
|
||||
#: nitter.php:54
|
||||
msgid "Save Settings"
|
||||
msgstr "Einstellungen Speichern"
|
||||
|
||||
#: nitter.php:65
|
||||
#: nitter.php:99
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Links to Twitter in this posting were replaced by links to the Nitter "
|
||||
"instance at %s"
|
||||
msgstr "In diesem Beitrag wurden Links nach twitter.com durch die Nitter Instanz auf %s ersetzt."
|
||||
"In an attempt to protect your privacy, links to Twitter in this posting were"
|
||||
" replaced by links to the Nitter instance at %s"
|
||||
msgstr ""
|
||||
"Um deine Privatsphäre zu schützen, wurden in diesem Beitrag Links nach "
|
||||
"twitter.com durch die Nitter Instanz auf %s ersetzt."
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
if(! function_exists("string_plural_select_de")) {
|
||||
function string_plural_select_de($n){
|
||||
$n = intval($n);
|
||||
return intval($n != 1);
|
||||
}}
|
||||
;
|
||||
$a->strings["Which nitter server shall be used for the replacements in the post bodies? Use the URL with servername and protocol. See %s for a list of available public Nitter servers."] = "Welcher Nitter server soll für die Ersetzungen verwendet werden? Gib die URL mit Servername und Protokoll an. Eine Liste von öffentlichen Nitter servern findest du unter %s.";
|
||||
$a->strings["Nitter server"] = "Nitter Server";
|
||||
$a->strings["Save Settings"] = "Einstellungen Speichern";
|
||||
$a->strings["Links to Twitter in this posting were replaced by links to the Nitter instance at %s"] = "In diesem Beitrag wurden Links nach twitter.com durch die Nitter Instanz auf %s ersetzt.";
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Name: nitter
|
||||
* Description: Replaces links to twitter.com to a nitter server in all displays of postings on a node.
|
||||
* Version: 1.1
|
||||
* Version: 2.0
|
||||
* Author: Tobias Diekershoff <tobias@social.diekershoff.de>
|
||||
*
|
||||
* Copyright (c) 2020 Tobias Diekershoff
|
||||
|
@ -30,7 +30,7 @@ use Friendica\DI;
|
|||
|
||||
function nitter_install()
|
||||
{
|
||||
Addon::registerHook ('prepare_body', 'addon/nitter/nitter.php', 'nitter_render');
|
||||
Addon::registerHook ('prepare_body_final', 'addon/nitter/nitter.php', 'nitter_render');
|
||||
}
|
||||
|
||||
/* Handle the send data from the admin settings
|
||||
|
@ -72,6 +72,6 @@ function nitter_render(&$a, &$o)
|
|||
$replaced = true;
|
||||
}
|
||||
if ($replaced) {
|
||||
$o['html'] .= '<hr><p>' . DI::l10n()->t('Links to Twitter in this posting were replaced by links to the Nitter instance at %s', $nitter) . '</p>';
|
||||
$o['html'] .= '<hr><p>' . DI::l10n()->t('In an attempt to protect your privacy, links to Twitter in this posting were replaced by links to the Nitter instance at %s', $nitter) . '</p>';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"abraham/twitteroauth": "^0.7.4",
|
||||
"abraham/twitteroauth": "2.0.0",
|
||||
"jublonet/codebird-php": "dev-master"
|
||||
},
|
||||
"license": "3-clause BSD license",
|
||||
|
|
|
@ -4,30 +4,33 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "eaeac282537509fd7d0bc4f92f01bc04",
|
||||
"content-hash": "fafd1db0b4f04c4268f5034ce8c7f6ea",
|
||||
"packages": [
|
||||
{
|
||||
"name": "abraham/twitteroauth",
|
||||
"version": "0.7.4",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/abraham/twitteroauth.git",
|
||||
"reference": "c6f9e692552dd037b2324ed0dfa28a4e60875acf"
|
||||
"reference": "96f49e67baec10f5e5cb703d87be16ba01a798a5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/abraham/twitteroauth/zipball/c6f9e692552dd037b2324ed0dfa28a4e60875acf",
|
||||
"reference": "c6f9e692552dd037b2324ed0dfa28a4e60875acf",
|
||||
"url": "https://api.github.com/repos/abraham/twitteroauth/zipball/96f49e67baec10f5e5cb703d87be16ba01a798a5",
|
||||
"reference": "96f49e67baec10f5e5cb703d87be16ba01a798a5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/ca-bundle": "^1.2",
|
||||
"ext-curl": "*",
|
||||
"php": "^5.6 || ^7.0"
|
||||
"php": "^7.2 || ^7.3 || ^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpmd/phpmd": "~2.6",
|
||||
"phpunit/phpunit": "~5.7",
|
||||
"squizlabs/php_codesniffer": "~3.0"
|
||||
"php-vcr/php-vcr": "^1",
|
||||
"php-vcr/phpunit-testlistener-vcr": "dev-php-8",
|
||||
"phpmd/phpmd": "^2",
|
||||
"phpunit/phpunit": "^8",
|
||||
"squizlabs/php_codesniffer": "^3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -58,7 +61,78 @@
|
|||
"social",
|
||||
"twitter"
|
||||
],
|
||||
"time": "2017-06-30T22:02:01+00:00"
|
||||
"time": "2020-12-02T01:27:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
"version": "1.2.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/ca-bundle.git",
|
||||
"reference": "9fdb22c2e97a614657716178093cd1da90a64aa8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/9fdb22c2e97a614657716178093cd1da90a64aa8",
|
||||
"reference": "9fdb22c2e97a614657716178093cd1da90a64aa8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.55",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5",
|
||||
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\CaBundle\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
|
||||
"keywords": [
|
||||
"cabundle",
|
||||
"cacert",
|
||||
"certificate",
|
||||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-07T13:58:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/installers",
|
||||
|
@ -185,12 +259,12 @@
|
|||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jublonet/codebird-php.git",
|
||||
"url": "https://github.com/jublo/codebird-php.git",
|
||||
"reference": "df362d8ad629aad6c4c7dbf36a440e569ec41368"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jublonet/codebird-php/zipball/df362d8ad629aad6c4c7dbf36a440e569ec41368",
|
||||
"url": "https://api.github.com/repos/jublo/codebird-php/zipball/df362d8ad629aad6c4c7dbf36a440e569ec41368",
|
||||
"reference": "df362d8ad629aad6c4c7dbf36a440e569ec41368",
|
||||
"shasum": ""
|
||||
},
|
||||
|
@ -249,5 +323,6 @@
|
|||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": []
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "1.1.0"
|
||||
}
|
||||
|
|
|
@ -104,7 +104,11 @@ function twitter_install()
|
|||
Hook::register('notifier_normal' , __FILE__, 'twitter_post_hook');
|
||||
Hook::register('jot_networks' , __FILE__, 'twitter_jot_nets');
|
||||
Hook::register('cron' , __FILE__, 'twitter_cron');
|
||||
Hook::register('support_follow' , __FILE__, 'twitter_support_follow');
|
||||
Hook::register('follow' , __FILE__, 'twitter_follow');
|
||||
Hook::register('unfollow' , __FILE__, 'twitter_unfollow');
|
||||
Hook::register('block' , __FILE__, 'twitter_block');
|
||||
Hook::register('unblock' , __FILE__, 'twitter_unblock');
|
||||
Hook::register('expire' , __FILE__, 'twitter_expire');
|
||||
Hook::register('prepare_body' , __FILE__, 'twitter_prepare_body');
|
||||
Hook::register('check_item_notification', __FILE__, 'twitter_check_item_notification');
|
||||
|
@ -134,6 +138,13 @@ function twitter_check_item_notification(App $a, array &$notification_data)
|
|||
}
|
||||
}
|
||||
|
||||
function twitter_support_follow(App $a, array &$data)
|
||||
{
|
||||
if ($data['protocol'] == Protocol::TWITTER) {
|
||||
$data['result'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
function twitter_follow(App $a, array &$contact)
|
||||
{
|
||||
Logger::info('Check if contact is twitter contact', ['url' => $contact["url"]]);
|
||||
|
@ -148,19 +159,7 @@ function twitter_follow(App $a, array &$contact)
|
|||
|
||||
$uid = $a->getLoggedInUserId();
|
||||
|
||||
$ckey = DI::config()->get('twitter', 'consumerkey');
|
||||
$csecret = DI::config()->get('twitter', 'consumersecret');
|
||||
$otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
|
||||
$osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
|
||||
|
||||
// If the addon is not configured (general or for this user) quit here
|
||||
if (empty($ckey) || empty($csecret) || empty($otoken) || empty($osecret)) {
|
||||
$contact = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
|
||||
$connection->post('friendships/create', ['screen_name' => $nickname]);
|
||||
twitter_api_contact('friendships/create', ['network' => Protocol::TWITTER, 'nick' => $nickname], $uid);
|
||||
|
||||
$user = twitter_fetchuser($nickname);
|
||||
|
||||
|
@ -173,6 +172,48 @@ function twitter_follow(App $a, array &$contact)
|
|||
}
|
||||
}
|
||||
|
||||
function twitter_unfollow(App $a, array &$hook_data)
|
||||
{
|
||||
$hook_data['result'] = twitter_api_contact('friendship/destroy', $hook_data['contact'], $hook_data['uid']);
|
||||
}
|
||||
|
||||
function twitter_block(App $a, array &$hook_data)
|
||||
{
|
||||
$hook_data['result'] = twitter_api_contact('blocks/create', $hook_data['contact'], $hook_data['uid']);
|
||||
}
|
||||
|
||||
function twitter_unblock(App $a, array &$hook_data)
|
||||
{
|
||||
$hook_data['result'] = twitter_api_contact('blocks/destroy', $hook_data['contact'], $hook_data['uid']);
|
||||
}
|
||||
|
||||
function twitter_api_contact(string $apiPath, array $contact, int $uid): ?bool
|
||||
{
|
||||
if ($contact['network'] !== Protocol::TWITTER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ckey = DI::config()->get('twitter', 'consumerkey');
|
||||
$csecret = DI::config()->get('twitter', 'consumersecret');
|
||||
$otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
|
||||
$osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
|
||||
|
||||
// If the addon is not configured (general or for this user) quit here
|
||||
if (empty($ckey) || empty($csecret) || empty($otoken) || empty($osecret)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
|
||||
$result = $connection->post($apiPath, ['screen_name' => $contact['nick']]);
|
||||
Logger::info('[twitter] API call successful', ['apiPath' => $apiPath, 'result' => $result]);
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
Logger::notice('[twitter] API call failed', ['apiPath' => $apiPath, 'uid' => $uid, 'url' => $contact['url'], 'exception' => $e]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function twitter_jot_nets(App $a, array &$jotnets_fields)
|
||||
{
|
||||
if (!local_user()) {
|
||||
|
@ -481,7 +522,7 @@ function twitter_probe_detect(App $a, array &$hookData)
|
|||
}
|
||||
}
|
||||
|
||||
function twitter_action(App $a, $uid, $pid, $action)
|
||||
function twitter_api_post(string $apiPath, string $pid, int $uid)
|
||||
{
|
||||
if (empty($pid)) {
|
||||
return;
|
||||
|
@ -496,34 +537,21 @@ function twitter_action(App $a, $uid, $pid, $action)
|
|||
|
||||
$post = ['id' => $pid];
|
||||
|
||||
Logger::debug('before action', ['action' => $action, 'pid' => $pid, 'data' => $post]);
|
||||
$result = [];
|
||||
Logger::debug('before action', ['action' => $apiPath, 'pid' => $pid, 'data' => $post]);
|
||||
|
||||
try {
|
||||
switch ($action) {
|
||||
case 'delete':
|
||||
// To-Do: $result = $connection->post('statuses/destroy', $post);
|
||||
break;
|
||||
case 'like':
|
||||
$result = $connection->post('favorites/create', $post);
|
||||
if ($connection->getLastHttpCode() != 200) {
|
||||
Logger::warning('Unable to create favorite', ['result' => $result]);
|
||||
}
|
||||
break;
|
||||
case 'unlike':
|
||||
$result = $connection->post('favorites/destroy', $post);
|
||||
if ($connection->getLastHttpCode() != 200) {
|
||||
Logger::warning('Unable to destroy favorite', ['result' => $result]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Logger::warning('Unhandled action', ['action' => $action]);
|
||||
$result = $connection->post($apiPath, $post);
|
||||
if ($connection->getLastHttpCode() != 200) {
|
||||
Logger::warning('[twitter] API call unsuccessful', ['apiPath' => $apiPath, 'post' => $post, 'result' => $result]);
|
||||
}
|
||||
} catch (TwitterOAuthException $twitterOAuthException) {
|
||||
Logger::warning('Unable to communicate with twitter', ['action' => $action, 'data' => $post, 'code' => $twitterOAuthException->getCode(), 'exception' => $twitterOAuthException]);
|
||||
Logger::warning('Unable to communicate with twitter', ['apiPath' => $apiPath, 'data' => $post, 'code' => $twitterOAuthException->getCode(), 'exception' => $twitterOAuthException]);
|
||||
$result = false;
|
||||
}
|
||||
|
||||
Logger::info('after action', ['action' => $action, 'result' => $result]);
|
||||
Logger::info('after action', ['action' => $apiPath, 'result' => $result]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function twitter_get_id(string $uri)
|
||||
|
@ -594,17 +622,19 @@ function twitter_post_hook(App $a, array &$b)
|
|||
}
|
||||
}
|
||||
|
||||
if (($b['verb'] == Activity::POST) && $b['deleted']) {
|
||||
twitter_action($a, $b['uid'], twitter_get_id($thr_parent['uri']), 'delete');
|
||||
}
|
||||
/**
|
||||
* @TODO This can't work at the moment:
|
||||
* - Posts created on Friendica and mirrored to Twitter don't have a Twitter ID
|
||||
* - Posts created on Twitter and mirrored on Friendica do not trigger the notifier hook this is part of.
|
||||
*/
|
||||
//if (($b['verb'] == Activity::POST) && $b['deleted']) {
|
||||
// twitter_api_post('statuses/destroy', twitter_get_id($thr_parent['uri']), $b['uid']);
|
||||
//}
|
||||
|
||||
if ($b['verb'] == Activity::LIKE) {
|
||||
Logger::info('Like', ['uid' => $b['uid'], 'id' => twitter_get_id($b["thr-parent"])]);
|
||||
if ($b['deleted']) {
|
||||
twitter_action($a, $b["uid"], twitter_get_id($b["thr-parent"]), "unlike");
|
||||
} else {
|
||||
twitter_action($a, $b["uid"], twitter_get_id($b["thr-parent"]), "like");
|
||||
}
|
||||
|
||||
twitter_api_post($b['deleted'] ? 'favorite/destroy' : 'favorite/create', twitter_get_id($b["thr-parent"]), $b["uid"]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -612,7 +642,11 @@ function twitter_post_hook(App $a, array &$b)
|
|||
if ($b['verb'] == Activity::ANNOUNCE) {
|
||||
Logger::info('Retweet', ['uid' => $b['uid'], 'id' => twitter_get_id($b["thr-parent"])]);
|
||||
if ($b['deleted']) {
|
||||
twitter_action($a, $b['uid'], twitter_get_id($thr_parent['extid']), 'delete');
|
||||
/**
|
||||
* @TODO This can't work at the moment:
|
||||
* - Twitter post reshare removal doesn't seem to trigger the notifier hook this is part of
|
||||
*/
|
||||
//twitter_api_post('statuses/destroy', twitter_get_id($thr_parent['extid']), $b['uid']);
|
||||
} else {
|
||||
twitter_retweet($b["uid"], twitter_get_id($b["thr-parent"]));
|
||||
}
|
||||
|
@ -740,8 +774,7 @@ function twitter_post_hook(App $a, array &$b)
|
|||
$post['in_reply_to_status_id'] = twitter_get_id($thr_parent['uri']);
|
||||
}
|
||||
|
||||
$url = 'statuses/update';
|
||||
$result = $connection->post($url, $post);
|
||||
$result = $connection->post('statuses/update', $post);
|
||||
Logger::info('twitter_post send', ['id' => $b['id'], 'result' => $result]);
|
||||
|
||||
if (!empty($result->source)) {
|
||||
|
@ -2116,13 +2149,7 @@ function twitter_retweet(int $uid, int $id, int $item_id = 0)
|
|||
{
|
||||
Logger::info('Retweeting', ['user' => $uid, 'id' => $id]);
|
||||
|
||||
$ckey = DI::config()->get('twitter', 'consumerkey');
|
||||
$csecret = DI::config()->get('twitter', 'consumersecret');
|
||||
$otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
|
||||
$osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
|
||||
|
||||
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
|
||||
$result = $connection->post('statuses/retweet/' . $id);
|
||||
$result = twitter_api_post('statuses/retweet', $id, $uid);
|
||||
|
||||
Logger::info('Retweeted', ['user' => $uid, 'id' => $id, 'result' => $result]);
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '11:00'
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: composer
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '11:00'
|
||||
open-pull-requests-limit: 10
|
|
@ -0,0 +1,12 @@
|
|||
name: Lint
|
||||
on: push
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
- run: npm ci
|
||||
- run: npm run lint
|
|
@ -0,0 +1,18 @@
|
|||
name: Test
|
||||
on: push
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.2', '7.3', '7.4', '8.0']
|
||||
name: PHP ${{ matrix.php-versions }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
- run: composer validate --no-interaction --strict
|
||||
- run: composer install --no-interaction --prefer-dist
|
||||
- run: npm test
|
|
@ -1,4 +1,5 @@
|
|||
.DS_Store
|
||||
composer.lock
|
||||
vendor
|
||||
env
|
||||
*.cache
|
||||
node_modules
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
vendor
|
||||
composer.lock
|
||||
tests/fixtures
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"phpVersion": "7.2",
|
||||
"trailingCommaPHP": true,
|
||||
"braceStyle": "psr-2"
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
language: php
|
||||
dist: trusty
|
||||
php:
|
||||
- '5.6'
|
||||
- '7.0'
|
||||
- '7.1'
|
||||
- hhvm
|
||||
sudo: false
|
||||
before_script:
|
||||
- composer self-update
|
||||
- composer install --prefer-source --no-interaction
|
||||
script:
|
||||
- vendor/bin/phpunit
|
|
@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo
|
|||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# Contributing to TwitterOAuth
|
||||
|
||||
## 👏 Thanks!
|
||||
|
||||
Thanks for your interest in contributing to TwitterOAuth. We appreciate contributions small and large.
|
||||
|
||||
## 🌱 Grow
|
||||
|
||||
If you have an idea for something new or would like to improve something. Please [open a quick issue](https://github.com/abraham/twitteroauth/issues/new) explaining the changes and the reasons for them. Everyone's time is important and we don't want you duplicating work someone else might already be working on.
|
||||
|
||||
GitHub has [outlined instructions](https://help.github.com/articles/fork-a-repo/) for forking a repo. To work on an update to this repo, you will:
|
||||
|
||||
- Fork the repo
|
||||
- Make the changes
|
||||
- Submit a pull request
|
||||
|
||||
Once the [pull request](https://help.github.com/articles/about-pull-requests/) is reviewed, if the changes are approved they will be merged in to the project.
|
||||
|
||||
## 🐛 Bugs
|
||||
|
||||
Please [open a new issue](https://github.com/abraham/twitteroauth/issues/new) and details what you are trying to do, what is happening, and what you expect to happen. Err on the side of providing more details.
|
|
@ -1,5 +1,5 @@
|
|||
Copyright (c) 2009 Abraham Williams - http://abrah.am - abraham@abrah.am
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
|
@ -8,10 +8,10 @@ copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<span itemprop="name">TwitterOAuth</span> [![Build Status](https://img.shields.io/travis/abraham/twitteroauth.svg)](https://travis-ci.org/abraham/twitteroauth) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/abraham/twitteroauth/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/abraham/twitteroauth/?branch=master) [![Issues Count](https://img.shields.io/github/issues/abraham/twitteroauth.svg)](https://github.com/abraham/twitteroauth/issues) [![Latest Version](https://img.shields.io/packagist/v/abraham/twitteroauth.svg)](https://packagist.org/packages/abraham/twitteroauth)
|
||||
------------
|
||||
<span itemprop="name">TwitterOAuth</span> [![Build Status](https://github.com/abraham/twitteroauth/workflows/Test/badge.svg)](https://github.com/abraham/twitteroauth/actions) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/abraham/twitteroauth/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/abraham/twitteroauth/?branch=master) [![Issues Count](https://img.shields.io/github/issues/abraham/twitteroauth.svg)](https://github.com/abraham/twitteroauth/issues) [![Latest Version](https://img.shields.io/packagist/v/abraham/twitteroauth.svg)](https://packagist.org/packages/abraham/twitteroauth) [![Downloads this Month](https://img.shields.io/packagist/dm/abraham/twitteroauth.svg)](https://packagist.org/packages/abraham/twitteroauth)
|
||||
|
||||
---
|
||||
|
||||
<p itemprop="description">The most popular PHP library for Twitter's OAuth REST API.</p>
|
||||
|
||||
|
@ -7,4 +8,4 @@ See documentation at https://twitteroauth.com.
|
|||
|
||||
PHP versions [listed](https://secure.php.net/supported-versions.php) as "active support" or "security fixes only" are supported.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/abraham/twitteroauth-demo/master/images/twitter-logo-blue.png" itemprop="image" alt="Twitter bird" width="200px">
|
||||
<img src="https://raw.githubusercontent.com/abraham/twitteroauth-com/master/images/twitter-logo-blue.png" itemprop="image" alt="Twitter bird" width="200px">
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
* @return void
|
||||
*/
|
||||
spl_autoload_register(function ($class) {
|
||||
|
||||
// project-specific namespace prefix
|
||||
$prefix = 'Abraham\\TwitterOAuth\\';
|
||||
|
||||
|
|
|
@ -1,34 +1,55 @@
|
|||
{
|
||||
"name": "abraham/twitteroauth",
|
||||
"type": "library",
|
||||
"description": "The most popular PHP library for use with the Twitter OAuth REST API.",
|
||||
"keywords": ["twitter", "api", "oauth", "rest", "social", "twitter api", "twitter oauth"],
|
||||
"license": "MIT",
|
||||
"homepage": "https://twitteroauth.com",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Abraham Williams",
|
||||
"email": "abraham@abrah.am",
|
||||
"homepage": "https://abrah.am",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/abraham/twitteroauth",
|
||||
"issues": "https://github.com/abraham/twitteroauth/issues"
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~5.7",
|
||||
"squizlabs/php_codesniffer": "~3.0",
|
||||
"phpmd/phpmd": "~2.6"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Abraham\\TwitterOAuth\\": "src"
|
||||
}
|
||||
"name": "abraham/twitteroauth",
|
||||
"type": "library",
|
||||
"description": "The most popular PHP library for use with the Twitter OAuth REST API.",
|
||||
"keywords": [
|
||||
"twitter",
|
||||
"api",
|
||||
"oauth",
|
||||
"rest",
|
||||
"social",
|
||||
"twitter api",
|
||||
"twitter oauth"
|
||||
],
|
||||
"license": "MIT",
|
||||
"homepage": "https://twitteroauth.com",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Abraham Williams",
|
||||
"email": "abraham@abrah.am",
|
||||
"homepage": "https://abrah.am",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/abraham/twitteroauth",
|
||||
"issues": "https://github.com/abraham/twitteroauth/issues"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/morozov/php-vcr"
|
||||
},
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/abraham/phpunit-testlistener-vcr"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2 || ^7.3 || ^7.4 || ^8.0",
|
||||
"ext-curl": "*",
|
||||
"composer/ca-bundle": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8",
|
||||
"squizlabs/php_codesniffer": "^3",
|
||||
"phpmd/phpmd": "^2",
|
||||
"php-vcr/php-vcr": "^1",
|
||||
"php-vcr/phpunit-testlistener-vcr": "dev-php-8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Abraham\\TwitterOAuth\\": "src"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,511 @@
|
|||
{
|
||||
"name": "twitteroauth",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@prettier/plugin-php": {
|
||||
"version": "0.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@prettier/plugin-php/-/plugin-php-0.16.0.tgz",
|
||||
"integrity": "sha512-HG/FamMUtq4/9hZmeuvwy0BWmOr4m9OWacvLSUmmgUrQd4+TRZW7Nqs2MAJkwSNiBIgAKTt2Vw9PK+33Gxxx8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"linguist-languages": "^7.5.1",
|
||||
"mem": "^8.0.0",
|
||||
"php-parser": "3.0.2"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^3.1.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wrap-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"concurrently": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.3.0.tgz",
|
||||
"integrity": "sha512-8MhqOB6PWlBfA2vJ8a0bSFKATOdWlHiQlk11IfmQBPaHVP8oP2gsh2MObE6UR3hqDHqvaIvLTyceNW6obVuFHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"date-fns": "^2.0.1",
|
||||
"lodash": "^4.17.15",
|
||||
"read-pkg": "^4.0.1",
|
||||
"rxjs": "^6.5.2",
|
||||
"spawn-command": "^0.0.2-1",
|
||||
"supports-color": "^6.1.0",
|
||||
"tree-kill": "^1.2.2",
|
||||
"yargs": "^13.3.0"
|
||||
}
|
||||
},
|
||||
"date-fns": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz",
|
||||
"integrity": "sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==",
|
||||
"dev": true
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
|
||||
"dev": true
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"dev": true
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
|
||||
"dev": true
|
||||
},
|
||||
"linguist-languages": {
|
||||
"version": "7.11.1",
|
||||
"resolved": "https://registry.npmjs.org/linguist-languages/-/linguist-languages-7.11.1.tgz",
|
||||
"integrity": "sha512-+cRUk+1WTbydcdzipXQER2iilX+wMrb1LPkbkGuDP/IcGPJRDmOZH6Olf1iH6sHlHwPnJYiNJH39YsFCVZxvUQ==",
|
||||
"dev": true
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-locate": "^3.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.19",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
|
||||
"dev": true
|
||||
},
|
||||
"map-age-cleaner": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
|
||||
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-defer": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"mem": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-8.0.0.tgz",
|
||||
"integrity": "sha512-qrcJOe6uD+EW8Wrci1Vdiua/15Xw3n/QnaNXE7varnB6InxSk7nu3/i5jfy3S6kWxr8WYJ6R1o0afMUtvorTsA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"map-age-cleaner": "^0.1.3",
|
||||
"mimic-fn": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
|
||||
"integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hosted-git-info": "^2.1.4",
|
||||
"resolve": "^1.10.0",
|
||||
"semver": "2 || 3 || 4 || 5",
|
||||
"validate-npm-package-license": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
|
||||
"dev": true
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-limit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"dev": true
|
||||
},
|
||||
"parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"error-ex": "^1.3.1",
|
||||
"json-parse-better-errors": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"php-parser": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.0.2.tgz",
|
||||
"integrity": "sha512-a7y1+odEGsceLDLpu7oNyspZ0pK8FMWJOoim4/yd82AtnEZNLdCLZ67arnOQZ9K0lHJiSp4/7lVUpGELVxE14w==",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
|
||||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
|
||||
"integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
|
||||
"dev": true
|
||||
},
|
||||
"prettier-plugin-package": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-package/-/prettier-plugin-package-1.3.0.tgz",
|
||||
"integrity": "sha512-KPNHR/Jm2zTevBp1SnjzMnooO1BOQW2bixVbOp8flOJoW+dxdDwEncObfsKZdkjwrv6AIH4oWqm5EO/etDmK9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz",
|
||||
"integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"normalize-package-data": "^2.3.2",
|
||||
"parse-json": "^4.0.0",
|
||||
"pify": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
||||
"dev": true
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz",
|
||||
"integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true
|
||||
},
|
||||
"spawn-command": {
|
||||
"version": "0.0.2-1",
|
||||
"resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
|
||||
"integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
|
||||
"dev": true
|
||||
},
|
||||
"spdx-correct": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
|
||||
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-expression-parse": "^3.0.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"spdx-exceptions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
|
||||
"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
|
||||
"dev": true
|
||||
},
|
||||
"spdx-expression-parse": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
|
||||
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-exceptions": "^2.1.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"spdx-license-ids": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
|
||||
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"emoji-regex": "^7.0.1",
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
|
||||
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tree-kill": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
|
||||
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
|
||||
"dev": true
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
|
||||
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
|
||||
"dev": true
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-correct": "^3.0.0",
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^3.0.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.3.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
|
||||
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^5.0.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^13.1.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "13.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
|
||||
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "twitteroauth",
|
||||
"version": "0.0.0",
|
||||
"description": "The most popular PHP library for use with the Twitter OAuth REST API.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/abraham/twitteroauth.git"
|
||||
},
|
||||
"author": "Abraham Williams <abraham@abrah.am>",
|
||||
"homepage": "https://github.com/abraham/twitteroauth#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/abraham/twitteroauth/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"fix": "concurrently npm:fix:*",
|
||||
"fix:phpcbf": "./vendor/bin/phpcbf src tests --standard=PSR12",
|
||||
"fix:prettier": "prettier . --write",
|
||||
"lint": "concurrently npm:lint:*",
|
||||
"lint:phpcs": "./vendor/bin/phpcs src tests --standard=PSR12",
|
||||
"lint:prettier": "prettier . --check",
|
||||
"postinstall": "composer install --no-interaction",
|
||||
"test": "./vendor/bin/phpunit"
|
||||
},
|
||||
"keywords": [
|
||||
"twitter",
|
||||
"api",
|
||||
"oauth",
|
||||
"rest",
|
||||
"social",
|
||||
"twitter-api",
|
||||
"twitter-oauth"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@prettier/plugin-php": "0.16.0",
|
||||
"concurrently": "^5.3.0",
|
||||
"prettier": "2.2.1",
|
||||
"prettier-plugin-package": "1.3.0"
|
||||
},
|
||||
"directories": {
|
||||
"test": "tests"
|
||||
}
|
||||
}
|
|
@ -1,11 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
colors="true"
|
||||
bootstrap="tests/bootstrap.php">
|
||||
bootstrap="tests/bootstrap.php"
|
||||
testdox="true">
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="TwitterOAuth Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<listeners>
|
||||
<listener
|
||||
class="VCR\PHPUnit\TestListener\VCRTestListener"
|
||||
file="vendor/php-vcr/phpunit-testlistener-vcr/src/VCRTestListener.php" />
|
||||
</listeners>
|
||||
</phpunit>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
|
@ -13,6 +15,11 @@ class Config
|
|||
protected $timeout = 5;
|
||||
/** @var int how long to wait while connecting to the API */
|
||||
protected $connectionTimeout = 5;
|
||||
/** @var int How many times we retry request when API is down */
|
||||
protected $maxRetries = 0;
|
||||
/** @var int Delay in seconds before we retry the request */
|
||||
protected $retriesDelay = 1;
|
||||
|
||||
/**
|
||||
* Decode JSON Response as associative Array
|
||||
*
|
||||
|
@ -38,32 +45,44 @@ class Config
|
|||
* @param int $connectionTimeout
|
||||
* @param int $timeout
|
||||
*/
|
||||
public function setTimeouts($connectionTimeout, $timeout)
|
||||
public function setTimeouts(int $connectionTimeout, int $timeout): void
|
||||
{
|
||||
$this->connectionTimeout = (int)$connectionTimeout;
|
||||
$this->timeout = (int)$timeout;
|
||||
$this->connectionTimeout = $connectionTimeout;
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of times to retry on error and how long between each.
|
||||
*
|
||||
* @param int $maxRetries
|
||||
* @param int $retriesDelay
|
||||
*/
|
||||
public function setRetries(int $maxRetries, int $retriesDelay): void
|
||||
{
|
||||
$this->maxRetries = $maxRetries;
|
||||
$this->retriesDelay = $retriesDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setDecodeJsonAsArray($value)
|
||||
public function setDecodeJsonAsArray(bool $value): void
|
||||
{
|
||||
$this->decodeJsonAsArray = (bool)$value;
|
||||
$this->decodeJsonAsArray = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userAgent
|
||||
*/
|
||||
public function setUserAgent($userAgent)
|
||||
public function setUserAgent(string $userAgent): void
|
||||
{
|
||||
$this->userAgent = (string)$userAgent;
|
||||
$this->userAgent = $userAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $proxy
|
||||
*/
|
||||
public function setProxy(array $proxy)
|
||||
public function setProxy(array $proxy): void
|
||||
{
|
||||
$this->proxy = $proxy;
|
||||
}
|
||||
|
@ -73,9 +92,9 @@ class Config
|
|||
*
|
||||
* @param boolean $gzipEncoding
|
||||
*/
|
||||
public function setGzipEncoding($gzipEncoding)
|
||||
public function setGzipEncoding(bool $gzipEncoding): void
|
||||
{
|
||||
$this->gzipEncoding = (bool)$gzipEncoding;
|
||||
$this->gzipEncoding = $gzipEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,8 +102,8 @@ class Config
|
|||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setChunkSize($value)
|
||||
public function setChunkSize(int $value): void
|
||||
{
|
||||
$this->chunkSize = (int)$value;
|
||||
$this->chunkSize = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Consumer
|
||||
|
@ -15,12 +19,15 @@ class Consumer
|
|||
public $callbackUrl;
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $secret
|
||||
* @param string|null $key
|
||||
* @param string|null $secret
|
||||
* @param null $callbackUrl
|
||||
*/
|
||||
public function __construct($key, $secret, $callbackUrl = null)
|
||||
{
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $secret,
|
||||
?string $callbackUrl = null
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$this->callbackUrl = $callbackUrl;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
|
@ -19,17 +23,20 @@ class HmacSha1 extends SignatureMethod
|
|||
*/
|
||||
public function getName()
|
||||
{
|
||||
return "HMAC-SHA1";
|
||||
return 'HMAC-SHA1';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function buildSignature(Request $request, Consumer $consumer, Token $token = null)
|
||||
{
|
||||
public function buildSignature(
|
||||
Request $request,
|
||||
Consumer $consumer,
|
||||
Token $token = null
|
||||
): string {
|
||||
$signatureBase = $request->getSignatureBaseString();
|
||||
|
||||
$parts = [$consumer->secret, null !== $token ? $token->secret : ""];
|
||||
$parts = [$consumer->secret, null !== $token ? $token->secret : ''];
|
||||
|
||||
$parts = Util::urlencodeRfc3986($parts);
|
||||
$key = implode('&', $parts);
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Request
|
||||
|
@ -10,6 +14,7 @@ class Request
|
|||
protected $parameters;
|
||||
protected $httpMethod;
|
||||
protected $httpUrl;
|
||||
protected $json;
|
||||
public static $version = '1.0';
|
||||
|
||||
/**
|
||||
|
@ -19,9 +24,15 @@ class Request
|
|||
* @param string $httpUrl
|
||||
* @param array|null $parameters
|
||||
*/
|
||||
public function __construct($httpMethod, $httpUrl, array $parameters = [])
|
||||
{
|
||||
$parameters = array_merge(Util::parseParameters(parse_url($httpUrl, PHP_URL_QUERY)), $parameters);
|
||||
public function __construct(
|
||||
string $httpMethod,
|
||||
string $httpUrl,
|
||||
?array $parameters = []
|
||||
) {
|
||||
$parameters = array_merge(
|
||||
Util::parseParameters(parse_url($httpUrl, PHP_URL_QUERY)),
|
||||
$parameters
|
||||
);
|
||||
$this->parameters = $parameters;
|
||||
$this->httpMethod = $httpMethod;
|
||||
$this->httpUrl = $httpUrl;
|
||||
|
@ -41,21 +52,28 @@ class Request
|
|||
public static function fromConsumerAndToken(
|
||||
Consumer $consumer,
|
||||
Token $token = null,
|
||||
$httpMethod,
|
||||
$httpUrl,
|
||||
array $parameters = []
|
||||
string $httpMethod,
|
||||
string $httpUrl,
|
||||
array $parameters = [],
|
||||
$json = false
|
||||
) {
|
||||
$defaults = [
|
||||
"oauth_version" => Request::$version,
|
||||
"oauth_nonce" => Request::generateNonce(),
|
||||
"oauth_timestamp" => time(),
|
||||
"oauth_consumer_key" => $consumer->key
|
||||
'oauth_version' => Request::$version,
|
||||
'oauth_nonce' => Request::generateNonce(),
|
||||
'oauth_timestamp' => time(),
|
||||
'oauth_consumer_key' => $consumer->key,
|
||||
];
|
||||
if (null !== $token) {
|
||||
$defaults['oauth_token'] = $token->key;
|
||||
}
|
||||
|
||||
$parameters = array_merge($defaults, $parameters);
|
||||
// The json payload is not included in the signature on json requests,
|
||||
// therefore it shouldn't be included in the parameters array.
|
||||
if ($json) {
|
||||
$parameters = $defaults;
|
||||
} else {
|
||||
$parameters = array_merge($defaults, $parameters);
|
||||
}
|
||||
|
||||
return new Request($httpMethod, $httpUrl, $parameters);
|
||||
}
|
||||
|
@ -64,33 +82,35 @@ class Request
|
|||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
public function setParameter(string $name, string $value)
|
||||
{
|
||||
$this->parameters[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getParameter($name)
|
||||
public function getParameter(string $name): ?string
|
||||
{
|
||||
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
|
||||
return isset($this->parameters[$name])
|
||||
? $this->parameters[$name]
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters()
|
||||
public function getParameters(): array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param string $name
|
||||
*/
|
||||
public function removeParameter($name)
|
||||
public function removeParameter(string $name): void
|
||||
{
|
||||
unset($this->parameters[$name]);
|
||||
}
|
||||
|
@ -100,7 +120,7 @@ class Request
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSignableParameters()
|
||||
public function getSignableParameters(): string
|
||||
{
|
||||
// Grab all parameters
|
||||
$params = $this->parameters;
|
||||
|
@ -123,12 +143,12 @@ class Request
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSignatureBaseString()
|
||||
public function getSignatureBaseString(): string
|
||||
{
|
||||
$parts = [
|
||||
$this->getNormalizedHttpMethod(),
|
||||
$this->getNormalizedHttpUrl(),
|
||||
$this->getSignableParameters()
|
||||
$this->getSignableParameters(),
|
||||
];
|
||||
|
||||
$parts = Util::urlencodeRfc3986($parts);
|
||||
|
@ -141,7 +161,7 @@ class Request
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNormalizedHttpMethod()
|
||||
public function getNormalizedHttpMethod(): string
|
||||
{
|
||||
return strtoupper($this->httpMethod);
|
||||
}
|
||||
|
@ -152,7 +172,7 @@ class Request
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNormalizedHttpUrl()
|
||||
public function getNormalizedHttpUrl(): string
|
||||
{
|
||||
$parts = parse_url($this->httpUrl);
|
||||
|
||||
|
@ -168,7 +188,7 @@ class Request
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toUrl()
|
||||
public function toUrl(): string
|
||||
{
|
||||
$postData = $this->toPostdata();
|
||||
$out = $this->getNormalizedHttpUrl();
|
||||
|
@ -183,7 +203,7 @@ class Request
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toPostdata()
|
||||
public function toPostdata(): string
|
||||
{
|
||||
return Util::buildHttpQuery($this->parameters);
|
||||
}
|
||||
|
@ -194,19 +214,25 @@ class Request
|
|||
* @return string
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
public function toHeader()
|
||||
public function toHeader(): string
|
||||
{
|
||||
$first = true;
|
||||
$out = 'Authorization: OAuth';
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if (substr($k, 0, 5) != "oauth") {
|
||||
if (substr($k, 0, 5) != 'oauth') {
|
||||
continue;
|
||||
}
|
||||
if (is_array($v)) {
|
||||
throw new TwitterOAuthException('Arrays not supported in headers');
|
||||
throw new TwitterOAuthException(
|
||||
'Arrays not supported in headers'
|
||||
);
|
||||
}
|
||||
$out .= ($first) ? ' ' : ', ';
|
||||
$out .= Util::urlencodeRfc3986($k) . '="' . Util::urlencodeRfc3986($v) . '"';
|
||||
$out .= $first ? ' ' : ', ';
|
||||
$out .=
|
||||
Util::urlencodeRfc3986($k) .
|
||||
'="' .
|
||||
Util::urlencodeRfc3986($v) .
|
||||
'"';
|
||||
$first = false;
|
||||
}
|
||||
return $out;
|
||||
|
@ -215,7 +241,7 @@ class Request
|
|||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toUrl();
|
||||
}
|
||||
|
@ -225,11 +251,17 @@ class Request
|
|||
* @param Consumer $consumer
|
||||
* @param Token $token
|
||||
*/
|
||||
public function signRequest(SignatureMethod $signatureMethod, Consumer $consumer, Token $token = null)
|
||||
{
|
||||
$this->setParameter("oauth_signature_method", $signatureMethod->getName());
|
||||
public function signRequest(
|
||||
SignatureMethod $signatureMethod,
|
||||
Consumer $consumer,
|
||||
Token $token = null
|
||||
) {
|
||||
$this->setParameter(
|
||||
'oauth_signature_method',
|
||||
$signatureMethod->getName()
|
||||
);
|
||||
$signature = $this->buildSignature($signatureMethod, $consumer, $token);
|
||||
$this->setParameter("oauth_signature", $signature);
|
||||
$this->setParameter('oauth_signature', $signature);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,15 +271,18 @@ class Request
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function buildSignature(SignatureMethod $signatureMethod, Consumer $consumer, Token $token = null)
|
||||
{
|
||||
public function buildSignature(
|
||||
SignatureMethod $signatureMethod,
|
||||
Consumer $consumer,
|
||||
Token $token = null
|
||||
): string {
|
||||
return $signatureMethod->buildSignature($this, $consumer, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function generateNonce()
|
||||
public static function generateNonce(): string
|
||||
{
|
||||
return md5(microtime() . mt_rand());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
|
@ -23,7 +25,7 @@ class Response
|
|||
/**
|
||||
* @param string $apiPath
|
||||
*/
|
||||
public function setApiPath($apiPath)
|
||||
public function setApiPath(string $apiPath): void
|
||||
{
|
||||
$this->apiPath = $apiPath;
|
||||
}
|
||||
|
@ -31,7 +33,7 @@ class Response
|
|||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApiPath()
|
||||
public function getApiPath(): ?string
|
||||
{
|
||||
return $this->apiPath;
|
||||
}
|
||||
|
@ -55,7 +57,7 @@ class Response
|
|||
/**
|
||||
* @param int $httpCode
|
||||
*/
|
||||
public function setHttpCode($httpCode)
|
||||
public function setHttpCode(int $httpCode): void
|
||||
{
|
||||
$this->httpCode = $httpCode;
|
||||
}
|
||||
|
@ -63,7 +65,7 @@ class Response
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getHttpCode()
|
||||
public function getHttpCode(): int
|
||||
{
|
||||
return $this->httpCode;
|
||||
}
|
||||
|
@ -71,7 +73,7 @@ class Response
|
|||
/**
|
||||
* @param array $headers
|
||||
*/
|
||||
public function setHeaders(array $headers)
|
||||
public function setHeaders(array $headers): void
|
||||
{
|
||||
foreach ($headers as $key => $value) {
|
||||
if (substr($key, 0, 1) == 'x') {
|
||||
|
@ -84,7 +86,7 @@ class Response
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getsHeaders()
|
||||
public function getsHeaders(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
@ -92,7 +94,7 @@ class Response
|
|||
/**
|
||||
* @param array $xHeaders
|
||||
*/
|
||||
public function setXHeaders(array $xHeaders = [])
|
||||
public function setXHeaders(array $xHeaders = []): void
|
||||
{
|
||||
$this->xHeaders = $xHeaders;
|
||||
}
|
||||
|
@ -100,7 +102,7 @@ class Response
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getXHeaders()
|
||||
public function getXHeaders(): array
|
||||
{
|
||||
return $this->xHeaders;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
|
@ -30,7 +34,11 @@ abstract class SignatureMethod
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function buildSignature(Request $request, Consumer $consumer, Token $token = null);
|
||||
abstract public function buildSignature(
|
||||
Request $request,
|
||||
Consumer $consumer,
|
||||
Token $token = null
|
||||
);
|
||||
|
||||
/**
|
||||
* Verifies that a given signature is correct
|
||||
|
@ -42,8 +50,12 @@ abstract class SignatureMethod
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkSignature(Request $request, Consumer $consumer, Token $token, $signature)
|
||||
{
|
||||
public function checkSignature(
|
||||
Request $request,
|
||||
Consumer $consumer,
|
||||
Token $token,
|
||||
string $signature
|
||||
): bool {
|
||||
$built = $this->buildSignature($request, $consumer, $token);
|
||||
|
||||
// Check for zero length, although unlikely here
|
||||
|
@ -58,7 +70,7 @@ abstract class SignatureMethod
|
|||
// Avoid a timing leak with a (hopefully) time insensitive compare
|
||||
$result = 0;
|
||||
for ($i = 0; $i < strlen($signature); $i++) {
|
||||
$result |= ord($built{$i}) ^ ord($signature{$i});
|
||||
$result |= ord($built[$i]) ^ ord($signature[$i]);
|
||||
}
|
||||
|
||||
return $result == 0;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Token
|
||||
|
@ -16,7 +20,7 @@ class Token
|
|||
* @param string $key The OAuth Token
|
||||
* @param string $secret The OAuth Token Secret
|
||||
*/
|
||||
public function __construct($key, $secret)
|
||||
public function __construct(?string $key, ?string $secret)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
|
@ -28,9 +32,10 @@ class Token
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf("oauth_token=%s&oauth_token_secret=%s",
|
||||
return sprintf(
|
||||
'oauth_token=%s&oauth_token_secret=%s',
|
||||
Util::urlencodeRfc3986($this->key),
|
||||
Util::urlencodeRfc3986($this->secret)
|
||||
);
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The most popular PHP library for use with the Twitter OAuth REST API.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
use Abraham\TwitterOAuth\Util\JsonDecoder;
|
||||
use Composer\CaBundle\CaBundle;
|
||||
|
||||
/**
|
||||
* TwitterOAuth class for interacting with the Twitter API.
|
||||
|
@ -15,9 +20,9 @@ use Abraham\TwitterOAuth\Util\JsonDecoder;
|
|||
*/
|
||||
class TwitterOAuth extends Config
|
||||
{
|
||||
const API_VERSION = '1.1';
|
||||
const API_HOST = 'https://api.twitter.com';
|
||||
const UPLOAD_HOST = 'https://upload.twitter.com';
|
||||
private const API_VERSION = '1.1';
|
||||
private const API_HOST = 'https://api.twitter.com';
|
||||
private const UPLOAD_HOST = 'https://upload.twitter.com';
|
||||
|
||||
/** @var Response details about the result of the last request */
|
||||
private $response;
|
||||
|
@ -29,6 +34,8 @@ class TwitterOAuth extends Config
|
|||
private $token;
|
||||
/** @var HmacSha1 OAuth 1 signature type used by Twitter */
|
||||
private $signatureMethod;
|
||||
/** @var int Number of attempts we made for the request */
|
||||
private $attempts = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -38,16 +45,20 @@ class TwitterOAuth extends Config
|
|||
* @param string|null $oauthToken The Client Token (optional)
|
||||
* @param string|null $oauthTokenSecret The Client Token Secret (optional)
|
||||
*/
|
||||
public function __construct($consumerKey, $consumerSecret, $oauthToken = null, $oauthTokenSecret = null)
|
||||
{
|
||||
public function __construct(
|
||||
string $consumerKey,
|
||||
string $consumerSecret,
|
||||
?string $oauthToken = null,
|
||||
?string $oauthTokenSecret = null
|
||||
) {
|
||||
$this->resetLastResponse();
|
||||
$this->signatureMethod = new HmacSha1();
|
||||
$this->consumer = new Consumer($consumerKey, $consumerSecret);
|
||||
if (!empty($oauthToken) && !empty($oauthTokenSecret)) {
|
||||
$this->token = new Token($oauthToken, $oauthTokenSecret);
|
||||
$this->setOauthToken($oauthToken, $oauthTokenSecret);
|
||||
}
|
||||
if (empty($oauthToken) && !empty($oauthTokenSecret)) {
|
||||
$this->bearer = $oauthTokenSecret;
|
||||
$this->setBearer($oauthTokenSecret);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,15 +66,27 @@ class TwitterOAuth extends Config
|
|||
* @param string $oauthToken
|
||||
* @param string $oauthTokenSecret
|
||||
*/
|
||||
public function setOauthToken($oauthToken, $oauthTokenSecret)
|
||||
{
|
||||
public function setOauthToken(
|
||||
string $oauthToken,
|
||||
string $oauthTokenSecret
|
||||
): void {
|
||||
$this->token = new Token($oauthToken, $oauthTokenSecret);
|
||||
$this->bearer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $oauthTokenSecret
|
||||
*/
|
||||
public function setBearer(string $oauthTokenSecret): void
|
||||
{
|
||||
$this->bearer = $oauthTokenSecret;
|
||||
$this->token = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLastApiPath()
|
||||
public function getLastApiPath(): ?string
|
||||
{
|
||||
return $this->response->getApiPath();
|
||||
}
|
||||
|
@ -71,7 +94,7 @@ class TwitterOAuth extends Config
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLastHttpCode()
|
||||
public function getLastHttpCode(): int
|
||||
{
|
||||
return $this->response->getHttpCode();
|
||||
}
|
||||
|
@ -79,7 +102,7 @@ class TwitterOAuth extends Config
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLastXHeaders()
|
||||
public function getLastXHeaders(): array
|
||||
{
|
||||
return $this->response->getXHeaders();
|
||||
}
|
||||
|
@ -95,11 +118,29 @@ class TwitterOAuth extends Config
|
|||
/**
|
||||
* Resets the last response cache.
|
||||
*/
|
||||
public function resetLastResponse()
|
||||
public function resetLastResponse(): void
|
||||
{
|
||||
$this->response = new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the attempts number.
|
||||
*/
|
||||
private function resetAttemptsNumber(): void
|
||||
{
|
||||
$this->attempts = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delays the retries when they're activated.
|
||||
*/
|
||||
private function sleepIfNeeded(): void
|
||||
{
|
||||
if ($this->maxRetries && $this->attempts) {
|
||||
sleep($this->retriesDelay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make URLs for user browser navigation.
|
||||
*
|
||||
|
@ -108,7 +149,7 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url($path, array $parameters)
|
||||
public function url(string $path, array $parameters): string
|
||||
{
|
||||
$this->resetLastResponse();
|
||||
$this->response->setApiPath($path);
|
||||
|
@ -125,7 +166,7 @@ class TwitterOAuth extends Config
|
|||
* @return array
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
public function oauth($path, array $parameters = [])
|
||||
public function oauth(string $path, array $parameters = []): array
|
||||
{
|
||||
$response = [];
|
||||
$this->resetLastResponse();
|
||||
|
@ -151,15 +192,28 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function oauth2($path, array $parameters = [])
|
||||
public function oauth2(string $path, array $parameters = [])
|
||||
{
|
||||
$method = 'POST';
|
||||
$this->resetLastResponse();
|
||||
$this->response->setApiPath($path);
|
||||
$url = sprintf('%s/%s', self::API_HOST, $path);
|
||||
$request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
|
||||
$authorization = 'Authorization: Basic ' . $this->encodeAppAuthorization($this->consumer);
|
||||
$result = $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters);
|
||||
$request = Request::fromConsumerAndToken(
|
||||
$this->consumer,
|
||||
$this->token,
|
||||
$method,
|
||||
$url,
|
||||
$parameters
|
||||
);
|
||||
$authorization =
|
||||
'Authorization: Basic ' .
|
||||
$this->encodeAppAuthorization($this->consumer);
|
||||
$result = $this->request(
|
||||
$request->getNormalizedHttpUrl(),
|
||||
$method,
|
||||
$authorization,
|
||||
$parameters
|
||||
);
|
||||
$response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
|
||||
$this->response->setBody($response);
|
||||
return $response;
|
||||
|
@ -173,9 +227,9 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function get($path, array $parameters = [])
|
||||
public function get(string $path, array $parameters = [])
|
||||
{
|
||||
return $this->http('GET', self::API_HOST, $path, $parameters);
|
||||
return $this->http('GET', self::API_HOST, $path, $parameters, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,12 +237,16 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param bool $json
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function post($path, array $parameters = [])
|
||||
{
|
||||
return $this->http('POST', self::API_HOST, $path, $parameters);
|
||||
public function post(
|
||||
string $path,
|
||||
array $parameters = [],
|
||||
bool $json = false
|
||||
) {
|
||||
return $this->http('POST', self::API_HOST, $path, $parameters, $json);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,9 +257,9 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function delete($path, array $parameters = [])
|
||||
public function delete(string $path, array $parameters = [])
|
||||
{
|
||||
return $this->http('DELETE', self::API_HOST, $path, $parameters);
|
||||
return $this->http('DELETE', self::API_HOST, $path, $parameters, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,9 +270,9 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function put($path, array $parameters = [])
|
||||
public function put(string $path, array $parameters = [])
|
||||
{
|
||||
return $this->http('PUT', self::API_HOST, $path, $parameters);
|
||||
return $this->http('PUT', self::API_HOST, $path, $parameters, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,8 +284,11 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function upload($path, array $parameters = [], $chunked = false)
|
||||
{
|
||||
public function upload(
|
||||
string $path,
|
||||
array $parameters = [],
|
||||
bool $chunked = false
|
||||
) {
|
||||
if ($chunked) {
|
||||
return $this->uploadMediaChunked($path, $parameters);
|
||||
} else {
|
||||
|
@ -235,6 +296,27 @@ class TwitterOAuth extends Config
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Progression of media upload
|
||||
*
|
||||
* @param string $media_id
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function mediaStatus(string $media_id)
|
||||
{
|
||||
return $this->http(
|
||||
'GET',
|
||||
self::UPLOAD_HOST,
|
||||
'media/upload',
|
||||
[
|
||||
'command' => 'STATUS',
|
||||
'media_id' => $media_id,
|
||||
],
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method to upload media (not chunked) to upload.twitter.com.
|
||||
*
|
||||
|
@ -243,12 +325,24 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function uploadMediaNotChunked($path, array $parameters)
|
||||
private function uploadMediaNotChunked(string $path, array $parameters)
|
||||
{
|
||||
$file = file_get_contents($parameters['media']);
|
||||
$base = base64_encode($file);
|
||||
$parameters['media'] = $base;
|
||||
return $this->http('POST', self::UPLOAD_HOST, $path, $parameters);
|
||||
if (
|
||||
!is_readable($parameters['media']) ||
|
||||
($file = file_get_contents($parameters['media'])) === false
|
||||
) {
|
||||
throw new \InvalidArgumentException(
|
||||
'You must supply a readable file'
|
||||
);
|
||||
}
|
||||
$parameters['media'] = base64_encode($file);
|
||||
return $this->http(
|
||||
'POST',
|
||||
self::UPLOAD_HOST,
|
||||
$path,
|
||||
$parameters,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,27 +353,46 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function uploadMediaChunked($path, array $parameters)
|
||||
private function uploadMediaChunked(string $path, array $parameters)
|
||||
{
|
||||
$init = $this->http('POST', self::UPLOAD_HOST, $path, $this->mediaInitParameters($parameters));
|
||||
$init = $this->http(
|
||||
'POST',
|
||||
self::UPLOAD_HOST,
|
||||
$path,
|
||||
$this->mediaInitParameters($parameters),
|
||||
false
|
||||
);
|
||||
// Append
|
||||
$segmentIndex = 0;
|
||||
$media = fopen($parameters['media'], 'rb');
|
||||
while (!feof($media))
|
||||
{
|
||||
$this->http('POST', self::UPLOAD_HOST, 'media/upload', [
|
||||
'command' => 'APPEND',
|
||||
'media_id' => $init->media_id_string,
|
||||
'segment_index' => $segmentIndex++,
|
||||
'media_data' => base64_encode(fread($media, $this->chunkSize))
|
||||
]);
|
||||
while (!feof($media)) {
|
||||
$this->http(
|
||||
'POST',
|
||||
self::UPLOAD_HOST,
|
||||
'media/upload',
|
||||
[
|
||||
'command' => 'APPEND',
|
||||
'media_id' => $init->media_id_string,
|
||||
'segment_index' => $segmentIndex++,
|
||||
'media_data' => base64_encode(
|
||||
fread($media, $this->chunkSize)
|
||||
),
|
||||
],
|
||||
false
|
||||
);
|
||||
}
|
||||
fclose($media);
|
||||
// Finalize
|
||||
$finalize = $this->http('POST', self::UPLOAD_HOST, 'media/upload', [
|
||||
'command' => 'FINALIZE',
|
||||
'media_id' => $init->media_id_string
|
||||
]);
|
||||
$finalize = $this->http(
|
||||
'POST',
|
||||
self::UPLOAD_HOST,
|
||||
'media/upload',
|
||||
[
|
||||
'command' => 'FINALIZE',
|
||||
'media_id' => $init->media_id_string,
|
||||
],
|
||||
false
|
||||
);
|
||||
return $finalize;
|
||||
}
|
||||
|
||||
|
@ -291,20 +404,41 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
private function mediaInitParameters(array $parameters)
|
||||
private function mediaInitParameters(array $parameters): array
|
||||
{
|
||||
$return = [
|
||||
'command' => 'INIT',
|
||||
'media_type' => $parameters['media_type'],
|
||||
'total_bytes' => filesize($parameters['media'])
|
||||
$allowed_keys = [
|
||||
'media_type',
|
||||
'additional_owners',
|
||||
'media_category',
|
||||
'shared',
|
||||
];
|
||||
if (isset($parameters['additional_owners'])) {
|
||||
$return['additional_owners'] = $parameters['additional_owners'];
|
||||
$base = [
|
||||
'command' => 'INIT',
|
||||
'total_bytes' => filesize($parameters['media']),
|
||||
];
|
||||
$allowed_parameters = array_intersect_key(
|
||||
$parameters,
|
||||
array_flip($allowed_keys)
|
||||
);
|
||||
return array_merge($base, $allowed_parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup any parameters that are known not to work.
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function cleanUpParameters(array $parameters)
|
||||
{
|
||||
foreach ($parameters as $key => $value) {
|
||||
// PHP coerces `true` to `"1"` which some Twitter APIs don't like.
|
||||
if (is_bool($value)) {
|
||||
$parameters[$key] = var_export($value, true);
|
||||
}
|
||||
}
|
||||
if (isset($parameters['media_category'])) {
|
||||
$return['media_category'] = $parameters['media_category'];
|
||||
}
|
||||
return $return;
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -312,39 +446,104 @@ class TwitterOAuth extends Config
|
|||
* @param string $host
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param bool $json
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function http($method, $host, $path, array $parameters)
|
||||
{
|
||||
private function http(
|
||||
string $method,
|
||||
string $host,
|
||||
string $path,
|
||||
array $parameters,
|
||||
bool $json
|
||||
) {
|
||||
$this->resetLastResponse();
|
||||
$this->resetAttemptsNumber();
|
||||
$url = sprintf('%s/%s/%s.json', $host, self::API_VERSION, $path);
|
||||
$this->response->setApiPath($path);
|
||||
$result = $this->oAuthRequest($url, $method, $parameters);
|
||||
$response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
|
||||
$this->response->setBody($response);
|
||||
if (!$json) {
|
||||
$parameters = $this->cleanUpParameters($parameters);
|
||||
}
|
||||
return $this->makeRequests($url, $method, $parameters, $json);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Make requests and retry them (if enabled) in case of Twitter's problems.
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param bool $json
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function makeRequests(
|
||||
string $url,
|
||||
string $method,
|
||||
array $parameters,
|
||||
bool $json
|
||||
) {
|
||||
do {
|
||||
$this->sleepIfNeeded();
|
||||
$result = $this->oAuthRequest($url, $method, $parameters, $json);
|
||||
$response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
|
||||
$this->response->setBody($response);
|
||||
$this->attempts++;
|
||||
// Retry up to our $maxRetries number if we get errors greater than 500 (over capacity etc)
|
||||
} while ($this->requestsAvailable());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we have to retry request if API is down.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function requestsAvailable(): bool
|
||||
{
|
||||
return $this->maxRetries &&
|
||||
$this->attempts <= $this->maxRetries &&
|
||||
$this->getLastHttpCode() >= 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and sign an OAuth / API request
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param bool $json
|
||||
*
|
||||
* @return string
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
private function oAuthRequest($url, $method, array $parameters)
|
||||
{
|
||||
$request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
|
||||
private function oAuthRequest(
|
||||
string $url,
|
||||
string $method,
|
||||
array $parameters,
|
||||
bool $json = false
|
||||
) {
|
||||
$request = Request::fromConsumerAndToken(
|
||||
$this->consumer,
|
||||
$this->token,
|
||||
$method,
|
||||
$url,
|
||||
$parameters,
|
||||
$json
|
||||
);
|
||||
if (array_key_exists('oauth_callback', $parameters)) {
|
||||
// Twitter doesn't like oauth_callback as a parameter.
|
||||
unset($parameters['oauth_callback']);
|
||||
}
|
||||
if ($this->bearer === null) {
|
||||
$request->signRequest($this->signatureMethod, $this->consumer, $this->token);
|
||||
$request->signRequest(
|
||||
$this->signatureMethod,
|
||||
$this->consumer,
|
||||
$this->token
|
||||
);
|
||||
$authorization = $request->toHeader();
|
||||
if (array_key_exists('oauth_verifier', $parameters)) {
|
||||
// Twitter doesn't always work with oauth in the body and in the header
|
||||
|
@ -354,7 +553,13 @@ class TwitterOAuth extends Config
|
|||
} else {
|
||||
$authorization = 'Authorization: Bearer ' . $this->bearer;
|
||||
}
|
||||
return $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters);
|
||||
return $this->request(
|
||||
$request->getNormalizedHttpUrl(),
|
||||
$method,
|
||||
$authorization,
|
||||
$parameters,
|
||||
$json
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -362,8 +567,9 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
private function curlOptions()
|
||||
private function curlOptions(): array
|
||||
{
|
||||
$bundlePath = CaBundle::getSystemCaRootBundlePath();
|
||||
$options = [
|
||||
// CURLOPT_VERBOSE => true,
|
||||
CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout,
|
||||
|
@ -373,19 +579,17 @@ class TwitterOAuth extends Config
|
|||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
CURLOPT_TIMEOUT => $this->timeout,
|
||||
CURLOPT_USERAGENT => $this->userAgent,
|
||||
$this->curlCaOpt($bundlePath) => $bundlePath,
|
||||
];
|
||||
|
||||
if ($this->useCAFile()) {
|
||||
$options[CURLOPT_CAINFO] = __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem';
|
||||
}
|
||||
|
||||
if($this->gzipEncoding) {
|
||||
if ($this->gzipEncoding) {
|
||||
$options[CURLOPT_ENCODING] = 'gzip';
|
||||
}
|
||||
|
||||
if (!empty($this->proxy)) {
|
||||
$options[CURLOPT_PROXY] = $this->proxy['CURLOPT_PROXY'];
|
||||
$options[CURLOPT_PROXYUSERPWD] = $this->proxy['CURLOPT_PROXYUSERPWD'];
|
||||
$options[CURLOPT_PROXYUSERPWD] =
|
||||
$this->proxy['CURLOPT_PROXYUSERPWD'];
|
||||
$options[CURLOPT_PROXYPORT] = $this->proxy['CURLOPT_PROXYPORT'];
|
||||
$options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
|
||||
$options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
|
||||
|
@ -401,22 +605,40 @@ class TwitterOAuth extends Config
|
|||
* @param string $method
|
||||
* @param string $authorization
|
||||
* @param array $postfields
|
||||
* @param bool $json
|
||||
*
|
||||
* @return string
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
private function request($url, $method, $authorization, array $postfields)
|
||||
{
|
||||
$options = $this->curlOptions($url, $authorization);
|
||||
private function request(
|
||||
string $url,
|
||||
string $method,
|
||||
string $authorization,
|
||||
array $postfields,
|
||||
bool $json = false
|
||||
): string {
|
||||
$options = $this->curlOptions();
|
||||
$options[CURLOPT_URL] = $url;
|
||||
$options[CURLOPT_HTTPHEADER] = ['Accept: application/json', $authorization, 'Expect:'];
|
||||
$options[CURLOPT_HTTPHEADER] = [
|
||||
'Accept: application/json',
|
||||
$authorization,
|
||||
'Expect:',
|
||||
];
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
break;
|
||||
case 'POST':
|
||||
$options[CURLOPT_POST] = true;
|
||||
$options[CURLOPT_POSTFIELDS] = Util::buildHttpQuery($postfields);
|
||||
if ($json) {
|
||||
$options[CURLOPT_HTTPHEADER][] =
|
||||
'Content-type: application/json';
|
||||
$options[CURLOPT_POSTFIELDS] = json_encode($postfields);
|
||||
} else {
|
||||
$options[CURLOPT_POSTFIELDS] = Util::buildHttpQuery(
|
||||
$postfields
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'DELETE':
|
||||
$options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
|
||||
|
@ -426,21 +648,28 @@ class TwitterOAuth extends Config
|
|||
break;
|
||||
}
|
||||
|
||||
if (in_array($method, ['GET', 'PUT', 'DELETE']) && !empty($postfields)) {
|
||||
if (
|
||||
in_array($method, ['GET', 'PUT', 'DELETE']) &&
|
||||
!empty($postfields)
|
||||
) {
|
||||
$options[CURLOPT_URL] .= '?' . Util::buildHttpQuery($postfields);
|
||||
}
|
||||
|
||||
|
||||
$curlHandle = curl_init();
|
||||
curl_setopt_array($curlHandle, $options);
|
||||
$response = curl_exec($curlHandle);
|
||||
|
||||
// Throw exceptions on cURL errors.
|
||||
if (curl_errno($curlHandle) > 0) {
|
||||
throw new TwitterOAuthException(curl_error($curlHandle), curl_errno($curlHandle));
|
||||
$error = curl_error($curlHandle);
|
||||
$errorNo = curl_errno($curlHandle);
|
||||
curl_close($curlHandle);
|
||||
throw new TwitterOAuthException($error, $errorNo);
|
||||
}
|
||||
|
||||
$this->response->setHttpCode(curl_getinfo($curlHandle, CURLINFO_HTTP_CODE));
|
||||
$this->response->setHttpCode(
|
||||
curl_getinfo($curlHandle, CURLINFO_HTTP_CODE)
|
||||
);
|
||||
$parts = explode("\r\n\r\n", $response);
|
||||
$responseBody = array_pop($parts);
|
||||
$responseHeader = array_pop($parts);
|
||||
|
@ -458,12 +687,12 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseHeaders($header)
|
||||
private function parseHeaders(string $header): array
|
||||
{
|
||||
$headers = [];
|
||||
foreach (explode("\r\n", $header) as $line) {
|
||||
if (strpos($line, ':') !== false) {
|
||||
list ($key, $value) = explode(': ', $line);
|
||||
[$key, $value] = explode(': ', $line);
|
||||
$key = str_replace('-', '_', strtolower($key));
|
||||
$headers[$key] = trim($value);
|
||||
}
|
||||
|
@ -478,7 +707,7 @@ class TwitterOAuth extends Config
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encodeAppAuthorization(Consumer $consumer)
|
||||
private function encodeAppAuthorization(Consumer $consumer): string
|
||||
{
|
||||
$key = rawurlencode($consumer->key);
|
||||
$secret = rawurlencode($consumer->secret);
|
||||
|
@ -486,23 +715,13 @@ class TwitterOAuth extends Config
|
|||
}
|
||||
|
||||
/**
|
||||
* Is the code running from a Phar module.
|
||||
* Get Curl CA option based on whether the given path is a directory or file.
|
||||
*
|
||||
* @return boolean
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
private function pharRunning()
|
||||
private function curlCaOpt(string $path): int
|
||||
{
|
||||
return class_exists('Phar') && \Phar::running(false) !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Use included CA file instead of OS provided list.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function useCAFile()
|
||||
{
|
||||
/* Use CACert file when not in a PHAR file. */
|
||||
return !$this->pharRunning();
|
||||
return is_dir($path) ? CURLOPT_CAPATH : CURLOPT_CAINFO;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,24 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* @param $input
|
||||
* @param mixed $input
|
||||
*
|
||||
* @return array|mixed|string
|
||||
* @return mixed
|
||||
*/
|
||||
public static function urlencodeRfc3986($input)
|
||||
{
|
||||
$output = '';
|
||||
if (is_array($input)) {
|
||||
$output = array_map([__NAMESPACE__ . '\Util', 'urlencodeRfc3986'], $input);
|
||||
$output = array_map(
|
||||
[__NAMESPACE__ . '\Util', 'urlencodeRfc3986'],
|
||||
$input
|
||||
);
|
||||
} elseif (is_scalar($input)) {
|
||||
$output = rawurlencode($input);
|
||||
$output = rawurlencode((string) $input);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
@ -28,7 +35,7 @@ class Util
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function urldecodeRfc3986($string)
|
||||
public static function urldecodeRfc3986($string): string
|
||||
{
|
||||
return urldecode($string);
|
||||
}
|
||||
|
@ -42,7 +49,7 @@ class Util
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parseParameters($input)
|
||||
public static function parseParameters($input): array
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
return [];
|
||||
|
@ -79,7 +86,7 @@ class Util
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function buildHttpQuery(array $params)
|
||||
public static function buildHttpQuery(array $params): string
|
||||
{
|
||||
if (empty($params)) {
|
||||
return '';
|
||||
|
|
|
@ -15,9 +15,12 @@ class JsonDecoder
|
|||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public static function decode($string, $asArray)
|
||||
public static function decode(string $string, bool $asArray)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
|
||||
if (
|
||||
version_compare(PHP_VERSION, '5.4.0', '>=') &&
|
||||
!(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)
|
||||
) {
|
||||
return json_decode($string, $asArray, 512, JSON_BIGINT_AS_STRING);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Abraham\TwitterOAuth\SignatureMethod;
|
||||
|
||||
abstract class AbstractSignatureMethodTest extends \PHPUnit_Framework_TestCase
|
||||
abstract class AbstractSignatureMethodTest extends TestCase
|
||||
{
|
||||
protected $name;
|
||||
|
||||
|
@ -25,7 +28,10 @@ abstract class AbstractSignatureMethodTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public function testBuildSignature($expected, $request, $consumer, $token)
|
||||
{
|
||||
$this->assertEquals($expected, $this->getClass()->buildSignature($request, $consumer, $token));
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$this->getClass()->buildSignature($request, $consumer, $token)
|
||||
);
|
||||
}
|
||||
|
||||
protected function getRequest()
|
||||
|
@ -35,8 +41,11 @@ abstract class AbstractSignatureMethodTest extends \PHPUnit_Framework_TestCase
|
|||
->getMock();
|
||||
}
|
||||
|
||||
protected function getConsumer($key = null, $secret = null, $callbackUrl = null)
|
||||
{
|
||||
protected function getConsumer(
|
||||
$key = null,
|
||||
$secret = null,
|
||||
$callbackUrl = null
|
||||
) {
|
||||
return $this->getMockBuilder('Abraham\TwitterOAuth\Consumer')
|
||||
->setConstructorArgs([$key, $secret, $callbackUrl])
|
||||
->getMock();
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Abraham\TwitterOAuth\Consumer;
|
||||
|
||||
class ConsumerTest extends \PHPUnit_Framework_TestCase {
|
||||
class ConsumerTest extends TestCase
|
||||
{
|
||||
public function testToString()
|
||||
{
|
||||
$key = uniqid();
|
||||
$secret = uniqid();
|
||||
$consumer = new Consumer($key, $secret);
|
||||
|
||||
$this->assertEquals("Consumer[key=$key,secret=$secret]", $consumer->__toString());
|
||||
$this->assertEquals(
|
||||
"Consumer[key=$key,secret=$secret]",
|
||||
$consumer->__toString()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth\Tests;
|
||||
|
||||
use Abraham\TwitterOAuth\HmacSha1;
|
||||
|
@ -16,20 +18,30 @@ class HmacSha1Test extends AbstractSignatureMethodTest
|
|||
public function signatureDataProvider()
|
||||
{
|
||||
return [
|
||||
['5CoEcoq7XoKFjwYCieQvuzadeUA=', $this->getRequest(), $this->getConsumer(), $this->getToken()],
|
||||
[
|
||||
'5CoEcoq7XoKFjwYCieQvuzadeUA=',
|
||||
$this->getRequest(),
|
||||
$this->getConsumer(),
|
||||
$this->getToken(),
|
||||
],
|
||||
[
|
||||
'EBw0gHngam3BTx8kfPfNNSyKem4=',
|
||||
$this->getRequest(),
|
||||
$this->getConsumer('key', 'secret'),
|
||||
$this->getToken()
|
||||
$this->getToken(),
|
||||
],
|
||||
[
|
||||
'kDsHFZzws2a5M6cAQjfpdNBo+v8=',
|
||||
$this->getRequest(),
|
||||
$this->getConsumer('key', 'secret'),
|
||||
$this->getToken('key', 'secret')
|
||||
$this->getToken('key', 'secret'),
|
||||
],
|
||||
[
|
||||
'EBw0gHngam3BTx8kfPfNNSyKem4=',
|
||||
$this->getRequest(),
|
||||
$this->getConsumer('key', 'secret'),
|
||||
null,
|
||||
],
|
||||
['EBw0gHngam3BTx8kfPfNNSyKem4=', $this->getRequest(), $this->getConsumer('key', 'secret'), null],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Abraham\TwitterOAuth\Token;
|
||||
|
||||
class TokenTest extends \PHPUnit_Framework_TestCase {
|
||||
class TokenTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider tokenProvider
|
||||
*/
|
||||
|
@ -19,8 +23,16 @@ class TokenTest extends \PHPUnit_Framework_TestCase {
|
|||
{
|
||||
return [
|
||||
['oauth_token=key&oauth_token_secret=secret', 'key', 'secret'],
|
||||
['oauth_token=key%2Bkey&oauth_token_secret=secret', 'key+key', 'secret'],
|
||||
['oauth_token=key~key&oauth_token_secret=secret', 'key~key', 'secret'],
|
||||
[
|
||||
'oauth_token=key%2Bkey&oauth_token_secret=secret',
|
||||
'key+key',
|
||||
'secret',
|
||||
],
|
||||
[
|
||||
'oauth_token=key~key&oauth_token_secret=secret',
|
||||
'key~key',
|
||||
'secret',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* WARNING: Running these tests will post and delete through the actual Twitter account.
|
||||
* WARNING: Running tests will post and delete through the actual Twitter account when updating or saving VCR cassettes.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Abraham\TwitterOAuth\TwitterOAuth;
|
||||
|
||||
class TwitterOAuthTest extends \PHPUnit_Framework_TestCase
|
||||
class TwitterOAuthTest extends TestCase
|
||||
{
|
||||
/** @var TwitterOAuth */
|
||||
protected $twitter;
|
||||
|
||||
protected function setUp()
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
|
||||
$this->twitter = new TwitterOAuth(
|
||||
CONSUMER_KEY,
|
||||
CONSUMER_SECRET,
|
||||
ACCESS_TOKEN,
|
||||
ACCESS_TOKEN_SECRET
|
||||
);
|
||||
$this->userId = explode('-', ACCESS_TOKEN)[0];
|
||||
}
|
||||
|
||||
public function testBuildClient()
|
||||
|
@ -22,20 +33,30 @@ class TwitterOAuthTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertObjectHasAttribute('token', $this->twitter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testSetOauthToken.json
|
||||
*/
|
||||
public function testSetOauthToken()
|
||||
{
|
||||
$twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
|
||||
$twitter->setOauthToken(ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
|
||||
$this->assertObjectHasAttribute('consumer', $twitter);
|
||||
$this->assertObjectHasAttribute('token', $twitter);
|
||||
$twitter->get('friendships/show', ['target_screen_name' => 'twitterapi']);
|
||||
$twitter->get('friendships/show', [
|
||||
'target_screen_name' => 'twitterapi',
|
||||
]);
|
||||
$this->assertEquals(200, $twitter->getLastHttpCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testOauth2Token.json
|
||||
*/
|
||||
public function testOauth2Token()
|
||||
{
|
||||
$twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
|
||||
$result = $twitter->oauth2('oauth2/token', ['grant_type' => 'client_credentials']);
|
||||
$result = $twitter->oauth2('oauth2/token', [
|
||||
'grant_type' => 'client_credentials',
|
||||
]);
|
||||
$this->assertEquals(200, $twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('token_type', $result);
|
||||
$this->assertObjectHasAttribute('access_token', $result);
|
||||
|
@ -45,40 +66,47 @@ class TwitterOAuthTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @depends testOauth2Token
|
||||
* @vcr testOauth2BearerToken.json
|
||||
*/
|
||||
public function testBearerToken($accessToken)
|
||||
public function testOauth2BearerToken($accessToken)
|
||||
{
|
||||
$twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, null, $accessToken->access_token);
|
||||
$result = $twitter->get('statuses/user_timeline', ['screen_name' => 'twitterapi']);
|
||||
if ($twitter->getLastHttpCode() !== 200) {
|
||||
$this->assertEquals('foo', substr($accessToken->access_token, 0, 75));
|
||||
$this->assertEquals('foo', print_r($result, true));
|
||||
}
|
||||
$twitter = new TwitterOAuth(
|
||||
CONSUMER_KEY,
|
||||
CONSUMER_SECRET,
|
||||
null,
|
||||
$accessToken->access_token
|
||||
);
|
||||
$result = $twitter->get('statuses/user_timeline', [
|
||||
'screen_name' => 'twitterapi',
|
||||
]);
|
||||
$this->assertEquals(200, $twitter->getLastHttpCode());
|
||||
return $accessToken;
|
||||
}
|
||||
|
||||
// This causes issues for parallel run tests.
|
||||
// /**
|
||||
// * @depends testBearerToken
|
||||
// */
|
||||
// public function testOauth2TokenInvalidate($accessToken)
|
||||
// {
|
||||
// $twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
|
||||
// // HACK: access_token is already urlencoded but gets urlencoded again breaking the invalidate request.
|
||||
// $result = $twitter->oauth2(
|
||||
// 'oauth2/invalidate_token',
|
||||
// array('access_token' => urldecode($accessToken->access_token))
|
||||
// );
|
||||
// $this->assertEquals(200, $twitter->getLastHttpCode());
|
||||
// $this->assertObjectHasAttribute('access_token', $result);
|
||||
// return $result;
|
||||
// }
|
||||
/**
|
||||
* @depends testOauth2BearerToken
|
||||
* @vcr testOauth2TokenInvalidate.json
|
||||
*/
|
||||
public function testOauth2TokenInvalidate($accessToken)
|
||||
{
|
||||
$twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
|
||||
// HACK: access_token is already urlencoded but gets urlencoded again breaking the invalidate request.
|
||||
$result = $twitter->oauth2('oauth2/invalidate_token', [
|
||||
'access_token' => urldecode($accessToken->access_token),
|
||||
]);
|
||||
$this->assertEquals(200, $twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('access_token', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testOauthRequestToken.json
|
||||
*/
|
||||
public function testOauthRequestToken()
|
||||
{
|
||||
$twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
|
||||
$result = $twitter->oauth('oauth/request_token', ['oauth_callback' => OAUTH_CALLBACK]);
|
||||
$result = $twitter->oauth('oauth/request_token', [
|
||||
'oauth_callback' => OAUTH_CALLBACK,
|
||||
]);
|
||||
$this->assertEquals(200, $twitter->getLastHttpCode());
|
||||
$this->assertArrayHasKey('oauth_token', $result);
|
||||
$this->assertArrayHasKey('oauth_token_secret', $result);
|
||||
|
@ -88,66 +116,95 @@ class TwitterOAuthTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Abraham\TwitterOAuth\TwitterOAuthException
|
||||
* @expectedExceptionMessage Could not authenticate you
|
||||
* @vcr testOauthRequestTokenException.json
|
||||
*/
|
||||
public function testOauthRequestTokenException()
|
||||
{
|
||||
$this->expectException(
|
||||
\Abraham\TwitterOAuth\TwitterOAuthException::class
|
||||
);
|
||||
$this->expectErrorMessage('Could not authenticate you');
|
||||
$twitter = new TwitterOAuth('CONSUMER_KEY', 'CONSUMER_SECRET');
|
||||
$result = $twitter->oauth('oauth/request_token', ['oauth_callback' => OAUTH_CALLBACK]);
|
||||
return $result;
|
||||
$result = $twitter->oauth('oauth/request_token', [
|
||||
'oauth_callback' => OAUTH_CALLBACK,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Abraham\TwitterOAuth\TwitterOAuthException
|
||||
* @expectedExceptionMessage Invalid oauth_verifier parameter
|
||||
* @depends testOauthRequestToken
|
||||
* @vcr testOauthAccessTokenTokenException.json
|
||||
*/
|
||||
public function testOauthAccessTokenTokenException(array $requestToken)
|
||||
{
|
||||
// Can't test this without a browser logging into Twitter so check for the correct error instead.
|
||||
$this->expectException(
|
||||
\Abraham\TwitterOAuth\TwitterOAuthException::class
|
||||
);
|
||||
$this->expectErrorMessage('Invalid oauth_verifier parameter');
|
||||
$twitter = new TwitterOAuth(
|
||||
CONSUMER_KEY,
|
||||
CONSUMER_SECRET,
|
||||
$requestToken['oauth_token'],
|
||||
$requestToken['oauth_token_secret']
|
||||
);
|
||||
$twitter->oauth("oauth/access_token", ["oauth_verifier" => "fake_oauth_verifier"]);
|
||||
$twitter->oauth('oauth/access_token', [
|
||||
'oauth_verifier' => 'fake_oauth_verifier',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUrl()
|
||||
{
|
||||
$url = $this->twitter->url('oauth/authorize', ['foo' => 'bar', 'baz' => 'qux']);
|
||||
$this->assertEquals('https://api.twitter.com/oauth/authorize?foo=bar&baz=qux', $url);
|
||||
$url = $this->twitter->url('oauth/authorize', [
|
||||
'foo' => 'bar',
|
||||
'baz' => 'qux',
|
||||
]);
|
||||
$this->assertEquals(
|
||||
'https://api.twitter.com/oauth/authorize?foo=bar&baz=qux',
|
||||
$url
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testGetAccountVerifyCredentials.json
|
||||
*/
|
||||
public function testGetAccountVerifyCredentials()
|
||||
{
|
||||
// Include entities boolean added to test parameter value cohearsion
|
||||
$this->twitter->get('account/verify_credentials', ["include_entities" => false]);
|
||||
$user = $this->twitter->get('account/verify_credentials', [
|
||||
'include_entities' => false,
|
||||
'include_email' => true,
|
||||
]);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('email', $user);
|
||||
}
|
||||
|
||||
// BUG: testing is too unreliable for now
|
||||
// public function testSetProxy()
|
||||
// {
|
||||
// $this->twitter->setProxy(array(
|
||||
// 'CURLOPT_PROXY' => PROXY,
|
||||
// 'CURLOPT_PROXYUSERPWD' => PROXYUSERPWD,
|
||||
// 'CURLOPT_PROXYPORT' => PROXYPORT,
|
||||
// ));
|
||||
// $this->twitter->setTimeouts(60, 60);
|
||||
// $result = $this->twitter->get('account/verify_credentials');
|
||||
// $this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
// $this->assertObjectHasAttribute('id', $result);
|
||||
// }
|
||||
/**
|
||||
* @vcr testSetProxy.json
|
||||
*/
|
||||
public function testSetProxy()
|
||||
{
|
||||
$this->twitter->setProxy([
|
||||
'CURLOPT_PROXY' => PROXY,
|
||||
'CURLOPT_PROXYUSERPWD' => PROXYUSERPWD,
|
||||
'CURLOPT_PROXYPORT' => PROXYPORT,
|
||||
]);
|
||||
$this->twitter->setTimeouts(60, 60);
|
||||
$result = $this->twitter->get('account/verify_credentials');
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('id', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testGetStatusesMentionsTimeline.json
|
||||
*/
|
||||
public function testGetStatusesMentionsTimeline()
|
||||
{
|
||||
$this->twitter->get('statuses/mentions_timeline');
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testGetSearchTweets.json
|
||||
*/
|
||||
public function testGetSearchTweets()
|
||||
{
|
||||
$result = $this->twitter->get('search/tweets', ['q' => 'twitter']);
|
||||
|
@ -157,27 +214,32 @@ class TwitterOAuthTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @depends testGetSearchTweets
|
||||
* @vcr testGetSearchTweetsWithMaxId.json
|
||||
*/
|
||||
public function testGetSearchTweetsWithMaxId($statuses)
|
||||
{
|
||||
$maxId = array_pop($statuses)->id_str;
|
||||
$this->twitter->get('search/tweets', ['q' => 'twitter', 'max_id' => $maxId]);
|
||||
$this->twitter->get('search/tweets', [
|
||||
'q' => 'twitter',
|
||||
'max_id' => $maxId,
|
||||
]);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testPostFavoritesCreate.json
|
||||
*/
|
||||
public function testPostFavoritesCreate()
|
||||
{
|
||||
$result = $this->twitter->post('favorites/create', ['id' => '6242973112']);
|
||||
if ($this->twitter->getLastHttpCode() == 403) {
|
||||
// Status already favorited
|
||||
$this->assertEquals(139, $result->errors[0]->code);
|
||||
} else {
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
}
|
||||
$result = $this->twitter->post('favorites/create', [
|
||||
'id' => '6242973112',
|
||||
]);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPostFavoritesCreate
|
||||
* @vcr testPostFavoritesDestroy.json
|
||||
*/
|
||||
public function testPostFavoritesDestroy()
|
||||
{
|
||||
|
@ -185,49 +247,121 @@ class TwitterOAuthTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
}
|
||||
|
||||
public function testPostStatusesUpdateWithMedia()
|
||||
/**
|
||||
* @vcr testPostDirectMessagesEventsNew.json
|
||||
*/
|
||||
public function testPostDirectMessagesEventsNew()
|
||||
{
|
||||
$this->twitter->setTimeouts(60, 30);
|
||||
// Image source https://www.flickr.com/photos/titrans/8548825587/
|
||||
$file_path = __DIR__ . '/kitten.jpg';
|
||||
$result = $this->twitter->upload('media/upload', ['media' => $file_path]);
|
||||
$data = [
|
||||
'event' => [
|
||||
'type' => 'message_create',
|
||||
'message_create' => [
|
||||
'target' => [
|
||||
'recipient_id' => $this->userId,
|
||||
],
|
||||
'message_data' => [
|
||||
'text' => 'Hello World!',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$result = $this->twitter->post(
|
||||
'direct_messages/events/new',
|
||||
$data,
|
||||
true
|
||||
);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('media_id_string', $result);
|
||||
$parameters = ['status' => 'Hello World ' . time(), 'media_ids' => $result->media_id_string];
|
||||
$result = $this->twitter->post('statuses/update', $parameters);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
if ($this->twitter->getLastHttpCode() == 200) {
|
||||
$result = $this->twitter->post('statuses/destroy/' . $result->id_str);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPostDirectMessagesEventsNew
|
||||
* @vcr testDeleteDirectMessagesEventsDestroy.json
|
||||
*/
|
||||
public function testDeleteDirectMessagesEventsDestroy($message)
|
||||
{
|
||||
$this->twitter->delete('direct_messages/events/destroy', [
|
||||
'id' => $message->event->id,
|
||||
]);
|
||||
$this->assertEquals(204, $this->twitter->getLastHttpCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testPostStatusesUpdateWithMedia.json
|
||||
*/
|
||||
public function testPostStatusesUpdateWithMedia()
|
||||
{
|
||||
$this->twitter->setTimeouts(60, 60);
|
||||
// Image source https://www.flickr.com/photos/titrans/8548825587/
|
||||
$file_path = __DIR__ . '/kitten.jpg';
|
||||
$result = $this->twitter->upload('media/upload', [
|
||||
'media' => $file_path,
|
||||
]);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('media_id_string', $result);
|
||||
$parameters = [
|
||||
'status' => 'Hello World ' . MOCK_TIME,
|
||||
'media_ids' => $result->media_id_string,
|
||||
];
|
||||
$result = $this->twitter->post('statuses/update', $parameters);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
$result = $this->twitter->post('statuses/destroy/' . $result->id_str);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testPostStatusUpdateWithInvalidMediaThrowsException.json
|
||||
*/
|
||||
public function testPostStatusUpdateWithInvalidMediaThrowsException()
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$file_path = __DIR__ . '/12345678900987654321.jpg';
|
||||
$this->assertFalse(\is_readable($file_path));
|
||||
$result = $this->twitter->upload('media/upload', [
|
||||
'media' => $file_path,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testPostStatusesUpdateWithMediaChunked.json
|
||||
*/
|
||||
public function testPostStatusesUpdateWithMediaChunked()
|
||||
{
|
||||
$this->twitter->setTimeouts(60, 30);
|
||||
// Video source http://www.sample-videos.com/
|
||||
$file_path = __DIR__ . '/video.mp4';
|
||||
$result = $this->twitter->upload('media/upload', ['media' => $file_path, 'media_type' => 'video/mp4'], true);
|
||||
$result = $this->twitter->upload(
|
||||
'media/upload',
|
||||
['media' => $file_path, 'media_type' => 'video/mp4'],
|
||||
true
|
||||
);
|
||||
$this->assertEquals(201, $this->twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('media_id_string', $result);
|
||||
$parameters = ['status' => 'Hello World ' . time(), 'media_ids' => $result->media_id_string];
|
||||
$parameters = [
|
||||
'status' => 'Hello World ' . MOCK_TIME,
|
||||
'media_ids' => $result->media_id_string,
|
||||
];
|
||||
$result = $this->twitter->post('statuses/update', $parameters);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
if ($this->twitter->getLastHttpCode() == 200) {
|
||||
$result = $this->twitter->post('statuses/destroy/' . $result->id_str);
|
||||
}
|
||||
$result = $this->twitter->post('statuses/destroy/' . $result->id_str);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testPostStatusesUpdateUtf8.json
|
||||
*/
|
||||
public function testPostStatusesUpdateUtf8()
|
||||
{
|
||||
$result = $this->twitter->post('statuses/update', ['status' => 'xこんにちは世界 ' . time()]);
|
||||
$result = $this->twitter->post('statuses/update', [
|
||||
'status' => 'xこんにちは世界 ' . MOCK_TIME,
|
||||
]);
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPostStatusesUpdateUtf8
|
||||
* @vcr testPostStatusesDestroy.json
|
||||
*/
|
||||
public function testPostStatusesDestroy($status)
|
||||
{
|
||||
|
@ -235,16 +369,23 @@ class TwitterOAuthTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @vcr testLastResult.json
|
||||
*/
|
||||
public function testLastResult()
|
||||
{
|
||||
$this->twitter->get('search/tweets', ['q' => 'twitter']);
|
||||
$this->assertEquals('search/tweets', $this->twitter->getLastApiPath());
|
||||
$this->assertEquals(200, $this->twitter->getLastHttpCode());
|
||||
$this->assertObjectHasAttribute('statuses', $this->twitter->getLastBody());
|
||||
$this->assertObjectHasAttribute(
|
||||
'statuses',
|
||||
$this->twitter->getLastBody()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testLastResult
|
||||
* @vcr testResetLastResponse.json
|
||||
*/
|
||||
public function testResetLastResponse()
|
||||
{
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace Abraham\TwitterOAuth\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Abraham\TwitterOAuth\Util\JsonDecoder;
|
||||
|
||||
class JsonDecoderTest extends \PHPUnit_Framework_TestCase
|
||||
class JsonDecoderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider jsonProvider
|
||||
|
@ -19,7 +20,11 @@ class JsonDecoderTest extends \PHPUnit_Framework_TestCase
|
|||
return [
|
||||
['[]', true, []],
|
||||
['[1,2,3]', true, [1, 2, 3]],
|
||||
['[{"id": 556179961825226750}]', true, [['id' => 556179961825226750]]],
|
||||
[
|
||||
'[{"id": 556179961825226750}]',
|
||||
true,
|
||||
[['id' => 556179961825226750]],
|
||||
],
|
||||
['[]', false, []],
|
||||
['[1,2,3]', false, [1, 2, 3]],
|
||||
[
|
||||
|
@ -29,10 +34,9 @@ class JsonDecoderTest extends \PHPUnit_Framework_TestCase
|
|||
$this->getClass(function ($object) {
|
||||
$object->id = 556179961825226750;
|
||||
return $object;
|
||||
})
|
||||
]
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
<?php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
declare(strict_types=1);
|
||||
|
||||
define('CONSUMER_KEY', getenv('TEST_CONSUMER_KEY'));
|
||||
define('CONSUMER_SECRET', getenv('TEST_CONSUMER_SECRET'));
|
||||
define('ACCESS_TOKEN', getenv('TEST_ACCESS_TOKEN'));
|
||||
define('ACCESS_TOKEN_SECRET', getenv('TEST_ACCESS_TOKEN_SECRET'));
|
||||
define('OAUTH_CALLBACK', getenv('TEST_OAUTH_CALLBACK'));
|
||||
define('PROXY', getenv('TEST_CURLOPT_PROXY'));
|
||||
define('PROXYUSERPWD', getenv('TEST_CURLOPT_PROXYUSERPWD'));
|
||||
define('PROXYPORT', getenv('TEST_CURLOPT_PROXYPORT'));
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
require 'vars.php';
|
||||
require 'mocks.php';
|
||||
|
||||
\VCR\VCR::configure()->setStorage('json');
|
||||
\VCR\VCR::turnOn();
|
||||
|
|
40
twitter/vendor/abraham/twitteroauth/tests/fixtures/testDeleteDirectMessagesEventsDestroy.json
vendored
Normal file
40
twitter/vendor/abraham/twitteroauth/tests/fixtures/testDeleteDirectMessagesEventsDestroy.json
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "DELETE",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/direct_messages\/events\/destroy.json?id=1254206523385032714",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"dY4KEaTg5Y6Bv4JlofNCjoArx%2F4%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "204",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-security-policy": "default-src 'self'; connect-src 'self'; font-src 'self' https:\/\/*.twimg.com https:\/\/twitter.com https:\/\/ton.twitter.com data:; frame-src 'self' https:\/\/*.twimg.com https:\/\/twitter.com https:\/\/ton.twitter.com; img-src 'self' https:\/\/*.twimg.com https:\/\/twitter.com https:\/\/ton.twitter.com data:; media-src 'self' https:\/\/*.twimg.com https:\/\/twitter.com https:\/\/ton.twitter.com; object-src 'none'; script-src 'self' https:\/\/*.twimg.com https:\/\/twitter.com https:\/\/ton.twitter.com; style-src 'self' https:\/\/*.twimg.com https:\/\/twitter.com https:\/\/ton.twitter.com; report-uri https:\/\/twitter.com\/i\/csp_report?a=NVQWGYLXFVSG2%3D%3D%3D&ro=false;",
|
||||
"content-type": "text\/html;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:52 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:52 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_asAbLVWtv6V2+ARemo0VNA==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:52 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786111220677678; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:52 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "204 No Content",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "5cbff6bc4105c0040c4738daac7adcf4",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "37",
|
||||
"x-transaction": "00f02f6c00e12e76",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
}
|
||||
}
|
||||
}]
|
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testGetAccountVerifyCredentials.json
vendored
Normal file
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testGetAccountVerifyCredentials.json
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/account\/verify_credentials.json?include_email=true&include_entities=false",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"k8h8edFh9R2W3DCNJy5Nb07tWo0%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "773",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:11 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:11 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_PPOKPD3f\/ek9QM3+ySQxjw==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:11 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786107181888587; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:11 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "7509696bc24b6d9d09d283b844a3c232",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-rate-limit-limit": "75",
|
||||
"x-rate-limit-remaining": "73",
|
||||
"x-rate-limit-reset": "1587861613",
|
||||
"x-response-time": "46",
|
||||
"x-transaction": "00cd4f6300163d67",
|
||||
"x-twitter-response-tags": "BouncerExempt, BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"id\":93915746,\"id_str\":\"93915746\",\"name\":\"OAuth Library Test\",\"screen_name\":\"oauthlibtest\",\"location\":\"\",\"description\":\"\",\"url\":null,\"entities\":{\"description\":{\"urls\":[]}},\"protected\":false,\"followers_count\":58,\"friends_count\":2,\"listed_count\":6,\"created_at\":\"Tue Dec 01 18:37:44 +0000 2009\",\"favourites_count\":0,\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"verified\":false,\"statuses_count\":5,\"lang\":null,\"status\":{\"created_at\":\"Tue Dec 01 18:38:07 +0000 2009\",\"id\":6242973112,\"id_str\":\"6242973112\",\"text\":\"Test!\",\"truncated\":false,\"source\":\"\\u003ca href=\\\"http:\\\/\\\/twitter.com\\\" rel=\\\"nofollow\\\"\\u003eTwitter Web Client\\u003c\\\/a\\u003e\",\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"retweet_count\":2258,\"favorite_count\":75,\"favorited\":false,\"retweeted\":false,\"lang\":\"en\"},\"contributors_enabled\":false,\"is_translator\":false,\"is_translation_enabled\":false,\"profile_background_color\":\"C0DEED\",\"profile_background_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_tile\":false,\"profile_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_link_color\":\"1DA1F2\",\"profile_sidebar_border_color\":\"C0DEED\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":true,\"has_extended_profile\":false,\"default_profile\":true,\"default_profile_image\":true,\"following\":false,\"follow_request_sent\":false,\"notifications\":false,\"translator_type\":\"none\",\"suspended\":false,\"needs_phone_verification\":false,\"email\":\"4braham+oauthlibtest@gmail.com\"}"
|
||||
}
|
||||
}]
|
File diff suppressed because one or more lines are too long
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testGetSearchTweetsWithMaxId.json
vendored
Normal file
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testGetSearchTweetsWithMaxId.json
vendored
Normal file
File diff suppressed because one or more lines are too long
49
twitter/vendor/abraham/twitteroauth/tests/fixtures/testGetStatusesMentionsTimeline.json
vendored
Normal file
49
twitter/vendor/abraham/twitteroauth/tests/fixtures/testGetStatusesMentionsTimeline.json
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
49
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauth2BearerToken.json
vendored
Normal file
49
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauth2BearerToken.json
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,46 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/oauth2\/token",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "Basic YXdKZk5ENHpGR2FwR09GS2Zkamc6TGZrbU5TUlBJWHdrUWtaVUI5RE5XU3p4NUxJYWl2U2tuVjRyeG5nb2pKYw==",
|
||||
"Expect": null
|
||||
},
|
||||
"body": "grant_type=client_credentials"
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "152",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:09 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:09 GMT",
|
||||
"ml": "A",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_NF00blSG9GZe8w8KpZvUDA==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:09 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, guest_id=v1%3A158786106988547101; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:09 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-connection-hash": "34e2373c53e7f9e0e80fe6af071dd6b8",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "DENY",
|
||||
"x-response-time": "20",
|
||||
"x-transaction": "007d4d19009f7a59",
|
||||
"x-tsa-request-body-time": "0",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-ua-compatible": "IE=edge,chrome=1",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"token_type\":\"bearer\",\"access_token\":\"AAAAAAAAAAAAAAAAAAAAAFobAAAAAAAAjPes3FlPiFKh9HaIg%2Fw80waE0s8%3DQqxjhHDgZyjihGIK7olugzbpS0R1Gg8KNhzmer58a6oVbsSGc0\"}"
|
||||
}
|
||||
}]
|
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauth2TokenInvalidate.json
vendored
Normal file
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauth2TokenInvalidate.json
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/oauth2\/invalidate_token",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "Basic YXdKZk5ENHpGR2FwR09GS2Zkamc6TGZrbU5TUlBJWHdrUWtaVUI5RE5XU3p4NUxJYWl2U2tuVjRyeG5nb2pKYw==",
|
||||
"Expect": null
|
||||
},
|
||||
"body": "access_token=AAAAAAAAAAAAAAAAAAAAAFobAAAAAAAAjPes3FlPiFKh9HaIg%2Fw80waE0s8%3DQqxjhHDgZyjihGIK7olugzbpS0R1Gg8KNhzmer58a6oVbsSGc0"
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "135",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:10 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:10 GMT",
|
||||
"ml": "A",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_8Iv+DqoXk8DVAVDoUVltSA==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:10 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, guest_id=v1%3A158786107054950627; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:10 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-connection-hash": "18b7327592f746230c1c016c344dd14d",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "DENY",
|
||||
"x-response-time": "19",
|
||||
"x-transaction": "00c5257f00b7d371",
|
||||
"x-tsa-request-body-time": "0",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-ua-compatible": "IE=edge,chrome=1",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"access_token\":\"AAAAAAAAAAAAAAAAAAAAAFobAAAAAAAAjPes3FlPiFKh9HaIg%2Fw80waE0s8%3DQqxjhHDgZyjihGIK7olugzbpS0R1Gg8KNhzmer58a6oVbsSGc0\"}"
|
||||
}
|
||||
}]
|
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauthAccessTokenTokenException.json
vendored
Normal file
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauthAccessTokenTokenException.json
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/oauth\/access_token",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"CE545gAAAAAAABtaAAABcbPlJBQ\", oauth_verifier=\"fake_oauth_verifier\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"0bcdtKs3nffzbE5abwaVjCI1HPw%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "401",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "93",
|
||||
"content-security-policy": "default-src 'none'; connect-src 'self'; font-src https:\/\/abs.twimg.com https:\/\/abs-0.twimg.com data:; frame-src 'self' twitter:; img-src https:\/\/abs.twimg.com https:\/\/*.twimg.com https:\/\/pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src https:\/\/abs.twimg.com https:\/\/abs-0.twimg.com https:\/\/twitter.com https:\/\/mobile.twitter.com; style-src https:\/\/abs.twimg.com https:\/\/abs-0.twimg.com; report-uri https:\/\/twitter.com\/i\/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;",
|
||||
"content-type": "text\/html;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:11 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:11 GMT",
|
||||
"ml": "A",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_n0ZAgT2oLIc0HI23qMIGCA==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:11 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, guest_id=v1%3A158786107147893563; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:11 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "401 Unauthorized",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"www-authenticate": "OAuth realm=\"https:\/\/api.twitter.com\"",
|
||||
"x-connection-hash": "90157d4bdfce3a9b90fd408819c767bc",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "41",
|
||||
"x-transaction": "0080cead006a758d",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-ua-compatible": "IE=edge,chrome=1",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "Error processing your OAuth request: Invalid oauth_verifier parameter"
|
||||
}
|
||||
}]
|
44
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauthRequestToken.json
vendored
Normal file
44
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauthRequestToken.json
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/oauth\/request_token",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_callback=\"https%3A%2F%2Ftwitteroauth.com%2Fcallback.php\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"LR7ZVqY%2Fcdisw1w3zssKI6Yjbls%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "127",
|
||||
"content-security-policy": "default-src 'none'; connect-src 'self'; font-src https:\/\/abs.twimg.com https:\/\/abs-0.twimg.com data:; frame-src 'self' twitter:; img-src https:\/\/abs.twimg.com https:\/\/*.twimg.com https:\/\/pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src https:\/\/abs.twimg.com https:\/\/abs-0.twimg.com https:\/\/twitter.com https:\/\/mobile.twitter.com; style-src https:\/\/abs.twimg.com https:\/\/abs-0.twimg.com; report-uri https:\/\/twitter.com\/i\/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;",
|
||||
"content-type": "text\/html;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:10 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:10 GMT",
|
||||
"ml": "A",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_mrnWVDThJvkLcAe4hmX0ng==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:10 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, guest_id=v1%3A158786107085601318; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:10 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-connection-hash": "bf00d267c647790cd34d8cd4a28f9895",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "24",
|
||||
"x-transaction": "0095391f006dd965",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-ua-compatible": "IE=edge,chrome=1",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "oauth_token=CE545gAAAAAAABtaAAABcbPlJBQ&oauth_token_secret=tTVYBva8AlQu0JxVudzbf9oHXAbIARg5&oauth_callback_confirmed=true"
|
||||
}
|
||||
}]
|
43
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauthRequestTokenException.json
vendored
Normal file
43
twitter/vendor/abraham/twitteroauth/tests/fixtures/testOauthRequestTokenException.json
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/oauth\/request_token",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"CONSUMER_KEY\", oauth_callback=\"https%3A%2F%2Ftwitteroauth.com%2Fcallback.php\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"wOUt6ZyVGpWnQhsHNWqcr%2BpOWAw%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "401",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "89",
|
||||
"content-type": "application\/json; charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:11 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:11 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_Vz8Os736+fzUwkQGIeIKuw==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:11 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, guest_id=v1%3A158786107116335546; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:11 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "401 Unauthorized",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"www-authenticate": "OAuth realm=\"https:\/\/api.twitter.com\", api_error_code=32",
|
||||
"x-connection-hash": "d620dbb5b35e124662532c3ef8e89c88",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "6",
|
||||
"x-transaction": "00bf1248004cdafa",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"errors\":[{\"code\":32,\"message\":\"Could not authenticate you.\"}]}"
|
||||
}
|
||||
}]
|
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostDirectMessagesEventsNew.json
vendored
Normal file
46
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostDirectMessagesEventsNew.json
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/direct_messages\/events\/new.json",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"3457NqeumGmcalZLF091L9lt7F8%3D\"",
|
||||
"Expect": null,
|
||||
"Content-type": "application\/json"
|
||||
},
|
||||
"body": "{\"event\":{\"type\":\"message_create\",\"message_create\":{\"target\":{\"recipient_id\":\"93915746\"},\"message_data\":{\"text\":\"Hello World!\"}}}}"
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "206",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:51 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:51 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_Tfqxs0gur2QR4FFIZ3Wq6w==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:51 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786111185015666; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:51 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "bb4f30d1c6406b2cd5d25f20fccfdc1a",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "70",
|
||||
"x-transaction": "0057fa4c00fb95a1",
|
||||
"x-tsa-request-body-time": "0",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"event\":{\"type\":\"message_create\",\"id\":\"1254206523385032714\",\"created_timestamp\":\"1587861111862\",\"message_create\":{\"target\":{\"recipient_id\":\"93915746\"},\"sender_id\":\"93915746\",\"message_data\":{\"text\":\"Hello World!\",\"entities\":{\"hashtags\":[],\"symbols\":[],\"user_mentions\":[],\"urls\":[]}}}}}"
|
||||
}
|
||||
}]
|
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostFavoritesCreate.json
vendored
Normal file
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostFavoritesCreate.json
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/favorites\/create.json",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"EA30eIQPgat0Aw%2F59GyltEiE4Xg%3D\"",
|
||||
"Expect": null
|
||||
},
|
||||
"body": "id=6242973112"
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "755",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:51 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:51 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_Jz87HIDSEIpDevFMBlDD7g==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:51 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786111115490266; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:51 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "7368af4d238e5c36df5379afb1bed3af",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "72",
|
||||
"x-transaction": "0012beac0086638b",
|
||||
"x-tsa-request-body-time": "0",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"created_at\":\"Tue Dec 01 18:38:07 +0000 2009\",\"id\":6242973112,\"id_str\":\"6242973112\",\"text\":\"Test!\",\"truncated\":false,\"entities\":{\"hashtags\":[],\"symbols\":[],\"user_mentions\":[],\"urls\":[]},\"source\":\"\\u003ca href=\\\"http:\\\/\\\/twitter.com\\\" rel=\\\"nofollow\\\"\\u003eTwitter Web Client\\u003c\\\/a\\u003e\",\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":93915746,\"id_str\":\"93915746\",\"name\":\"OAuth Library Test\",\"screen_name\":\"oauthlibtest\",\"location\":\"\",\"description\":\"\",\"url\":null,\"entities\":{\"description\":{\"urls\":[]}},\"protected\":false,\"followers_count\":58,\"friends_count\":2,\"listed_count\":6,\"created_at\":\"Tue Dec 01 18:37:44 +0000 2009\",\"favourites_count\":1,\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"verified\":false,\"statuses_count\":5,\"lang\":null,\"contributors_enabled\":false,\"is_translator\":false,\"is_translation_enabled\":false,\"profile_background_color\":\"C0DEED\",\"profile_background_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_tile\":false,\"profile_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_link_color\":\"1DA1F2\",\"profile_sidebar_border_color\":\"C0DEED\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":true,\"has_extended_profile\":false,\"default_profile\":true,\"default_profile_image\":true,\"following\":false,\"follow_request_sent\":false,\"notifications\":false,\"translator_type\":\"none\"},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"retweet_count\":2258,\"favorite_count\":76,\"favorited\":true,\"retweeted\":false,\"lang\":\"en\"}"
|
||||
}
|
||||
}]
|
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostFavoritesDestroy.json
vendored
Normal file
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostFavoritesDestroy.json
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/favorites\/destroy.json",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"w3Nti04O5BMi8bySXjmO8%2BW5Pus%3D\"",
|
||||
"Expect": null
|
||||
},
|
||||
"body": "id=6242973112"
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "753",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:51 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:51 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_s1J1pMUNrQO4\/v371oE9AQ==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:51 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786111151392082; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:51 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "a0dc865f09447e41b0d77e9eed981519",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "44",
|
||||
"x-transaction": "005d9083009bd4c9",
|
||||
"x-tsa-request-body-time": "0",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"created_at\":\"Tue Dec 01 18:38:07 +0000 2009\",\"id\":6242973112,\"id_str\":\"6242973112\",\"text\":\"Test!\",\"truncated\":false,\"entities\":{\"hashtags\":[],\"symbols\":[],\"user_mentions\":[],\"urls\":[]},\"source\":\"\\u003ca href=\\\"http:\\\/\\\/twitter.com\\\" rel=\\\"nofollow\\\"\\u003eTwitter Web Client\\u003c\\\/a\\u003e\",\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":93915746,\"id_str\":\"93915746\",\"name\":\"OAuth Library Test\",\"screen_name\":\"oauthlibtest\",\"location\":\"\",\"description\":\"\",\"url\":null,\"entities\":{\"description\":{\"urls\":[]}},\"protected\":false,\"followers_count\":58,\"friends_count\":2,\"listed_count\":6,\"created_at\":\"Tue Dec 01 18:37:44 +0000 2009\",\"favourites_count\":0,\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"verified\":false,\"statuses_count\":5,\"lang\":null,\"contributors_enabled\":false,\"is_translator\":false,\"is_translation_enabled\":false,\"profile_background_color\":\"C0DEED\",\"profile_background_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_tile\":false,\"profile_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_link_color\":\"1DA1F2\",\"profile_sidebar_border_color\":\"C0DEED\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":true,\"has_extended_profile\":false,\"default_profile\":true,\"default_profile_image\":true,\"following\":false,\"follow_request_sent\":false,\"notifications\":false,\"translator_type\":\"none\"},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"retweet_count\":2258,\"favorite_count\":75,\"favorited\":false,\"retweeted\":false,\"lang\":\"en\"}"
|
||||
}
|
||||
}]
|
|
@ -0,0 +1 @@
|
|||
[]
|
43
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesDestroy.json
vendored
Normal file
43
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesDestroy.json
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/statuses\/destroy\/1254206657548226561.json",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"kyOKi3x9Ar3foSG5%2BN9XzBbnIOw%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "804",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:32:24 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:32:24 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_juPKvfSeQeQoZAVeLglnhA==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:32:24 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786114418847477; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:32:24 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "f4375157b19d6cd139b9917a6d76d0b0",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "198",
|
||||
"x-transaction": "00f3e731001ccb87",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"created_at\":\"Sun Apr 26 00:32:23 +0000 2020\",\"id\":1254206657548226561,\"id_str\":\"1254206657548226561\",\"text\":\"x\\u3053\\u3093\\u306b\\u3061\\u306f\\u4e16\\u754c 1587861062\",\"truncated\":false,\"entities\":{\"hashtags\":[],\"symbols\":[],\"user_mentions\":[],\"urls\":[]},\"source\":\"\\u003ca href=\\\"https:\\\/\\\/twitteroauth.com\\\" rel=\\\"nofollow\\\"\\u003eTwitterOAuth dev\\u003c\\\/a\\u003e\",\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":93915746,\"id_str\":\"93915746\",\"name\":\"OAuth Library Test\",\"screen_name\":\"oauthlibtest\",\"location\":\"\",\"description\":\"\",\"url\":null,\"entities\":{\"description\":{\"urls\":[]}},\"protected\":false,\"followers_count\":58,\"friends_count\":2,\"listed_count\":6,\"created_at\":\"Tue Dec 01 18:37:44 +0000 2009\",\"favourites_count\":0,\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"verified\":false,\"statuses_count\":6,\"lang\":null,\"contributors_enabled\":false,\"is_translator\":false,\"is_translation_enabled\":false,\"profile_background_color\":\"C0DEED\",\"profile_background_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_tile\":false,\"profile_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_link_color\":\"1DA1F2\",\"profile_sidebar_border_color\":\"C0DEED\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":true,\"has_extended_profile\":false,\"default_profile\":true,\"default_profile_image\":true,\"following\":false,\"follow_request_sent\":false,\"notifications\":false,\"translator_type\":\"none\"},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"retweet_count\":0,\"favorite_count\":0,\"favorited\":false,\"retweeted\":false,\"lang\":\"ja\"}"
|
||||
}
|
||||
}]
|
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesUpdateUtf8.json
vendored
Normal file
45
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesUpdateUtf8.json
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/statuses\/update.json",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"zIzkM9jxroYElpL1fPTyYnYE%2Bys%3D\"",
|
||||
"Expect": null
|
||||
},
|
||||
"body": "status=x%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C%201587861062"
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "804",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:32:23 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:32:23 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_8nFfK\/V8KyJDl1aminWCQw==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:32:23 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786114384224672; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:32:23 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "54c0be65e0c80b57d5b7c895e58061c8",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-response-time": "55",
|
||||
"x-transaction": "00eb7dbc0057ef33",
|
||||
"x-tsa-request-body-time": "0",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"created_at\":\"Sun Apr 26 00:32:23 +0000 2020\",\"id\":1254206657548226561,\"id_str\":\"1254206657548226561\",\"text\":\"x\\u3053\\u3093\\u306b\\u3061\\u306f\\u4e16\\u754c 1587861062\",\"truncated\":false,\"entities\":{\"hashtags\":[],\"symbols\":[],\"user_mentions\":[],\"urls\":[]},\"source\":\"\\u003ca href=\\\"https:\\\/\\\/twitteroauth.com\\\" rel=\\\"nofollow\\\"\\u003eTwitterOAuth dev\\u003c\\\/a\\u003e\",\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":93915746,\"id_str\":\"93915746\",\"name\":\"OAuth Library Test\",\"screen_name\":\"oauthlibtest\",\"location\":\"\",\"description\":\"\",\"url\":null,\"entities\":{\"description\":{\"urls\":[]}},\"protected\":false,\"followers_count\":58,\"friends_count\":2,\"listed_count\":6,\"created_at\":\"Tue Dec 01 18:37:44 +0000 2009\",\"favourites_count\":0,\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"verified\":false,\"statuses_count\":6,\"lang\":null,\"contributors_enabled\":false,\"is_translator\":false,\"is_translation_enabled\":false,\"profile_background_color\":\"C0DEED\",\"profile_background_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_tile\":false,\"profile_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_link_color\":\"1DA1F2\",\"profile_sidebar_border_color\":\"C0DEED\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":true,\"has_extended_profile\":false,\"default_profile\":true,\"default_profile_image\":true,\"following\":false,\"follow_request_sent\":false,\"notifications\":false,\"translator_type\":\"none\"},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"retweet_count\":0,\"favorite_count\":0,\"favorited\":false,\"retweeted\":false,\"lang\":\"ja\"}"
|
||||
}
|
||||
}]
|
134
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesUpdateWithMedia.json
vendored
Normal file
134
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesUpdateWithMedia.json
vendored
Normal file
File diff suppressed because one or more lines are too long
2392
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesUpdateWithMediaChunked.json
vendored
Normal file
2392
twitter/vendor/abraham/twitteroauth/tests/fixtures/testPostStatusesUpdateWithMediaChunked.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
twitter/vendor/abraham/twitteroauth/tests/fixtures/testResetLastResponse.json
vendored
Normal file
1
twitter/vendor/abraham/twitteroauth/tests/fixtures/testResetLastResponse.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,46 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/friendships\/show.json?target_screen_name=twitterapi",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"TzPCDLbvxIAlxBqg5Fpf4JZpFJo%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "2",
|
||||
"code": "200",
|
||||
"message": ""
|
||||
},
|
||||
"headers": {
|
||||
"cache-control": "no-cache, no-store, must-revalidate, pre-check=0, post-check=0",
|
||||
"content-disposition": "attachment; filename=json.json",
|
||||
"content-encoding": "gzip",
|
||||
"content-length": "246",
|
||||
"content-type": "application\/json;charset=utf-8",
|
||||
"date": "Sun, 26 Apr 2020 00:31:09 GMT",
|
||||
"expires": "Tue, 31 Mar 1981 05:00:00 GMT",
|
||||
"last-modified": "Sun, 26 Apr 2020 00:31:09 GMT",
|
||||
"pragma": "no-cache",
|
||||
"server": "tsa_b",
|
||||
"set-cookie": "personalization_id=\"v1_1Yr9ogG1fxy1wdDOY63jAw==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:09 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None, lang=en; Path=\/, guest_id=v1%3A158786106956820884; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:09 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None",
|
||||
"status": "200 OK",
|
||||
"strict-transport-security": "max-age=631138519",
|
||||
"x-access-level": "read-write-directmessages",
|
||||
"x-connection-hash": "e8b1e309982b5c1d1adedc814fa2e6c3",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-frame-options": "SAMEORIGIN",
|
||||
"x-rate-limit-limit": "180",
|
||||
"x-rate-limit-remaining": "178",
|
||||
"x-rate-limit-reset": "1587861610",
|
||||
"x-response-time": "20",
|
||||
"x-transaction": "0075ffd2008ff583",
|
||||
"x-twitter-response-tags": "BouncerCompliant",
|
||||
"x-xss-protection": "0"
|
||||
},
|
||||
"body": "{\"relationship\":{\"source\":{\"id\":93915746,\"id_str\":\"93915746\",\"screen_name\":\"oauthlibtest\",\"following\":false,\"followed_by\":false,\"live_following\":false,\"following_received\":false,\"following_requested\":false,\"notifications_enabled\":false,\"can_dm\":false,\"blocking\":false,\"blocked_by\":false,\"muting\":false,\"want_retweets\":false,\"all_replies\":false,\"marked_spam\":false},\"target\":{\"id\":6253282,\"id_str\":\"6253282\",\"screen_name\":\"TwitterAPI\",\"following\":false,\"followed_by\":false,\"following_received\":false,\"following_requested\":false}}}"
|
||||
}
|
||||
}]
|
|
@ -0,0 +1,20 @@
|
|||
[{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "https:\/\/api.twitter.com\/1.1\/account\/verify_credentials.json",
|
||||
"headers": {
|
||||
"Host": "api.twitter.com",
|
||||
"Accept": "application\/json",
|
||||
"Authorization": "OAuth oauth_version=\"1.0\", oauth_nonce=\"2b67ebbeace76543f356ba8bbd59abde\", oauth_timestamp=\"1587861062\", oauth_consumer_key=\"awJfND4zFGapGOFKfdjg\", oauth_token=\"93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"ZN1bM0df5EPRy1d7oYcoZfj3Mpw%3D\"",
|
||||
"Expect": null
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": {
|
||||
"http_version": "1.1",
|
||||
"code": "200",
|
||||
"message": "OK"
|
||||
},
|
||||
"body": "HTTP\/2 200 \r\ncache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0\r\ncontent-disposition: attachment; filename=json.json\r\ncontent-encoding: gzip\r\ncontent-length: 778\r\ncontent-type: application\/json;charset=utf-8\r\ndate: Sun, 26 Apr 2020 00:31:49 GMT\r\nexpires: Tue, 31 Mar 1981 05:00:00 GMT\r\nlast-modified: Sun, 26 Apr 2020 00:31:49 GMT\r\npragma: no-cache\r\nserver: tsa_a\r\nset-cookie: personalization_id=\"v1_hI7rl+lJjoy5n7HgyNo9LQ==\"; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:49 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None\r\nset-cookie: lang=en; Path=\/\r\nset-cookie: guest_id=v1%3A158786110929931313; Max-Age=63072000; Expires=Tue, 26 Apr 2022 00:31:49 GMT; Path=\/; Domain=.twitter.com; Secure; SameSite=None\r\nstatus: 200 OK\r\nstrict-transport-security: max-age=631138519\r\nx-access-level: read-write-directmessages\r\nx-connection-hash: 18e8b1b5df2ee964aebf8f85055ada9c\r\nx-content-type-options: nosniff\r\nx-frame-options: SAMEORIGIN\r\nx-rate-limit-limit: 75\r\nx-rate-limit-remaining: 72\r\nx-rate-limit-reset: 1587861178\r\nx-response-time: 34\r\nx-transaction: 00716cfd00f6fd8d\r\nx-twitter-response-tags: BouncerExempt\r\nx-twitter-response-tags: BouncerCompliant\r\nx-xss-protection: 0\r\n\r\n{\"id\":93915746,\"id_str\":\"93915746\",\"name\":\"OAuth Library Test\",\"screen_name\":\"oauthlibtest\",\"location\":\"\",\"description\":\"\",\"url\":null,\"entities\":{\"description\":{\"urls\":[]}},\"protected\":false,\"followers_count\":58,\"friends_count\":2,\"listed_count\":6,\"created_at\":\"Tue Dec 01 18:37:44 +0000 2009\",\"favourites_count\":0,\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"verified\":false,\"statuses_count\":1,\"lang\":null,\"status\":{\"created_at\":\"Tue Dec 01 18:38:07 +0000 2009\",\"id\":6242973112,\"id_str\":\"6242973112\",\"text\":\"Test!\",\"truncated\":false,\"entities\":{\"hashtags\":[],\"symbols\":[],\"user_mentions\":[],\"urls\":[]},\"source\":\"\\u003ca href=\\\"http:\\\/\\\/twitter.com\\\" rel=\\\"nofollow\\\"\\u003eTwitter Web Client\\u003c\\\/a\\u003e\",\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"retweet_count\":2258,\"favorite_count\":74,\"favorited\":false,\"retweeted\":false,\"lang\":\"en\"},\"contributors_enabled\":false,\"is_translator\":false,\"is_translation_enabled\":false,\"profile_background_color\":\"C0DEED\",\"profile_background_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/images\\\/themes\\\/theme1\\\/bg.png\",\"profile_background_tile\":false,\"profile_image_url\":\"http:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_image_url_https\":\"https:\\\/\\\/abs.twimg.com\\\/sticky\\\/default_profile_images\\\/default_profile_normal.png\",\"profile_link_color\":\"1DA1F2\",\"profile_sidebar_border_color\":\"C0DEED\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":true,\"has_extended_profile\":false,\"default_profile\":true,\"default_profile_image\":true,\"following\":false,\"follow_request_sent\":false,\"notifications\":false,\"translator_type\":\"none\",\"suspended\":false,\"needs_phone_verification\":false}"
|
||||
}
|
||||
}]
|
Binary file not shown.
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 211 KiB |
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
// Mock time and random values for consistent tests with VCR
|
||||
function time()
|
||||
{
|
||||
return MOCK_TIME;
|
||||
}
|
||||
|
||||
function microtime()
|
||||
{
|
||||
return 'FAKE_MICROTIME';
|
||||
}
|
||||
|
||||
function mt_rand()
|
||||
{
|
||||
return 123456789;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
# WARNING: Running the tests will perform live actions as the Twitter account.
|
||||
# Set all values, move to `env`, run `source tests/env` and `phpunit` to start testing.
|
||||
|
||||
# To run the tests you must register Twitter application at https://app.twitter.com/.
|
||||
export TEST_CONSUMER_KEY=
|
||||
export TEST_CONSUMER_SECRET=
|
||||
export TEST_ACCESS_TOKEN=
|
||||
export TEST_ACCESS_TOKEN_SECRET=
|
||||
export TEST_OAUTH_CALLBACK=
|
||||
# You can find proxies for testing at http://proxylist.hidemyass.com/.
|
||||
export TEST_CURLOPT_PROXY=
|
||||
export TEST_CURLOPT_PROXYUSERPWD=
|
||||
export TEST_CURLOPT_PROXYPORT=
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// These keys have been revoked and are only valid for teh VCR cassettes.
|
||||
// To request new VCR cassettes please open an issue: https://github.com/abraham/twitteroauth/issues
|
||||
|
||||
// To update VCR cassettes
|
||||
// 1. Delete all `tests/fixtures/*` files
|
||||
// `rm tests/fixtures/*`
|
||||
// 2. Set application and suer authorization credentials below
|
||||
// 3. Set MOCK_TIME to current unix time
|
||||
// 4. Run PHPUnit tests
|
||||
// 5. Reset application credentials on Twitter dashboard
|
||||
// 6. Commit new cassettes and revoked credentials
|
||||
|
||||
// TwitterOAuth dev
|
||||
define('CONSUMER_KEY', 'awJfND4zFGapGOFKfdjg');
|
||||
define('CONSUMER_SECRET', 'LfkmNSRPIXwkQkZUB9DNWSzx5LIaivSknV4rxngojJc');
|
||||
define('OAUTH_CALLBACK', 'https://twitteroauth.com/callback.php');
|
||||
|
||||
// oauthlibtest
|
||||
define('ACCESS_TOKEN', '93915746-KjE3c27dCt8awONxuUAaJ00yishXXwcH5CdLBnO1x');
|
||||
define('ACCESS_TOKEN_SECRET', 'vurSbgJw6nHvv7xBfqKnBLWEQekOi59KFkXDLiY3Vqn3u');
|
||||
|
||||
// Timestamp the VCR cassettes were last updated
|
||||
define('MOCK_TIME', 1587861062);
|
||||
|
||||
// https://free-proxy-list.net/
|
||||
define('PROXY', '12.218.209.130');
|
||||
define('PROXYUSERPWD', '');
|
||||
define('PROXYPORT', '53281');
|
|
@ -60,7 +60,7 @@ class ClassLoader
|
|||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
|
@ -279,7 +279,7 @@ class ClassLoader
|
|||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,5 +7,6 @@ $baseDir = dirname($vendorDir);
|
|||
|
||||
return array(
|
||||
'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
|
||||
'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),
|
||||
'Abraham\\TwitterOAuth\\' => array($vendorDir . '/abraham/twitteroauth/src'),
|
||||
);
|
||||
|
|
|
@ -13,6 +13,9 @@ class ComposerAutoloaderInitTwitterAddon
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
|
|
|
@ -10,6 +10,7 @@ class ComposerStaticInitTwitterAddon
|
|||
'C' =>
|
||||
array (
|
||||
'Composer\\Installers\\' => 20,
|
||||
'Composer\\CaBundle\\' => 18,
|
||||
),
|
||||
'A' =>
|
||||
array (
|
||||
|
@ -22,6 +23,10 @@ class ComposerStaticInitTwitterAddon
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
|
||||
),
|
||||
'Composer\\CaBundle\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/composer/ca-bundle/src',
|
||||
),
|
||||
'Abraham\\TwitterOAuth\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/abraham/twitteroauth/src',
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (C) 2016 Composer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,85 @@
|
|||
composer/ca-bundle
|
||||
==================
|
||||
|
||||
Small utility library that lets you find a path to the system CA bundle,
|
||||
and includes a fallback to the Mozilla CA bundle.
|
||||
|
||||
Originally written as part of [composer/composer](https://github.com/composer/composer),
|
||||
now extracted and made available as a stand-alone library.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Install the latest version with:
|
||||
|
||||
```bash
|
||||
$ composer require composer/ca-bundle
|
||||
```
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
* PHP 5.3.2 is required but using the latest version of PHP is highly recommended.
|
||||
|
||||
|
||||
Basic usage
|
||||
-----------
|
||||
|
||||
### `Composer\CaBundle\CaBundle`
|
||||
|
||||
- `CaBundle::getSystemCaRootBundlePath()`: Returns the system CA bundle path, or a path to the bundled one as fallback
|
||||
- `CaBundle::getBundledCaBundlePath()`: Returns the path to the bundled CA file
|
||||
- `CaBundle::validateCaFile($filename)`: Validates a CA file using openssl_x509_parse only if it is safe to use
|
||||
- `CaBundle::isOpensslParseSafe()`: Test if it is safe to use the PHP function openssl_x509_parse()
|
||||
- `CaBundle::reset()`: Resets the static caches
|
||||
|
||||
|
||||
#### To use with curl
|
||||
|
||||
```php
|
||||
$curl = curl_init("https://example.org/");
|
||||
|
||||
$caPathOrFile = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
|
||||
if (is_dir($caPathOrFile)) {
|
||||
curl_setopt($curl, CURLOPT_CAPATH, $caPathOrFile);
|
||||
} else {
|
||||
curl_setopt($curl, CURLOPT_CAINFO, $caPathOrFile);
|
||||
}
|
||||
|
||||
$result = curl_exec($curl);
|
||||
```
|
||||
|
||||
#### To use with php streams
|
||||
|
||||
```php
|
||||
$opts = array(
|
||||
'http' => array(
|
||||
'method' => "GET"
|
||||
)
|
||||
);
|
||||
|
||||
$caPathOrFile = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
|
||||
if (is_dir($caPathOrFile)) {
|
||||
$opts['ssl']['capath'] = $caPathOrFile;
|
||||
} else {
|
||||
$opts['ssl']['cafile'] = $caPathOrFile;
|
||||
}
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
$result = file_get_contents('https://example.com', false, $context);
|
||||
```
|
||||
|
||||
#### To use with Guzzle
|
||||
|
||||
```php
|
||||
$client = new \GuzzleHttp\Client([
|
||||
\GuzzleHttp\RequestOptions::VERIFY => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath()
|
||||
]);
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
composer/ca-bundle is licensed under the MIT License, see the LICENSE file for details.
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"name": "composer/ca-bundle",
|
||||
"description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"cabundle",
|
||||
"cacert",
|
||||
"certificate",
|
||||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"issues": "https://github.com/composer/ca-bundle/issues"
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5",
|
||||
"phpstan/phpstan": "^0.12.55",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\CaBundle\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Composer\\CaBundle\\": "tests"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit",
|
||||
"phpstan": "vendor/bin/phpstan analyse"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,353 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/ca-bundle.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\CaBundle;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Process\PhpProcess;
|
||||
|
||||
/**
|
||||
* @author Chris Smith <chris@cs278.org>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class CaBundle
|
||||
{
|
||||
/** @var string|null */
|
||||
private static $caPath;
|
||||
/** @var array<string, bool> */
|
||||
private static $caFileValidity = array();
|
||||
/** @var bool|null */
|
||||
private static $useOpensslParse;
|
||||
|
||||
/**
|
||||
* Returns the system CA bundle path, or a path to the bundled one
|
||||
*
|
||||
* This method was adapted from Sslurp.
|
||||
* https://github.com/EvanDotPro/Sslurp
|
||||
*
|
||||
* (c) Evan Coury <me@evancoury.com>
|
||||
*
|
||||
* For the full copyright and license information, please see below:
|
||||
*
|
||||
* Copyright (c) 2013, Evan Coury
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @param LoggerInterface $logger optional logger for information about which CA files were loaded
|
||||
* @return string path to a CA bundle file or directory
|
||||
*/
|
||||
public static function getSystemCaRootBundlePath(LoggerInterface $logger = null)
|
||||
{
|
||||
if (self::$caPath !== null) {
|
||||
return self::$caPath;
|
||||
}
|
||||
$caBundlePaths = array();
|
||||
|
||||
// If SSL_CERT_FILE env variable points to a valid certificate/bundle, use that.
|
||||
// This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
|
||||
$caBundlePaths[] = self::getEnvVariable('SSL_CERT_FILE');
|
||||
|
||||
// If SSL_CERT_DIR env variable points to a valid certificate/bundle, use that.
|
||||
// This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
|
||||
$caBundlePaths[] = self::getEnvVariable('SSL_CERT_DIR');
|
||||
|
||||
$caBundlePaths[] = ini_get('openssl.cafile');
|
||||
$caBundlePaths[] = ini_get('openssl.capath');
|
||||
|
||||
$otherLocations = array(
|
||||
'/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package)
|
||||
'/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package)
|
||||
'/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package)
|
||||
'/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package)
|
||||
'/usr/ssl/certs/ca-bundle.crt', // Cygwin
|
||||
'/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package
|
||||
'/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option)
|
||||
'/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat?
|
||||
'/etc/ssl/cert.pem', // OpenBSD
|
||||
'/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x
|
||||
'/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package
|
||||
'/usr/local/etc/openssl@1.1/cert.pem', // OS X homebrew, openssl@1.1 package
|
||||
);
|
||||
|
||||
foreach($otherLocations as $location) {
|
||||
$otherLocations[] = dirname($location);
|
||||
}
|
||||
|
||||
$caBundlePaths = array_merge($caBundlePaths, $otherLocations);
|
||||
|
||||
foreach ($caBundlePaths as $caBundle) {
|
||||
if ($caBundle && self::caFileUsable($caBundle, $logger)) {
|
||||
return self::$caPath = $caBundle;
|
||||
}
|
||||
|
||||
if ($caBundle && self::caDirUsable($caBundle)) {
|
||||
return self::$caPath = $caBundle;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$caPath = static::getBundledCaBundlePath(); // Bundled CA file, last resort
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the bundled CA file
|
||||
*
|
||||
* In case you don't want to trust the user or the system, you can use this directly
|
||||
*
|
||||
* @return string path to a CA bundle file
|
||||
*/
|
||||
public static function getBundledCaBundlePath()
|
||||
{
|
||||
$caBundleFile = __DIR__.'/../res/cacert.pem';
|
||||
|
||||
// cURL does not understand 'phar://' paths
|
||||
// see https://github.com/composer/ca-bundle/issues/10
|
||||
if (0 === strpos($caBundleFile, 'phar://')) {
|
||||
$tempCaBundleFile = tempnam(sys_get_temp_dir(), 'openssl-ca-bundle-');
|
||||
if (false === $tempCaBundleFile) {
|
||||
throw new \RuntimeException('Could not create a temporary file to store the bundled CA file');
|
||||
}
|
||||
|
||||
file_put_contents(
|
||||
$tempCaBundleFile,
|
||||
file_get_contents($caBundleFile)
|
||||
);
|
||||
|
||||
register_shutdown_function(function() use ($tempCaBundleFile) {
|
||||
@unlink($tempCaBundleFile);
|
||||
});
|
||||
|
||||
$caBundleFile = $tempCaBundleFile;
|
||||
}
|
||||
|
||||
return $caBundleFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a CA file using opensl_x509_parse only if it is safe to use
|
||||
*
|
||||
* @param string $filename
|
||||
* @param LoggerInterface $logger optional logger for information about which CA files were loaded
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateCaFile($filename, LoggerInterface $logger = null)
|
||||
{
|
||||
static $warned = false;
|
||||
|
||||
if (isset(self::$caFileValidity[$filename])) {
|
||||
return self::$caFileValidity[$filename];
|
||||
}
|
||||
|
||||
$contents = file_get_contents($filename);
|
||||
|
||||
// assume the CA is valid if php is vulnerable to
|
||||
// https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html
|
||||
if (!static::isOpensslParseSafe()) {
|
||||
if (!$warned && $logger) {
|
||||
$logger->warning(sprintf(
|
||||
'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.',
|
||||
PHP_VERSION
|
||||
));
|
||||
$warned = true;
|
||||
}
|
||||
|
||||
$isValid = !empty($contents);
|
||||
} elseif (is_string($contents) && strlen($contents) > 0) {
|
||||
$contents = preg_replace("/^(\\-+(?:BEGIN|END))\\s+TRUSTED\\s+(CERTIFICATE\\-+)\$/m", '$1 $2', $contents);
|
||||
if (null === $contents) {
|
||||
// regex extraction failed
|
||||
$isValid = false;
|
||||
} else {
|
||||
$isValid = (bool) openssl_x509_parse($contents);
|
||||
}
|
||||
} else {
|
||||
$isValid = false;
|
||||
}
|
||||
|
||||
if ($logger) {
|
||||
$logger->debug('Checked CA file '.realpath($filename).': '.($isValid ? 'valid' : 'invalid'));
|
||||
}
|
||||
|
||||
return self::$caFileValidity[$filename] = $isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if it is safe to use the PHP function openssl_x509_parse().
|
||||
*
|
||||
* This checks if OpenSSL extensions is vulnerable to remote code execution
|
||||
* via the exploit documented as CVE-2013-6420.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isOpensslParseSafe()
|
||||
{
|
||||
if (null !== self::$useOpensslParse) {
|
||||
return self::$useOpensslParse;
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
// Vulnerable:
|
||||
// PHP 5.3.0 - PHP 5.3.27
|
||||
// PHP 5.4.0 - PHP 5.4.22
|
||||
// PHP 5.5.0 - PHP 5.5.6
|
||||
if (
|
||||
(PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328)
|
||||
|| (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423)
|
||||
|| PHP_VERSION_ID >= 50507
|
||||
) {
|
||||
// This version of PHP has the fix for CVE-2013-6420 applied.
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
// Windows is probably insecure in this case.
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
$compareDistroVersionPrefix = function ($prefix, $fixedVersion) {
|
||||
$regex = '{^'.preg_quote($prefix).'([0-9]+)$}';
|
||||
|
||||
if (preg_match($regex, PHP_VERSION, $m)) {
|
||||
return ((int) $m[1]) >= $fixedVersion;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Hard coded list of PHP distributions with the fix backported.
|
||||
if (
|
||||
$compareDistroVersionPrefix('5.3.3-7+squeeze', 18) // Debian 6 (Squeeze)
|
||||
|| $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) // Debian 7 (Wheezy)
|
||||
|| $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) // Ubuntu 12.04 (Precise)
|
||||
) {
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
// Symfony Process component is missing so we assume it is unsafe at this point
|
||||
if (!class_exists('Symfony\Component\Process\PhpProcess')) {
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
// This is where things get crazy, because distros backport security
|
||||
// fixes the chances are on NIX systems the fix has been applied but
|
||||
// it's not possible to verify that from the PHP version.
|
||||
//
|
||||
// To verify exec a new PHP process and run the issue testcase with
|
||||
// known safe input that replicates the bug.
|
||||
|
||||
// Based on testcase in https://github.com/php/php-src/commit/c1224573c773b6845e83505f717fbf820fc18415
|
||||
// changes in https://github.com/php/php-src/commit/76a7fd893b7d6101300cc656058704a73254d593
|
||||
$cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K';
|
||||
$script = <<<'EOT'
|
||||
|
||||
error_reporting(-1);
|
||||
$info = openssl_x509_parse(base64_decode('%s'));
|
||||
var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']);
|
||||
|
||||
EOT;
|
||||
$script = '<'."?php\n".sprintf($script, $cert);
|
||||
|
||||
try {
|
||||
$process = new PhpProcess($script);
|
||||
$process->mustRun();
|
||||
} catch (\Exception $e) {
|
||||
// In the case of any exceptions just accept it is not possible to
|
||||
// determine the safety of openssl_x509_parse and bail out.
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
$output = preg_split('{\r?\n}', trim($process->getOutput()));
|
||||
$errorOutput = trim($process->getErrorOutput());
|
||||
|
||||
if (
|
||||
is_array($output)
|
||||
&& count($output) === 3
|
||||
&& $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION)
|
||||
&& $output[1] === 'string(27) "stefan.esser@sektioneins.de"'
|
||||
&& $output[2] === 'int(-1)'
|
||||
&& preg_match('{openssl_x509_parse\(\): illegal (?:ASN1 data type for|length in) timestamp in - on line \d+}', $errorOutput)
|
||||
) {
|
||||
// This PHP has the fix backported probably by a distro security team.
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the static caches
|
||||
* @return void
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
self::$caFileValidity = array();
|
||||
self::$caPath = null;
|
||||
self::$useOpensslParse = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string|false
|
||||
*/
|
||||
private static function getEnvVariable($name)
|
||||
{
|
||||
if (isset($_SERVER[$name])) {
|
||||
return (string) $_SERVER[$name];
|
||||
}
|
||||
|
||||
if (PHP_SAPI === 'cli' && ($value = getenv($name)) !== false && $value !== null) {
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|false $certFile
|
||||
* @return bool
|
||||
*/
|
||||
private static function caFileUsable($certFile, LoggerInterface $logger = null)
|
||||
{
|
||||
return $certFile && @is_file($certFile) && @is_readable($certFile) && static::validateCaFile($certFile, $logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|false $certDir
|
||||
* @return bool
|
||||
*/
|
||||
private static function caDirUsable($certDir)
|
||||
{
|
||||
return $certDir && @is_dir($certDir) && @is_readable($certDir) && glob($certDir . '/*');
|
||||
}
|
||||
}
|
|
@ -1,29 +1,32 @@
|
|||
[
|
||||
{
|
||||
"name": "abraham/twitteroauth",
|
||||
"version": "0.7.4",
|
||||
"version_normalized": "0.7.4.0",
|
||||
"version": "2.0.0",
|
||||
"version_normalized": "2.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/abraham/twitteroauth.git",
|
||||
"reference": "c6f9e692552dd037b2324ed0dfa28a4e60875acf"
|
||||
"reference": "96f49e67baec10f5e5cb703d87be16ba01a798a5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/abraham/twitteroauth/zipball/c6f9e692552dd037b2324ed0dfa28a4e60875acf",
|
||||
"reference": "c6f9e692552dd037b2324ed0dfa28a4e60875acf",
|
||||
"url": "https://api.github.com/repos/abraham/twitteroauth/zipball/96f49e67baec10f5e5cb703d87be16ba01a798a5",
|
||||
"reference": "96f49e67baec10f5e5cb703d87be16ba01a798a5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/ca-bundle": "^1.2",
|
||||
"ext-curl": "*",
|
||||
"php": "^5.6 || ^7.0"
|
||||
"php": "^7.2 || ^7.3 || ^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpmd/phpmd": "~2.6",
|
||||
"phpunit/phpunit": "~5.7",
|
||||
"squizlabs/php_codesniffer": "~3.0"
|
||||
"php-vcr/php-vcr": "^1",
|
||||
"php-vcr/phpunit-testlistener-vcr": "dev-php-8",
|
||||
"phpmd/phpmd": "^2",
|
||||
"phpunit/phpunit": "^8",
|
||||
"squizlabs/php_codesniffer": "^3"
|
||||
},
|
||||
"time": "2017-06-30T22:02:01+00:00",
|
||||
"time": "2020-12-02T01:27:06+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
|
@ -55,6 +58,79 @@
|
|||
"twitter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
"version": "1.2.10",
|
||||
"version_normalized": "1.2.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/ca-bundle.git",
|
||||
"reference": "9fdb22c2e97a614657716178093cd1da90a64aa8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/9fdb22c2e97a614657716178093cd1da90a64aa8",
|
||||
"reference": "9fdb22c2e97a614657716178093cd1da90a64aa8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.55",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5",
|
||||
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
|
||||
},
|
||||
"time": "2021-06-07T13:58:28+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\CaBundle\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
|
||||
"keywords": [
|
||||
"cabundle",
|
||||
"cacert",
|
||||
"certificate",
|
||||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "composer/installers",
|
||||
"version": "v1.6.0",
|
||||
|
@ -183,12 +259,12 @@
|
|||
"version_normalized": "9999999-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jublonet/codebird-php.git",
|
||||
"url": "https://github.com/jublo/codebird-php.git",
|
||||
"reference": "df362d8ad629aad6c4c7dbf36a440e569ec41368"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jublonet/codebird-php/zipball/df362d8ad629aad6c4c7dbf36a440e569ec41368",
|
||||
"url": "https://api.github.com/repos/jublo/codebird-php/zipball/df362d8ad629aad6c4c7dbf36a440e569ec41368",
|
||||
"reference": "df362d8ad629aad6c4c7dbf36a440e569ec41368",
|
||||
"shasum": ""
|
||||
},
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2012 Kyle Robinson Young
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,105 @@
|
|||
{
|
||||
"name": "composer/installers",
|
||||
"type": "composer-plugin",
|
||||
"license": "MIT",
|
||||
"description": "A multi-framework Composer library installer",
|
||||
"keywords": [
|
||||
"installer",
|
||||
"Aimeos",
|
||||
"AGL",
|
||||
"AnnotateCms",
|
||||
"Attogram",
|
||||
"Bitrix",
|
||||
"CakePHP",
|
||||
"Chef",
|
||||
"Cockpit",
|
||||
"CodeIgniter",
|
||||
"concrete5",
|
||||
"Craft",
|
||||
"Croogo",
|
||||
"DokuWiki",
|
||||
"Dolibarr",
|
||||
"Drupal",
|
||||
"Elgg",
|
||||
"Eliasis",
|
||||
"ExpressionEngine",
|
||||
"eZ Platform",
|
||||
"FuelPHP",
|
||||
"Grav",
|
||||
"Hurad",
|
||||
"ImageCMS",
|
||||
"iTop",
|
||||
"Joomla",
|
||||
"Kanboard",
|
||||
"Kohana",
|
||||
"Lan Management System",
|
||||
"Laravel",
|
||||
"Lavalite",
|
||||
"Lithium",
|
||||
"Magento",
|
||||
"majima",
|
||||
"Mako",
|
||||
"Mautic",
|
||||
"Maya",
|
||||
"MODX",
|
||||
"MODX Evo",
|
||||
"MediaWiki",
|
||||
"OXID",
|
||||
"osclass",
|
||||
"MODULEWork",
|
||||
"Moodle",
|
||||
"Piwik",
|
||||
"pxcms",
|
||||
"phpBB",
|
||||
"Plentymarkets",
|
||||
"PPI",
|
||||
"Puppet",
|
||||
"Porto",
|
||||
"RadPHP",
|
||||
"ReIndex",
|
||||
"Roundcube",
|
||||
"shopware",
|
||||
"SilverStripe",
|
||||
"SMF",
|
||||
"SyDES",
|
||||
"symfony",
|
||||
"Thelia",
|
||||
"TYPO3",
|
||||
"WolfCMS",
|
||||
"WordPress",
|
||||
"YAWIK",
|
||||
"Zend",
|
||||
"Zikula"
|
||||
],
|
||||
"homepage": "https://composer.github.io/installers/",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kyle Robinson Young",
|
||||
"email": "kyle@dontkry.com",
|
||||
"homepage": "https://github.com/shama"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
|
||||
},
|
||||
"extra": {
|
||||
"class": "Composer\\Installers\\Plugin",
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
"shama/baton": "*",
|
||||
"roundcube/plugin-installer": "*"
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "1.0.*@dev",
|
||||
"phpunit/phpunit": "^4.8.36"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class AglInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'module' => 'More/{$name}/',
|
||||
);
|
||||
|
||||
/**
|
||||
* Format package name to CamelCase
|
||||
*/
|
||||
public function inflectPackageVars($vars)
|
||||
{
|
||||
$vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
|
||||
return strtoupper($matches[1]);
|
||||
}, $vars['name']);
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
9
twitter/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
vendored
Normal file
9
twitter/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class AimeosInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'extension' => 'ext/{$name}/',
|
||||
);
|
||||
}
|
11
twitter/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
vendored
Normal file
11
twitter/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class AnnotateCmsInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'module' => 'addons/modules/{$name}/',
|
||||
'component' => 'addons/components/{$name}/',
|
||||
'service' => 'addons/services/{$name}/',
|
||||
);
|
||||
}
|
49
twitter/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
vendored
Normal file
49
twitter/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class AsgardInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'module' => 'Modules/{$name}/',
|
||||
'theme' => 'Themes/{$name}/'
|
||||
);
|
||||
|
||||
/**
|
||||
* Format package name.
|
||||
*
|
||||
* For package type asgard-module, cut off a trailing '-plugin' if present.
|
||||
*
|
||||
* For package type asgard-theme, cut off a trailing '-theme' if present.
|
||||
*
|
||||
*/
|
||||
public function inflectPackageVars($vars)
|
||||
{
|
||||
if ($vars['type'] === 'asgard-module') {
|
||||
return $this->inflectPluginVars($vars);
|
||||
}
|
||||
|
||||
if ($vars['type'] === 'asgard-theme') {
|
||||
return $this->inflectThemeVars($vars);
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
protected function inflectPluginVars($vars)
|
||||
{
|
||||
$vars['name'] = preg_replace('/-module$/', '', $vars['name']);
|
||||
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
||||
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
protected function inflectThemeVars($vars)
|
||||
{
|
||||
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
|
||||
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
|
||||
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
9
twitter/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
vendored
Normal file
9
twitter/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class AttogramInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'module' => 'modules/{$name}/',
|
||||
);
|
||||
}
|
136
twitter/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
vendored
Normal file
136
twitter/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Composer;
|
||||
use Composer\Package\PackageInterface;
|
||||
|
||||
abstract class BaseInstaller
|
||||
{
|
||||
protected $locations = array();
|
||||
protected $composer;
|
||||
protected $package;
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* Initializes base installer.
|
||||
*
|
||||
* @param PackageInterface $package
|
||||
* @param Composer $composer
|
||||
* @param IOInterface $io
|
||||
*/
|
||||
public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null)
|
||||
{
|
||||
$this->composer = $composer;
|
||||
$this->package = $package;
|
||||
$this->io = $io;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the install path based on package type.
|
||||
*
|
||||
* @param PackageInterface $package
|
||||
* @param string $frameworkType
|
||||
* @return string
|
||||
*/
|
||||
public function getInstallPath(PackageInterface $package, $frameworkType = '')
|
||||
{
|
||||
$type = $this->package->getType();
|
||||
|
||||
$prettyName = $this->package->getPrettyName();
|
||||
if (strpos($prettyName, '/') !== false) {
|
||||
list($vendor, $name) = explode('/', $prettyName);
|
||||
} else {
|
||||
$vendor = '';
|
||||
$name = $prettyName;
|
||||
}
|
||||
|
||||
$availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
|
||||
|
||||
$extra = $package->getExtra();
|
||||
if (!empty($extra['installer-name'])) {
|
||||
$availableVars['name'] = $extra['installer-name'];
|
||||
}
|
||||
|
||||
if ($this->composer->getPackage()) {
|
||||
$extra = $this->composer->getPackage()->getExtra();
|
||||
if (!empty($extra['installer-paths'])) {
|
||||
$customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
|
||||
if ($customPath !== false) {
|
||||
return $this->templatePath($customPath, $availableVars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$packageType = substr($type, strlen($frameworkType) + 1);
|
||||
$locations = $this->getLocations();
|
||||
if (!isset($locations[$packageType])) {
|
||||
throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
|
||||
}
|
||||
|
||||
return $this->templatePath($locations[$packageType], $availableVars);
|
||||
}
|
||||
|
||||
/**
|
||||
* For an installer to override to modify the vars per installer.
|
||||
*
|
||||
* @param array $vars
|
||||
* @return array
|
||||
*/
|
||||
public function inflectPackageVars($vars)
|
||||
{
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the installer's locations
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocations()
|
||||
{
|
||||
return $this->locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace vars in a path
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $vars
|
||||
* @return string
|
||||
*/
|
||||
protected function templatePath($path, array $vars = array())
|
||||
{
|
||||
if (strpos($path, '{') !== false) {
|
||||
extract($vars);
|
||||
preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
foreach ($matches[1] as $var) {
|
||||
$path = str_replace('{$' . $var . '}', $$var, $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search through a passed paths array for a custom install path.
|
||||
*
|
||||
* @param array $paths
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $vendor = NULL
|
||||
* @return string
|
||||
*/
|
||||
protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
|
||||
{
|
||||
foreach ($paths as $path => $names) {
|
||||
if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
126
twitter/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
vendored
Normal file
126
twitter/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
namespace Composer\Installers;
|
||||
|
||||
use Composer\Util\Filesystem;
|
||||
|
||||
/**
|
||||
* Installer for Bitrix Framework. Supported types of extensions:
|
||||
* - `bitrix-d7-module` — copy the module to directory `bitrix/modules/<vendor>.<name>`.
|
||||
* - `bitrix-d7-component` — copy the component to directory `bitrix/components/<vendor>/<name>`.
|
||||
* - `bitrix-d7-template` — copy the template to directory `bitrix/templates/<vendor>_<name>`.
|
||||
*
|
||||
* You can set custom path to directory with Bitrix kernel in `composer.json`:
|
||||
*
|
||||
* ```json
|
||||
* {
|
||||
* "extra": {
|
||||
* "bitrix-dir": "s1/bitrix"
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @author Nik Samokhvalov <nik@samokhvalov.info>
|
||||
* @author Denis Kulichkin <onexhovia@gmail.com>
|
||||
*/
|
||||
class BitrixInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
|
||||
'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
|
||||
'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
|
||||
'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
|
||||
'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
|
||||
'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array Storage for informations about duplicates at all the time of installation packages.
|
||||
*/
|
||||
private static $checkedDuplicates = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function inflectPackageVars($vars)
|
||||
{
|
||||
if ($this->composer->getPackage()) {
|
||||
$extra = $this->composer->getPackage()->getExtra();
|
||||
|
||||
if (isset($extra['bitrix-dir'])) {
|
||||
$vars['bitrix_dir'] = $extra['bitrix-dir'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($vars['bitrix_dir'])) {
|
||||
$vars['bitrix_dir'] = 'bitrix';
|
||||
}
|
||||
|
||||
return parent::inflectPackageVars($vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function templatePath($path, array $vars = array())
|
||||
{
|
||||
$templatePath = parent::templatePath($path, $vars);
|
||||
$this->checkDuplicates($templatePath, $vars);
|
||||
|
||||
return $templatePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates search packages.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $vars
|
||||
*/
|
||||
protected function checkDuplicates($path, array $vars = array())
|
||||
{
|
||||
$packageType = substr($vars['type'], strlen('bitrix') + 1);
|
||||
$localDir = explode('/', $vars['bitrix_dir']);
|
||||
array_pop($localDir);
|
||||
$localDir[] = 'local';
|
||||
$localDir = implode('/', $localDir);
|
||||
|
||||
$oldPath = str_replace(
|
||||
array('{$bitrix_dir}', '{$name}'),
|
||||
array($localDir, $vars['name']),
|
||||
$this->locations[$packageType]
|
||||
);
|
||||
|
||||
if (in_array($oldPath, static::$checkedDuplicates)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
|
||||
|
||||
$this->io->writeError(' <error>Duplication of packages:</error>');
|
||||
$this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
|
||||
|
||||
while (true) {
|
||||
switch ($this->io->ask(' <info>Delete ' . $oldPath . ' [y,n,?]?</info> ', '?')) {
|
||||
case 'y':
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory($oldPath);
|
||||
break 2;
|
||||
|
||||
case 'n':
|
||||
break 2;
|
||||
|
||||
case '?':
|
||||
default:
|
||||
$this->io->writeError(array(
|
||||
' y - delete package ' . $oldPath . ' and to continue with the installation',
|
||||
' n - don\'t delete and to continue with the installation',
|
||||
));
|
||||
$this->io->writeError(' ? - print help');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static::$checkedDuplicates[] = $oldPath;
|
||||
}
|
||||
}
|
9
twitter/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
vendored
Normal file
9
twitter/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class BonefishInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'package' => 'Packages/{$vendor}/{$name}/'
|
||||
);
|
||||
}
|
82
twitter/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
vendored
Normal file
82
twitter/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
use Composer\DependencyResolver\Pool;
|
||||
|
||||
class CakePHPInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'plugin' => 'Plugin/{$name}/',
|
||||
);
|
||||
|
||||
/**
|
||||
* Format package name to CamelCase
|
||||
*/
|
||||
public function inflectPackageVars($vars)
|
||||
{
|
||||
if ($this->matchesCakeVersion('>=', '3.0.0')) {
|
||||
return $vars;
|
||||
}
|
||||
|
||||
$nameParts = explode('/', $vars['name']);
|
||||
foreach ($nameParts as &$value) {
|
||||
$value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
|
||||
$value = str_replace(array('-', '_'), ' ', $value);
|
||||
$value = str_replace(' ', '', ucwords($value));
|
||||
}
|
||||
$vars['name'] = implode('/', $nameParts);
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the default plugin location when cakephp >= 3.0
|
||||
*/
|
||||
public function getLocations()
|
||||
{
|
||||
if ($this->matchesCakeVersion('>=', '3.0.0')) {
|
||||
$this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
|
||||
}
|
||||
return $this->locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if CakePHP version matches against a version
|
||||
*
|
||||
* @param string $matcher
|
||||
* @param string $version
|
||||
* @return bool
|
||||
*/
|
||||
protected function matchesCakeVersion($matcher, $version)
|
||||
{
|
||||
if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
|
||||
$multiClass = 'Composer\Semver\Constraint\MultiConstraint';
|
||||
$constraintClass = 'Composer\Semver\Constraint\Constraint';
|
||||
} else {
|
||||
$multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
|
||||
$constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
|
||||
}
|
||||
|
||||
$repositoryManager = $this->composer->getRepositoryManager();
|
||||
if ($repositoryManager) {
|
||||
$repos = $repositoryManager->getLocalRepository();
|
||||
if (!$repos) {
|
||||
return false;
|
||||
}
|
||||
$cake3 = new $multiClass(array(
|
||||
new $constraintClass($matcher, $version),
|
||||
new $constraintClass('!=', '9999999-dev'),
|
||||
));
|
||||
$pool = new Pool('dev');
|
||||
$pool->addRepository($repos);
|
||||
$packages = $pool->whatProvides('cakephp/cakephp');
|
||||
foreach ($packages as $package) {
|
||||
$installed = new $constraintClass('=', $package->getVersion());
|
||||
if ($cake3->matches($installed)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
11
twitter/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
vendored
Normal file
11
twitter/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class ChefInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'cookbook' => 'Chef/{$vendor}/{$name}/',
|
||||
'role' => 'Chef/roles/{$name}/',
|
||||
);
|
||||
}
|
||||
|
9
twitter/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
vendored
Normal file
9
twitter/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class CiviCrmInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'ext' => 'ext/{$name}/'
|
||||
);
|
||||
}
|
10
twitter/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
vendored
Normal file
10
twitter/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class ClanCatsFrameworkInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'ship' => 'CCF/orbit/{$name}/',
|
||||
'theme' => 'CCF/app/themes/{$name}/',
|
||||
);
|
||||
}
|
34
twitter/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
vendored
Normal file
34
twitter/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class CockpitInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'module' => 'cockpit/modules/addons/{$name}/',
|
||||
);
|
||||
|
||||
/**
|
||||
* Format module name.
|
||||
*
|
||||
* Strip `module-` prefix from package name.
|
||||
*
|
||||
* @param array @vars
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function inflectPackageVars($vars)
|
||||
{
|
||||
if ($vars['type'] == 'cockpit-module') {
|
||||
return $this->inflectModuleVars($vars);
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
public function inflectModuleVars($vars)
|
||||
{
|
||||
$vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
11
twitter/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
vendored
Normal file
11
twitter/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class CodeIgniterInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'library' => 'application/libraries/{$name}/',
|
||||
'third-party' => 'application/third_party/{$name}/',
|
||||
'module' => 'application/modules/{$name}/',
|
||||
);
|
||||
}
|
13
twitter/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
vendored
Normal file
13
twitter/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class Concrete5Installer extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'core' => 'concrete/',
|
||||
'block' => 'application/blocks/{$name}/',
|
||||
'package' => 'packages/{$name}/',
|
||||
'theme' => 'application/themes/{$name}/',
|
||||
'update' => 'updates/{$name}/',
|
||||
);
|
||||
}
|
35
twitter/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
vendored
Normal file
35
twitter/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
/**
|
||||
* Installer for Craft Plugins
|
||||
*/
|
||||
class CraftInstaller extends BaseInstaller
|
||||
{
|
||||
const NAME_PREFIX = 'craft';
|
||||
const NAME_SUFFIX = 'plugin';
|
||||
|
||||
protected $locations = array(
|
||||
'plugin' => 'craft/plugins/{$name}/',
|
||||
);
|
||||
|
||||
/**
|
||||
* Strip `craft-` prefix and/or `-plugin` suffix from package names
|
||||
*
|
||||
* @param array $vars
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function inflectPackageVars($vars)
|
||||
{
|
||||
return $this->inflectPluginVars($vars);
|
||||
}
|
||||
|
||||
private function inflectPluginVars($vars)
|
||||
{
|
||||
$vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
|
||||
$vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
21
twitter/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
vendored
Normal file
21
twitter/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class CroogoInstaller extends BaseInstaller
|
||||
{
|
||||
protected $locations = array(
|
||||
'plugin' => 'Plugin/{$name}/',
|
||||
'theme' => 'View/Themed/{$name}/',
|
||||
);
|
||||
|
||||
/**
|
||||
* Format package name to CamelCase
|
||||
*/
|
||||
public function inflectPackageVars($vars)
|
||||
{
|
||||
$vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
|
||||
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
10
twitter/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
vendored
Normal file
10
twitter/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
namespace Composer\Installers;
|
||||
|
||||
class DecibelInstaller extends BaseInstaller
|
||||
{
|
||||
/** @var array */
|
||||
protected $locations = array(
|
||||
'app' => 'app/{$name}/',
|
||||
);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user