Merge branch 'dev' of /home/macgirvin/z into dev

This commit is contained in:
nobody 2020-11-10 18:52:23 -08:00
commit 50c7dd18be
155 changed files with 3204 additions and 13472 deletions

View file

@ -106,9 +106,26 @@ class Activity {
} }
if ($x['success']) { if ($x['success']) {
$y = json_decode($x['body'],true); $y = json_decode($x['body'],true);
logger('returned: ' . json_encode($y,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)); logger('returned: ' . json_encode($y,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
// check for a valid signature, but only if this is not an actor object. If it is signed, it must be valid.
// Ignore actors because of the potential for infinite recursion if we perform this step while
// fetching an actor key to validate a signature elsewhere. This should validate relayed activities
// over litepub which arrived at our inbox that do not use LD signatures
if (($y['type']) && (! ActivityStreams::is_an_actor($y['type']))) {
$sigblock = HTTPSig::verify($x);
if (($sigblock['header_signed']) && (! $sigblock['header_valid'])) {
return null;
}
}
return json_decode($x['body'], true); return json_decode($x['body'], true);
} }
else { else {
logger('fetch failed: ' . $url); logger('fetch failed: ' . $url);
@ -330,8 +347,9 @@ class Activity {
$ptr = [ $ptr ]; $ptr = [ $ptr ];
} }
foreach ($ptr as $t) { foreach ($ptr as $t) {
if (! array_key_exists('type',$t)) if (! array_key_exists('type',$t)) {
$t['type'] = 'Hashtag'; $t['type'] = 'Hashtag';
}
switch($t['type']) { switch($t['type']) {
case 'Hashtag': case 'Hashtag':
@ -342,6 +360,10 @@ class Activity {
$ret[] = [ 'ttype' => TERM_PCATEGORY, 'url' => $t['href'], 'term' => escape_tags($t['name']) ]; $ret[] = [ 'ttype' => TERM_PCATEGORY, 'url' => $t['href'], 'term' => escape_tags($t['name']) ];
break; break;
case 'Category':
$ret[] = [ 'ttype' => TERM_CATEGORY, 'url' => $t['href'], 'term' => escape_tags($t['name']) ];
break;
case 'Mention': case 'Mention':
$mention_type = substr($t['name'],0,1); $mention_type = substr($t['name'],0,1);
if ($mention_type === '!') { if ($mention_type === '!') {
@ -386,6 +408,12 @@ class Activity {
} }
break; break;
case TERM_CATEGORY:
if ($t['url'] && $t['term']) {
$ret[] = [ 'type' => 'Category', 'href' => $t['url'], 'name' => $t['term'] ];
}
break;
case TERM_FORUM: case TERM_FORUM:
$term = self::lookup_term_addr($t['url'],$t['term']); $term = self::lookup_term_addr($t['url'],$t['term']);
$ret[] = [ 'type' => 'Mention', 'href' => $t['url'], 'name' => '!' . (($term) ? $term : $t['term']) ]; $ret[] = [ 'type' => 'Mention', 'href' => $t['url'], 'name' => '!' . (($term) ? $term : $t['term']) ];
@ -1876,15 +1904,22 @@ class Activity {
$software = ((array_path_exists('software/name',$ni)) ? $ni['software']['name'] : ''); $software = ((array_path_exists('software/name',$ni)) ? $ni['software']['name'] : '');
$version = ((array_path_exists('software/version',$ni)) ? $ni['software']['version'] : ''); $version = ((array_path_exists('software/version',$ni)) ? $ni['software']['version'] : '');
$r = q("select * from site where site_url = '%s'", $site = q("select * from site where site_url = '%s'",
dbesc($site_url) dbesc($site_url)
); );
if ($r) { if ($site) {
q("update site set site_project = '%s', site_version = '%s' where site_url = '%s'", q("update site set site_project = '%s', site_version = '%s', where site_url = '%s'",
dbesc($software), dbesc($software),
dbesc($version), dbesc($version),
dbesc($site_url) dbesc($site_url)
); );
// it may have been saved originally as an unknown type, but we now know what it is
if (intval($site[0]['site_type']) === SITE_TYPE_UNKNOWN) {
q("update site set site_type = %d where site_url = '%s'",
intval(SITE_TYPE_NOTZOT),
dbesc($site_url)
);
}
} }
else { else {
site_store_lowlevel( site_store_lowlevel(

View file

@ -236,13 +236,15 @@ class ActivityPub {
return; return;
} }
$orig_follow = get_abconfig($x['sender']['channel_id'],$x['recipient']['xchan_hash'],'activitypub','their_follow_id');
$msg = array_merge(['@context' => [ $msg = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV, ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1', 'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV z_root() . ZOT_APSCHEMA_REV
]], ]],
[ [
'id' => z_root() . '/follow/' . $x['recipient']['abook_id'], 'id' => z_root() . '/follow/' . $x['recipient']['abook_id'] . (($orig_follow) ? '/' . md5($orig_follow) : EMPTY_STR),
'type' => 'Follow', 'type' => 'Follow',
'actor' => $p, 'actor' => $p,
'object' => $x['recipient']['xchan_hash'], 'object' => $x['recipient']['xchan_hash'],
@ -295,7 +297,7 @@ class ActivityPub {
z_root() . ZOT_APSCHEMA_REV z_root() . ZOT_APSCHEMA_REV
]], ]],
[ [
'id' => z_root() . '/follow/' . $x['recipient']['abook_id'], 'id' => z_root() . '/follow/' . $x['recipient']['abook_id'] . '/' . md5($accept),
'type' => 'Accept', 'type' => 'Accept',
'actor' => $p, 'actor' => $p,
'object' => [ 'object' => [
@ -359,7 +361,7 @@ class ActivityPub {
z_root() . ZOT_APSCHEMA_REV z_root() . ZOT_APSCHEMA_REV
]], ]],
[ [
'id' => z_root() . '/follow/' . $recip[0]['abook_id'] . '#reject', 'id' => z_root() . '/follow/' . $recip[0]['abook_id'] . '/' . md5($orig_activity) . '#reject',
'type' => 'Reject', 'type' => 'Reject',
'actor' => $p, 'actor' => $p,
'object' => [ 'object' => [
@ -383,11 +385,11 @@ class ActivityPub {
z_root() . ZOT_APSCHEMA_REV z_root() . ZOT_APSCHEMA_REV
]], ]],
[ [
'id' => z_root() . '/follow/' . $recip[0]['abook_id'] . '#Undo', 'id' => z_root() . '/follow/' . $recip[0]['abook_id'] . (($orig_activity) ? '/' . md5($orig_activity) : EMPTY_STR) . '#Undo',
'type' => 'Undo', 'type' => 'Undo',
'actor' => $p, 'actor' => $p,
'object' => [ 'object' => [
'id' => z_root() . '/follow/' . $recip[0]['abook_id'], 'id' => z_root() . '/follow/' . $recip[0]['abook_id'] . (($orig_activity) ? '/' . md5($orig_activity) : EMPTY_STR),
'type' => 'Follow', 'type' => 'Follow',
'actor' => $p, 'actor' => $p,
'object' => $recip[0]['xchan_hash'] 'object' => $recip[0]['xchan_hash']

View file

@ -322,6 +322,7 @@ class Apps {
'Report Bug' => t('Report Bug'), 'Report Bug' => t('Report Bug'),
'View Bookmarks' => t('View Bookmarks'), 'View Bookmarks' => t('View Bookmarks'),
'Chatrooms' => t('Chatrooms'), 'Chatrooms' => t('Chatrooms'),
'Followlist' => t('Followlist'),
'Content Import' => t('Content Import'), 'Content Import' => t('Content Import'),
'Connections' => t('Connections'), 'Connections' => t('Connections'),
'Expire Posts' => t('Expire Posts'), 'Expire Posts' => t('Expire Posts'),

View file

@ -11,10 +11,10 @@ class Apschema extends Controller {
$arr = [ $arr = [
'@context' => [ '@context' => [
'zot' => z_root() . '/apschema#', 'zot' => z_root() . '/apschema#',
'id' => '@id', 'as' => 'https://www.w3.org/ns/activitystreams#',
'type' => '@type',
'toot' => 'http://joinmastodon.org/ns#', 'toot' => 'http://joinmastodon.org/ns#',
'ostatus' => 'http://ostatus.org#', 'ostatus' => 'http://ostatus.org#',
'schema' => 'http://schema.org#',
'conversation' => 'ostatus:conversation', 'conversation' => 'ostatus:conversation',
'sensitive' => 'as:sensitive', 'sensitive' => 'as:sensitive',
'movedTo' => 'as:movedTo', 'movedTo' => 'as:movedTo',
@ -28,8 +28,8 @@ class Apschema extends Controller {
'emojiReaction' => 'zot:emojiReaction', 'emojiReaction' => 'zot:emojiReaction',
'expires' => 'zot:expires', 'expires' => 'zot:expires',
'directMessage' => 'zot:directMessage', 'directMessage' => 'zot:directMessage',
'Category' => 'zot:Category',
'replyTo' => 'zot:replyTo', 'replyTo' => 'zot:replyTo',
'schema' => 'http://schema.org#',
'PropertyValue' => 'schema:PropertyValue', 'PropertyValue' => 'schema:PropertyValue',
'value' => 'schema:value', 'value' => 'schema:value',
'discoverable' => 'toot:discoverable', 'discoverable' => 'toot:discoverable',

View file

@ -75,7 +75,7 @@ class Filestorage extends Controller {
attach_change_permissions($channel_id, $resource, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], $recurse, true); attach_change_permissions($channel_id, $resource, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], $recurse, true);
$sync = attach_export_data($channel,$resource,true); $sync = attach_export_data($channel,$resource,false);
if ($sync) { if ($sync) {
Libsync::build_sync_packet($channel_id,array('file' => array($sync))); Libsync::build_sync_packet($channel_id,array('file' => array($sync)));
} }

View file

@ -17,7 +17,7 @@ class Follow extends Controller {
function init() { function init() {
if (ActivityStreams::is_as_request() && argc() == 2) { if (ActivityStreams::is_as_request() && argc() >= 2) {
$abook_id = intval(argv(1)); $abook_id = intval(argv(1));
if(! $abook_id) if(! $abook_id)
return; return;
@ -40,13 +40,21 @@ class Follow extends Controller {
http_status_exit(404, 'Not found'); http_status_exit(404, 'Not found');
} }
// Pleroma requires a unique follow id for every follow and follow response
// instead of our method of re-using the abook_id. This causes issues if they unfollow
// and re-follow so md5 their follow id and slap it on the end so they don't simply discard our
// subsequent accept/reject actions.
$orig_follow = get_abconfig($chan['channel_id'],$r[0]['xchan_hash'],'activitypub','their_follow_id');
$x = array_merge(['@context' => [ $x = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV, ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1', 'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV z_root() . ZOT_APSCHEMA_REV
]], ]],
[ [
'id' => z_root() . '/follow/' . $r[0]['abook_id'], 'id' => z_root() . '/follow/' . $r[0]['abook_id'] . (($orig_follow) ? '/' . md5($orig_follow) : EMPTY_STR),
'type' => 'Follow', 'type' => 'Follow',
'actor' => $actor, 'actor' => $actor,
'object' => $r[0]['xchan_url'] 'object' => $r[0]['xchan_url']

View file

@ -80,43 +80,6 @@ class Inbox extends Controller {
return; return;
} }
// $observer_hash in this case is the sender
if ($hsig['header_valid'] && $hsig['content_valid'] && $hsig['portable_id']) {
$observer_hash = $hsig['portable_id'];
// fetch the portable_id for the actor, which may or may not be the sender
$v = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s'",
dbesc($AS->actor['id']),
dbesc($AS->actor['id'])
);
// only allow relayed activities if the activity is signed with LDSigs
// AND the signature is valid AND the signer is the actor.
if ($v && $v[0]['hubloc_hash'] !== $observer_hash) {
if ($AS->signer && $AS->signer !== $AS->actor['id']) {
return;
}
if (! $AS->sigok) {
return;
}
}
}
else {
$observer_hash = $AS->actor['id'];
}
if (! $observer_hash) {
return;
}
$m = parse_url($observer_hash);
if ($m && $m['scheme'] && $m['host']) {
if (! check_siteallowed($m['scheme'] . '://' . $m['host'])) {
http_status_exit(403,'Permission denied');
}
}
if (! check_channelallowed($observer_hash)) {
http_status_exit(403,'Permission denied');
}
if (is_array($AS->actor) && array_key_exists('id',$AS->actor)) { if (is_array($AS->actor) && array_key_exists('id',$AS->actor)) {
Activity::actor_store($AS->actor['id'],$AS->actor); Activity::actor_store($AS->actor['id'],$AS->actor);
@ -133,22 +96,77 @@ class Inbox extends Controller {
} }
} }
// Validate that the channel that sent us this activity has authority to do so.
// Require a valid HTTPSignature with a signed Digest header.
// Only permit relayed activities if the activity is signed with LDSigs
// AND the signature is valid AND the signer is the actor.
if ($hsig['header_valid'] && $hsig['content_valid'] && $hsig['portable_id']) {
// fetch the portable_id for the actor, which may or may not be the sender
$v = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' or hubloc_hash = '%s'",
dbesc($AS->actor['id']),
dbesc($AS->actor['id'])
);
if ($v && $v[0]['hubloc_hash'] !== $hsig['portable_id']) {
// The sender is not actually the activity actor, so verify the LD signature.
// litepub activities (with no LD signature) will always have a matching actor and sender
if ($AS->signer && is_array($AS->signer) && $AS->signer['id'] !== $AS->actor['id']) {
// the activity wasn't signed by the activity actor
return;
}
if (! $AS->sigok) {
// The activity signature isn't valid.
return;
}
}
if ($v) {
// The sender has been validated and stored
$observer_hash = $hsig['portable_id'];
}
}
if (! $observer_hash) {
return;
}
// verify that this site has permitted communication with the sender.
$m = parse_url($observer_hash);
if ($m && $m['scheme'] && $m['host']) {
if (! check_siteallowed($m['scheme'] . '://' . $m['host'])) {
http_status_exit(403,'Permission denied');
}
// this site obviously isn't dead because they are trying to communicate with us.
$test = q("update site set site_dead = 0 where site_dead = 1 and site_url = '%s' ",
dbesc($m['scheme'] . '://' . $m['host'])
);
}
if (! check_channelallowed($observer_hash)) {
http_status_exit(403,'Permission denied');
}
// update the hubloc_connected timestamp, ignore failures // update the hubloc_connected timestamp, ignore failures
$test = q("update hubloc set hubloc_connected = '%s' where hubloc_hash = '%s' and hubloc_network = 'activitypub'", $test = q("update hubloc set hubloc_connected = '%s' where hubloc_hash = '%s' and hubloc_network = 'activitypub'",
dbesc(datetime_convert()), dbesc(datetime_convert()),
dbesc($observer_hash) dbesc($observer_hash)
); );
$m = parse_url($observer_hash);
if ($m['scheme'] && $m['host']) {
$test = q("update site set site_dead = 0 where site_dead = 1 and site_url = '%s' ", // Now figure out who the recipients are
dbesc($m['scheme'] . '://' . $m['host'])
);
}
if ($is_public) { if ($is_public) {
if ($AS->type === 'Follow' && is_array($AS->obj) && ActivityStreams::is_an_actor($AS->obj['type'])) { if (in_array($AS->type, [ 'Follow', 'Join' ]) && is_array($AS->obj) && ActivityStreams::is_an_actor($AS->obj['type'])) {
$channels = q("SELECT * from channel where channel_address = '%s' and channel_removed = 0 ", $channels = q("SELECT * from channel where channel_address = '%s' and channel_removed = 0 ",
dbesc(basename($AS->obj['id'])) dbesc(basename($AS->obj['id']))
); );

View file

@ -207,7 +207,7 @@ class Photos extends Controller {
if(($m) && ($m[0]['folder'] != $_POST['move_to_album'])) { if(($m) && ($m[0]['folder'] != $_POST['move_to_album'])) {
attach_move($page_owner_uid,argv(2),$_POST['move_to_album']); attach_move($page_owner_uid,argv(2),$_POST['move_to_album']);
$sync = attach_export_data(App::$data['channel'],argv(2),true); $sync = attach_export_data(App::$data['channel'],argv(2),false);
if($sync) if($sync)
Libsync::build_sync_packet($page_owner_uid,array('file' => array($sync))); Libsync::build_sync_packet($page_owner_uid,array('file' => array($sync)));

View file

@ -16,7 +16,7 @@ use Zotlabs\Daemon\Run;
* @brief This file defines some global constants and includes the central App class. * @brief This file defines some global constants and includes the central App class.
*/ */
define ( 'STD_VERSION', '20.10.27' ); define ( 'STD_VERSION', '20.11.11' );
define ( 'ZOT_REVISION', '6.0' ); define ( 'ZOT_REVISION', '6.0' );
define ( 'DB_UPDATE_VERSION', 1243 ); define ( 'DB_UPDATE_VERSION', 1243 );
@ -468,7 +468,7 @@ define ( 'NAMESPACE_YMEDIA', 'http://search.yahoo.com/mrss/' );
define ( 'ACTIVITYSTREAMS_JSONLD_REV', 'https://www.w3.org/ns/activitystreams' ); define ( 'ACTIVITYSTREAMS_JSONLD_REV', 'https://www.w3.org/ns/activitystreams' );
define ( 'ZOT_APSCHEMA_REV', '/apschema/v1.17' ); define ( 'ZOT_APSCHEMA_REV', '/apschema/v1.19' );
/** /**
* activity stream defines * activity stream defines

903
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -38,6 +38,7 @@ function z_mime_content_type($filename) {
'md' => 'text/markdown', 'md' => 'text/markdown',
'bb' => 'text/bbcode', 'bb' => 'text/bbcode',
'abc' => 'text/vnd.abc', 'abc' => 'text/vnd.abc',
'csv' => 'text/csv',
'js' => 'application/javascript', 'js' => 'application/javascript',
'json' => 'application/json', 'json' => 'application/json',
'xml' => 'application/xml', 'xml' => 'application/xml',
@ -2672,6 +2673,12 @@ function save_chunk($channel,$start,$end,$len) {
$new_path = $new_base . '/' . $_FILES['files']['name'] . '.ftmp'; $new_path = $new_base . '/' . $_FILES['files']['name'] . '.ftmp';
if(file_exists($new_path) && intval($start) === 0) {
$result['partial'] = true;
$result['length'] = intval(filesize($new_path));
return $result;
}
if(! file_exists($new_path)) { if(! file_exists($new_path)) {
rename($tmp_path,$new_path); rename($tmp_path,$new_path);
} }

View file

@ -958,6 +958,16 @@ function bb_imgoptions($match) {
} }
function bb_code_preprotect($matches) {
return '[code' . $matches[1] . ']' . 'b64.^8e%.' . base64_encode($matches[2]) . '.b64.$8e%' . '[/code]';
}
function bb_code_preunprotect($s) {
return preg_replace_callback('|b64\.\^8e\%\.(.*?)\.b64\.\$8e\%|ism','bb_code_unprotect_sub',$s);
}
function bb_code_protect($s) { function bb_code_protect($s) {
return 'b64.^9e%.' . base64_encode($s) . '.b64.$9e%'; return 'b64.^9e%.' . base64_encode($s) . '.b64.$9e%';
} }
@ -1295,8 +1305,11 @@ function bbcode($Text, $options = []) {
$Text = str_replace("\r\n", "\n", $Text); $Text = str_replace("\r\n", "\n", $Text);
// Perform some markdown conversions before translating linefeeds so as to keep the regexes manageable // save code blocks from being interpreted as markdown
$Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_preprotect', $Text);
// Perform some markdown conversions before translating linefeeds so as to keep the regexes manageable
$Text = preg_replace('#(?<!\\\)([*_]{3})([^\n]+?)\1#','<strong><em>$2</em></strong>',$Text); $Text = preg_replace('#(?<!\\\)([*_]{3})([^\n]+?)\1#','<strong><em>$2</em></strong>',$Text);
$Text = preg_replace('#(?<!\\\)([*_]{2})([^\n]+?)\1#','<strong>$2</strong>',$Text); $Text = preg_replace('#(?<!\\\)([*_]{2})([^\n]+?)\1#','<strong>$2</strong>',$Text);
@ -1316,6 +1329,7 @@ function bbcode($Text, $options = []) {
// links // links
$Text = preg_replace_callback('#!\[[^\]]*\]\((.*?)(?=\"|\))(\".*\")?\)(?!`)#','md_image',$Text); $Text = preg_replace_callback('#!\[[^\]]*\]\((.*?)(?=\"|\))(\".*\")?\)(?!`)#','md_image',$Text);
$Text = preg_replace('#\[([^\[]+)\]\((?:javascript:)?([^\)]+)\)(?!`)#','<a href="$2">$1</a>',$Text); $Text = preg_replace('#\[([^\[]+)\]\((?:javascript:)?([^\)]+)\)(?!`)#','<a href="$2">$1</a>',$Text);
// unordered lists // unordered lists
$Text = preg_replace('#^ *[*\-+] +(.*?)$#m','<ul><li>$1</li></ul>',$Text); $Text = preg_replace('#^ *[*\-+] +(.*?)$#m','<ul><li>$1</li></ul>',$Text);
// order lists // order lists
@ -1323,6 +1337,8 @@ function bbcode($Text, $options = []) {
$Text = preg_replace('/\s*<\/(ol|ul)>\n+<\1>\s*/',"\n",$Text); $Text = preg_replace('/\s*<\/(ol|ul)>\n+<\1>\s*/',"\n",$Text);
$Text = bb_code_preunprotect($Text);
// Convert new line chars to html <br> tags // Convert new line chars to html <br> tags
$Text = str_replace(array("\r", "\n"), array('<br>', '<br>'), $Text); $Text = str_replace(array("\r", "\n"), array('<br>', '<br>'), $Text);

View file

@ -12,6 +12,7 @@ use Zotlabs\Lib\SvgSanitizer;
use Zotlabs\Lib\Img_cache; use Zotlabs\Lib\Img_cache;
use Zotlabs\Lib\PConfig; use Zotlabs\Lib\PConfig;
use Zotlabs\Lib\Config; use Zotlabs\Lib\Config;
use Zotlabs\Lib\Activity;
use Michelf\MarkdownExtra; use Michelf\MarkdownExtra;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
@ -1457,8 +1458,13 @@ function format_hashtags(&$item) {
$term = htmlspecialchars($t['term'], ENT_COMPAT, 'UTF-8', false) ; $term = htmlspecialchars($t['term'], ENT_COMPAT, 'UTF-8', false) ;
if(! trim($term)) if(! trim($term))
continue; continue;
if($t['url'] && stripos($item['body'], $t['url']))
// Pleroma uses example.com/tags/xxx in the taglist but example.com/tag/xxx in the body. Possibly a bug because one of these leads to
// an error page, but it messes up our detection of whether the tag was already present in the body.
if($t['url'] && ((stripos($item['body'], $t['url']) !== false) || (stripos($item['body'], str_replace('/tags/','/tag/',$t['url']))))) {
continue; continue;
}
if($s) if($s)
$s .= ' '; $s .= ' ';
@ -1474,17 +1480,58 @@ function format_hashtags(&$item) {
function format_mentions(&$item) { function format_mentions(&$item) {
$s = ''; $s = '';
$pref = intval(PConfig::Get($item['uid'],'system','tag_username',Config::Get('system','tag_username',false)));
// hide "auto mentions" by default - this hidden pref let's you display them.
$show = intval(PConfig::Get($item['uid'],'system','show_auto_mentions',false));
if ((! $show) && (! $item['resource_type'])) {
return;
}
if ($pref === 127) {
return;
}
$terms = get_terms_oftype($item['term'],TERM_MENTION); $terms = get_terms_oftype($item['term'],TERM_MENTION);
if($terms) { if($terms) {
foreach($terms as $t) { foreach($terms as $t) {
$term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ;
if(! trim($term)) if(! trim($term))
continue; continue;
if(strpos($item['body'], urlencode($t['url'])))
if($t['url'] && stripos($item['body'], $t['url']) !== false)
continue; continue;
// some platforms put the identity url into href rather than the profile url. Accept either form.
$x = q("select * from xchan where xchan_url = '%s' or xchan_hash = '%s' limit 1",
dbesc($t['url']),
dbesc($t['url'])
);
if ($x) {
switch ($pref) {
case 0:
$txt = $x[0]['xchan_name'];
break;
case 1:
$txt = (($x[0]['xchan_addr']) ? $x[0]['xchan_addr'] : $x[0]['xchan_name']);
break;
case 2:
default;
if ($x[0]['xchan_addr']) {
$txt = sprintf( t('%1$s (%2$s)'), $x[0]['xchan_name'], $x[0]['xchan_addr']);
}
else {
$txt = $x[0]['xchan_name'];
}
break;
}
}
if($s) if($s)
$s .= ' '; $s .= ' ';
$s .= '<span class="badge badge-pill badge-success"><i class="fa fa-at"></i>&nbsp;<a class="text-white" href="' . zid(chanlink_url($t['url'])) . '" >' . $term . '</a></span>'; $s .= '<span class="badge badge-pill badge-success"><i class="fa fa-at"></i>&nbsp;<a class="text-white" href="' . zid(chanlink_url($t['url'])) . '" >' . $txt . '</a></span>';
} }
} }
@ -1681,7 +1728,6 @@ function prepare_body(&$item,$attach = false,$opts = false) {
$tags = format_hashtags($item); $tags = format_hashtags($item);
if($item['resource_type'])
$mentions = format_mentions($item); $mentions = format_mentions($item);
$categories = format_categories($item,$writeable); $categories = format_categories($item,$writeable);

View file

@ -6,8 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'ArithmeticError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php', 'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
'CommerceGuys\\Intl\\Calculator' => $vendorDir . '/commerceguys/intl/src/Calculator.php', 'CommerceGuys\\Intl\\Calculator' => $vendorDir . '/commerceguys/intl/src/Calculator.php',
'CommerceGuys\\Intl\\Country\\Country' => $vendorDir . '/commerceguys/intl/src/Country/Country.php', 'CommerceGuys\\Intl\\Country\\Country' => $vendorDir . '/commerceguys/intl/src/Country/Country.php',
'CommerceGuys\\Intl\\Country\\CountryEntityInterface' => $vendorDir . '/commerceguys/intl/src/Country/CountryEntityInterface.php', 'CommerceGuys\\Intl\\Country\\CountryEntityInterface' => $vendorDir . '/commerceguys/intl/src/Country/CountryEntityInterface.php',
@ -38,7 +37,6 @@ return array(
'CommerceGuys\\Intl\\NumberFormat\\NumberFormatInterface' => $vendorDir . '/commerceguys/intl/src/NumberFormat/NumberFormatInterface.php', 'CommerceGuys\\Intl\\NumberFormat\\NumberFormatInterface' => $vendorDir . '/commerceguys/intl/src/NumberFormat/NumberFormatInterface.php',
'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepository' => $vendorDir . '/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php', 'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepository' => $vendorDir . '/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php',
'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepositoryInterface' => $vendorDir . '/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php', 'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepositoryInterface' => $vendorDir . '/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php',
'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
'Doctrine\\Common\\Collections\\AbstractLazyCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php', 'Doctrine\\Common\\Collections\\AbstractLazyCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php',
'Doctrine\\Common\\Collections\\ArrayCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php', 'Doctrine\\Common\\Collections\\ArrayCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php',
'Doctrine\\Common\\Collections\\Collection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php', 'Doctrine\\Common\\Collections\\Collection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php',
@ -51,7 +49,6 @@ return array(
'Doctrine\\Common\\Collections\\Expr\\Value' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php', 'Doctrine\\Common\\Collections\\Expr\\Value' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php',
'Doctrine\\Common\\Collections\\ExpressionBuilder' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php', 'Doctrine\\Common\\Collections\\ExpressionBuilder' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php',
'Doctrine\\Common\\Collections\\Selectable' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php', 'Doctrine\\Common\\Collections\\Selectable' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php',
'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php',
'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php', 'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php',
'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php', 'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php',
'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', 'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php',
@ -85,8 +82,11 @@ return array(
'GuzzleHttp\\Promise\\AggregateException' => $vendorDir . '/guzzlehttp/promises/src/AggregateException.php', 'GuzzleHttp\\Promise\\AggregateException' => $vendorDir . '/guzzlehttp/promises/src/AggregateException.php',
'GuzzleHttp\\Promise\\CancellationException' => $vendorDir . '/guzzlehttp/promises/src/CancellationException.php', 'GuzzleHttp\\Promise\\CancellationException' => $vendorDir . '/guzzlehttp/promises/src/CancellationException.php',
'GuzzleHttp\\Promise\\Coroutine' => $vendorDir . '/guzzlehttp/promises/src/Coroutine.php', 'GuzzleHttp\\Promise\\Coroutine' => $vendorDir . '/guzzlehttp/promises/src/Coroutine.php',
'GuzzleHttp\\Promise\\Create' => $vendorDir . '/guzzlehttp/promises/src/Create.php',
'GuzzleHttp\\Promise\\Each' => $vendorDir . '/guzzlehttp/promises/src/Each.php',
'GuzzleHttp\\Promise\\EachPromise' => $vendorDir . '/guzzlehttp/promises/src/EachPromise.php', 'GuzzleHttp\\Promise\\EachPromise' => $vendorDir . '/guzzlehttp/promises/src/EachPromise.php',
'GuzzleHttp\\Promise\\FulfilledPromise' => $vendorDir . '/guzzlehttp/promises/src/FulfilledPromise.php', 'GuzzleHttp\\Promise\\FulfilledPromise' => $vendorDir . '/guzzlehttp/promises/src/FulfilledPromise.php',
'GuzzleHttp\\Promise\\Is' => $vendorDir . '/guzzlehttp/promises/src/Is.php',
'GuzzleHttp\\Promise\\Promise' => $vendorDir . '/guzzlehttp/promises/src/Promise.php', 'GuzzleHttp\\Promise\\Promise' => $vendorDir . '/guzzlehttp/promises/src/Promise.php',
'GuzzleHttp\\Promise\\PromiseInterface' => $vendorDir . '/guzzlehttp/promises/src/PromiseInterface.php', 'GuzzleHttp\\Promise\\PromiseInterface' => $vendorDir . '/guzzlehttp/promises/src/PromiseInterface.php',
'GuzzleHttp\\Promise\\PromisorInterface' => $vendorDir . '/guzzlehttp/promises/src/PromisorInterface.php', 'GuzzleHttp\\Promise\\PromisorInterface' => $vendorDir . '/guzzlehttp/promises/src/PromisorInterface.php',
@ -94,18 +94,23 @@ return array(
'GuzzleHttp\\Promise\\RejectionException' => $vendorDir . '/guzzlehttp/promises/src/RejectionException.php', 'GuzzleHttp\\Promise\\RejectionException' => $vendorDir . '/guzzlehttp/promises/src/RejectionException.php',
'GuzzleHttp\\Promise\\TaskQueue' => $vendorDir . '/guzzlehttp/promises/src/TaskQueue.php', 'GuzzleHttp\\Promise\\TaskQueue' => $vendorDir . '/guzzlehttp/promises/src/TaskQueue.php',
'GuzzleHttp\\Promise\\TaskQueueInterface' => $vendorDir . '/guzzlehttp/promises/src/TaskQueueInterface.php', 'GuzzleHttp\\Promise\\TaskQueueInterface' => $vendorDir . '/guzzlehttp/promises/src/TaskQueueInterface.php',
'GuzzleHttp\\Promise\\Utils' => $vendorDir . '/guzzlehttp/promises/src/Utils.php',
'GuzzleHttp\\Psr7\\AppendStream' => $vendorDir . '/guzzlehttp/psr7/src/AppendStream.php', 'GuzzleHttp\\Psr7\\AppendStream' => $vendorDir . '/guzzlehttp/psr7/src/AppendStream.php',
'GuzzleHttp\\Psr7\\BufferStream' => $vendorDir . '/guzzlehttp/psr7/src/BufferStream.php', 'GuzzleHttp\\Psr7\\BufferStream' => $vendorDir . '/guzzlehttp/psr7/src/BufferStream.php',
'GuzzleHttp\\Psr7\\CachingStream' => $vendorDir . '/guzzlehttp/psr7/src/CachingStream.php', 'GuzzleHttp\\Psr7\\CachingStream' => $vendorDir . '/guzzlehttp/psr7/src/CachingStream.php',
'GuzzleHttp\\Psr7\\DroppingStream' => $vendorDir . '/guzzlehttp/psr7/src/DroppingStream.php', 'GuzzleHttp\\Psr7\\DroppingStream' => $vendorDir . '/guzzlehttp/psr7/src/DroppingStream.php',
'GuzzleHttp\\Psr7\\FnStream' => $vendorDir . '/guzzlehttp/psr7/src/FnStream.php', 'GuzzleHttp\\Psr7\\FnStream' => $vendorDir . '/guzzlehttp/psr7/src/FnStream.php',
'GuzzleHttp\\Psr7\\Header' => $vendorDir . '/guzzlehttp/psr7/src/Header.php',
'GuzzleHttp\\Psr7\\InflateStream' => $vendorDir . '/guzzlehttp/psr7/src/InflateStream.php', 'GuzzleHttp\\Psr7\\InflateStream' => $vendorDir . '/guzzlehttp/psr7/src/InflateStream.php',
'GuzzleHttp\\Psr7\\LazyOpenStream' => $vendorDir . '/guzzlehttp/psr7/src/LazyOpenStream.php', 'GuzzleHttp\\Psr7\\LazyOpenStream' => $vendorDir . '/guzzlehttp/psr7/src/LazyOpenStream.php',
'GuzzleHttp\\Psr7\\LimitStream' => $vendorDir . '/guzzlehttp/psr7/src/LimitStream.php', 'GuzzleHttp\\Psr7\\LimitStream' => $vendorDir . '/guzzlehttp/psr7/src/LimitStream.php',
'GuzzleHttp\\Psr7\\Message' => $vendorDir . '/guzzlehttp/psr7/src/Message.php',
'GuzzleHttp\\Psr7\\MessageTrait' => $vendorDir . '/guzzlehttp/psr7/src/MessageTrait.php', 'GuzzleHttp\\Psr7\\MessageTrait' => $vendorDir . '/guzzlehttp/psr7/src/MessageTrait.php',
'GuzzleHttp\\Psr7\\MimeType' => $vendorDir . '/guzzlehttp/psr7/src/MimeType.php',
'GuzzleHttp\\Psr7\\MultipartStream' => $vendorDir . '/guzzlehttp/psr7/src/MultipartStream.php', 'GuzzleHttp\\Psr7\\MultipartStream' => $vendorDir . '/guzzlehttp/psr7/src/MultipartStream.php',
'GuzzleHttp\\Psr7\\NoSeekStream' => $vendorDir . '/guzzlehttp/psr7/src/NoSeekStream.php', 'GuzzleHttp\\Psr7\\NoSeekStream' => $vendorDir . '/guzzlehttp/psr7/src/NoSeekStream.php',
'GuzzleHttp\\Psr7\\PumpStream' => $vendorDir . '/guzzlehttp/psr7/src/PumpStream.php', 'GuzzleHttp\\Psr7\\PumpStream' => $vendorDir . '/guzzlehttp/psr7/src/PumpStream.php',
'GuzzleHttp\\Psr7\\Query' => $vendorDir . '/guzzlehttp/psr7/src/Query.php',
'GuzzleHttp\\Psr7\\Request' => $vendorDir . '/guzzlehttp/psr7/src/Request.php', 'GuzzleHttp\\Psr7\\Request' => $vendorDir . '/guzzlehttp/psr7/src/Request.php',
'GuzzleHttp\\Psr7\\Response' => $vendorDir . '/guzzlehttp/psr7/src/Response.php', 'GuzzleHttp\\Psr7\\Response' => $vendorDir . '/guzzlehttp/psr7/src/Response.php',
'GuzzleHttp\\Psr7\\Rfc7230' => $vendorDir . '/guzzlehttp/psr7/src/Rfc7230.php', 'GuzzleHttp\\Psr7\\Rfc7230' => $vendorDir . '/guzzlehttp/psr7/src/Rfc7230.php',
@ -117,6 +122,7 @@ return array(
'GuzzleHttp\\Psr7\\Uri' => $vendorDir . '/guzzlehttp/psr7/src/Uri.php', 'GuzzleHttp\\Psr7\\Uri' => $vendorDir . '/guzzlehttp/psr7/src/Uri.php',
'GuzzleHttp\\Psr7\\UriNormalizer' => $vendorDir . '/guzzlehttp/psr7/src/UriNormalizer.php', 'GuzzleHttp\\Psr7\\UriNormalizer' => $vendorDir . '/guzzlehttp/psr7/src/UriNormalizer.php',
'GuzzleHttp\\Psr7\\UriResolver' => $vendorDir . '/guzzlehttp/psr7/src/UriResolver.php', 'GuzzleHttp\\Psr7\\UriResolver' => $vendorDir . '/guzzlehttp/psr7/src/UriResolver.php',
'GuzzleHttp\\Psr7\\Utils' => $vendorDir . '/guzzlehttp/psr7/src/Utils.php',
'GuzzleHttp\\RedirectMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RedirectMiddleware.php', 'GuzzleHttp\\RedirectMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RedirectMiddleware.php',
'GuzzleHttp\\RequestOptions' => $vendorDir . '/guzzlehttp/guzzle/src/RequestOptions.php', 'GuzzleHttp\\RequestOptions' => $vendorDir . '/guzzlehttp/guzzle/src/RequestOptions.php',
'GuzzleHttp\\RetryMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RetryMiddleware.php', 'GuzzleHttp\\RetryMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RetryMiddleware.php',
@ -603,7 +609,6 @@ return array(
'PHPGit\\Command\\TreeCommand' => $vendorDir . '/kzykhys/git/src/PHPGit/Command/TreeCommand.php', 'PHPGit\\Command\\TreeCommand' => $vendorDir . '/kzykhys/git/src/PHPGit/Command/TreeCommand.php',
'PHPGit\\Exception\\GitException' => $vendorDir . '/kzykhys/git/src/PHPGit/Exception/GitException.php', 'PHPGit\\Exception\\GitException' => $vendorDir . '/kzykhys/git/src/PHPGit/Exception/GitException.php',
'PHPGit\\Git' => $vendorDir . '/kzykhys/git/src/PHPGit/Git.php', 'PHPGit\\Git' => $vendorDir . '/kzykhys/git/src/PHPGit/Git.php',
'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
'Psr\\Http\\Message\\MessageInterface' => $vendorDir . '/psr/http-message/src/MessageInterface.php', 'Psr\\Http\\Message\\MessageInterface' => $vendorDir . '/psr/http-message/src/MessageInterface.php',
'Psr\\Http\\Message\\RequestInterface' => $vendorDir . '/psr/http-message/src/RequestInterface.php', 'Psr\\Http\\Message\\RequestInterface' => $vendorDir . '/psr/http-message/src/RequestInterface.php',
'Psr\\Http\\Message\\ResponseInterface' => $vendorDir . '/psr/http-message/src/ResponseInterface.php', 'Psr\\Http\\Message\\ResponseInterface' => $vendorDir . '/psr/http-message/src/ResponseInterface.php',
@ -619,6 +624,9 @@ return array(
'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/DummyTest.php',
'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php',
'Ramsey\\Uuid\\BinaryUtils' => $vendorDir . '/ramsey/uuid/src/BinaryUtils.php', 'Ramsey\\Uuid\\BinaryUtils' => $vendorDir . '/ramsey/uuid/src/BinaryUtils.php',
'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php', 'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php', 'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
@ -1030,7 +1038,6 @@ return array(
'Sabre\\Xml\\Writer' => $vendorDir . '/sabre/xml/lib/Writer.php', 'Sabre\\Xml\\Writer' => $vendorDir . '/sabre/xml/lib/Writer.php',
'Sabre\\Xml\\XmlDeserializable' => $vendorDir . '/sabre/xml/lib/XmlDeserializable.php', 'Sabre\\Xml\\XmlDeserializable' => $vendorDir . '/sabre/xml/lib/XmlDeserializable.php',
'Sabre\\Xml\\XmlSerializable' => $vendorDir . '/sabre/xml/lib/XmlSerializable.php', 'Sabre\\Xml\\XmlSerializable' => $vendorDir . '/sabre/xml/lib/XmlSerializable.php',
'SessionUpdateTimestampHandlerInterface' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',
'Smarty' => $vendorDir . '/smarty/smarty/libs/Smarty.class.php', 'Smarty' => $vendorDir . '/smarty/smarty/libs/Smarty.class.php',
'SmartyBC' => $vendorDir . '/smarty/smarty/libs/SmartyBC.class.php', 'SmartyBC' => $vendorDir . '/smarty/smarty/libs/SmartyBC.class.php',
'SmartyCompilerException' => $vendorDir . '/smarty/smarty/libs/sysplugins/smartycompilerexception.php', 'SmartyCompilerException' => $vendorDir . '/smarty/smarty/libs/sysplugins/smartycompilerexception.php',
@ -1239,12 +1246,10 @@ return array(
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\DisallowedRanges' => $vendorDir . '/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php', 'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\DisallowedRanges' => $vendorDir . '/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php',
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => $vendorDir . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php', 'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => $vendorDir . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php',
'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php', 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php',
'Symfony\\Polyfill\\Php70\\Php70' => $vendorDir . '/symfony/polyfill-php70/Php70.php',
'Symfony\\Polyfill\\Php72\\Php72' => $vendorDir . '/symfony/polyfill-php72/Php72.php', 'Symfony\\Polyfill\\Php72\\Php72' => $vendorDir . '/symfony/polyfill-php72/Php72.php',
'Symfony\\Polyfill\\Php80\\Php80' => $vendorDir . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\Php80' => $vendorDir . '/symfony/polyfill-php80/Php80.php',
'TPC_yyStackEntry' => $vendorDir . '/smarty/smarty/libs/sysplugins/smarty_internal_configfileparser.php', 'TPC_yyStackEntry' => $vendorDir . '/smarty/smarty/libs/sysplugins/smarty_internal_configfileparser.php',
'TP_yyStackEntry' => $vendorDir . '/smarty/smarty/libs/sysplugins/smarty_internal_templateparser.php', 'TP_yyStackEntry' => $vendorDir . '/smarty/smarty/libs/sysplugins/smarty_internal_templateparser.php',
'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',
'URLify' => $vendorDir . '/jbroadway/urlify/URLify.php', 'URLify' => $vendorDir . '/jbroadway/urlify/URLify.php',
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'UploadHandler' => $vendorDir . '/blueimp/jquery-file-upload/server/php/UploadHandler.php', 'UploadHandler' => $vendorDir . '/blueimp/jquery-file-upload/server/php/UploadHandler.php',
@ -1257,7 +1262,6 @@ return array(
'Zotlabs\\Daemon\\CacheThumb' => $baseDir . '/Zotlabs/Daemon/CacheThumb.php', 'Zotlabs\\Daemon\\CacheThumb' => $baseDir . '/Zotlabs/Daemon/CacheThumb.php',
'Zotlabs\\Daemon\\Cache_embeds' => $baseDir . '/Zotlabs/Daemon/Cache_embeds.php', 'Zotlabs\\Daemon\\Cache_embeds' => $baseDir . '/Zotlabs/Daemon/Cache_embeds.php',
'Zotlabs\\Daemon\\Checksites' => $baseDir . '/Zotlabs/Daemon/Checksites.php', 'Zotlabs\\Daemon\\Checksites' => $baseDir . '/Zotlabs/Daemon/Checksites.php',
'Zotlabs\\Daemon\\Cli_suggest' => $baseDir . '/Zotlabs/Daemon/Cli_suggest.php',
'Zotlabs\\Daemon\\Convo' => $baseDir . '/Zotlabs/Daemon/Convo.php', 'Zotlabs\\Daemon\\Convo' => $baseDir . '/Zotlabs/Daemon/Convo.php',
'Zotlabs\\Daemon\\Cron' => $baseDir . '/Zotlabs/Daemon/Cron.php', 'Zotlabs\\Daemon\\Cron' => $baseDir . '/Zotlabs/Daemon/Cron.php',
'Zotlabs\\Daemon\\Cron_daily' => $baseDir . '/Zotlabs/Daemon/Cron_daily.php', 'Zotlabs\\Daemon\\Cron_daily' => $baseDir . '/Zotlabs/Daemon/Cron_daily.php',
@ -1320,6 +1324,7 @@ return array(
'Zotlabs\\Lib\\Markdown' => $baseDir . '/Zotlabs/Lib/Markdown.php', 'Zotlabs\\Lib\\Markdown' => $baseDir . '/Zotlabs/Lib/Markdown.php',
'Zotlabs\\Lib\\MarkdownSoap' => $baseDir . '/Zotlabs/Lib/MarkdownSoap.php', 'Zotlabs\\Lib\\MarkdownSoap' => $baseDir . '/Zotlabs/Lib/MarkdownSoap.php',
'Zotlabs\\Lib\\MessageFilter' => $baseDir . '/Zotlabs/Lib/MessageFilter.php', 'Zotlabs\\Lib\\MessageFilter' => $baseDir . '/Zotlabs/Lib/MessageFilter.php',
'Zotlabs\\Lib\\Nodeinfo' => $baseDir . '/Zotlabs/Lib/Nodeinfo.php',
'Zotlabs\\Lib\\PConfig' => $baseDir . '/Zotlabs/Lib/PConfig.php', 'Zotlabs\\Lib\\PConfig' => $baseDir . '/Zotlabs/Lib/PConfig.php',
'Zotlabs\\Lib\\Permcat' => $baseDir . '/Zotlabs/Lib/Permcat.php', 'Zotlabs\\Lib\\Permcat' => $baseDir . '/Zotlabs/Lib/Permcat.php',
'Zotlabs\\Lib\\PermissionDescription' => $baseDir . '/Zotlabs/Lib/PermissionDescription.php', 'Zotlabs\\Lib\\PermissionDescription' => $baseDir . '/Zotlabs/Lib/PermissionDescription.php',
@ -1483,7 +1488,6 @@ return array(
'Zotlabs\\Module\\Q' => $baseDir . '/Zotlabs/Module/Q.php', 'Zotlabs\\Module\\Q' => $baseDir . '/Zotlabs/Module/Q.php',
'Zotlabs\\Module\\Randprof' => $baseDir . '/Zotlabs/Module/Randprof.php', 'Zotlabs\\Module\\Randprof' => $baseDir . '/Zotlabs/Module/Randprof.php',
'Zotlabs\\Module\\React' => $baseDir . '/Zotlabs/Module/React.php', 'Zotlabs\\Module\\React' => $baseDir . '/Zotlabs/Module/React.php',
'Zotlabs\\Module\\Regdir' => $baseDir . '/Zotlabs/Module/Regdir.php',
'Zotlabs\\Module\\Register' => $baseDir . '/Zotlabs/Module/Register.php', 'Zotlabs\\Module\\Register' => $baseDir . '/Zotlabs/Module/Register.php',
'Zotlabs\\Module\\Regmod' => $baseDir . '/Zotlabs/Module/Regmod.php', 'Zotlabs\\Module\\Regmod' => $baseDir . '/Zotlabs/Module/Regmod.php',
'Zotlabs\\Module\\Regver' => $baseDir . '/Zotlabs/Module/Regver.php', 'Zotlabs\\Module\\Regver' => $baseDir . '/Zotlabs/Module/Regver.php',
@ -1521,6 +1525,7 @@ return array(
'Zotlabs\\Module\\Subthread' => $baseDir . '/Zotlabs/Module/Subthread.php', 'Zotlabs\\Module\\Subthread' => $baseDir . '/Zotlabs/Module/Subthread.php',
'Zotlabs\\Module\\Suggestions' => $baseDir . '/Zotlabs/Module/Suggestions.php', 'Zotlabs\\Module\\Suggestions' => $baseDir . '/Zotlabs/Module/Suggestions.php',
'Zotlabs\\Module\\Superblock' => $baseDir . '/Zotlabs/Module/Superblock.php', 'Zotlabs\\Module\\Superblock' => $baseDir . '/Zotlabs/Module/Superblock.php',
'Zotlabs\\Module\\Tagadelic' => $baseDir . '/Zotlabs/Module/Tagadelic.php',
'Zotlabs\\Module\\Tagger' => $baseDir . '/Zotlabs/Module/Tagger.php', 'Zotlabs\\Module\\Tagger' => $baseDir . '/Zotlabs/Module/Tagger.php',
'Zotlabs\\Module\\Tagrm' => $baseDir . '/Zotlabs/Module/Tagrm.php', 'Zotlabs\\Module\\Tagrm' => $baseDir . '/Zotlabs/Module/Tagrm.php',
'Zotlabs\\Module\\Tasks' => $baseDir . '/Zotlabs/Module/Tasks.php', 'Zotlabs\\Module\\Tasks' => $baseDir . '/Zotlabs/Module/Tasks.php',

View file

@ -8,7 +8,6 @@ $baseDir = dirname($vendorDir);
return array( return array(
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',

View file

@ -10,7 +10,6 @@ return array(
'Zotlabs\\' => array($baseDir . '/Zotlabs'), 'Zotlabs\\' => array($baseDir . '/Zotlabs'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'),
'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),

View file

@ -9,7 +9,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
public static $files = array ( public static $files = array (
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
@ -46,7 +45,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
array ( array (
'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Php80\\' => 23,
'Symfony\\Polyfill\\Php72\\' => 23, 'Symfony\\Polyfill\\Php72\\' => 23,
'Symfony\\Polyfill\\Php70\\' => 23,
'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33,
'Symfony\\Polyfill\\Intl\\Idn\\' => 26, 'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
'Symfony\\Polyfill\\Ctype\\' => 23, 'Symfony\\Polyfill\\Ctype\\' => 23,
@ -122,10 +120,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
array ( array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php72', 0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
), ),
'Symfony\\Polyfill\\Php70\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php70',
),
'Symfony\\Polyfill\\Intl\\Normalizer\\' => 'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
array ( array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer',
@ -282,8 +276,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
); );
public static $classMap = array ( public static $classMap = array (
'ArithmeticError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php', 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
'CommerceGuys\\Intl\\Calculator' => __DIR__ . '/..' . '/commerceguys/intl/src/Calculator.php', 'CommerceGuys\\Intl\\Calculator' => __DIR__ . '/..' . '/commerceguys/intl/src/Calculator.php',
'CommerceGuys\\Intl\\Country\\Country' => __DIR__ . '/..' . '/commerceguys/intl/src/Country/Country.php', 'CommerceGuys\\Intl\\Country\\Country' => __DIR__ . '/..' . '/commerceguys/intl/src/Country/Country.php',
'CommerceGuys\\Intl\\Country\\CountryEntityInterface' => __DIR__ . '/..' . '/commerceguys/intl/src/Country/CountryEntityInterface.php', 'CommerceGuys\\Intl\\Country\\CountryEntityInterface' => __DIR__ . '/..' . '/commerceguys/intl/src/Country/CountryEntityInterface.php',
@ -314,7 +307,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'CommerceGuys\\Intl\\NumberFormat\\NumberFormatInterface' => __DIR__ . '/..' . '/commerceguys/intl/src/NumberFormat/NumberFormatInterface.php', 'CommerceGuys\\Intl\\NumberFormat\\NumberFormatInterface' => __DIR__ . '/..' . '/commerceguys/intl/src/NumberFormat/NumberFormatInterface.php',
'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepository' => __DIR__ . '/..' . '/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php', 'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepository' => __DIR__ . '/..' . '/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php',
'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepositoryInterface' => __DIR__ . '/..' . '/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php', 'CommerceGuys\\Intl\\NumberFormat\\NumberFormatRepositoryInterface' => __DIR__ . '/..' . '/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php',
'DivisionByZeroError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
'Doctrine\\Common\\Collections\\AbstractLazyCollection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php', 'Doctrine\\Common\\Collections\\AbstractLazyCollection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php',
'Doctrine\\Common\\Collections\\ArrayCollection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php', 'Doctrine\\Common\\Collections\\ArrayCollection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php',
'Doctrine\\Common\\Collections\\Collection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php', 'Doctrine\\Common\\Collections\\Collection' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php',
@ -327,7 +319,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Doctrine\\Common\\Collections\\Expr\\Value' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php', 'Doctrine\\Common\\Collections\\Expr\\Value' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php',
'Doctrine\\Common\\Collections\\ExpressionBuilder' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php', 'Doctrine\\Common\\Collections\\ExpressionBuilder' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php',
'Doctrine\\Common\\Collections\\Selectable' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php', 'Doctrine\\Common\\Collections\\Selectable' => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php',
'Error' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/Error.php',
'GuzzleHttp\\Client' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Client.php', 'GuzzleHttp\\Client' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Client.php',
'GuzzleHttp\\ClientInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/ClientInterface.php', 'GuzzleHttp\\ClientInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/ClientInterface.php',
'GuzzleHttp\\Cookie\\CookieJar' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', 'GuzzleHttp\\Cookie\\CookieJar' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php',
@ -361,8 +352,11 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'GuzzleHttp\\Promise\\AggregateException' => __DIR__ . '/..' . '/guzzlehttp/promises/src/AggregateException.php', 'GuzzleHttp\\Promise\\AggregateException' => __DIR__ . '/..' . '/guzzlehttp/promises/src/AggregateException.php',
'GuzzleHttp\\Promise\\CancellationException' => __DIR__ . '/..' . '/guzzlehttp/promises/src/CancellationException.php', 'GuzzleHttp\\Promise\\CancellationException' => __DIR__ . '/..' . '/guzzlehttp/promises/src/CancellationException.php',
'GuzzleHttp\\Promise\\Coroutine' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Coroutine.php', 'GuzzleHttp\\Promise\\Coroutine' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Coroutine.php',
'GuzzleHttp\\Promise\\Create' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Create.php',
'GuzzleHttp\\Promise\\Each' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Each.php',
'GuzzleHttp\\Promise\\EachPromise' => __DIR__ . '/..' . '/guzzlehttp/promises/src/EachPromise.php', 'GuzzleHttp\\Promise\\EachPromise' => __DIR__ . '/..' . '/guzzlehttp/promises/src/EachPromise.php',
'GuzzleHttp\\Promise\\FulfilledPromise' => __DIR__ . '/..' . '/guzzlehttp/promises/src/FulfilledPromise.php', 'GuzzleHttp\\Promise\\FulfilledPromise' => __DIR__ . '/..' . '/guzzlehttp/promises/src/FulfilledPromise.php',
'GuzzleHttp\\Promise\\Is' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Is.php',
'GuzzleHttp\\Promise\\Promise' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Promise.php', 'GuzzleHttp\\Promise\\Promise' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Promise.php',
'GuzzleHttp\\Promise\\PromiseInterface' => __DIR__ . '/..' . '/guzzlehttp/promises/src/PromiseInterface.php', 'GuzzleHttp\\Promise\\PromiseInterface' => __DIR__ . '/..' . '/guzzlehttp/promises/src/PromiseInterface.php',
'GuzzleHttp\\Promise\\PromisorInterface' => __DIR__ . '/..' . '/guzzlehttp/promises/src/PromisorInterface.php', 'GuzzleHttp\\Promise\\PromisorInterface' => __DIR__ . '/..' . '/guzzlehttp/promises/src/PromisorInterface.php',
@ -370,18 +364,23 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'GuzzleHttp\\Promise\\RejectionException' => __DIR__ . '/..' . '/guzzlehttp/promises/src/RejectionException.php', 'GuzzleHttp\\Promise\\RejectionException' => __DIR__ . '/..' . '/guzzlehttp/promises/src/RejectionException.php',
'GuzzleHttp\\Promise\\TaskQueue' => __DIR__ . '/..' . '/guzzlehttp/promises/src/TaskQueue.php', 'GuzzleHttp\\Promise\\TaskQueue' => __DIR__ . '/..' . '/guzzlehttp/promises/src/TaskQueue.php',
'GuzzleHttp\\Promise\\TaskQueueInterface' => __DIR__ . '/..' . '/guzzlehttp/promises/src/TaskQueueInterface.php', 'GuzzleHttp\\Promise\\TaskQueueInterface' => __DIR__ . '/..' . '/guzzlehttp/promises/src/TaskQueueInterface.php',
'GuzzleHttp\\Promise\\Utils' => __DIR__ . '/..' . '/guzzlehttp/promises/src/Utils.php',
'GuzzleHttp\\Psr7\\AppendStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/AppendStream.php', 'GuzzleHttp\\Psr7\\AppendStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/AppendStream.php',
'GuzzleHttp\\Psr7\\BufferStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/BufferStream.php', 'GuzzleHttp\\Psr7\\BufferStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/BufferStream.php',
'GuzzleHttp\\Psr7\\CachingStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/CachingStream.php', 'GuzzleHttp\\Psr7\\CachingStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/CachingStream.php',
'GuzzleHttp\\Psr7\\DroppingStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/DroppingStream.php', 'GuzzleHttp\\Psr7\\DroppingStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/DroppingStream.php',
'GuzzleHttp\\Psr7\\FnStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/FnStream.php', 'GuzzleHttp\\Psr7\\FnStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/FnStream.php',
'GuzzleHttp\\Psr7\\Header' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Header.php',
'GuzzleHttp\\Psr7\\InflateStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/InflateStream.php', 'GuzzleHttp\\Psr7\\InflateStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/InflateStream.php',
'GuzzleHttp\\Psr7\\LazyOpenStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/LazyOpenStream.php', 'GuzzleHttp\\Psr7\\LazyOpenStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/LazyOpenStream.php',
'GuzzleHttp\\Psr7\\LimitStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/LimitStream.php', 'GuzzleHttp\\Psr7\\LimitStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/LimitStream.php',
'GuzzleHttp\\Psr7\\Message' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Message.php',
'GuzzleHttp\\Psr7\\MessageTrait' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/MessageTrait.php', 'GuzzleHttp\\Psr7\\MessageTrait' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/MessageTrait.php',
'GuzzleHttp\\Psr7\\MimeType' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/MimeType.php',
'GuzzleHttp\\Psr7\\MultipartStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/MultipartStream.php', 'GuzzleHttp\\Psr7\\MultipartStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/MultipartStream.php',
'GuzzleHttp\\Psr7\\NoSeekStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/NoSeekStream.php', 'GuzzleHttp\\Psr7\\NoSeekStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/NoSeekStream.php',
'GuzzleHttp\\Psr7\\PumpStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/PumpStream.php', 'GuzzleHttp\\Psr7\\PumpStream' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/PumpStream.php',
'GuzzleHttp\\Psr7\\Query' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Query.php',
'GuzzleHttp\\Psr7\\Request' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Request.php', 'GuzzleHttp\\Psr7\\Request' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Request.php',
'GuzzleHttp\\Psr7\\Response' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Response.php', 'GuzzleHttp\\Psr7\\Response' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Response.php',
'GuzzleHttp\\Psr7\\Rfc7230' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Rfc7230.php', 'GuzzleHttp\\Psr7\\Rfc7230' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Rfc7230.php',
@ -393,6 +392,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'GuzzleHttp\\Psr7\\Uri' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Uri.php', 'GuzzleHttp\\Psr7\\Uri' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Uri.php',
'GuzzleHttp\\Psr7\\UriNormalizer' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/UriNormalizer.php', 'GuzzleHttp\\Psr7\\UriNormalizer' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/UriNormalizer.php',
'GuzzleHttp\\Psr7\\UriResolver' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/UriResolver.php', 'GuzzleHttp\\Psr7\\UriResolver' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/UriResolver.php',
'GuzzleHttp\\Psr7\\Utils' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/Utils.php',
'GuzzleHttp\\RedirectMiddleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RedirectMiddleware.php', 'GuzzleHttp\\RedirectMiddleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RedirectMiddleware.php',
'GuzzleHttp\\RequestOptions' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RequestOptions.php', 'GuzzleHttp\\RequestOptions' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RequestOptions.php',
'GuzzleHttp\\RetryMiddleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RetryMiddleware.php', 'GuzzleHttp\\RetryMiddleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RetryMiddleware.php',
@ -879,7 +879,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'PHPGit\\Command\\TreeCommand' => __DIR__ . '/..' . '/kzykhys/git/src/PHPGit/Command/TreeCommand.php', 'PHPGit\\Command\\TreeCommand' => __DIR__ . '/..' . '/kzykhys/git/src/PHPGit/Command/TreeCommand.php',
'PHPGit\\Exception\\GitException' => __DIR__ . '/..' . '/kzykhys/git/src/PHPGit/Exception/GitException.php', 'PHPGit\\Exception\\GitException' => __DIR__ . '/..' . '/kzykhys/git/src/PHPGit/Exception/GitException.php',
'PHPGit\\Git' => __DIR__ . '/..' . '/kzykhys/git/src/PHPGit/Git.php', 'PHPGit\\Git' => __DIR__ . '/..' . '/kzykhys/git/src/PHPGit/Git.php',
'ParseError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
'Psr\\Http\\Message\\MessageInterface' => __DIR__ . '/..' . '/psr/http-message/src/MessageInterface.php', 'Psr\\Http\\Message\\MessageInterface' => __DIR__ . '/..' . '/psr/http-message/src/MessageInterface.php',
'Psr\\Http\\Message\\RequestInterface' => __DIR__ . '/..' . '/psr/http-message/src/RequestInterface.php', 'Psr\\Http\\Message\\RequestInterface' => __DIR__ . '/..' . '/psr/http-message/src/RequestInterface.php',
'Psr\\Http\\Message\\ResponseInterface' => __DIR__ . '/..' . '/psr/http-message/src/ResponseInterface.php', 'Psr\\Http\\Message\\ResponseInterface' => __DIR__ . '/..' . '/psr/http-message/src/ResponseInterface.php',
@ -895,6 +894,9 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php',
'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php',
'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php', 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php',
'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/DummyTest.php',
'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php',
'Ramsey\\Uuid\\BinaryUtils' => __DIR__ . '/..' . '/ramsey/uuid/src/BinaryUtils.php', 'Ramsey\\Uuid\\BinaryUtils' => __DIR__ . '/..' . '/ramsey/uuid/src/BinaryUtils.php',
'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php', 'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php', 'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
@ -1306,7 +1308,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Sabre\\Xml\\Writer' => __DIR__ . '/..' . '/sabre/xml/lib/Writer.php', 'Sabre\\Xml\\Writer' => __DIR__ . '/..' . '/sabre/xml/lib/Writer.php',
'Sabre\\Xml\\XmlDeserializable' => __DIR__ . '/..' . '/sabre/xml/lib/XmlDeserializable.php', 'Sabre\\Xml\\XmlDeserializable' => __DIR__ . '/..' . '/sabre/xml/lib/XmlDeserializable.php',
'Sabre\\Xml\\XmlSerializable' => __DIR__ . '/..' . '/sabre/xml/lib/XmlSerializable.php', 'Sabre\\Xml\\XmlSerializable' => __DIR__ . '/..' . '/sabre/xml/lib/XmlSerializable.php',
'SessionUpdateTimestampHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',
'Smarty' => __DIR__ . '/..' . '/smarty/smarty/libs/Smarty.class.php', 'Smarty' => __DIR__ . '/..' . '/smarty/smarty/libs/Smarty.class.php',
'SmartyBC' => __DIR__ . '/..' . '/smarty/smarty/libs/SmartyBC.class.php', 'SmartyBC' => __DIR__ . '/..' . '/smarty/smarty/libs/SmartyBC.class.php',
'SmartyCompilerException' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smartycompilerexception.php', 'SmartyCompilerException' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smartycompilerexception.php',
@ -1515,12 +1516,10 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\DisallowedRanges' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php', 'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\DisallowedRanges' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php',
'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php', 'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php',
'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php', 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php',
'Symfony\\Polyfill\\Php70\\Php70' => __DIR__ . '/..' . '/symfony/polyfill-php70/Php70.php',
'Symfony\\Polyfill\\Php72\\Php72' => __DIR__ . '/..' . '/symfony/polyfill-php72/Php72.php', 'Symfony\\Polyfill\\Php72\\Php72' => __DIR__ . '/..' . '/symfony/polyfill-php72/Php72.php',
'Symfony\\Polyfill\\Php80\\Php80' => __DIR__ . '/..' . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\Php80' => __DIR__ . '/..' . '/symfony/polyfill-php80/Php80.php',
'TPC_yyStackEntry' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smarty_internal_configfileparser.php', 'TPC_yyStackEntry' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smarty_internal_configfileparser.php',
'TP_yyStackEntry' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smarty_internal_templateparser.php', 'TP_yyStackEntry' => __DIR__ . '/..' . '/smarty/smarty/libs/sysplugins/smarty_internal_templateparser.php',
'TypeError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',
'URLify' => __DIR__ . '/..' . '/jbroadway/urlify/URLify.php', 'URLify' => __DIR__ . '/..' . '/jbroadway/urlify/URLify.php',
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'UploadHandler' => __DIR__ . '/..' . '/blueimp/jquery-file-upload/server/php/UploadHandler.php', 'UploadHandler' => __DIR__ . '/..' . '/blueimp/jquery-file-upload/server/php/UploadHandler.php',
@ -1533,7 +1532,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Zotlabs\\Daemon\\CacheThumb' => __DIR__ . '/../..' . '/Zotlabs/Daemon/CacheThumb.php', 'Zotlabs\\Daemon\\CacheThumb' => __DIR__ . '/../..' . '/Zotlabs/Daemon/CacheThumb.php',
'Zotlabs\\Daemon\\Cache_embeds' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cache_embeds.php', 'Zotlabs\\Daemon\\Cache_embeds' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cache_embeds.php',
'Zotlabs\\Daemon\\Checksites' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Checksites.php', 'Zotlabs\\Daemon\\Checksites' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Checksites.php',
'Zotlabs\\Daemon\\Cli_suggest' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cli_suggest.php',
'Zotlabs\\Daemon\\Convo' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Convo.php', 'Zotlabs\\Daemon\\Convo' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Convo.php',
'Zotlabs\\Daemon\\Cron' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cron.php', 'Zotlabs\\Daemon\\Cron' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cron.php',
'Zotlabs\\Daemon\\Cron_daily' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cron_daily.php', 'Zotlabs\\Daemon\\Cron_daily' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cron_daily.php',
@ -1596,6 +1594,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Zotlabs\\Lib\\Markdown' => __DIR__ . '/../..' . '/Zotlabs/Lib/Markdown.php', 'Zotlabs\\Lib\\Markdown' => __DIR__ . '/../..' . '/Zotlabs/Lib/Markdown.php',
'Zotlabs\\Lib\\MarkdownSoap' => __DIR__ . '/../..' . '/Zotlabs/Lib/MarkdownSoap.php', 'Zotlabs\\Lib\\MarkdownSoap' => __DIR__ . '/../..' . '/Zotlabs/Lib/MarkdownSoap.php',
'Zotlabs\\Lib\\MessageFilter' => __DIR__ . '/../..' . '/Zotlabs/Lib/MessageFilter.php', 'Zotlabs\\Lib\\MessageFilter' => __DIR__ . '/../..' . '/Zotlabs/Lib/MessageFilter.php',
'Zotlabs\\Lib\\Nodeinfo' => __DIR__ . '/../..' . '/Zotlabs/Lib/Nodeinfo.php',
'Zotlabs\\Lib\\PConfig' => __DIR__ . '/../..' . '/Zotlabs/Lib/PConfig.php', 'Zotlabs\\Lib\\PConfig' => __DIR__ . '/../..' . '/Zotlabs/Lib/PConfig.php',
'Zotlabs\\Lib\\Permcat' => __DIR__ . '/../..' . '/Zotlabs/Lib/Permcat.php', 'Zotlabs\\Lib\\Permcat' => __DIR__ . '/../..' . '/Zotlabs/Lib/Permcat.php',
'Zotlabs\\Lib\\PermissionDescription' => __DIR__ . '/../..' . '/Zotlabs/Lib/PermissionDescription.php', 'Zotlabs\\Lib\\PermissionDescription' => __DIR__ . '/../..' . '/Zotlabs/Lib/PermissionDescription.php',
@ -1759,7 +1758,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Zotlabs\\Module\\Q' => __DIR__ . '/../..' . '/Zotlabs/Module/Q.php', 'Zotlabs\\Module\\Q' => __DIR__ . '/../..' . '/Zotlabs/Module/Q.php',
'Zotlabs\\Module\\Randprof' => __DIR__ . '/../..' . '/Zotlabs/Module/Randprof.php', 'Zotlabs\\Module\\Randprof' => __DIR__ . '/../..' . '/Zotlabs/Module/Randprof.php',
'Zotlabs\\Module\\React' => __DIR__ . '/../..' . '/Zotlabs/Module/React.php', 'Zotlabs\\Module\\React' => __DIR__ . '/../..' . '/Zotlabs/Module/React.php',
'Zotlabs\\Module\\Regdir' => __DIR__ . '/../..' . '/Zotlabs/Module/Regdir.php',
'Zotlabs\\Module\\Register' => __DIR__ . '/../..' . '/Zotlabs/Module/Register.php', 'Zotlabs\\Module\\Register' => __DIR__ . '/../..' . '/Zotlabs/Module/Register.php',
'Zotlabs\\Module\\Regmod' => __DIR__ . '/../..' . '/Zotlabs/Module/Regmod.php', 'Zotlabs\\Module\\Regmod' => __DIR__ . '/../..' . '/Zotlabs/Module/Regmod.php',
'Zotlabs\\Module\\Regver' => __DIR__ . '/../..' . '/Zotlabs/Module/Regver.php', 'Zotlabs\\Module\\Regver' => __DIR__ . '/../..' . '/Zotlabs/Module/Regver.php',
@ -1797,6 +1795,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Zotlabs\\Module\\Subthread' => __DIR__ . '/../..' . '/Zotlabs/Module/Subthread.php', 'Zotlabs\\Module\\Subthread' => __DIR__ . '/../..' . '/Zotlabs/Module/Subthread.php',
'Zotlabs\\Module\\Suggestions' => __DIR__ . '/../..' . '/Zotlabs/Module/Suggestions.php', 'Zotlabs\\Module\\Suggestions' => __DIR__ . '/../..' . '/Zotlabs/Module/Suggestions.php',
'Zotlabs\\Module\\Superblock' => __DIR__ . '/../..' . '/Zotlabs/Module/Superblock.php', 'Zotlabs\\Module\\Superblock' => __DIR__ . '/../..' . '/Zotlabs/Module/Superblock.php',
'Zotlabs\\Module\\Tagadelic' => __DIR__ . '/../..' . '/Zotlabs/Module/Tagadelic.php',
'Zotlabs\\Module\\Tagger' => __DIR__ . '/../..' . '/Zotlabs/Module/Tagger.php', 'Zotlabs\\Module\\Tagger' => __DIR__ . '/../..' . '/Zotlabs/Module/Tagger.php',
'Zotlabs\\Module\\Tagrm' => __DIR__ . '/../..' . '/Zotlabs/Module/Tagrm.php', 'Zotlabs\\Module\\Tagrm' => __DIR__ . '/../..' . '/Zotlabs/Module/Tagrm.php',
'Zotlabs\\Module\\Tasks' => __DIR__ . '/../..' . '/Zotlabs/Module/Tasks.php', 'Zotlabs\\Module\\Tasks' => __DIR__ . '/../..' . '/Zotlabs/Module/Tasks.php',

View file

@ -407,26 +407,26 @@
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
"version": "v1.3.1", "version": "1.4.0",
"version_normalized": "1.3.1.0", "version_normalized": "1.4.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/promises.git", "url": "https://github.com/guzzle/promises.git",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" "reference": "60d379c243457e073cff02bc323a2a86cb355631"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", "reference": "60d379c243457e073cff02bc323a2a86cb355631",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.5.0" "php": ">=5.5"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.0" "symfony/phpunit-bridge": "^4.4 || ^5.1"
}, },
"time": "2016-12-20T10:07:11+00:00", "time": "2020-09-30T07:37:28+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -460,17 +460,17 @@
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
"version": "1.6.1", "version": "1.7.0",
"version_normalized": "1.6.1.0", "version_normalized": "1.7.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/psr7.git", "url": "https://github.com/guzzle/psr7.git",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a" "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a", "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -483,16 +483,16 @@
}, },
"require-dev": { "require-dev": {
"ext-zlib": "*", "ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
}, },
"suggest": { "suggest": {
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
}, },
"time": "2019-07-01T23:21:34+00:00", "time": "2020-09-30T07:37:11+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.6-dev" "dev-master": "1.7-dev"
} }
}, },
"installation-source": "dist", "installation-source": "dist",
@ -891,17 +891,17 @@
}, },
{ {
"name": "league/mime-type-detection", "name": "league/mime-type-detection",
"version": "1.5.0", "version": "1.5.1",
"version_normalized": "1.5.0.0", "version_normalized": "1.5.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git", "url": "https://github.com/thephpleague/mime-type-detection.git",
"reference": "ea2fbfc988bade315acd5967e6d02274086d0f28" "reference": "353f66d7555d8a90781f6f5e7091932f9a4250aa"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ea2fbfc988bade315acd5967e6d02274086d0f28", "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/353f66d7555d8a90781f6f5e7091932f9a4250aa",
"reference": "ea2fbfc988bade315acd5967e6d02274086d0f28", "reference": "353f66d7555d8a90781f6f5e7091932f9a4250aa",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -912,7 +912,7 @@
"phpstan/phpstan": "^0.12.36", "phpstan/phpstan": "^0.12.36",
"phpunit/phpunit": "^8.5.8" "phpunit/phpunit": "^8.5.8"
}, },
"time": "2020-09-21T18:10:53+00:00", "time": "2020-10-18T11:50:25+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -944,32 +944,31 @@
}, },
{ {
"name": "league/oauth2-client", "name": "league/oauth2-client",
"version": "2.5.0", "version": "2.6.0",
"version_normalized": "2.5.0.0", "version_normalized": "2.6.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/oauth2-client.git", "url": "https://github.com/thephpleague/oauth2-client.git",
"reference": "d9f2a1e000dc14eb3c02e15d15759385ec7ff0fb" "reference": "badb01e62383430706433191b82506b6df24ad98"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/d9f2a1e000dc14eb3c02e15d15759385ec7ff0fb", "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/badb01e62383430706433191b82506b6df24ad98",
"reference": "d9f2a1e000dc14eb3c02e15d15759385ec7ff0fb", "reference": "badb01e62383430706433191b82506b6df24ad98",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"guzzlehttp/guzzle": "^6.0 || ^7.0", "guzzlehttp/guzzle": "^6.0 || ^7.0",
"paragonie/random_compat": "^1|^2|^9.99", "paragonie/random_compat": "^1 || ^2 || ^9.99",
"php": "^5.6|^7.0" "php": "^5.6 || ^7.0 || ^8.0"
}, },
"require-dev": { "require-dev": {
"eloquent/liberator": "^2.0", "mockery/mockery": "^1.3",
"eloquent/phony-phpunit": "^1.0|^3.0", "php-parallel-lint/php-parallel-lint": "^1.2",
"jakub-onderka/php-parallel-lint": "^0.9.2", "phpunit/phpunit": "^5.7 || ^6.0 || ^9.3",
"phpunit/phpunit": "^5.7|^6.0", "squizlabs/php_codesniffer": "^2.3 || ^3.0"
"squizlabs/php_codesniffer": "^2.3|^3.0"
}, },
"time": "2020-07-18T17:54:32+00:00", "time": "2020-10-28T02:03:40+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -1013,17 +1012,17 @@
}, },
{ {
"name": "league/oauth2-facebook", "name": "league/oauth2-facebook",
"version": "2.0.2", "version": "2.0.3",
"version_normalized": "2.0.2.0", "version_normalized": "2.0.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/oauth2-facebook.git", "url": "https://github.com/thephpleague/oauth2-facebook.git",
"reference": "c482a851c93a6cb718270773635d6a0c8384b560" "reference": "093cf588b9d508ee426c71d6bc68f138fe914ddc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth2-facebook/zipball/c482a851c93a6cb718270773635d6a0c8384b560", "url": "https://api.github.com/repos/thephpleague/oauth2-facebook/zipball/093cf588b9d508ee426c71d6bc68f138fe914ddc",
"reference": "c482a851c93a6cb718270773635d6a0c8384b560", "reference": "093cf588b9d508ee426c71d6bc68f138fe914ddc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1036,7 +1035,7 @@
"phpunit/phpunit": "^5.7|^6.0", "phpunit/phpunit": "^5.7|^6.0",
"squizlabs/php_codesniffer": "~3.0" "squizlabs/php_codesniffer": "~3.0"
}, },
"time": "2020-07-25T13:30:06+00:00", "time": "2020-10-01T15:22:47+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -1293,17 +1292,17 @@
}, },
{ {
"name": "masterminds/html5", "name": "masterminds/html5",
"version": "2.7.3", "version": "2.7.4",
"version_normalized": "2.7.3.0", "version_normalized": "2.7.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Masterminds/html5-php.git", "url": "https://github.com/Masterminds/html5-php.git",
"reference": "aad73dbfefd71d46072138109ce1288d96c329cc" "reference": "9227822783c75406cfe400984b2f095cdf03d417"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/aad73dbfefd71d46072138109ce1288d96c329cc", "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/9227822783c75406cfe400984b2f095cdf03d417",
"reference": "aad73dbfefd71d46072138109ce1288d96c329cc", "reference": "9227822783c75406cfe400984b2f095cdf03d417",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1313,11 +1312,9 @@
"php": ">=5.3.0" "php": ">=5.3.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8.35", "phpunit/phpunit": "^4.8.35"
"sami/sami": "~2.0",
"satooshi/php-coveralls": "1.0.*"
}, },
"time": "2020-07-05T07:53:37+00:00", "time": "2020-10-01T13:52:52+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -2449,17 +2446,17 @@
}, },
{ {
"name": "symfony/options-resolver", "name": "symfony/options-resolver",
"version": "v5.1.5", "version": "v5.1.8",
"version_normalized": "5.1.5.0", "version_normalized": "5.1.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/options-resolver.git", "url": "https://github.com/symfony/options-resolver.git",
"reference": "9ff59517938f88d90b6e65311fef08faa640f681" "reference": "c6a02905e4ffc7a1498e8ee019db2b477cd1cc02"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/9ff59517938f88d90b6e65311fef08faa640f681", "url": "https://api.github.com/repos/symfony/options-resolver/zipball/c6a02905e4ffc7a1498e8ee019db2b477cd1cc02",
"reference": "9ff59517938f88d90b6e65311fef08faa640f681", "reference": "c6a02905e4ffc7a1498e8ee019db2b477cd1cc02",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2467,13 +2464,8 @@
"symfony/deprecation-contracts": "^2.1", "symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-php80": "^1.15" "symfony/polyfill-php80": "^1.15"
}, },
"time": "2020-07-12T12:58:00+00:00", "time": "2020-10-24T12:01:57+00:00",
"type": "library", "type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.1-dev"
}
},
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -2521,30 +2513,30 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.18.1", "version": "v1.20.0",
"version_normalized": "1.18.1.0", "version_normalized": "1.20.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "1c302646f6efc070cd46856e600e5e0684d6b454" "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41",
"reference": "1c302646f6efc070cd46856e600e5e0684d6b454", "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=7.1"
}, },
"suggest": { "suggest": {
"ext-ctype": "For best performance" "ext-ctype": "For best performance"
}, },
"time": "2020-07-14T12:35:20+00:00", "time": "2020-10-23T14:02:19+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.18-dev" "dev-main": "1.20-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -2599,33 +2591,32 @@
}, },
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
"version": "v1.18.1", "version": "v1.20.0",
"version_normalized": "1.18.1.0", "version_normalized": "1.20.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git", "url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251" "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/5dcab1bc7146cf8c1beaa4502a3d9be344334251", "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3b75acd829741c768bc8b1f84eb33265e7cc5117",
"reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251", "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3", "php": ">=7.1",
"symfony/polyfill-intl-normalizer": "^1.10", "symfony/polyfill-intl-normalizer": "^1.10",
"symfony/polyfill-php70": "^1.10",
"symfony/polyfill-php72": "^1.10" "symfony/polyfill-php72": "^1.10"
}, },
"suggest": { "suggest": {
"ext-intl": "For best performance" "ext-intl": "For best performance"
}, },
"time": "2020-08-04T06:02:08+00:00", "time": "2020-10-23T14:02:19+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.18-dev" "dev-main": "1.20-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -2686,30 +2677,30 @@
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.18.1", "version": "v1.20.0",
"version_normalized": "1.18.1.0", "version_normalized": "1.20.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e" "reference": "727d1096295d807c309fb01a851577302394c897"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897",
"reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", "reference": "727d1096295d807c309fb01a851577302394c897",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=7.1"
}, },
"suggest": { "suggest": {
"ext-intl": "For best performance" "ext-intl": "For best performance"
}, },
"time": "2020-07-14T12:35:20+00:00", "time": "2020-10-23T14:02:19+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.18-dev" "dev-main": "1.20-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -2767,108 +2758,29 @@
} }
] ]
}, },
{
"name": "symfony/polyfill-php70",
"version": "v1.18.1",
"version_normalized": "1.18.1.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php70.git",
"reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0dd93f2c578bdc9c72697eaa5f1dd25644e618d3",
"reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3",
"shasum": ""
},
"require": {
"paragonie/random_compat": "~1.0|~2.0|~9.99",
"php": ">=5.3.3"
},
"time": "2020-07-14T12:35:20+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.18-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php70\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
]
},
{ {
"name": "symfony/polyfill-php72", "name": "symfony/polyfill-php72",
"version": "v1.18.1", "version": "v1.20.0",
"version_normalized": "1.18.1.0", "version_normalized": "1.20.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php72.git", "url": "https://github.com/symfony/polyfill-php72.git",
"reference": "639447d008615574653fb3bc60d1986d7172eaae" "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/639447d008615574653fb3bc60d1986d7172eaae", "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930",
"reference": "639447d008615574653fb3bc60d1986d7172eaae", "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=7.1"
}, },
"time": "2020-07-14T12:35:20+00:00", "time": "2020-10-23T14:02:19+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.18-dev" "dev-main": "1.20-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -2923,27 +2835,27 @@
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.18.1", "version": "v1.20.0",
"version_normalized": "1.18.1.0", "version_normalized": "1.20.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981" "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/d87d5766cbf48d72388a9f6b85f280c8ad51f981", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981", "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.0.8" "php": ">=7.1"
}, },
"time": "2020-07-14T12:35:20+00:00", "time": "2020-10-23T14:02:19+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.18-dev" "dev-main": "1.20-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -3005,30 +2917,25 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v5.1.5", "version": "v5.1.8",
"version_normalized": "5.1.5.0", "version_normalized": "5.1.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "1864216226af21eb76d9477f691e7cbf198e0402" "reference": "f00872c3f6804150d6a0f73b4151daab96248101"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/1864216226af21eb76d9477f691e7cbf198e0402", "url": "https://api.github.com/repos/symfony/process/zipball/f00872c3f6804150d6a0f73b4151daab96248101",
"reference": "1864216226af21eb76d9477f691e7cbf198e0402", "reference": "f00872c3f6804150d6a0f73b4151daab96248101",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.2.5", "php": ">=7.2.5",
"symfony/polyfill-php80": "^1.15" "symfony/polyfill-php80": "^1.15"
}, },
"time": "2020-07-23T08:36:24+00:00", "time": "2020-10-24T12:01:57+00:00",
"type": "library", "type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.1-dev"
}
},
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -3124,29 +3031,29 @@
}, },
{ {
"name": "voku/portable-ascii", "name": "voku/portable-ascii",
"version": "1.5.3", "version": "1.5.4",
"version_normalized": "1.5.3.0", "version_normalized": "1.5.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/voku/portable-ascii.git", "url": "https://github.com/voku/portable-ascii.git",
"reference": "25bcbf01678930251fd572891447d9e318a6e2b8" "reference": "87dc337d4200b32717dd3849fea846319e897658"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/voku/portable-ascii/zipball/25bcbf01678930251fd572891447d9e318a6e2b8", "url": "https://api.github.com/repos/voku/portable-ascii/zipball/87dc337d4200b32717dd3849fea846319e897658",
"reference": "25bcbf01678930251fd572891447d9e318a6e2b8", "reference": "87dc337d4200b32717dd3849fea846319e897658",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.0.0" "php": ">=7.0.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~6.0 || ~7.0" "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
}, },
"suggest": { "suggest": {
"ext-intl": "Use Intl for transliterator_transliterate() support" "ext-intl": "Use Intl for transliterator_transliterate() support"
}, },
"time": "2020-07-22T23:32:04+00:00", "time": "2020-11-08T21:15:15+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {

88
vendor/guzzlehttp/promises/.php_cs.dist vendored Normal file
View file

@ -0,0 +1,88 @@
<?php
$config = PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => ['operators' => ['=>' => null]],
'blank_line_after_opening_tag' => true,
'class_attributes_separation' => ['elements' => ['method']],
'compact_nullable_typehint' => true,
'concat_space' => ['spacing' => 'one'],
'declare_equal_normalize' => ['space' => 'none'],
'declare_strict_types' => false,
'dir_constant' => true,
'final_static_access' => true,
'fully_qualified_strict_types' => true,
'function_to_constant' => true,
'function_typehint_space' => true,
'header_comment' => false,
'is_null' => ['use_yoda_style' => false],
'list_syntax' => ['syntax' => 'short'],
'lowercase_cast' => true,
'magic_method_casing' => true,
'modernize_types_casting' => true,
'multiline_comment_opening_closing' => true,
//'native_constant_invocation' => true,
'no_alias_functions' => true,
'no_alternative_syntax' => true,
'no_blank_lines_after_phpdoc' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_extra_blank_lines' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_spaces_around_offset' => true,
'no_superfluous_phpdoc_tags' => ['allow_mixed' => true],
'no_trailing_comma_in_singleline_array' => true,
'no_unneeded_control_parentheses' => true,
'no_unset_cast' => true,
'no_unused_imports' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'no_whitespace_in_blank_line' => true,
'normalize_index_brace' => true,
'ordered_imports' => true,
'php_unit_construct' => true,
'php_unit_dedicate_assert' => ['target' => 'newest'],
'php_unit_dedicate_assert_internal_type' => ['target' => 'newest'],
'php_unit_expectation' => ['target' => 'newest'],
'php_unit_mock' => ['target' => 'newest'],
'php_unit_mock_short_will_return' => true,
'php_unit_no_expectation_annotation' => ['target' => 'newest'],
'php_unit_test_annotation' => ['style' => 'prefix'],
//'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'phpdoc_align' => ['align' => 'vertical'],
//'phpdoc_line_span' => ['method' => 'multi', 'property' => 'multi'],
'phpdoc_no_package' => true,
'phpdoc_no_useless_inheritdoc' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_trim' => true,
'phpdoc_trim_consecutive_blank_line_separation' => true,
'phpdoc_types' => true,
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
'phpdoc_var_without_name' => true,
'return_assignment' => true,
'short_scalar_cast' => true,
'single_trait_insert_per_statement' => true,
'standardize_not_equals' => true,
//'static_lambda' => true,
'ternary_to_null_coalescing' => true,
'trim_array_spaces' => true,
'visibility_required' => true,
'yoda_style' => false,
// 'native_function_invocation' => true,
'braces' => ['allow_single_line_closure'=>true],
])
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
->in(__DIR__.'/tests')
->name('*.php')
)
;
return $config;

View file

@ -1,6 +1,22 @@
# CHANGELOG # CHANGELOG
## 1.4.0 - 2020-09-30
### Added
- Support for PHP 8
- Optional `$recursive` flag to `all`
- Replaced functions by static methods
### Fixed
- Fix empty `each` processing
- Fix promise handling for Iterators of non-unique keys
- Fixed `method_exists` crashes on PHP 8
- Memory leak on exceptions
## 1.3.1 - 2016-12-20 ## 1.3.1 - 2016-12-20
### Fixed ### Fixed

View file

@ -26,7 +26,7 @@ for a general introduction to promises.
- Promises can be cancelled. - Promises can be cancelled.
- Works with any object that has a `then` function. - Works with any object that has a `then` function.
- C# style async/await coroutine promises using - C# style async/await coroutine promises using
`GuzzleHttp\Promise\coroutine()`. `GuzzleHttp\Promise\Coroutine::of()`.
# Quick start # Quick start
@ -88,7 +88,7 @@ $promise
}); });
// Resolving the promise triggers the $onFulfilled callbacks and outputs // Resolving the promise triggers the $onFulfilled callbacks and outputs
// "Hello, reader". // "Hello, reader."
$promise->resolve('reader.'); $promise->resolve('reader.');
``` ```
@ -150,7 +150,7 @@ use GuzzleHttp\Promise\Promise;
$promise = new Promise(); $promise = new Promise();
$promise->then(null, function ($reason) { $promise->then(null, function ($reason) {
throw new \Exception($reason); throw new Exception($reason);
})->then(null, function ($reason) { })->then(null, function ($reason) {
assert($reason->getMessage() === 'Error!'); assert($reason->getMessage() === 'Error!');
}); });
@ -182,7 +182,6 @@ invoked using the value returned from the `$onRejected` callback.
```php ```php
use GuzzleHttp\Promise\Promise; use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
$promise = new Promise(); $promise = new Promise();
$promise $promise
@ -220,7 +219,7 @@ the promise is rejected with the exception and the exception is thrown.
```php ```php
$promise = new Promise(function () use (&$promise) { $promise = new Promise(function () use (&$promise) {
throw new \Exception('foo'); throw new Exception('foo');
}); });
$promise->wait(); // throws the exception. $promise->wait(); // throws the exception.
@ -397,7 +396,7 @@ $deferred = new React\Promise\Deferred();
$reactPromise = $deferred->promise(); $reactPromise = $deferred->promise();
// Create a Guzzle promise that is fulfilled with a React promise. // Create a Guzzle promise that is fulfilled with a React promise.
$guzzlePromise = new \GuzzleHttp\Promise\Promise(); $guzzlePromise = new GuzzleHttp\Promise\Promise();
$guzzlePromise->then(function ($value) use ($reactPromise) { $guzzlePromise->then(function ($value) use ($reactPromise) {
// Do something something with the value... // Do something something with the value...
// Return the React promise // Return the React promise
@ -424,7 +423,7 @@ instance.
```php ```php
// Get the global task queue // Get the global task queue
$queue = \GuzzleHttp\Promise\queue(); $queue = GuzzleHttp\Promise\Utils::queue();
$queue->run(); $queue->run();
``` ```
@ -502,3 +501,32 @@ $promise->then(function ($value) { echo $value; });
$promise->resolve('foo'); $promise->resolve('foo');
// prints "foo" // prints "foo"
``` ```
## Upgrading from Function API
A static API was first introduced in 1.4.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience:
| Original Function | Replacement Method |
|----------------|----------------|
| `queue` | `Utils::queue` |
| `task` | `Utils::task` |
| `promise_for` | `Create::promiseFor` |
| `rejection_for` | `Create::rejectionFor` |
| `exception_for` | `Create::exceptionFor` |
| `iter_for` | `Create::iterFor` |
| `inspect` | `Utils::inspect` |
| `inspect_all` | `Utils::inspectAll` |
| `unwrap` | `Utils::unwrap` |
| `all` | `Utils::all` |
| `some` | `Utils::some` |
| `any` | `Utils::any` |
| `settle` | `Utils::settle` |
| `each` | `Each::of` |
| `each_limit` | `Each::ofLimit` |
| `each_limit_all` | `Each::ofLimitAll` |
| `!is_fulfilled` | `Is::pending` |
| `is_fulfilled` | `Is::fulfilled` |
| `is_rejected` | `Is::rejected` |
| `is_settled` | `Is::settled` |
| `coroutine` | `Coroutine::of` |

View file

@ -11,10 +11,10 @@
} }
], ],
"require": { "require": {
"php": ">=5.5.0" "php": ">=5.5"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.0" "symfony/phpunit-bridge": "^4.4 || ^5.1"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -22,9 +22,14 @@
}, },
"files": ["src/functions_include.php"] "files": ["src/functions_include.php"]
}, },
"autoload-dev": {
"psr-4": {
"GuzzleHttp\\Promise\\Tests\\": "tests/"
}
},
"scripts": { "scripts": {
"test": "vendor/bin/phpunit", "test": "vendor/bin/simple-phpunit",
"test-ci": "vendor/bin/phpunit --coverage-text" "test-ci": "vendor/bin/simple-phpunit --coverage-text"
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {

View file

@ -0,0 +1,7 @@
parameters:
ignoreErrors:
-
message: "#^Parameter \\#1 \\$function of function register_shutdown_function expects callable\\(\\)\\: void, Closure\\(\\)\\: mixed given\\.$#"
count: 1
path: src/TaskQueue.php

View file

@ -0,0 +1,10 @@
includes:
- phpstan-baseline.neon
parameters:
level: 5
paths:
- src
ignoreErrors:
- "#^Dead catch - Exception is already caught by Throwable above\\.$#"

15
vendor/guzzlehttp/promises/psalm.xml vendored Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<psalm
errorLevel="4"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
use Exception; use Exception;
@ -9,7 +10,7 @@ use Throwable;
* Creates a promise that is resolved using a generator that yields values or * Creates a promise that is resolved using a generator that yields values or
* promises (somewhat similar to C#'s async keyword). * promises (somewhat similar to C#'s async keyword).
* *
* When called, the coroutine function will start an instance of the generator * When called, the Coroutine::of method will start an instance of the generator
* and returns a promise that is fulfilled with its final yielded value. * and returns a promise that is fulfilled with its final yielded value.
* *
* Control is returned back to the generator when the yielded promise settles. * Control is returned back to the generator when the yielded promise settles.
@ -22,7 +23,7 @@ use Throwable;
* return new Promise\FulfilledPromise($value); * return new Promise\FulfilledPromise($value);
* } * }
* *
* $promise = Promise\coroutine(function () { * $promise = Promise\Coroutine::of(function () {
* $value = (yield createPromise('a')); * $value = (yield createPromise('a'));
* try { * try {
* $value = (yield createPromise($value . 'b')); * $value = (yield createPromise($value . 'b'));
@ -38,6 +39,7 @@ use Throwable;
* @param callable $generatorFn Generator function to wrap into a promise. * @param callable $generatorFn Generator function to wrap into a promise.
* *
* @return Promise * @return Promise
*
* @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
*/ */
final class Coroutine implements PromiseInterface final class Coroutine implements PromiseInterface
@ -65,7 +67,23 @@ final class Coroutine implements PromiseInterface
$this->currentPromise->wait(); $this->currentPromise->wait();
} }
}); });
try {
$this->nextCoroutine($this->generator->current()); $this->nextCoroutine($this->generator->current());
} catch (\Exception $exception) {
$this->result->reject($exception);
} catch (Throwable $throwable) {
$this->result->reject($throwable);
}
}
/**
* Create a new coroutine.
*
* @return self
*/
public static function of(callable $generatorFn)
{
return new self($generatorFn);
} }
public function then( public function then(
@ -108,7 +126,7 @@ final class Coroutine implements PromiseInterface
private function nextCoroutine($yielded) private function nextCoroutine($yielded)
{ {
$this->currentPromise = promise_for($yielded) $this->currentPromise = Create::promiseFor($yielded)
->then([$this, '_handleSuccess'], [$this, '_handleFailure']); ->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
} }
@ -139,7 +157,7 @@ final class Coroutine implements PromiseInterface
{ {
unset($this->currentPromise); unset($this->currentPromise);
try { try {
$nextYield = $this->generator->throw(exception_for($reason)); $nextYield = $this->generator->throw(Create::exceptionFor($reason));
// The throw was caught, so keep iterating on the coroutine // The throw was caught, so keep iterating on the coroutine
$this->nextCoroutine($nextYield); $this->nextCoroutine($nextYield);
} catch (Exception $exception) { } catch (Exception $exception) {

View file

@ -0,0 +1,84 @@
<?php
namespace GuzzleHttp\Promise;
final class Create
{
/**
* Creates a promise for a value if the value is not a promise.
*
* @param mixed $value Promise or value.
*
* @return PromiseInterface
*/
public static function promiseFor($value)
{
if ($value instanceof PromiseInterface) {
return $value;
}
// Return a Guzzle promise that shadows the given promise.
if (is_object($value) && method_exists($value, 'then')) {
$wfn = method_exists($value, 'wait') ? [$value, 'wait'] : null;
$cfn = method_exists($value, 'cancel') ? [$value, 'cancel'] : null;
$promise = new Promise($wfn, $cfn);
$value->then([$promise, 'resolve'], [$promise, 'reject']);
return $promise;
}
return new FulfilledPromise($value);
}
/**
* Creates a rejected promise for a reason if the reason is not a promise.
* If the provided reason is a promise, then it is returned as-is.
*
* @param mixed $reason Promise or reason.
*
* @return PromiseInterface
*/
public static function rejectionFor($reason)
{
if ($reason instanceof PromiseInterface) {
return $reason;
}
return new RejectedPromise($reason);
}
/**
* Create an exception for a rejected promise value.
*
* @param mixed $reason
*
* @return \Exception|\Throwable
*/
public static function exceptionFor($reason)
{
if ($reason instanceof \Exception || $reason instanceof \Throwable) {
return $reason;
}
return new RejectionException($reason);
}
/**
* Returns an iterator for the given value.
*
* @param mixed $value
*
* @return \Iterator
*/
public static function iterFor($value)
{
if ($value instanceof \Iterator) {
return $value;
}
if (is_array($value)) {
return new \ArrayIterator($value);
}
return new \ArrayIterator([$value]);
}
}

90
vendor/guzzlehttp/promises/src/Each.php vendored Normal file
View file

@ -0,0 +1,90 @@
<?php
namespace GuzzleHttp\Promise;
final class Each
{
/**
* Given an iterator that yields promises or values, returns a promise that
* is fulfilled with a null value when the iterator has been consumed or
* the aggregate promise has been fulfilled or rejected.
*
* $onFulfilled is a function that accepts the fulfilled value, iterator
* index, and the aggregate promise. The callback can invoke any necessary
* side effects and choose to resolve or reject the aggregate if needed.
*
* $onRejected is a function that accepts the rejection reason, iterator
* index, and the aggregate promise. The callback can invoke any necessary
* side effects and choose to resolve or reject the aggregate if needed.
*
* @param mixed $iterable Iterator or array to iterate over.
* @param callable $onFulfilled
* @param callable $onRejected
*
* @return PromiseInterface
*/
public static function of(
$iterable,
callable $onFulfilled = null,
callable $onRejected = null
) {
return (new EachPromise($iterable, [
'fulfilled' => $onFulfilled,
'rejected' => $onRejected
]))->promise();
}
/**
* Like of, but only allows a certain number of outstanding promises at any
* given time.
*
* $concurrency may be an integer or a function that accepts the number of
* pending promises and returns a numeric concurrency limit value to allow
* for dynamic a concurrency size.
*
* @param mixed $iterable
* @param int|callable $concurrency
* @param callable $onFulfilled
* @param callable $onRejected
*
* @return PromiseInterface
*/
public static function ofLimit(
$iterable,
$concurrency,
callable $onFulfilled = null,
callable $onRejected = null
) {
return (new EachPromise($iterable, [
'fulfilled' => $onFulfilled,
'rejected' => $onRejected,
'concurrency' => $concurrency
]))->promise();
}
/**
* Like limit, but ensures that no promise in the given $iterable argument
* is rejected. If any promise is rejected, then the aggregate promise is
* rejected with the encountered rejection.
*
* @param mixed $iterable
* @param int|callable $concurrency
* @param callable $onFulfilled
*
* @return PromiseInterface
*/
public static function ofLimitAll(
$iterable,
$concurrency,
callable $onFulfilled = null
) {
return each_limit(
$iterable,
$concurrency,
$onFulfilled,
function ($reason, $idx, PromiseInterface $aggregate) {
$aggregate->reject($reason);
}
);
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**
@ -9,22 +10,22 @@ class EachPromise implements PromisorInterface
{ {
private $pending = []; private $pending = [];
/** @var \Iterator */ /** @var \Iterator|null */
private $iterable; private $iterable;
/** @var callable|int */ /** @var callable|int|null */
private $concurrency; private $concurrency;
/** @var callable */ /** @var callable|null */
private $onFulfilled; private $onFulfilled;
/** @var callable */ /** @var callable|null */
private $onRejected; private $onRejected;
/** @var Promise */ /** @var Promise|null */
private $aggregate; private $aggregate;
/** @var bool */ /** @var bool|null */
private $mutex; private $mutex;
/** /**
@ -50,7 +51,7 @@ class EachPromise implements PromisorInterface
*/ */
public function __construct($iterable, array $config = []) public function __construct($iterable, array $config = [])
{ {
$this->iterable = iter_for($iterable); $this->iterable = Create::iterFor($iterable);
if (isset($config['concurrency'])) { if (isset($config['concurrency'])) {
$this->concurrency = $config['concurrency']; $this->concurrency = $config['concurrency'];
@ -65,6 +66,7 @@ class EachPromise implements PromisorInterface
} }
} }
/** @psalm-suppress InvalidNullableReturnType */
public function promise() public function promise()
{ {
if ($this->aggregate) { if ($this->aggregate) {
@ -73,14 +75,29 @@ class EachPromise implements PromisorInterface
try { try {
$this->createPromise(); $this->createPromise();
/** @psalm-assert Promise $this->aggregate */
$this->iterable->rewind(); $this->iterable->rewind();
if (!$this->checkIfFinished()) {
$this->refillPending(); $this->refillPending();
}
} catch (\Throwable $e) { } catch (\Throwable $e) {
/**
* @psalm-suppress NullReference
* @phpstan-ignore-next-line
*/
$this->aggregate->reject($e); $this->aggregate->reject($e);
} catch (\Exception $e) { } catch (\Exception $e) {
/**
* @psalm-suppress NullReference
* @phpstan-ignore-next-line
*/
$this->aggregate->reject($e); $this->aggregate->reject($e);
} }
/**
* @psalm-suppress NullableReturnStatement
* @phpstan-ignore-next-line
*/
return $this->aggregate; return $this->aggregate;
} }
@ -89,17 +106,12 @@ class EachPromise implements PromisorInterface
$this->mutex = false; $this->mutex = false;
$this->aggregate = new Promise(function () { $this->aggregate = new Promise(function () {
reset($this->pending); reset($this->pending);
if (empty($this->pending) && !$this->iterable->valid()) {
$this->aggregate->resolve(null);
return;
}
// Consume a potentially fluctuating list of promises while // Consume a potentially fluctuating list of promises while
// ensuring that indexes are maintained (precluding array_shift). // ensuring that indexes are maintained (precluding array_shift).
while ($promise = current($this->pending)) { while ($promise = current($this->pending)) {
next($this->pending); next($this->pending);
$promise->wait(); $promise->wait();
if ($this->aggregate->getState() !== PromiseInterface::PENDING) { if (Is::settled($this->aggregate)) {
return; return;
} }
} }
@ -148,22 +160,34 @@ class EachPromise implements PromisorInterface
return false; return false;
} }
$promise = promise_for($this->iterable->current()); $promise = Create::promiseFor($this->iterable->current());
$idx = $this->iterable->key(); $key = $this->iterable->key();
// Iterable keys may not be unique, so we add the promises at the end
// of the pending array and retrieve the array index being used
$this->pending[] = null;
end($this->pending);
$idx = key($this->pending);
$this->pending[$idx] = $promise->then( $this->pending[$idx] = $promise->then(
function ($value) use ($idx) { function ($value) use ($idx, $key) {
if ($this->onFulfilled) { if ($this->onFulfilled) {
call_user_func( call_user_func(
$this->onFulfilled, $value, $idx, $this->aggregate $this->onFulfilled,
$value,
$key,
$this->aggregate
); );
} }
$this->step($idx); $this->step($idx);
}, },
function ($reason) use ($idx) { function ($reason) use ($idx, $key) {
if ($this->onRejected) { if ($this->onRejected) {
call_user_func( call_user_func(
$this->onRejected, $reason, $idx, $this->aggregate $this->onRejected,
$reason,
$key,
$this->aggregate
); );
} }
$this->step($idx); $this->step($idx);
@ -201,7 +225,7 @@ class EachPromise implements PromisorInterface
private function step($idx) private function step($idx)
{ {
// If the promise was already resolved, then ignore this step. // If the promise was already resolved, then ignore this step.
if ($this->aggregate->getState() !== PromiseInterface::PENDING) { if (Is::settled($this->aggregate)) {
return; return;
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**
@ -13,9 +14,10 @@ class FulfilledPromise implements PromiseInterface
public function __construct($value) public function __construct($value)
{ {
if (method_exists($value, 'then')) { if (is_object($value) && method_exists($value, 'then')) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
'You cannot create a FulfilledPromise with a promise.'); 'You cannot create a FulfilledPromise with a promise.'
);
} }
$this->value = $value; $this->value = $value;
@ -30,11 +32,11 @@ class FulfilledPromise implements PromiseInterface
return $this; return $this;
} }
$queue = queue(); $queue = Utils::queue();
$p = new Promise([$queue, 'run']); $p = new Promise([$queue, 'run']);
$value = $this->value; $value = $this->value;
$queue->add(static function () use ($p, $value, $onFulfilled) { $queue->add(static function () use ($p, $value, $onFulfilled) {
if ($p->getState() === self::PENDING) { if (Is::pending($p)) {
try { try {
$p->resolve($onFulfilled($value)); $p->resolve($onFulfilled($value));
} catch (\Throwable $e) { } catch (\Throwable $e) {

46
vendor/guzzlehttp/promises/src/Is.php vendored Normal file
View file

@ -0,0 +1,46 @@
<?php
namespace GuzzleHttp\Promise;
final class Is
{
/**
* Returns true if a promise is pending.
*
* @return bool
*/
public static function pending(PromiseInterface $promise)
{
return $promise->getState() === PromiseInterface::PENDING;
}
/**
* Returns true if a promise is fulfilled or rejected.
*
* @return bool
*/
public static function settled(PromiseInterface $promise)
{
return $promise->getState() !== PromiseInterface::PENDING;
}
/**
* Returns true if a promise is fulfilled.
*
* @return bool
*/
public static function fulfilled(PromiseInterface $promise)
{
return $promise->getState() === PromiseInterface::FULFILLED;
}
/**
* Returns true if a promise is rejected.
*
* @return bool
*/
public static function rejected(PromiseInterface $promise)
{
return $promise->getState() === PromiseInterface::REJECTED;
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**
@ -41,14 +42,13 @@ class Promise implements PromiseInterface
// Return a fulfilled promise and immediately invoke any callbacks. // Return a fulfilled promise and immediately invoke any callbacks.
if ($this->state === self::FULFILLED) { if ($this->state === self::FULFILLED) {
return $onFulfilled $promise = Create::promiseFor($this->result);
? promise_for($this->result)->then($onFulfilled) return $onFulfilled ? $promise->then($onFulfilled) : $promise;
: promise_for($this->result);
} }
// It's either cancelled or rejected, so return a rejected promise // It's either cancelled or rejected, so return a rejected promise
// and immediately invoke any callbacks. // and immediately invoke any callbacks.
$rejection = rejection_for($this->result); $rejection = Create::rejectionFor($this->result);
return $onRejected ? $rejection->then(null, $onRejected) : $rejection; return $onRejected ? $rejection->then(null, $onRejected) : $rejection;
} }
@ -61,19 +61,15 @@ class Promise implements PromiseInterface
{ {
$this->waitIfPending(); $this->waitIfPending();
$inner = $this->result instanceof PromiseInterface if ($this->result instanceof PromiseInterface) {
? $this->result->wait($unwrap) return $this->result->wait($unwrap);
: $this->result;
if ($unwrap) {
if ($this->result instanceof PromiseInterface
|| $this->state === self::FULFILLED
) {
return $inner;
} else {
// It's rejected so "unwrap" and throw an exception.
throw exception_for($inner);
} }
if ($unwrap) {
if ($this->state === self::FULFILLED) {
return $this->result;
}
// It's rejected so "unwrap" and throw an exception.
throw Create::exceptionFor($this->result);
} }
} }
@ -103,6 +99,7 @@ class Promise implements PromiseInterface
} }
// Reject the promise only if it wasn't rejected in a then callback. // Reject the promise only if it wasn't rejected in a then callback.
/** @psalm-suppress RedundantCondition */
if ($this->state === self::PENDING) { if ($this->state === self::PENDING) {
$this->reject(new CancellationException('Promise has been cancelled')); $this->reject(new CancellationException('Promise has been cancelled'));
} }
@ -148,17 +145,15 @@ class Promise implements PromiseInterface
// If the value was not a settled promise or a thenable, then resolve // If the value was not a settled promise or a thenable, then resolve
// it in the task queue using the correct ID. // it in the task queue using the correct ID.
if (!method_exists($value, 'then')) { if (!is_object($value) || !method_exists($value, 'then')) {
$id = $state === self::FULFILLED ? 1 : 2; $id = $state === self::FULFILLED ? 1 : 2;
// It's a success, so resolve the handlers in the queue. // It's a success, so resolve the handlers in the queue.
queue()->add(static function () use ($id, $value, $handlers) { Utils::queue()->add(static function () use ($id, $value, $handlers) {
foreach ($handlers as $handler) { foreach ($handlers as $handler) {
self::callHandler($id, $value, $handler); self::callHandler($id, $value, $handler);
} }
}); });
} elseif ($value instanceof Promise } elseif ($value instanceof Promise && Is::pending($value)) {
&& $value->getState() === self::PENDING
) {
// We can just merge our handlers onto the next promise. // We can just merge our handlers onto the next promise.
$value->handlers = array_merge($value->handlers, $handlers); $value->handlers = array_merge($value->handlers, $handlers);
} else { } else {
@ -184,8 +179,6 @@ class Promise implements PromiseInterface
* @param int $index 1 (resolve) or 2 (reject). * @param int $index 1 (resolve) or 2 (reject).
* @param mixed $value Value to pass to the callback. * @param mixed $value Value to pass to the callback.
* @param array $handler Array of handler data (promise and callbacks). * @param array $handler Array of handler data (promise and callbacks).
*
* @return array Returns the next group to resolve.
*/ */
private static function callHandler($index, $value, array $handler) private static function callHandler($index, $value, array $handler)
{ {
@ -194,13 +187,21 @@ class Promise implements PromiseInterface
// The promise may have been cancelled or resolved before placing // The promise may have been cancelled or resolved before placing
// this thunk in the queue. // this thunk in the queue.
if ($promise->getState() !== self::PENDING) { if (Is::settled($promise)) {
return; return;
} }
try { try {
if (isset($handler[$index])) { if (isset($handler[$index])) {
$promise->resolve($handler[$index]($value)); /*
* If $f throws an exception, then $handler will be in the exception
* stack trace. Since $handler contains a reference to the callable
* itself we get a circular reference. We clear the $handler
* here to avoid that memory leak.
*/
$f = $handler[$index];
unset($handler);
$promise->resolve($f($value));
} elseif ($index === 1) { } elseif ($index === 1) {
// Forward resolution values as-is. // Forward resolution values as-is.
$promise->resolve($value); $promise->resolve($value);
@ -224,15 +225,16 @@ class Promise implements PromiseInterface
} elseif ($this->waitList) { } elseif ($this->waitList) {
$this->invokeWaitList(); $this->invokeWaitList();
} else { } else {
// If there's not wait function, then reject the promise. // If there's no wait function, then reject the promise.
$this->reject('Cannot wait on a promise that has ' $this->reject('Cannot wait on a promise that has '
. 'no internal wait function. You must provide a wait ' . 'no internal wait function. You must provide a wait '
. 'function when constructing the promise to be able to ' . 'function when constructing the promise to be able to '
. 'wait on a promise.'); . 'wait on a promise.');
} }
queue()->run(); Utils::queue()->run();
/** @psalm-suppress RedundantCondition */
if ($this->state === self::PENDING) { if ($this->state === self::PENDING) {
$this->reject('Invoking the wait callback did not resolve the promise'); $this->reject('Invoking the wait callback did not resolve the promise');
} }
@ -263,17 +265,13 @@ class Promise implements PromiseInterface
$this->waitList = null; $this->waitList = null;
foreach ($waitList as $result) { foreach ($waitList as $result) {
while (true) { do {
$result->waitIfPending(); $result->waitIfPending();
if ($result->result instanceof Promise) {
$result = $result->result; $result = $result->result;
} else { } while ($result instanceof Promise);
if ($result->result instanceof PromiseInterface) {
$result->result->wait(false); if ($result instanceof PromiseInterface) {
} $result->wait(false);
break;
}
} }
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**
@ -56,6 +57,7 @@ interface PromiseInterface
* Resolve the promise with the given value. * Resolve the promise with the given value.
* *
* @param mixed $value * @param mixed $value
*
* @throws \RuntimeException if the promise is already resolved. * @throws \RuntimeException if the promise is already resolved.
*/ */
public function resolve($value); public function resolve($value);
@ -64,6 +66,7 @@ interface PromiseInterface
* Reject the promise with the given reason. * Reject the promise with the given reason.
* *
* @param mixed $reason * @param mixed $reason
*
* @throws \RuntimeException if the promise is already resolved. * @throws \RuntimeException if the promise is already resolved.
*/ */
public function reject($reason); public function reject($reason);
@ -86,6 +89,7 @@ interface PromiseInterface
* @param bool $unwrap * @param bool $unwrap
* *
* @return mixed * @return mixed
*
* @throws \LogicException if the promise has no wait function or if the * @throws \LogicException if the promise has no wait function or if the
* promise does not settle after waiting. * promise does not settle after waiting.
*/ */

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**
@ -13,9 +14,10 @@ class RejectedPromise implements PromiseInterface
public function __construct($reason) public function __construct($reason)
{ {
if (method_exists($reason, 'then')) { if (is_object($reason) && method_exists($reason, 'then')) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
'You cannot create a RejectedPromise with a promise.'); 'You cannot create a RejectedPromise with a promise.'
);
} }
$this->reason = $reason; $this->reason = $reason;
@ -30,11 +32,11 @@ class RejectedPromise implements PromiseInterface
return $this; return $this;
} }
$queue = queue(); $queue = Utils::queue();
$reason = $this->reason; $reason = $this->reason;
$p = new Promise([$queue, 'run']); $p = new Promise([$queue, 'run']);
$queue->add(static function () use ($p, $reason, $onRejected) { $queue->add(static function () use ($p, $reason, $onRejected) {
if ($p->getState() === self::PENDING) { if (Is::pending($p)) {
try { try {
// Return a resolved promise if onRejected does not throw. // Return a resolved promise if onRejected does not throw.
$p->resolve($onRejected($reason)); $p->resolve($onRejected($reason));
@ -59,8 +61,10 @@ class RejectedPromise implements PromiseInterface
public function wait($unwrap = true, $defaultDelivery = null) public function wait($unwrap = true, $defaultDelivery = null)
{ {
if ($unwrap) { if ($unwrap) {
throw exception_for($this->reason); throw Create::exceptionFor($this->reason);
} }
return null;
} }
public function getState() public function getState()

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**
@ -8,7 +9,7 @@ namespace GuzzleHttp\Promise;
* maintains a constant stack size. You can use the task queue asynchronously * maintains a constant stack size. You can use the task queue asynchronously
* by calling the `run()` function of the global task queue in an event loop. * by calling the `run()` function of the global task queue in an event loop.
* *
* GuzzleHttp\Promise\queue()->run(); * GuzzleHttp\Promise\Utils::queue()->run();
*/ */
class TaskQueue implements TaskQueueInterface class TaskQueue implements TaskQueueInterface
{ {
@ -42,8 +43,8 @@ class TaskQueue implements TaskQueueInterface
public function run() public function run()
{ {
/** @var callable $task */
while ($task = array_shift($this->queue)) { while ($task = array_shift($this->queue)) {
/** @var callable $task */
$task(); $task();
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
interface TaskQueueInterface interface TaskQueueInterface
@ -13,8 +14,6 @@ interface TaskQueueInterface
/** /**
* Adds a task to the queue that will be executed the next time run is * Adds a task to the queue that will be executed the next time run is
* called. * called.
*
* @param callable $task
*/ */
public function add(callable $task); public function add(callable $task);

274
vendor/guzzlehttp/promises/src/Utils.php vendored Normal file
View file

@ -0,0 +1,274 @@
<?php
namespace GuzzleHttp\Promise;
final class Utils
{
/**
* Get the global task queue used for promise resolution.
*
* This task queue MUST be run in an event loop in order for promises to be
* settled asynchronously. It will be automatically run when synchronously
* waiting on a promise.
*
* <code>
* while ($eventLoop->isRunning()) {
* GuzzleHttp\Promise\Utils::queue()->run();
* }
* </code>
*
* @param TaskQueueInterface $assign Optionally specify a new queue instance.
*
* @return TaskQueueInterface
*/
public static function queue(TaskQueueInterface $assign = null)
{
static $queue;
if ($assign) {
$queue = $assign;
} elseif (!$queue) {
$queue = new TaskQueue();
}
return $queue;
}
/**
* Adds a function to run in the task queue when it is next `run()` and
* returns a promise that is fulfilled or rejected with the result.
*
* @param callable $task Task function to run.
*
* @return PromiseInterface
*/
public static function task(callable $task)
{
$queue = self::queue();
$promise = new Promise([$queue, 'run']);
$queue->add(function () use ($task, $promise) {
try {
$promise->resolve($task());
} catch (\Throwable $e) {
$promise->reject($e);
} catch (\Exception $e) {
$promise->reject($e);
}
});
return $promise;
}
/**
* Synchronously waits on a promise to resolve and returns an inspection
* state array.
*
* Returns a state associative array containing a "state" key mapping to a
* valid promise state. If the state of the promise is "fulfilled", the
* array will contain a "value" key mapping to the fulfilled value of the
* promise. If the promise is rejected, the array will contain a "reason"
* key mapping to the rejection reason of the promise.
*
* @param PromiseInterface $promise Promise or value.
*
* @return array
*/
public static function inspect(PromiseInterface $promise)
{
try {
return [
'state' => PromiseInterface::FULFILLED,
'value' => $promise->wait()
];
} catch (RejectionException $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()];
} catch (\Throwable $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
} catch (\Exception $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
}
}
/**
* Waits on all of the provided promises, but does not unwrap rejected
* promises as thrown exception.
*
* Returns an array of inspection state arrays.
*
* @see inspect for the inspection state array format.
*
* @param PromiseInterface[] $promises Traversable of promises to wait upon.
*
* @return array
*/
public static function inspectAll($promises)
{
$results = [];
foreach ($promises as $key => $promise) {
$results[$key] = inspect($promise);
}
return $results;
}
/**
* Waits on all of the provided promises and returns the fulfilled values.
*
* Returns an array that contains the value of each promise (in the same
* order the promises were provided). An exception is thrown if any of the
* promises are rejected.
*
* @param iterable<PromiseInterface> $promises Iterable of PromiseInterface objects to wait on.
*
* @return array
*
* @throws \Exception on error
* @throws \Throwable on error in PHP >=7
*/
public static function unwrap($promises)
{
$results = [];
foreach ($promises as $key => $promise) {
$results[$key] = $promise->wait();
}
return $results;
}
/**
* Given an array of promises, return a promise that is fulfilled when all
* the items in the array are fulfilled.
*
* The promise's fulfillment value is an array with fulfillment values at
* respective positions to the original array. If any promise in the array
* rejects, the returned promise is rejected with the rejection reason.
*
* @param mixed $promises Promises or values.
* @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution.
*
* @return PromiseInterface
*/
public static function all($promises, $recursive = false)
{
$results = [];
$promise = Each::of(
$promises,
function ($value, $idx) use (&$results) {
$results[$idx] = $value;
},
function ($reason, $idx, Promise $aggregate) {
$aggregate->reject($reason);
}
)->then(function () use (&$results) {
ksort($results);
return $results;
});
if (true === $recursive) {
$promise = $promise->then(function ($results) use ($recursive, &$promises) {
foreach ($promises as $promise) {
if (Is::pending($promise)) {
return self::all($promises, $recursive);
}
}
return $results;
});
}
return $promise;
}
/**
* Initiate a competitive race between multiple promises or values (values
* will become immediately fulfilled promises).
*
* When count amount of promises have been fulfilled, the returned promise
* is fulfilled with an array that contains the fulfillment values of the
* winners in order of resolution.
*
* This promise is rejected with a {@see AggregateException} if the number
* of fulfilled promises is less than the desired $count.
*
* @param int $count Total number of promises.
* @param mixed $promises Promises or values.
*
* @return PromiseInterface
*/
public static function some($count, $promises)
{
$results = [];
$rejections = [];
return Each::of(
$promises,
function ($value, $idx, PromiseInterface $p) use (&$results, $count) {
if (Is::settled($p)) {
return;
}
$results[$idx] = $value;
if (count($results) >= $count) {
$p->resolve(null);
}
},
function ($reason) use (&$rejections) {
$rejections[] = $reason;
}
)->then(
function () use (&$results, &$rejections, $count) {
if (count($results) !== $count) {
throw new AggregateException(
'Not enough promises to fulfill count',
$rejections
);
}
ksort($results);
return array_values($results);
}
);
}
/**
* Like some(), with 1 as count. However, if the promise fulfills, the
* fulfillment value is not an array of 1 but the value directly.
*
* @param mixed $promises Promises or values.
*
* @return PromiseInterface
*/
public static function any($promises)
{
return self::some(1, $promises)->then(function ($values) {
return $values[0];
});
}
/**
* Returns a promise that is fulfilled when all of the provided promises have
* been fulfilled or rejected.
*
* The returned promise is fulfilled with an array of inspection state arrays.
*
* @see inspect for the inspection state array format.
*
* @param mixed $promises Promises or values.
*
* @return PromiseInterface
*/
public static function settle($promises)
{
$results = [];
return Each::of(
$promises,
function ($value, $idx) use (&$results) {
$results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value];
},
function ($reason, $idx) use (&$results) {
$results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason];
}
)->then(function () use (&$results) {
ksort($results);
return $results;
});
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Promise; namespace GuzzleHttp\Promise;
/** /**
@ -17,18 +18,12 @@ namespace GuzzleHttp\Promise;
* @param TaskQueueInterface $assign Optionally specify a new queue instance. * @param TaskQueueInterface $assign Optionally specify a new queue instance.
* *
* @return TaskQueueInterface * @return TaskQueueInterface
*
* @deprecated queue will be removed in guzzlehttp/promises:2.0. Use Utils::queue instead.
*/ */
function queue(TaskQueueInterface $assign = null) function queue(TaskQueueInterface $assign = null)
{ {
static $queue; return Utils::queue($assign);
if ($assign) {
$queue = $assign;
} elseif (!$queue) {
$queue = new TaskQueue();
}
return $queue;
} }
/** /**
@ -38,22 +33,12 @@ function queue(TaskQueueInterface $assign = null)
* @param callable $task Task function to run. * @param callable $task Task function to run.
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated task will be removed in guzzlehttp/promises:2.0. Use Utils::task instead.
*/ */
function task(callable $task) function task(callable $task)
{ {
$queue = queue(); return Utils::task($task);
$promise = new Promise([$queue, 'run']);
$queue->add(function () use ($task, $promise) {
try {
$promise->resolve($task());
} catch (\Throwable $e) {
$promise->reject($e);
} catch (\Exception $e) {
$promise->reject($e);
}
});
return $promise;
} }
/** /**
@ -62,23 +47,12 @@ function task(callable $task)
* @param mixed $value Promise or value. * @param mixed $value Promise or value.
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated promise_for will be removed in guzzlehttp/promises:2.0. Use Create::promiseFor instead.
*/ */
function promise_for($value) function promise_for($value)
{ {
if ($value instanceof PromiseInterface) { return Create::promiseFor($value);
return $value;
}
// Return a Guzzle promise that shadows the given promise.
if (method_exists($value, 'then')) {
$wfn = method_exists($value, 'wait') ? [$value, 'wait'] : null;
$cfn = method_exists($value, 'cancel') ? [$value, 'cancel'] : null;
$promise = new Promise($wfn, $cfn);
$value->then([$promise, 'resolve'], [$promise, 'reject']);
return $promise;
}
return new FulfilledPromise($value);
} }
/** /**
@ -88,14 +62,12 @@ function promise_for($value)
* @param mixed $reason Promise or reason. * @param mixed $reason Promise or reason.
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated rejection_for will be removed in guzzlehttp/promises:2.0. Use Create::rejectionFor instead.
*/ */
function rejection_for($reason) function rejection_for($reason)
{ {
if ($reason instanceof PromiseInterface) { return Create::rejectionFor($reason);
return $reason;
}
return new RejectedPromise($reason);
} }
/** /**
@ -104,12 +76,12 @@ function rejection_for($reason)
* @param mixed $reason * @param mixed $reason
* *
* @return \Exception|\Throwable * @return \Exception|\Throwable
*
* @deprecated exception_for will be removed in guzzlehttp/promises:2.0. Use Create::exceptionFor instead.
*/ */
function exception_for($reason) function exception_for($reason)
{ {
return $reason instanceof \Exception || $reason instanceof \Throwable return Create::exceptionFor($reason);
? $reason
: new RejectionException($reason);
} }
/** /**
@ -118,16 +90,12 @@ function exception_for($reason)
* @param mixed $value * @param mixed $value
* *
* @return \Iterator * @return \Iterator
*
* @deprecated iter_for will be removed in guzzlehttp/promises:2.0. Use Create::iterFor instead.
*/ */
function iter_for($value) function iter_for($value)
{ {
if ($value instanceof \Iterator) { return Create::iterFor($value);
return $value;
} elseif (is_array($value)) {
return new \ArrayIterator($value);
} else {
return new \ArrayIterator([$value]);
}
} }
/** /**
@ -143,21 +111,12 @@ function iter_for($value)
* @param PromiseInterface $promise Promise or value. * @param PromiseInterface $promise Promise or value.
* *
* @return array * @return array
*
* @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspect instead.
*/ */
function inspect(PromiseInterface $promise) function inspect(PromiseInterface $promise)
{ {
try { return Utils::inspect($promise);
return [
'state' => PromiseInterface::FULFILLED,
'value' => $promise->wait()
];
} catch (RejectionException $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()];
} catch (\Throwable $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
} catch (\Exception $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
}
} }
/** /**
@ -166,19 +125,17 @@ function inspect(PromiseInterface $promise)
* *
* Returns an array of inspection state arrays. * Returns an array of inspection state arrays.
* *
* @see inspect for the inspection state array format.
*
* @param PromiseInterface[] $promises Traversable of promises to wait upon. * @param PromiseInterface[] $promises Traversable of promises to wait upon.
* *
* @return array * @return array
* @see GuzzleHttp\Promise\inspect for the inspection state array format. *
* @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspectAll instead.
*/ */
function inspect_all($promises) function inspect_all($promises)
{ {
$results = []; return Utils::inspectAll($promises);
foreach ($promises as $key => $promise) {
$results[$key] = inspect($promise);
}
return $results;
} }
/** /**
@ -188,20 +145,18 @@ function inspect_all($promises)
* the promises were provided). An exception is thrown if any of the promises * the promises were provided). An exception is thrown if any of the promises
* are rejected. * are rejected.
* *
* @param mixed $promises Iterable of PromiseInterface objects to wait on. * @param iterable<PromiseInterface> $promises Iterable of PromiseInterface objects to wait on.
* *
* @return array * @return array
*
* @throws \Exception on error * @throws \Exception on error
* @throws \Throwable on error in PHP >=7 * @throws \Throwable on error in PHP >=7
*
* @deprecated unwrap will be removed in guzzlehttp/promises:2.0. Use Utils::unwrap instead.
*/ */
function unwrap($promises) function unwrap($promises)
{ {
$results = []; return Utils::unwrap($promises);
foreach ($promises as $key => $promise) {
$results[$key] = $promise->wait();
}
return $results;
} }
/** /**
@ -213,24 +168,15 @@ function unwrap($promises)
* rejects, the returned promise is rejected with the rejection reason. * rejects, the returned promise is rejected with the rejection reason.
* *
* @param mixed $promises Promises or values. * @param mixed $promises Promises or values.
* @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution.
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated all will be removed in guzzlehttp/promises:2.0. Use Utils::all instead.
*/ */
function all($promises) function all($promises, $recursive = false)
{ {
$results = []; return Utils::all($promises, $recursive);
return each(
$promises,
function ($value, $idx) use (&$results) {
$results[$idx] = $value;
},
function ($reason, $idx, Promise $aggregate) {
$aggregate->reject($reason);
}
)->then(function () use (&$results) {
ksort($results);
return $results;
});
} }
/** /**
@ -241,45 +187,19 @@ function all($promises)
* fulfilled with an array that contains the fulfillment values of the winners * fulfilled with an array that contains the fulfillment values of the winners
* in order of resolution. * in order of resolution.
* *
* This prommise is rejected with a {@see GuzzleHttp\Promise\AggregateException} * This promise is rejected with a {@see AggregateException} if the number of
* if the number of fulfilled promises is less than the desired $count. * fulfilled promises is less than the desired $count.
* *
* @param int $count Total number of promises. * @param int $count Total number of promises.
* @param mixed $promises Promises or values. * @param mixed $promises Promises or values.
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated some will be removed in guzzlehttp/promises:2.0. Use Utils::some instead.
*/ */
function some($count, $promises) function some($count, $promises)
{ {
$results = []; return Utils::some($count, $promises);
$rejections = [];
return each(
$promises,
function ($value, $idx, PromiseInterface $p) use (&$results, $count) {
if ($p->getState() !== PromiseInterface::PENDING) {
return;
}
$results[$idx] = $value;
if (count($results) >= $count) {
$p->resolve(null);
}
},
function ($reason) use (&$rejections) {
$rejections[] = $reason;
}
)->then(
function () use (&$results, &$rejections, $count) {
if (count($results) !== $count) {
throw new AggregateException(
'Not enough promises to fulfill count',
$rejections
);
}
ksort($results);
return array_values($results);
}
);
} }
/** /**
@ -289,10 +209,12 @@ function some($count, $promises)
* @param mixed $promises Promises or values. * @param mixed $promises Promises or values.
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated any will be removed in guzzlehttp/promises:2.0. Use Utils::any instead.
*/ */
function any($promises) function any($promises)
{ {
return some(1, $promises)->then(function ($values) { return $values[0]; }); return Utils::any($promises);
} }
/** /**
@ -301,27 +223,17 @@ function any($promises)
* *
* The returned promise is fulfilled with an array of inspection state arrays. * The returned promise is fulfilled with an array of inspection state arrays.
* *
* @see inspect for the inspection state array format.
*
* @param mixed $promises Promises or values. * @param mixed $promises Promises or values.
* *
* @return PromiseInterface * @return PromiseInterface
* @see GuzzleHttp\Promise\inspect for the inspection state array format. *
* @deprecated settle will be removed in guzzlehttp/promises:2.0. Use Utils::settle instead.
*/ */
function settle($promises) function settle($promises)
{ {
$results = []; return Utils::settle($promises);
return each(
$promises,
function ($value, $idx) use (&$results) {
$results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value];
},
function ($reason, $idx) use (&$results) {
$results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason];
}
)->then(function () use (&$results) {
ksort($results);
return $results;
});
} }
/** /**
@ -329,29 +241,28 @@ function settle($promises)
* fulfilled with a null value when the iterator has been consumed or the * fulfilled with a null value when the iterator has been consumed or the
* aggregate promise has been fulfilled or rejected. * aggregate promise has been fulfilled or rejected.
* *
* $onFulfilled is a function that accepts the fulfilled value, iterator * $onFulfilled is a function that accepts the fulfilled value, iterator index,
* index, and the aggregate promise. The callback can invoke any necessary side * and the aggregate promise. The callback can invoke any necessary side
* effects and choose to resolve or reject the aggregate promise if needed. * effects and choose to resolve or reject the aggregate if needed.
* *
* $onRejected is a function that accepts the rejection reason, iterator * $onRejected is a function that accepts the rejection reason, iterator index,
* index, and the aggregate promise. The callback can invoke any necessary side * and the aggregate promise. The callback can invoke any necessary side
* effects and choose to resolve or reject the aggregate promise if needed. * effects and choose to resolve or reject the aggregate if needed.
* *
* @param mixed $iterable Iterator or array to iterate over. * @param mixed $iterable Iterator or array to iterate over.
* @param callable $onFulfilled * @param callable $onFulfilled
* @param callable $onRejected * @param callable $onRejected
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated each will be removed in guzzlehttp/promises:2.0. Use Each::of instead.
*/ */
function each( function each(
$iterable, $iterable,
callable $onFulfilled = null, callable $onFulfilled = null,
callable $onRejected = null callable $onRejected = null
) { ) {
return (new EachPromise($iterable, [ return Each::of($iterable, $onFulfilled, $onRejected);
'fulfilled' => $onFulfilled,
'rejected' => $onRejected
]))->promise();
} }
/** /**
@ -368,6 +279,8 @@ function each(
* @param callable $onRejected * @param callable $onRejected
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated each_limit will be removed in guzzlehttp/promises:2.0. Use Each::ofLimit instead.
*/ */
function each_limit( function each_limit(
$iterable, $iterable,
@ -375,11 +288,7 @@ function each_limit(
callable $onFulfilled = null, callable $onFulfilled = null,
callable $onRejected = null callable $onRejected = null
) { ) {
return (new EachPromise($iterable, [ return Each::ofLimit($iterable, $concurrency, $onFulfilled, $onRejected);
'fulfilled' => $onFulfilled,
'rejected' => $onRejected,
'concurrency' => $concurrency
]))->promise();
} }
/** /**
@ -392,66 +301,63 @@ function each_limit(
* @param callable $onFulfilled * @param callable $onFulfilled
* *
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated each_limit_all will be removed in guzzlehttp/promises:2.0. Use Each::ofLimitAll instead.
*/ */
function each_limit_all( function each_limit_all(
$iterable, $iterable,
$concurrency, $concurrency,
callable $onFulfilled = null callable $onFulfilled = null
) { ) {
return each_limit( return Each::ofLimitAll($iterable, $concurrency, $onFulfilled);
$iterable,
$concurrency,
$onFulfilled,
function ($reason, $idx, PromiseInterface $aggregate) {
$aggregate->reject($reason);
}
);
} }
/** /**
* Returns true if a promise is fulfilled. * Returns true if a promise is fulfilled.
* *
* @param PromiseInterface $promise
*
* @return bool * @return bool
*
* @deprecated is_fulfilled will be removed in guzzlehttp/promises:2.0. Use Is::fulfilled instead.
*/ */
function is_fulfilled(PromiseInterface $promise) function is_fulfilled(PromiseInterface $promise)
{ {
return $promise->getState() === PromiseInterface::FULFILLED; return Is::fulfilled($promise);
} }
/** /**
* Returns true if a promise is rejected. * Returns true if a promise is rejected.
* *
* @param PromiseInterface $promise
*
* @return bool * @return bool
*
* @deprecated is_rejected will be removed in guzzlehttp/promises:2.0. Use Is::rejected instead.
*/ */
function is_rejected(PromiseInterface $promise) function is_rejected(PromiseInterface $promise)
{ {
return $promise->getState() === PromiseInterface::REJECTED; return Is::rejected($promise);
} }
/** /**
* Returns true if a promise is fulfilled or rejected. * Returns true if a promise is fulfilled or rejected.
* *
* @param PromiseInterface $promise
*
* @return bool * @return bool
*
* @deprecated is_settled will be removed in guzzlehttp/promises:2.0. Use Is::settled instead.
*/ */
function is_settled(PromiseInterface $promise) function is_settled(PromiseInterface $promise)
{ {
return $promise->getState() !== PromiseInterface::PENDING; return Is::settled($promise);
} }
/** /**
* Create a new coroutine.
*
* @see Coroutine * @see Coroutine
* *
* @param callable $generatorFn
*
* @return PromiseInterface * @return PromiseInterface
*
* @deprecated coroutine will be removed in guzzlehttp/promises:2.0. Use Coroutine::of instead.
*/ */
function coroutine(callable $generatorFn) function coroutine(callable $generatorFn)
{ {
return new Coroutine($generatorFn); return Coroutine::of($generatorFn);
} }

View file

@ -9,8 +9,32 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] ## [Unreleased]
## [1.7.0] - 2020-09-30
## [1.6.0] ### Added
- Replaced functions by static methods
### Fixed
- Converting a non-seekable stream to a string
- Handle multiple Set-Cookie correctly
- Ignore array keys in header values when merging
- Allow multibyte characters to be parsed in `Message:bodySummary()`
### Changed
- Restored partial HHVM 3 support
## [1.6.1] - 2019-07-02
### Fixed
- Accept null and bool header values again
## [1.6.0] - 2019-06-30
### Added ### Added

View file

@ -23,11 +23,11 @@ Reads from multiple streams, one after the other.
```php ```php
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
$a = Psr7\stream_for('abc, '); $a = Psr7\Utils::streamFor('abc, ');
$b = Psr7\stream_for('123.'); $b = Psr7\Utils::streamFor('123.');
$composed = new Psr7\AppendStream([$a, $b]); $composed = new Psr7\AppendStream([$a, $b]);
$composed->addStream(Psr7\stream_for(' Above all listen to me')); $composed->addStream(Psr7\Utils::streamFor(' Above all listen to me'));
echo $composed; // abc, 123. Above all listen to me. echo $composed; // abc, 123. Above all listen to me.
``` ```
@ -65,7 +65,7 @@ then on disk.
```php ```php
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
$original = Psr7\stream_for(fopen('http://www.google.com', 'r')); $original = Psr7\Utils::streamFor(fopen('http://www.google.com', 'r'));
$stream = new Psr7\CachingStream($original); $stream = new Psr7\CachingStream($original);
$stream->read(1024); $stream->read(1024);
@ -89,7 +89,7 @@ stream becomes too full.
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
// Create an empty stream // Create an empty stream
$stream = Psr7\stream_for(); $stream = Psr7\Utils::streamFor();
// Start dropping data when the stream has more than 10 bytes // Start dropping data when the stream has more than 10 bytes
$dropping = new Psr7\DroppingStream($stream, 10); $dropping = new Psr7\DroppingStream($stream, 10);
@ -112,7 +112,7 @@ to create a concrete class for a simple extension point.
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
$stream = Psr7\stream_for('hi'); $stream = Psr7\Utils::streamFor('hi');
$fnStream = Psr7\FnStream::decorate($stream, [ $fnStream = Psr7\FnStream::decorate($stream, [
'rewind' => function () use ($stream) { 'rewind' => function () use ($stream) {
echo 'About to rewind - '; echo 'About to rewind - ';
@ -167,7 +167,7 @@ chunks (e.g. Amazon S3's multipart upload API).
```php ```php
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
$original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+')); $original = Psr7\Utils::streamFor(fopen('/tmp/test.txt', 'r+'));
echo $original->getSize(); echo $original->getSize();
// >>> 1048576 // >>> 1048576
@ -197,7 +197,7 @@ NoSeekStream wraps a stream and does not allow seeking.
```php ```php
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
$original = Psr7\stream_for('foo'); $original = Psr7\Utils::streamFor('foo');
$noSeek = new Psr7\NoSeekStream($original); $noSeek = new Psr7\NoSeekStream($original);
echo $noSeek->read(3); echo $noSeek->read(3);
@ -271,7 +271,7 @@ This decorator could be added to any existing stream and used like so:
```php ```php
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
$original = Psr7\stream_for('foo'); $original = Psr7\Utils::streamFor('foo');
$eofStream = new EofCallbackStream($original, function () { $eofStream = new EofCallbackStream($original, function () {
echo 'EOF!'; echo 'EOF!';
@ -297,53 +297,189 @@ stream from a PSR-7 stream.
```php ```php
use GuzzleHttp\Psr7\StreamWrapper; use GuzzleHttp\Psr7\StreamWrapper;
$stream = GuzzleHttp\Psr7\stream_for('hello!'); $stream = GuzzleHttp\Psr7\Utils::streamFor('hello!');
$resource = StreamWrapper::getResource($stream); $resource = StreamWrapper::getResource($stream);
echo fread($resource, 6); // outputs hello! echo fread($resource, 6); // outputs hello!
``` ```
# Function API # Static API
There are various functions available under the `GuzzleHttp\Psr7` namespace. There are various static methods available under the `GuzzleHttp\Psr7` namespace.
## `function str` ## `GuzzleHttp\Psr7\Message::toString`
`function str(MessageInterface $message)` `public static function toString(MessageInterface $message): string`
Returns the string representation of an HTTP message. Returns the string representation of an HTTP message.
```php ```php
$request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com'); $request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
echo GuzzleHttp\Psr7\str($request); echo GuzzleHttp\Psr7\Message::toString($request);
``` ```
## `function uri_for` ## `GuzzleHttp\Psr7\Message::bodySummary`
`function uri_for($uri)` `public static function bodySummary(MessageInterface $message, int $truncateAt = 120): string|null`
This function accepts a string or `Psr\Http\Message\UriInterface` and returns a Get a short summary of the message body.
UriInterface for the given value. If the value is already a `UriInterface`, it
is returned as-is.
```php Will return `null` if the response is not printable.
$uri = GuzzleHttp\Psr7\uri_for('http://example.com');
assert($uri === GuzzleHttp\Psr7\uri_for($uri));
```
## `function stream_for` ## `GuzzleHttp\Psr7\Message::rewindBody`
`function stream_for($resource = '', array $options = [])` `public static function rewindBody(MessageInterface $message): void`
Attempts to rewind a message body and throws an exception on failure.
The body of the message will only be rewound if a call to `tell()`
returns a value other than `0`.
## `GuzzleHttp\Psr7\Message::parseMessage`
`public static function parseMessage(string $message): array`
Parses an HTTP message into an associative array.
The array contains the "start-line" key containing the start line of
the message, "headers" key containing an associative array of header
array values, and a "body" key containing the body of the message.
## `GuzzleHttp\Psr7\Message::parseRequestUri`
`public static function parseRequestUri(string $path, array $headers): string`
Constructs a URI for an HTTP request message.
## `GuzzleHttp\Psr7\Message::parseRequest`
`public static function parseRequest(string $message): Request`
Parses a request message string into a request object.
## `GuzzleHttp\Psr7\Message::parseResponse`
`public static function parseResponse(string $message): Response`
Parses a response message string into a response object.
## `GuzzleHttp\Psr7\Header::parse`
`public static function parse(string|array $header): array`
Parse an array of header values containing ";" separated data into an
array of associative arrays representing the header key value pair data
of the header. When a parameter does not contain a value, but just
contains a key, this function will inject a key with a '' string value.
## `GuzzleHttp\Psr7\Header::normalize`
`public static function normalize(string|array $header): array`
Converts an array of header values that may contain comma separated
headers into an array of headers with no comma separated values.
## `GuzzleHttp\Psr7\Query::parse`
`public static function parse(string $str, int|bool $urlEncoding = true): array`
Parse a query string into an associative array.
If multiple values are found for the same key, the value of that key
value pair will become an array. This function does not parse nested
PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
## `GuzzleHttp\Psr7\Query::build`
`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986): string`
Build a query string from an array of key value pairs.
This function can use the return value of `parse()` to build a query
string. This function does not modify the provided keys when an array is
encountered (like `http_build_query()` would).
## `GuzzleHttp\Psr7\Utils::caselessRemove`
`public static function caselessRemove(iterable<string> $keys, $keys, array $data): array`
Remove the items given by the keys, case insensitively from the data.
## `GuzzleHttp\Psr7\Utils::copyToStream`
`public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1): void`
Copy the contents of a stream into another stream until the given number
of bytes have been read.
## `GuzzleHttp\Psr7\Utils::copyToString`
`public static function copyToString(StreamInterface $stream, int $maxLen = -1): string`
Copy the contents of a stream into a string until the given number of
bytes have been read.
## `GuzzleHttp\Psr7\Utils::hash`
`public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = false): string`
Calculate a hash of a stream.
This method reads the entire stream to calculate a rolling hash, based on
PHP's `hash_init` functions.
## `GuzzleHttp\Psr7\Utils::modifyRequest`
`public static function modifyRequest(RequestInterface $request, array $changes): RequestInterface`
Clone and modify a request with the given changes.
This method is useful for reducing the number of clones needed to mutate
a message.
- method: (string) Changes the HTTP method.
- set_headers: (array) Sets the given headers.
- remove_headers: (array) Remove the given headers.
- body: (mixed) Sets the given body.
- uri: (UriInterface) Set the URI.
- query: (string) Set the query string value of the URI.
- version: (string) Set the protocol version.
## `GuzzleHttp\Psr7\Utils::readLine`
`public static function readLine(StreamInterface $stream, int $maxLength = null): string`
Read a line from the stream up to the maximum allowed buffer length.
## `GuzzleHttp\Psr7\Utils::streamFor`
`public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface`
Create a new stream based on the input type. Create a new stream based on the input type.
Options is an associative array that can contain the following keys: Options is an associative array that can contain the following keys:
* - metadata: Array of custom metadata. - metadata: Array of custom metadata.
* - size: Size of the stream. - size: Size of the stream.
This method accepts the following `$resource` types: This method accepts the following `$resource` types:
@ -369,8 +505,8 @@ This method accepts the following `$resource` types:
buffered and used in subsequent reads. buffered and used in subsequent reads.
```php ```php
$stream = GuzzleHttp\Psr7\stream_for('foo'); $stream = GuzzleHttp\Psr7\Utils::streamFor('foo');
$stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r')); $stream = GuzzleHttp\Psr7\Utils::streamFor(fopen('/path/to/file', 'r'));
$generator = function ($bytes) { $generator = function ($bytes) {
for ($i = 0; $i < $bytes; $i++) { for ($i = 0; $i < $bytes; $i++) {
@ -378,147 +514,75 @@ $generator = function ($bytes) {
} }
} }
$stream = GuzzleHttp\Psr7\stream_for($generator(100)); $stream = GuzzleHttp\Psr7\Utils::streamFor($generator(100));
``` ```
## `function parse_header` ## `GuzzleHttp\Psr7\Utils::tryFopen`
`function parse_header($header)` `public static function tryFopen(string $filename, string $mode): resource`
Parse an array of header values containing ";" separated data into an array of
associative arrays representing the header key value pair data of the header.
When a parameter does not contain a value, but just contains a key, this
function will inject a key with a '' string value.
## `function normalize_header`
`function normalize_header($header)`
Converts an array of header values that may contain comma separated headers
into an array of headers with no comma separated values.
## `function modify_request`
`function modify_request(RequestInterface $request, array $changes)`
Clone and modify a request with the given changes. This method is useful for
reducing the number of clones needed to mutate a message.
The changes can be one of:
- method: (string) Changes the HTTP method.
- set_headers: (array) Sets the given headers.
- remove_headers: (array) Remove the given headers.
- body: (mixed) Sets the given body.
- uri: (UriInterface) Set the URI.
- query: (string) Set the query string value of the URI.
- version: (string) Set the protocol version.
## `function rewind_body`
`function rewind_body(MessageInterface $message)`
Attempts to rewind a message body and throws an exception on failure. The body
of the message will only be rewound if a call to `tell()` returns a value other
than `0`.
## `function try_fopen`
`function try_fopen($filename, $mode)`
Safely opens a PHP stream resource using a filename. Safely opens a PHP stream resource using a filename.
When fopen fails, PHP normally raises a warning. This function adds an error When fopen fails, PHP normally raises a warning. This function adds an
handler that checks for errors and throws an exception instead. error handler that checks for errors and throws an exception instead.
## `function copy_to_string` ## `GuzzleHttp\Psr7\Utils::uriFor`
`function copy_to_string(StreamInterface $stream, $maxLen = -1)` `public static function uriFor(string|UriInterface $uri): UriInterface`
Copy the contents of a stream into a string until the given number of bytes Returns a UriInterface for the given value.
have been read.
This function accepts a string or UriInterface and returns a
UriInterface for the given value. If the value is already a
UriInterface, it is returned as-is.
## `function copy_to_stream` ## `GuzzleHttp\Psr7\MimeType::fromFilename`
`function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)` `public static function fromFilename(string $filename): string|null`
Copy the contents of a stream into another stream until the given number of
bytes have been read.
## `function hash`
`function hash(StreamInterface $stream, $algo, $rawOutput = false)`
Calculate a hash of a Stream. This method reads the entire stream to calculate
a rolling hash (based on PHP's hash_init functions).
## `function readline`
`function readline(StreamInterface $stream, $maxLength = null)`
Read a line from the stream up to the maximum allowed buffer length.
## `function parse_request`
`function parse_request($message)`
Parses a request message string into a request object.
## `function parse_response`
`function parse_response($message)`
Parses a response message string into a response object.
## `function parse_query`
`function parse_query($str, $urlEncoding = true)`
Parse a query string into an associative array.
If multiple values are found for the same key, the value of that key value pair
will become an array. This function does not parse nested PHP style arrays into
an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into
`['foo[a]' => '1', 'foo[b]' => '2']`).
## `function build_query`
`function build_query(array $params, $encoding = PHP_QUERY_RFC3986)`
Build a query string from an array of key value pairs.
This function can use the return value of parse_query() to build a query string.
This function does not modify the provided keys when an array is encountered
(like http_build_query would).
## `function mimetype_from_filename`
`function mimetype_from_filename($filename)`
Determines the mimetype of a file by looking at its extension. Determines the mimetype of a file by looking at its extension.
## `function mimetype_from_extension` ## `GuzzleHttp\Psr7\MimeType::fromExtension`
`function mimetype_from_extension($extension)` `public static function fromExtension(string $extension): string|null`
Maps a file extensions to a mimetype. Maps a file extensions to a mimetype.
## Upgrading from Function API
The static API was first introduced in 1.7.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience:
| Original Function | Replacement Method |
|----------------|----------------|
| `str` | `Message::toString` |
| `uri_for` | `Utils::uriFor` |
| `stream_for` | `Utils::streamFor` |
| `parse_header` | `Header::parse` |
| `normalize_header` | `Header::normalize` |
| `modify_request` | `Utils::modifyRequest` |
| `rewind_body` | `Message::rewindBody` |
| `try_fopen` | `Utils::tryFopen` |
| `copy_to_string` | `Utils::copyToString` |
| `copy_to_stream` | `Utils::copyToStream` |
| `hash` | `Utils::hash` |
| `readline` | `Utils::readLine` |
| `parse_request` | `Message::parseRequest` |
| `parse_response` | `Message::parseResponse` |
| `parse_query` | `Query::parse` |
| `build_query` | `Query::build` |
| `mimetype_from_filename` | `MimeType::fromFilename` |
| `mimetype_from_extension` | `MimeType::fromExtension` |
| `_parse_message` | `Message::parseMessage` |
| `_parse_request_uri` | `Message::parseRequestUri` |
| `get_message_body_summary` | `Message::bodySummary` |
| `_caseless_remove` | `Utils::caselessRemove` |
# Additional URI Methods # Additional URI Methods
Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class, Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class,

View file

@ -21,14 +21,14 @@
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0" "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8", "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10",
"ext-zlib": "*" "ext-zlib": "*"
}, },
"provide": { "provide": {
"psr/http-message-implementation": "1.0" "psr/http-message-implementation": "1.0"
}, },
"suggest": { "suggest": {
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -43,7 +43,7 @@
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.6-dev" "dev-master": "1.7-dev"
} }
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -61,7 +62,7 @@ class AppendStream implements StreamInterface
public function getContents() public function getContents()
{ {
return copy_to_string($this); return Utils::copyToString($this);
} }
/** /**
@ -98,6 +99,8 @@ class AppendStream implements StreamInterface
} }
$this->streams = []; $this->streams = [];
return null;
} }
public function tell() public function tell()

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -49,6 +50,8 @@ class BufferStream implements StreamInterface
public function detach() public function detach()
{ {
$this->close(); $this->close();
return null;
} }
public function getSize() public function getSize()

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -131,7 +132,7 @@ class CachingStream implements StreamInterface
private function cacheEntireStream() private function cacheEntireStream()
{ {
$target = new FnStream(['write' => 'strlen']); $target = new FnStream(['write' => 'strlen']);
copy_to_stream($this, $target); Utils::copyToStream($this, $target);
return $this->tell(); return $this->tell();
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -34,6 +35,7 @@ class FnStream implements StreamInterface
/** /**
* Lazily determine which methods are not implemented. * Lazily determine which methods are not implemented.
*
* @throws \BadMethodCallException * @throws \BadMethodCallException
*/ */
public function __get($name) public function __get($name)

71
vendor/guzzlehttp/psr7/src/Header.php vendored Normal file
View file

@ -0,0 +1,71 @@
<?php
namespace GuzzleHttp\Psr7;
final class Header
{
/**
* Parse an array of header values containing ";" separated data into an
* array of associative arrays representing the header key value pair data
* of the header. When a parameter does not contain a value, but just
* contains a key, this function will inject a key with a '' string value.
*
* @param string|array $header Header to parse into components.
*
* @return array Returns the parsed header values.
*/
public static function parse($header)
{
static $trimmed = "\"' \n\t\r";
$params = $matches = [];
foreach (self::normalize($header) as $val) {
$part = [];
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
$m = $matches[0];
if (isset($m[1])) {
$part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
} else {
$part[] = trim($m[0], $trimmed);
}
}
}
if ($part) {
$params[] = $part;
}
}
return $params;
}
/**
* Converts an array of header values that may contain comma separated
* headers into an array of headers with no comma separated values.
*
* @param string|array $header Header to normalize.
*
* @return array Returns the normalized header field values.
*/
public static function normalize($header)
{
if (!is_array($header)) {
return array_map('trim', explode(',', $header));
}
$result = [];
foreach ($header as $value) {
foreach ((array) $value as $v) {
if (strpos($v, ',') === false) {
$result[] = $v;
continue;
}
foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
$result[] = trim($vv);
}
}
}
return $result;
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -34,6 +35,6 @@ class LazyOpenStream implements StreamInterface
*/ */
protected function createStream() protected function createStream()
{ {
return stream_for(try_fopen($this->filename, $this->mode)); return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode));
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;

252
vendor/guzzlehttp/psr7/src/Message.php vendored Normal file
View file

@ -0,0 +1,252 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
final class Message
{
/**
* Returns the string representation of an HTTP message.
*
* @param MessageInterface $message Message to convert to a string.
*
* @return string
*/
public static function toString(MessageInterface $message)
{
if ($message instanceof RequestInterface) {
$msg = trim($message->getMethod() . ' '
. $message->getRequestTarget())
. ' HTTP/' . $message->getProtocolVersion();
if (!$message->hasHeader('host')) {
$msg .= "\r\nHost: " . $message->getUri()->getHost();
}
} elseif ($message instanceof ResponseInterface) {
$msg = 'HTTP/' . $message->getProtocolVersion() . ' '
. $message->getStatusCode() . ' '
. $message->getReasonPhrase();
} else {
throw new \InvalidArgumentException('Unknown message type');
}
foreach ($message->getHeaders() as $name => $values) {
if (strtolower($name) === 'set-cookie') {
foreach ($values as $value) {
$msg .= "\r\n{$name}: " . $value;
}
} else {
$msg .= "\r\n{$name}: " . implode(', ', $values);
}
}
return "{$msg}\r\n\r\n" . $message->getBody();
}
/**
* Get a short summary of the message body.
*
* Will return `null` if the response is not printable.
*
* @param MessageInterface $message The message to get the body summary
* @param int $truncateAt The maximum allowed size of the summary
*
* @return string|null
*/
public static function bodySummary(MessageInterface $message, $truncateAt = 120)
{
$body = $message->getBody();
if (!$body->isSeekable() || !$body->isReadable()) {
return null;
}
$size = $body->getSize();
if ($size === 0) {
return null;
}
$summary = $body->read($truncateAt);
$body->rewind();
if ($size > $truncateAt) {
$summary .= ' (truncated...)';
}
// Matches any printable character, including unicode characters:
// letters, marks, numbers, punctuation, spacing, and separators.
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/u', $summary)) {
return null;
}
return $summary;
}
/**
* Attempts to rewind a message body and throws an exception on failure.
*
* The body of the message will only be rewound if a call to `tell()`
* returns a value other than `0`.
*
* @param MessageInterface $message Message to rewind
*
* @throws \RuntimeException
*/
public static function rewindBody(MessageInterface $message)
{
$body = $message->getBody();
if ($body->tell()) {
$body->rewind();
}
}
/**
* Parses an HTTP message into an associative array.
*
* The array contains the "start-line" key containing the start line of
* the message, "headers" key containing an associative array of header
* array values, and a "body" key containing the body of the message.
*
* @param string $message HTTP request or response to parse.
*
* @return array
*/
public static function parseMessage($message)
{
if (!$message) {
throw new \InvalidArgumentException('Invalid message');
}
$message = ltrim($message, "\r\n");
$messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
if ($messageParts === false || count($messageParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
}
list($rawHeaders, $body) = $messageParts;
$rawHeaders .= "\r\n"; // Put back the delimiter we split previously
$headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
if ($headerParts === false || count($headerParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing status line');
}
list($startLine, $rawHeaders) = $headerParts;
if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
// Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
$rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
}
/** @var array[] $headerLines */
$count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
// If these aren't the same, then one line didn't match and there's an invalid header.
if ($count !== substr_count($rawHeaders, "\n")) {
// Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
}
throw new \InvalidArgumentException('Invalid header syntax');
}
$headers = [];
foreach ($headerLines as $headerLine) {
$headers[$headerLine[1]][] = $headerLine[2];
}
return [
'start-line' => $startLine,
'headers' => $headers,
'body' => $body,
];
}
/**
* Constructs a URI for an HTTP request message.
*
* @param string $path Path from the start-line
* @param array $headers Array of headers (each value an array).
*
* @return string
*/
public static function parseRequestUri($path, array $headers)
{
$hostKey = array_filter(array_keys($headers), function ($k) {
return strtolower($k) === 'host';
});
// If no host is found, then a full URI cannot be constructed.
if (!$hostKey) {
return $path;
}
$host = $headers[reset($hostKey)][0];
$scheme = substr($host, -4) === ':443' ? 'https' : 'http';
return $scheme . '://' . $host . '/' . ltrim($path, '/');
}
/**
* Parses a request message string into a request object.
*
* @param string $message Request message string.
*
* @return Request
*/
public static function parseRequest($message)
{
$data = self::parseMessage($message);
$matches = [];
if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
throw new \InvalidArgumentException('Invalid request string');
}
$parts = explode(' ', $data['start-line'], 3);
$version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
$request = new Request(
$parts[0],
$matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1],
$data['headers'],
$data['body'],
$version
);
return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
}
/**
* Parses a response message string into a response object.
*
* @param string $message Response message string.
*
* @return Response
*/
public static function parseResponse($message)
{
$data = self::parseMessage($message);
// According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
// between status-code and reason-phrase is required. But browsers accept
// responses without space and reason as well.
if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
}
$parts = explode(' ', $data['start-line'], 3);
return new Response(
(int) $parts[1],
$data['headers'],
$data['body'],
explode('/', $parts[0])[1],
isset($parts[2]) ? $parts[2] : null
);
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -17,7 +18,7 @@ trait MessageTrait
/** @var string */ /** @var string */
private $protocol = '1.1'; private $protocol = '1.1';
/** @var StreamInterface */ /** @var StreamInterface|null */
private $stream; private $stream;
public function getProtocolVersion() public function getProtocolVersion()
@ -117,7 +118,7 @@ trait MessageTrait
public function getBody() public function getBody()
{ {
if (!$this->stream) { if (!$this->stream) {
$this->stream = stream_for(''); $this->stream = Utils::streamFor('');
} }
return $this->stream; return $this->stream;
@ -194,7 +195,7 @@ trait MessageTrait
} }
return trim((string) $value, " \t"); return trim((string) $value, " \t");
}, $values); }, array_values($values));
} }
private function assertHeader($header) private function assertHeader($header)

140
vendor/guzzlehttp/psr7/src/MimeType.php vendored Normal file
View file

@ -0,0 +1,140 @@
<?php
namespace GuzzleHttp\Psr7;
final class MimeType
{
/**
* Determines the mimetype of a file by looking at its extension.
*
* @param string $filename
*
* @return string|null
*/
public static function fromFilename($filename)
{
return self::fromExtension(pathinfo($filename, PATHINFO_EXTENSION));
}
/**
* Maps a file extensions to a mimetype.
*
* @param string $extension string The file extension.
*
* @return string|null
*
* @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
*/
public static function fromExtension($extension)
{
static $mimetypes = [
'3gp' => 'video/3gpp',
'7z' => 'application/x-7z-compressed',
'aac' => 'audio/x-aac',
'ai' => 'application/postscript',
'aif' => 'audio/x-aiff',
'asc' => 'text/plain',
'asf' => 'video/x-ms-asf',
'atom' => 'application/atom+xml',
'avi' => 'video/x-msvideo',
'bmp' => 'image/bmp',
'bz2' => 'application/x-bzip2',
'cer' => 'application/pkix-cert',
'crl' => 'application/pkix-crl',
'crt' => 'application/x-x509-ca-cert',
'css' => 'text/css',
'csv' => 'text/csv',
'cu' => 'application/cu-seeme',
'deb' => 'application/x-debian-package',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dvi' => 'application/x-dvi',
'eot' => 'application/vnd.ms-fontobject',
'eps' => 'application/postscript',
'epub' => 'application/epub+zip',
'etx' => 'text/x-setext',
'flac' => 'audio/flac',
'flv' => 'video/x-flv',
'gif' => 'image/gif',
'gz' => 'application/gzip',
'htm' => 'text/html',
'html' => 'text/html',
'ico' => 'image/x-icon',
'ics' => 'text/calendar',
'ini' => 'text/plain',
'iso' => 'application/x-iso9660-image',
'jar' => 'application/java-archive',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'js' => 'text/javascript',
'json' => 'application/json',
'latex' => 'application/x-latex',
'log' => 'text/plain',
'm4a' => 'audio/mp4',
'm4v' => 'video/mp4',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mov' => 'video/quicktime',
'mkv' => 'video/x-matroska',
'mp3' => 'audio/mpeg',
'mp4' => 'video/mp4',
'mp4a' => 'audio/mp4',
'mp4v' => 'video/mp4',
'mpe' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpg4' => 'video/mp4',
'oga' => 'audio/ogg',
'ogg' => 'audio/ogg',
'ogv' => 'video/ogg',
'ogx' => 'application/ogg',
'pbm' => 'image/x-portable-bitmap',
'pdf' => 'application/pdf',
'pgm' => 'image/x-portable-graymap',
'png' => 'image/png',
'pnm' => 'image/x-portable-anymap',
'ppm' => 'image/x-portable-pixmap',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'ps' => 'application/postscript',
'qt' => 'video/quicktime',
'rar' => 'application/x-rar-compressed',
'ras' => 'image/x-cmu-raster',
'rss' => 'application/rss+xml',
'rtf' => 'application/rtf',
'sgm' => 'text/sgml',
'sgml' => 'text/sgml',
'svg' => 'image/svg+xml',
'swf' => 'application/x-shockwave-flash',
'tar' => 'application/x-tar',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'torrent' => 'application/x-bittorrent',
'ttf' => 'application/x-font-ttf',
'txt' => 'text/plain',
'wav' => 'audio/x-wav',
'webm' => 'video/webm',
'webp' => 'image/webp',
'wma' => 'audio/x-ms-wma',
'wmv' => 'video/x-ms-wmv',
'woff' => 'application/x-font-woff',
'wsdl' => 'application/wsdl+xml',
'xbm' => 'image/x-xbitmap',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xml' => 'application/xml',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'yaml' => 'text/yaml',
'yml' => 'text/yaml',
'zip' => 'application/zip',
];
$extension = strtolower($extension);
return isset($mimetypes[$extension])
? $mimetypes[$extension]
: null;
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -71,7 +72,7 @@ class MultipartStream implements StreamInterface
} }
// Add the trailing boundary with CRLF // Add the trailing boundary with CRLF
$stream->addStream(stream_for("--{$this->boundary}--\r\n")); $stream->addStream(Utils::streamFor("--{$this->boundary}--\r\n"));
return $stream; return $stream;
} }
@ -84,7 +85,7 @@ class MultipartStream implements StreamInterface
} }
} }
$element['contents'] = stream_for($element['contents']); $element['contents'] = Utils::streamFor($element['contents']);
if (empty($element['filename'])) { if (empty($element['filename'])) {
$uri = $element['contents']->getMetadata('uri'); $uri = $element['contents']->getMetadata('uri');
@ -100,9 +101,9 @@ class MultipartStream implements StreamInterface
isset($element['headers']) ? $element['headers'] : [] isset($element['headers']) ? $element['headers'] : []
); );
$stream->addStream(stream_for($this->getHeaders($headers))); $stream->addStream(Utils::streamFor($this->getHeaders($headers)));
$stream->addStream($body); $stream->addStream($body);
$stream->addStream(stream_for("\r\n")); $stream->addStream(Utils::streamFor("\r\n"));
} }
/** /**
@ -131,7 +132,7 @@ class MultipartStream implements StreamInterface
// Set a default Content-Type if one was not supplied // Set a default Content-Type if one was not supplied
$type = $this->getHeader($headers, 'content-type'); $type = $this->getHeader($headers, 'content-type');
if (!$type && ($filename === '0' || $filename)) { if (!$type && ($filename === '0' || $filename)) {
if ($type = mimetype_from_filename($filename)) { if ($type = MimeType::fromFilename($filename)) {
$headers['Content-Type'] = $type; $headers['Content-Type'] = $type;
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -51,7 +52,7 @@ class PumpStream implements StreamInterface
public function __toString() public function __toString()
{ {
try { try {
return copy_to_string($this); return Utils::copyToString($this);
} catch (\Exception $e) { } catch (\Exception $e) {
return ''; return '';
} }
@ -66,6 +67,8 @@ class PumpStream implements StreamInterface
{ {
$this->tellPos = false; $this->tellPos = false;
$this->source = null; $this->source = null;
return null;
} }
public function getSize() public function getSize()

108
vendor/guzzlehttp/psr7/src/Query.php vendored Normal file
View file

@ -0,0 +1,108 @@
<?php
namespace GuzzleHttp\Psr7;
final class Query
{
/**
* Parse a query string into an associative array.
*
* If multiple values are found for the same key, the value of that key
* value pair will become an array. This function does not parse nested
* PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
* will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
*
* @param string $str Query string to parse
* @param int|bool $urlEncoding How the query string is encoded
*
* @return array
*/
public static function parse($str, $urlEncoding = true)
{
$result = [];
if ($str === '') {
return $result;
}
if ($urlEncoding === true) {
$decoder = function ($value) {
return rawurldecode(str_replace('+', ' ', $value));
};
} elseif ($urlEncoding === PHP_QUERY_RFC3986) {
$decoder = 'rawurldecode';
} elseif ($urlEncoding === PHP_QUERY_RFC1738) {
$decoder = 'urldecode';
} else {
$decoder = function ($str) { return $str; };
}
foreach (explode('&', $str) as $kvp) {
$parts = explode('=', $kvp, 2);
$key = $decoder($parts[0]);
$value = isset($parts[1]) ? $decoder($parts[1]) : null;
if (!isset($result[$key])) {
$result[$key] = $value;
} else {
if (!is_array($result[$key])) {
$result[$key] = [$result[$key]];
}
$result[$key][] = $value;
}
}
return $result;
}
/**
* Build a query string from an array of key value pairs.
*
* This function can use the return value of `parse()` to build a query
* string. This function does not modify the provided keys when an array is
* encountered (like `http_build_query()` would).
*
* @param array $params Query string parameters.
* @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
* to encode using RFC3986, or PHP_QUERY_RFC1738
* to encode using RFC1738.
* @return string
*/
public static function build(array $params, $encoding = PHP_QUERY_RFC3986)
{
if (!$params) {
return '';
}
if ($encoding === false) {
$encoder = function ($str) { return $str; };
} elseif ($encoding === PHP_QUERY_RFC3986) {
$encoder = 'rawurlencode';
} elseif ($encoding === PHP_QUERY_RFC1738) {
$encoder = 'urlencode';
} else {
throw new \InvalidArgumentException('Invalid type');
}
$qs = '';
foreach ($params as $k => $v) {
$k = $encoder($k);
if (!is_array($v)) {
$qs .= $k;
if ($v !== null) {
$qs .= '=' . $encoder($v);
}
$qs .= '&';
} else {
foreach ($v as $vv) {
$qs .= $k;
if ($vv !== null) {
$qs .= '=' . $encoder($vv);
}
$qs .= '&';
}
}
}
return $qs ? (string) substr($qs, 0, -1) : '';
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use InvalidArgumentException; use InvalidArgumentException;
@ -51,7 +52,7 @@ class Request implements RequestInterface
} }
if ($body !== '' && $body !== null) { if ($body !== '' && $body !== null) {
$this->stream = stream_for($body); $this->stream = Utils::streamFor($body);
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
@ -100,7 +101,7 @@ class Response implements ResponseInterface
$this->statusCode = $status; $this->statusCode = $status;
if ($body !== '' && $body !== null) { if ($body !== '' && $body !== null) {
$this->stream = stream_for($body); $this->stream = Utils::streamFor($body);
} }
$this->setHeaders($headers); $this->setHeaders($headers);
@ -134,7 +135,7 @@ class Response implements ResponseInterface
if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) { if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) {
$reasonPhrase = self::$phrases[$new->statusCode]; $reasonPhrase = self::$phrases[$new->statusCode];
} }
$new->reasonPhrase = $reasonPhrase; $new->reasonPhrase = (string) $reasonPhrase;
return $new; return $new;
} }

View file

@ -79,8 +79,10 @@ class ServerRequest extends Request implements ServerRequestInterface
* Return an UploadedFile instance array. * Return an UploadedFile instance array.
* *
* @param array $files A array which respect $_FILES structure * @param array $files A array which respect $_FILES structure
* @throws InvalidArgumentException for unrecognized values *
* @return array * @return array
*
* @throws InvalidArgumentException for unrecognized values
*/ */
public static function normalizeFiles(array $files) public static function normalizeFiles(array $files)
{ {

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -76,8 +77,10 @@ class Stream implements StreamInterface
public function __toString() public function __toString()
{ {
try { try {
if ($this->isSeekable()) {
$this->seek(0); $this->seek(0);
return (string) stream_get_contents($this->stream); }
return $this->getContents();
} catch (\Exception $e) { } catch (\Exception $e) {
return ''; return '';
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -52,7 +53,7 @@ trait StreamDecoratorTrait
public function getContents() public function getContents()
{ {
return copy_to_string($this); return Utils::copyToString($this);
} }
/** /**
@ -140,6 +141,7 @@ trait StreamDecoratorTrait
* Implement in subclasses to dynamically create streams when requested. * Implement in subclasses to dynamically create streams when requested.
* *
* @return StreamInterface * @return StreamInterface
*
* @throws \BadMethodCallException * @throws \BadMethodCallException
*/ */
protected function createStream() protected function createStream()

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -23,6 +24,7 @@ class StreamWrapper
* @param StreamInterface $stream The stream to get a resource for * @param StreamInterface $stream The stream to get a resource for
* *
* @return resource * @return resource
*
* @throws \InvalidArgumentException if stream is not readable or writable * @throws \InvalidArgumentException if stream is not readable or writable
*/ */
public static function getResource(StreamInterface $stream) public static function getResource(StreamInterface $stream)

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use InvalidArgumentException; use InvalidArgumentException;
@ -85,6 +86,7 @@ class UploadedFile implements UploadedFileInterface
* Depending on the value set file or stream variable * Depending on the value set file or stream variable
* *
* @param mixed $streamOrFile * @param mixed $streamOrFile
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
private function setStreamOrFile($streamOrFile) private function setStreamOrFile($streamOrFile)
@ -104,6 +106,7 @@ class UploadedFile implements UploadedFileInterface
/** /**
* @param int $error * @param int $error
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
private function setError($error) private function setError($error)
@ -125,6 +128,7 @@ class UploadedFile implements UploadedFileInterface
/** /**
* @param int $size * @param int $size
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
private function setSize($size) private function setSize($size)
@ -158,6 +162,7 @@ class UploadedFile implements UploadedFileInterface
/** /**
* @param string|null $clientFilename * @param string|null $clientFilename
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
private function setClientFilename($clientFilename) private function setClientFilename($clientFilename)
@ -173,6 +178,7 @@ class UploadedFile implements UploadedFileInterface
/** /**
* @param string|null $clientMediaType * @param string|null $clientMediaType
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
private function setClientMediaType($clientMediaType) private function setClientMediaType($clientMediaType)
@ -220,6 +226,7 @@ class UploadedFile implements UploadedFileInterface
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @throws RuntimeException if the upload was not successful. * @throws RuntimeException if the upload was not successful.
*/ */
public function getStream() public function getStream()
@ -238,7 +245,9 @@ class UploadedFile implements UploadedFileInterface
* *
* @see http://php.net/is_uploaded_file * @see http://php.net/is_uploaded_file
* @see http://php.net/move_uploaded_file * @see http://php.net/move_uploaded_file
*
* @param string $targetPath Path to which to move the uploaded file. * @param string $targetPath Path to which to move the uploaded file.
*
* @throws RuntimeException if the upload was not successful. * @throws RuntimeException if the upload was not successful.
* @throws InvalidArgumentException if the $path specified is invalid. * @throws InvalidArgumentException if the $path specified is invalid.
* @throws RuntimeException on any error during the move operation, or on * @throws RuntimeException on any error during the move operation, or on
@ -259,7 +268,7 @@ class UploadedFile implements UploadedFileInterface
? rename($this->file, $targetPath) ? rename($this->file, $targetPath)
: move_uploaded_file($this->file, $targetPath); : move_uploaded_file($this->file, $targetPath);
} else { } else {
copy_to_stream( Utils::copyToStream(
$this->getStream(), $this->getStream(),
new LazyOpenStream($targetPath, 'w') new LazyOpenStream($targetPath, 'w')
); );

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;

398
vendor/guzzlehttp/psr7/src/Utils.php vendored Normal file
View file

@ -0,0 +1,398 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
final class Utils
{
/**
* Remove the items given by the keys, case insensitively from the data.
*
* @param iterable<string> $keys
*
* @return array
*/
public static function caselessRemove($keys, array $data)
{
$result = [];
foreach ($keys as &$key) {
$key = strtolower($key);
}
foreach ($data as $k => $v) {
if (!in_array(strtolower($k), $keys)) {
$result[$k] = $v;
}
}
return $result;
}
/**
* Copy the contents of a stream into another stream until the given number
* of bytes have been read.
*
* @param StreamInterface $source Stream to read from
* @param StreamInterface $dest Stream to write to
* @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream.
*
* @throws \RuntimeException on error.
*/
public static function copyToStream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)
{
$bufferSize = 8192;
if ($maxLen === -1) {
while (!$source->eof()) {
if (!$dest->write($source->read($bufferSize))) {
break;
}
}
} else {
$remaining = $maxLen;
while ($remaining > 0 && !$source->eof()) {
$buf = $source->read(min($bufferSize, $remaining));
$len = strlen($buf);
if (!$len) {
break;
}
$remaining -= $len;
$dest->write($buf);
}
}
}
/**
* Copy the contents of a stream into a string until the given number of
* bytes have been read.
*
* @param StreamInterface $stream Stream to read
* @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream.
* @return string
*
* @throws \RuntimeException on error.
*/
public static function copyToString(StreamInterface $stream, $maxLen = -1)
{
$buffer = '';
if ($maxLen === -1) {
while (!$stream->eof()) {
$buf = $stream->read(1048576);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
}
return $buffer;
}
$len = 0;
while (!$stream->eof() && $len < $maxLen) {
$buf = $stream->read($maxLen - $len);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
$len = strlen($buffer);
}
return $buffer;
}
/**
* Calculate a hash of a stream.
*
* This method reads the entire stream to calculate a rolling hash, based
* on PHP's `hash_init` functions.
*
* @param StreamInterface $stream Stream to calculate the hash for
* @param string $algo Hash algorithm (e.g. md5, crc32, etc)
* @param bool $rawOutput Whether or not to use raw output
*
* @return string Returns the hash of the stream
*
* @throws \RuntimeException on error.
*/
public static function hash(StreamInterface $stream, $algo, $rawOutput = false)
{
$pos = $stream->tell();
if ($pos > 0) {
$stream->rewind();
}
$ctx = hash_init($algo);
while (!$stream->eof()) {
hash_update($ctx, $stream->read(1048576));
}
$out = hash_final($ctx, (bool) $rawOutput);
$stream->seek($pos);
return $out;
}
/**
* Clone and modify a request with the given changes.
*
* This method is useful for reducing the number of clones needed to mutate
* a message.
*
* The changes can be one of:
* - method: (string) Changes the HTTP method.
* - set_headers: (array) Sets the given headers.
* - remove_headers: (array) Remove the given headers.
* - body: (mixed) Sets the given body.
* - uri: (UriInterface) Set the URI.
* - query: (string) Set the query string value of the URI.
* - version: (string) Set the protocol version.
*
* @param RequestInterface $request Request to clone and modify.
* @param array $changes Changes to apply.
*
* @return RequestInterface
*/
public static function modifyRequest(RequestInterface $request, array $changes)
{
if (!$changes) {
return $request;
}
$headers = $request->getHeaders();
if (!isset($changes['uri'])) {
$uri = $request->getUri();
} else {
// Remove the host header if one is on the URI
if ($host = $changes['uri']->getHost()) {
$changes['set_headers']['Host'] = $host;
if ($port = $changes['uri']->getPort()) {
$standardPorts = ['http' => 80, 'https' => 443];
$scheme = $changes['uri']->getScheme();
if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
$changes['set_headers']['Host'] .= ':'.$port;
}
}
}
$uri = $changes['uri'];
}
if (!empty($changes['remove_headers'])) {
$headers = self::caselessRemove($changes['remove_headers'], $headers);
}
if (!empty($changes['set_headers'])) {
$headers = self::caselessRemove(array_keys($changes['set_headers']), $headers);
$headers = $changes['set_headers'] + $headers;
}
if (isset($changes['query'])) {
$uri = $uri->withQuery($changes['query']);
}
if ($request instanceof ServerRequestInterface) {
return (new ServerRequest(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion(),
$request->getServerParams()
))
->withParsedBody($request->getParsedBody())
->withQueryParams($request->getQueryParams())
->withCookieParams($request->getCookieParams())
->withUploadedFiles($request->getUploadedFiles());
}
return new Request(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion()
);
}
/**
* Read a line from the stream up to the maximum allowed buffer length.
*
* @param StreamInterface $stream Stream to read from
* @param int|null $maxLength Maximum buffer length
*
* @return string
*/
public static function readLine(StreamInterface $stream, $maxLength = null)
{
$buffer = '';
$size = 0;
while (!$stream->eof()) {
// Using a loose equality here to match on '' and false.
if (null == ($byte = $stream->read(1))) {
return $buffer;
}
$buffer .= $byte;
// Break when a new line is found or the max length - 1 is reached
if ($byte === "\n" || ++$size === $maxLength - 1) {
break;
}
}
return $buffer;
}
/**
* Create a new stream based on the input type.
*
* Options is an associative array that can contain the following keys:
* - metadata: Array of custom metadata.
* - size: Size of the stream.
*
* This method accepts the following `$resource` types:
* - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
* - `string`: Creates a stream object that uses the given string as the contents.
* - `resource`: Creates a stream object that wraps the given PHP stream resource.
* - `Iterator`: If the provided value implements `Iterator`, then a read-only
* stream object will be created that wraps the given iterable. Each time the
* stream is read from, data from the iterator will fill a buffer and will be
* continuously called until the buffer is equal to the requested read size.
* Subsequent read calls will first read from the buffer and then call `next`
* on the underlying iterator until it is exhausted.
* - `object` with `__toString()`: If the object has the `__toString()` method,
* the object will be cast to a string and then a stream will be returned that
* uses the string value.
* - `NULL`: When `null` is passed, an empty stream object is returned.
* - `callable` When a callable is passed, a read-only stream object will be
* created that invokes the given callable. The callable is invoked with the
* number of suggested bytes to read. The callable can return any number of
* bytes, but MUST return `false` when there is no more data to return. The
* stream object that wraps the callable will invoke the callable until the
* number of requested bytes are available. Any additional bytes will be
* buffered and used in subsequent reads.
*
* @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data
* @param array $options Additional options
*
* @return StreamInterface
*
* @throws \InvalidArgumentException if the $resource arg is not valid.
*/
public static function streamFor($resource = '', array $options = [])
{
if (is_scalar($resource)) {
$stream = fopen('php://temp', 'r+');
if ($resource !== '') {
fwrite($stream, $resource);
fseek($stream, 0);
}
return new Stream($stream, $options);
}
switch (gettype($resource)) {
case 'resource':
return new Stream($resource, $options);
case 'object':
if ($resource instanceof StreamInterface) {
return $resource;
} elseif ($resource instanceof \Iterator) {
return new PumpStream(function () use ($resource) {
if (!$resource->valid()) {
return false;
}
$result = $resource->current();
$resource->next();
return $result;
}, $options);
} elseif (method_exists($resource, '__toString')) {
return Utils::streamFor((string) $resource, $options);
}
break;
case 'NULL':
return new Stream(fopen('php://temp', 'r+'), $options);
}
if (is_callable($resource)) {
return new PumpStream($resource, $options);
}
throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
}
/**
* Safely opens a PHP stream resource using a filename.
*
* When fopen fails, PHP normally raises a warning. This function adds an
* error handler that checks for errors and throws an exception instead.
*
* @param string $filename File to open
* @param string $mode Mode used to open the file
*
* @return resource
*
* @throws \RuntimeException if the file cannot be opened
*/
public static function tryFopen($filename, $mode)
{
$ex = null;
set_error_handler(function () use ($filename, $mode, &$ex) {
$ex = new \RuntimeException(sprintf(
'Unable to open %s using mode %s: %s',
$filename,
$mode,
func_get_args()[1]
));
});
$handle = fopen($filename, $mode);
restore_error_handler();
if ($ex) {
/** @var $ex \RuntimeException */
throw $ex;
}
return $handle;
}
/**
* Returns a UriInterface for the given value.
*
* This function accepts a string or UriInterface and returns a
* UriInterface for the given value. If the value is already a
* UriInterface, it is returned as-is.
*
* @param string|UriInterface $uri
*
* @return UriInterface
*
* @throws \InvalidArgumentException
*/
public static function uriFor($uri)
{
if ($uri instanceof UriInterface) {
return $uri;
}
if (is_string($uri)) {
return new Uri($uri);
}
throw new \InvalidArgumentException('URI must be a string or UriInterface');
}
}

View file

@ -1,10 +1,9 @@
<?php <?php
namespace GuzzleHttp\Psr7; namespace GuzzleHttp\Psr7;
use Psr\Http\Message\MessageInterface; use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
@ -14,52 +13,32 @@ use Psr\Http\Message\UriInterface;
* @param MessageInterface $message Message to convert to a string. * @param MessageInterface $message Message to convert to a string.
* *
* @return string * @return string
*
* @deprecated str will be removed in guzzlehttp/psr7:2.0. Use Message::toString instead.
*/ */
function str(MessageInterface $message) function str(MessageInterface $message)
{ {
if ($message instanceof RequestInterface) { return Message::toString($message);
$msg = trim($message->getMethod() . ' '
. $message->getRequestTarget())
. ' HTTP/' . $message->getProtocolVersion();
if (!$message->hasHeader('host')) {
$msg .= "\r\nHost: " . $message->getUri()->getHost();
}
} elseif ($message instanceof ResponseInterface) {
$msg = 'HTTP/' . $message->getProtocolVersion() . ' '
. $message->getStatusCode() . ' '
. $message->getReasonPhrase();
} else {
throw new \InvalidArgumentException('Unknown message type');
}
foreach ($message->getHeaders() as $name => $values) {
$msg .= "\r\n{$name}: " . implode(', ', $values);
}
return "{$msg}\r\n\r\n" . $message->getBody();
} }
/** /**
* Returns a UriInterface for the given value. * Returns a UriInterface for the given value.
* *
* This function accepts a string or {@see Psr\Http\Message\UriInterface} and * This function accepts a string or UriInterface and returns a
* returns a UriInterface for the given value. If the value is already a * UriInterface for the given value. If the value is already a
* `UriInterface`, it is returned as-is. * UriInterface, it is returned as-is.
* *
* @param string|UriInterface $uri * @param string|UriInterface $uri
* *
* @return UriInterface * @return UriInterface
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*
* @deprecated uri_for will be removed in guzzlehttp/psr7:2.0. Use Utils::uriFor instead.
*/ */
function uri_for($uri) function uri_for($uri)
{ {
if ($uri instanceof UriInterface) { return Utils::uriFor($uri);
return $uri;
} elseif (is_string($uri)) {
return new Uri($uri);
}
throw new \InvalidArgumentException('URI must be a string or UriInterface');
} }
/** /**
@ -69,86 +48,57 @@ function uri_for($uri)
* - metadata: Array of custom metadata. * - metadata: Array of custom metadata.
* - size: Size of the stream. * - size: Size of the stream.
* *
* This method accepts the following `$resource` types:
* - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
* - `string`: Creates a stream object that uses the given string as the contents.
* - `resource`: Creates a stream object that wraps the given PHP stream resource.
* - `Iterator`: If the provided value implements `Iterator`, then a read-only
* stream object will be created that wraps the given iterable. Each time the
* stream is read from, data from the iterator will fill a buffer and will be
* continuously called until the buffer is equal to the requested read size.
* Subsequent read calls will first read from the buffer and then call `next`
* on the underlying iterator until it is exhausted.
* - `object` with `__toString()`: If the object has the `__toString()` method,
* the object will be cast to a string and then a stream will be returned that
* uses the string value.
* - `NULL`: When `null` is passed, an empty stream object is returned.
* - `callable` When a callable is passed, a read-only stream object will be
* created that invokes the given callable. The callable is invoked with the
* number of suggested bytes to read. The callable can return any number of
* bytes, but MUST return `false` when there is no more data to return. The
* stream object that wraps the callable will invoke the callable until the
* number of requested bytes are available. Any additional bytes will be
* buffered and used in subsequent reads.
*
* @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data * @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data
* @param array $options Additional options * @param array $options Additional options
* *
* @return StreamInterface * @return StreamInterface
*
* @throws \InvalidArgumentException if the $resource arg is not valid. * @throws \InvalidArgumentException if the $resource arg is not valid.
*
* @deprecated stream_for will be removed in guzzlehttp/psr7:2.0. Use Utils::streamFor instead.
*/ */
function stream_for($resource = '', array $options = []) function stream_for($resource = '', array $options = [])
{ {
if (is_scalar($resource)) { return Utils::streamFor($resource, $options);
$stream = fopen('php://temp', 'r+');
if ($resource !== '') {
fwrite($stream, $resource);
fseek($stream, 0);
}
return new Stream($stream, $options);
}
switch (gettype($resource)) {
case 'resource':
return new Stream($resource, $options);
case 'object':
if ($resource instanceof StreamInterface) {
return $resource;
} elseif ($resource instanceof \Iterator) {
return new PumpStream(function () use ($resource) {
if (!$resource->valid()) {
return false;
}
$result = $resource->current();
$resource->next();
return $result;
}, $options);
} elseif (method_exists($resource, '__toString')) {
return stream_for((string) $resource, $options);
}
break;
case 'NULL':
return new Stream(fopen('php://temp', 'r+'), $options);
}
if (is_callable($resource)) {
return new PumpStream($resource, $options);
}
throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
} }
/** /**
* Parse an array of header values containing ";" separated data into an * Parse an array of header values containing ";" separated data into an
* array of associative arrays representing the header key value pair * array of associative arrays representing the header key value pair data
* data of the header. When a parameter does not contain a value, but just * of the header. When a parameter does not contain a value, but just
* contains a key, this function will inject a key with a '' string value. * contains a key, this function will inject a key with a '' string value.
* *
* @param string|array $header Header to parse into components. * @param string|array $header Header to parse into components.
* *
* @return array Returns the parsed header values. * @return array Returns the parsed header values.
*
* @deprecated parse_header will be removed in guzzlehttp/psr7:2.0. Use Header::parse instead.
*/ */
function parse_header($header) function parse_header($header)
{ {
static $trimmed = "\"' \n\t\r"; return Header::parse($header);
$params = $matches = [];
foreach (normalize_header($header) as $val) {
$part = [];
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
$m = $matches[0];
if (isset($m[1])) {
$part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
} else {
$part[] = trim($m[0], $trimmed);
}
}
}
if ($part) {
$params[] = $part;
}
}
return $params;
} }
/** /**
@ -158,32 +108,20 @@ function parse_header($header)
* @param string|array $header Header to normalize. * @param string|array $header Header to normalize.
* *
* @return array Returns the normalized header field values. * @return array Returns the normalized header field values.
*
* @deprecated normalize_header will be removed in guzzlehttp/psr7:2.0. Use Header::normalize instead.
*/ */
function normalize_header($header) function normalize_header($header)
{ {
if (!is_array($header)) { return Header::normalize($header);
return array_map('trim', explode(',', $header));
}
$result = [];
foreach ($header as $value) {
foreach ((array) $value as $v) {
if (strpos($v, ',') === false) {
$result[] = $v;
continue;
}
foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
$result[] = trim($vv);
}
}
}
return $result;
} }
/** /**
* Clone and modify a request with the given changes. * Clone and modify a request with the given changes.
* *
* This method is useful for reducing the number of clones needed to mutate a
* message.
*
* The changes can be one of: * The changes can be one of:
* - method: (string) Changes the HTTP method. * - method: (string) Changes the HTTP method.
* - set_headers: (array) Sets the given headers. * - set_headers: (array) Sets the given headers.
@ -197,72 +135,12 @@ function normalize_header($header)
* @param array $changes Changes to apply. * @param array $changes Changes to apply.
* *
* @return RequestInterface * @return RequestInterface
*
* @deprecated modify_request will be removed in guzzlehttp/psr7:2.0. Use Utils::modifyRequest instead.
*/ */
function modify_request(RequestInterface $request, array $changes) function modify_request(RequestInterface $request, array $changes)
{ {
if (!$changes) { return Utils::modifyRequest($request, $changes);
return $request;
}
$headers = $request->getHeaders();
if (!isset($changes['uri'])) {
$uri = $request->getUri();
} else {
// Remove the host header if one is on the URI
if ($host = $changes['uri']->getHost()) {
$changes['set_headers']['Host'] = $host;
if ($port = $changes['uri']->getPort()) {
$standardPorts = ['http' => 80, 'https' => 443];
$scheme = $changes['uri']->getScheme();
if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
$changes['set_headers']['Host'] .= ':'.$port;
}
}
}
$uri = $changes['uri'];
}
if (!empty($changes['remove_headers'])) {
$headers = _caseless_remove($changes['remove_headers'], $headers);
}
if (!empty($changes['set_headers'])) {
$headers = _caseless_remove(array_keys($changes['set_headers']), $headers);
$headers = $changes['set_headers'] + $headers;
}
if (isset($changes['query'])) {
$uri = $uri->withQuery($changes['query']);
}
if ($request instanceof ServerRequestInterface) {
return (new ServerRequest(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion(),
$request->getServerParams()
))
->withParsedBody($request->getParsedBody())
->withQueryParams($request->getQueryParams())
->withCookieParams($request->getCookieParams())
->withUploadedFiles($request->getUploadedFiles());
}
return new Request(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion()
);
} }
/** /**
@ -274,14 +152,12 @@ function modify_request(RequestInterface $request, array $changes)
* @param MessageInterface $message Message to rewind * @param MessageInterface $message Message to rewind
* *
* @throws \RuntimeException * @throws \RuntimeException
*
* @deprecated rewind_body will be removed in guzzlehttp/psr7:2.0. Use Message::rewindBody instead.
*/ */
function rewind_body(MessageInterface $message) function rewind_body(MessageInterface $message)
{ {
$body = $message->getBody(); Message::rewindBody($message);
if ($body->tell()) {
$body->rewind();
}
} }
/** /**
@ -294,29 +170,14 @@ function rewind_body(MessageInterface $message)
* @param string $mode Mode used to open the file * @param string $mode Mode used to open the file
* *
* @return resource * @return resource
*
* @throws \RuntimeException if the file cannot be opened * @throws \RuntimeException if the file cannot be opened
*
* @deprecated try_fopen will be removed in guzzlehttp/psr7:2.0. Use Utils::tryFopen instead.
*/ */
function try_fopen($filename, $mode) function try_fopen($filename, $mode)
{ {
$ex = null; return Utils::tryFopen($filename, $mode);
set_error_handler(function () use ($filename, $mode, &$ex) {
$ex = new \RuntimeException(sprintf(
'Unable to open %s using mode %s: %s',
$filename,
$mode,
func_get_args()[1]
));
});
$handle = fopen($filename, $mode);
restore_error_handler();
if ($ex) {
/** @var $ex \RuntimeException */
throw $ex;
}
return $handle;
} }
/** /**
@ -327,36 +188,14 @@ function try_fopen($filename, $mode)
* @param int $maxLen Maximum number of bytes to read. Pass -1 * @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream. * to read the entire stream.
* @return string * @return string
*
* @throws \RuntimeException on error. * @throws \RuntimeException on error.
*
* @deprecated copy_to_string will be removed in guzzlehttp/psr7:2.0. Use Utils::copyToString instead.
*/ */
function copy_to_string(StreamInterface $stream, $maxLen = -1) function copy_to_string(StreamInterface $stream, $maxLen = -1)
{ {
$buffer = ''; return Utils::copyToString($stream, $maxLen);
if ($maxLen === -1) {
while (!$stream->eof()) {
$buf = $stream->read(1048576);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
}
return $buffer;
}
$len = 0;
while (!$stream->eof() && $len < $maxLen) {
$buf = $stream->read($maxLen - $len);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
$len = strlen($buffer);
}
return $buffer;
} }
/** /**
@ -369,92 +208,48 @@ function copy_to_string(StreamInterface $stream, $maxLen = -1)
* to read the entire stream. * to read the entire stream.
* *
* @throws \RuntimeException on error. * @throws \RuntimeException on error.
*
* @deprecated copy_to_stream will be removed in guzzlehttp/psr7:2.0. Use Utils::copyToStream instead.
*/ */
function copy_to_stream( function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)
StreamInterface $source, {
StreamInterface $dest, return Utils::copyToStream($source, $dest, $maxLen);
$maxLen = -1
) {
$bufferSize = 8192;
if ($maxLen === -1) {
while (!$source->eof()) {
if (!$dest->write($source->read($bufferSize))) {
break;
}
}
} else {
$remaining = $maxLen;
while ($remaining > 0 && !$source->eof()) {
$buf = $source->read(min($bufferSize, $remaining));
$len = strlen($buf);
if (!$len) {
break;
}
$remaining -= $len;
$dest->write($buf);
}
}
} }
/** /**
* Calculate a hash of a Stream * Calculate a hash of a stream.
*
* This method reads the entire stream to calculate a rolling hash, based on
* PHP's `hash_init` functions.
* *
* @param StreamInterface $stream Stream to calculate the hash for * @param StreamInterface $stream Stream to calculate the hash for
* @param string $algo Hash algorithm (e.g. md5, crc32, etc) * @param string $algo Hash algorithm (e.g. md5, crc32, etc)
* @param bool $rawOutput Whether or not to use raw output * @param bool $rawOutput Whether or not to use raw output
* *
* @return string Returns the hash of the stream * @return string Returns the hash of the stream
*
* @throws \RuntimeException on error. * @throws \RuntimeException on error.
*
* @deprecated hash will be removed in guzzlehttp/psr7:2.0. Use Utils::hash instead.
*/ */
function hash( function hash(StreamInterface $stream, $algo, $rawOutput = false)
StreamInterface $stream, {
$algo, return Utils::hash($stream, $algo, $rawOutput);
$rawOutput = false
) {
$pos = $stream->tell();
if ($pos > 0) {
$stream->rewind();
}
$ctx = hash_init($algo);
while (!$stream->eof()) {
hash_update($ctx, $stream->read(1048576));
}
$out = hash_final($ctx, (bool) $rawOutput);
$stream->seek($pos);
return $out;
} }
/** /**
* Read a line from the stream up to the maximum allowed buffer length * Read a line from the stream up to the maximum allowed buffer length.
* *
* @param StreamInterface $stream Stream to read from * @param StreamInterface $stream Stream to read from
* @param int $maxLength Maximum buffer length * @param int|null $maxLength Maximum buffer length
* *
* @return string * @return string
*
* @deprecated readline will be removed in guzzlehttp/psr7:2.0. Use Utils::readLine instead.
*/ */
function readline(StreamInterface $stream, $maxLength = null) function readline(StreamInterface $stream, $maxLength = null)
{ {
$buffer = ''; return Utils::readLine($stream, $maxLength);
$size = 0;
while (!$stream->eof()) {
// Using a loose equality here to match on '' and false.
if (null == ($byte = $stream->read(1))) {
return $buffer;
}
$buffer .= $byte;
// Break when a new line is found or the max length - 1 is reached
if ($byte === "\n" || ++$size === $maxLength - 1) {
break;
}
}
return $buffer;
} }
/** /**
@ -463,26 +258,12 @@ function readline(StreamInterface $stream, $maxLength = null)
* @param string $message Request message string. * @param string $message Request message string.
* *
* @return Request * @return Request
*
* @deprecated parse_request will be removed in guzzlehttp/psr7:2.0. Use Message::parseRequest instead.
*/ */
function parse_request($message) function parse_request($message)
{ {
$data = _parse_message($message); return Message::parseRequest($message);
$matches = [];
if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
throw new \InvalidArgumentException('Invalid request string');
}
$parts = explode(' ', $data['start-line'], 3);
$version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
$request = new Request(
$parts[0],
$matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1],
$data['headers'],
$data['body'],
$version
);
return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
} }
/** /**
@ -491,139 +272,66 @@ function parse_request($message)
* @param string $message Response message string. * @param string $message Response message string.
* *
* @return Response * @return Response
*
* @deprecated parse_response will be removed in guzzlehttp/psr7:2.0. Use Message::parseResponse instead.
*/ */
function parse_response($message) function parse_response($message)
{ {
$data = _parse_message($message); return Message::parseResponse($message);
// According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
// between status-code and reason-phrase is required. But browsers accept
// responses without space and reason as well.
if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
}
$parts = explode(' ', $data['start-line'], 3);
return new Response(
$parts[1],
$data['headers'],
$data['body'],
explode('/', $parts[0])[1],
isset($parts[2]) ? $parts[2] : null
);
} }
/** /**
* Parse a query string into an associative array. * Parse a query string into an associative array.
* *
* If multiple values are found for the same key, the value of that key * If multiple values are found for the same key, the value of that key value
* value pair will become an array. This function does not parse nested * pair will become an array. This function does not parse nested PHP style
* PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will * arrays into an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed
* be parsed into ['foo[a]' => '1', 'foo[b]' => '2']). * into `['foo[a]' => '1', 'foo[b]' => '2'])`.
* *
* @param string $str Query string to parse * @param string $str Query string to parse
* @param int|bool $urlEncoding How the query string is encoded * @param int|bool $urlEncoding How the query string is encoded
* *
* @return array * @return array
*
* @deprecated parse_query will be removed in guzzlehttp/psr7:2.0. Use Query::parse instead.
*/ */
function parse_query($str, $urlEncoding = true) function parse_query($str, $urlEncoding = true)
{ {
$result = []; return Query::parse($str, $urlEncoding);
if ($str === '') {
return $result;
}
if ($urlEncoding === true) {
$decoder = function ($value) {
return rawurldecode(str_replace('+', ' ', $value));
};
} elseif ($urlEncoding === PHP_QUERY_RFC3986) {
$decoder = 'rawurldecode';
} elseif ($urlEncoding === PHP_QUERY_RFC1738) {
$decoder = 'urldecode';
} else {
$decoder = function ($str) { return $str; };
}
foreach (explode('&', $str) as $kvp) {
$parts = explode('=', $kvp, 2);
$key = $decoder($parts[0]);
$value = isset($parts[1]) ? $decoder($parts[1]) : null;
if (!isset($result[$key])) {
$result[$key] = $value;
} else {
if (!is_array($result[$key])) {
$result[$key] = [$result[$key]];
}
$result[$key][] = $value;
}
}
return $result;
} }
/** /**
* Build a query string from an array of key value pairs. * Build a query string from an array of key value pairs.
* *
* This function can use the return value of parse_query() to build a query * This function can use the return value of `parse_query()` to build a query
* string. This function does not modify the provided keys when an array is * string. This function does not modify the provided keys when an array is
* encountered (like http_build_query would). * encountered (like `http_build_query()` would).
* *
* @param array $params Query string parameters. * @param array $params Query string parameters.
* @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
* to encode using RFC3986, or PHP_QUERY_RFC1738 * to encode using RFC3986, or PHP_QUERY_RFC1738
* to encode using RFC1738. * to encode using RFC1738.
* @return string * @return string
*
* @deprecated build_query will be removed in guzzlehttp/psr7:2.0. Use Query::build instead.
*/ */
function build_query(array $params, $encoding = PHP_QUERY_RFC3986) function build_query(array $params, $encoding = PHP_QUERY_RFC3986)
{ {
if (!$params) { return Query::build($params, $encoding);
return '';
}
if ($encoding === false) {
$encoder = function ($str) { return $str; };
} elseif ($encoding === PHP_QUERY_RFC3986) {
$encoder = 'rawurlencode';
} elseif ($encoding === PHP_QUERY_RFC1738) {
$encoder = 'urlencode';
} else {
throw new \InvalidArgumentException('Invalid type');
}
$qs = '';
foreach ($params as $k => $v) {
$k = $encoder($k);
if (!is_array($v)) {
$qs .= $k;
if ($v !== null) {
$qs .= '=' . $encoder($v);
}
$qs .= '&';
} else {
foreach ($v as $vv) {
$qs .= $k;
if ($vv !== null) {
$qs .= '=' . $encoder($vv);
}
$qs .= '&';
}
}
}
return $qs ? (string) substr($qs, 0, -1) : '';
} }
/** /**
* Determines the mimetype of a file by looking at its extension. * Determines the mimetype of a file by looking at its extension.
* *
* @param $filename * @param string $filename
* *
* @return null|string * @return string|null
*
* @deprecated mimetype_from_filename will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromFilename instead.
*/ */
function mimetype_from_filename($filename) function mimetype_from_filename($filename)
{ {
return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION)); return MimeType::fromFilename($filename);
} }
/** /**
@ -632,119 +340,13 @@ function mimetype_from_filename($filename)
* @param $extension string The file extension. * @param $extension string The file extension.
* *
* @return string|null * @return string|null
*
* @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
* @deprecated mimetype_from_extension will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromExtension instead.
*/ */
function mimetype_from_extension($extension) function mimetype_from_extension($extension)
{ {
static $mimetypes = [ return MimeType::fromExtension($extension);
'3gp' => 'video/3gpp',
'7z' => 'application/x-7z-compressed',
'aac' => 'audio/x-aac',
'ai' => 'application/postscript',
'aif' => 'audio/x-aiff',
'asc' => 'text/plain',
'asf' => 'video/x-ms-asf',
'atom' => 'application/atom+xml',
'avi' => 'video/x-msvideo',
'bmp' => 'image/bmp',
'bz2' => 'application/x-bzip2',
'cer' => 'application/pkix-cert',
'crl' => 'application/pkix-crl',
'crt' => 'application/x-x509-ca-cert',
'css' => 'text/css',
'csv' => 'text/csv',
'cu' => 'application/cu-seeme',
'deb' => 'application/x-debian-package',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dvi' => 'application/x-dvi',
'eot' => 'application/vnd.ms-fontobject',
'eps' => 'application/postscript',
'epub' => 'application/epub+zip',
'etx' => 'text/x-setext',
'flac' => 'audio/flac',
'flv' => 'video/x-flv',
'gif' => 'image/gif',
'gz' => 'application/gzip',
'htm' => 'text/html',
'html' => 'text/html',
'ico' => 'image/x-icon',
'ics' => 'text/calendar',
'ini' => 'text/plain',
'iso' => 'application/x-iso9660-image',
'jar' => 'application/java-archive',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'js' => 'text/javascript',
'json' => 'application/json',
'latex' => 'application/x-latex',
'log' => 'text/plain',
'm4a' => 'audio/mp4',
'm4v' => 'video/mp4',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mov' => 'video/quicktime',
'mkv' => 'video/x-matroska',
'mp3' => 'audio/mpeg',
'mp4' => 'video/mp4',
'mp4a' => 'audio/mp4',
'mp4v' => 'video/mp4',
'mpe' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpg4' => 'video/mp4',
'oga' => 'audio/ogg',
'ogg' => 'audio/ogg',
'ogv' => 'video/ogg',
'ogx' => 'application/ogg',
'pbm' => 'image/x-portable-bitmap',
'pdf' => 'application/pdf',
'pgm' => 'image/x-portable-graymap',
'png' => 'image/png',
'pnm' => 'image/x-portable-anymap',
'ppm' => 'image/x-portable-pixmap',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'ps' => 'application/postscript',
'qt' => 'video/quicktime',
'rar' => 'application/x-rar-compressed',
'ras' => 'image/x-cmu-raster',
'rss' => 'application/rss+xml',
'rtf' => 'application/rtf',
'sgm' => 'text/sgml',
'sgml' => 'text/sgml',
'svg' => 'image/svg+xml',
'swf' => 'application/x-shockwave-flash',
'tar' => 'application/x-tar',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'torrent' => 'application/x-bittorrent',
'ttf' => 'application/x-font-ttf',
'txt' => 'text/plain',
'wav' => 'audio/x-wav',
'webm' => 'video/webm',
'webp' => 'image/webp',
'wma' => 'audio/x-ms-wma',
'wmv' => 'video/x-ms-wmv',
'woff' => 'application/x-font-woff',
'wsdl' => 'application/wsdl+xml',
'xbm' => 'image/x-xbitmap',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xml' => 'application/xml',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'yaml' => 'text/yaml',
'yml' => 'text/yaml',
'zip' => 'application/zip',
];
$extension = strtolower($extension);
return isset($mimetypes[$extension])
? $mimetypes[$extension]
: null;
} }
/** /**
@ -757,61 +359,13 @@ function mimetype_from_extension($extension)
* @param string $message HTTP request or response to parse. * @param string $message HTTP request or response to parse.
* *
* @return array * @return array
*
* @internal * @internal
* @deprecated _parse_message will be removed in guzzlehttp/psr7:2.0. Use Message::parseMessage instead.
*/ */
function _parse_message($message) function _parse_message($message)
{ {
if (!$message) { return Message::parseMessage($message);
throw new \InvalidArgumentException('Invalid message');
}
$message = ltrim($message, "\r\n");
$messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
if ($messageParts === false || count($messageParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
}
list($rawHeaders, $body) = $messageParts;
$rawHeaders .= "\r\n"; // Put back the delimiter we split previously
$headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
if ($headerParts === false || count($headerParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing status line');
}
list($startLine, $rawHeaders) = $headerParts;
if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
// Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
$rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
}
/** @var array[] $headerLines */
$count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
// If these aren't the same, then one line didn't match and there's an invalid header.
if ($count !== substr_count($rawHeaders, "\n")) {
// Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
}
throw new \InvalidArgumentException('Invalid header syntax');
}
$headers = [];
foreach ($headerLines as $headerLine) {
$headers[$headerLine[1]][] = $headerLine[2];
}
return [
'start-line' => $startLine,
'headers' => $headers,
'body' => $body,
];
} }
/** /**
@ -821,79 +375,43 @@ function _parse_message($message)
* @param array $headers Array of headers (each value an array). * @param array $headers Array of headers (each value an array).
* *
* @return string * @return string
*
* @internal * @internal
* @deprecated _parse_request_uri will be removed in guzzlehttp/psr7:2.0. Use Message::parseRequestUri instead.
*/ */
function _parse_request_uri($path, array $headers) function _parse_request_uri($path, array $headers)
{ {
$hostKey = array_filter(array_keys($headers), function ($k) { return Message::parseRequestUri($path, $headers);
return strtolower($k) === 'host';
});
// If no host is found, then a full URI cannot be constructed.
if (!$hostKey) {
return $path;
}
$host = $headers[reset($hostKey)][0];
$scheme = substr($host, -4) === ':443' ? 'https' : 'http';
return $scheme . '://' . $host . '/' . ltrim($path, '/');
} }
/** /**
* Get a short summary of the message body * Get a short summary of the message body.
* *
* Will return `null` if the response is not printable. * Will return `null` if the response is not printable.
* *
* @param MessageInterface $message The message to get the body summary * @param MessageInterface $message The message to get the body summary
* @param int $truncateAt The maximum allowed size of the summary * @param int $truncateAt The maximum allowed size of the summary
* *
* @return null|string * @return string|null
*
* @deprecated get_message_body_summary will be removed in guzzlehttp/psr7:2.0. Use Message::bodySummary instead.
*/ */
function get_message_body_summary(MessageInterface $message, $truncateAt = 120) function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
{ {
$body = $message->getBody(); return Message::bodySummary($message, $truncateAt);
if (!$body->isSeekable() || !$body->isReadable()) {
return null;
}
$size = $body->getSize();
if ($size === 0) {
return null;
}
$summary = $body->read($truncateAt);
$body->rewind();
if ($size > $truncateAt) {
$summary .= ' (truncated...)';
}
// Matches any printable character, including unicode characters:
// letters, marks, numbers, punctuation, spacing, and separators.
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
return null;
}
return $summary;
} }
/** @internal */ /**
* Remove the items given by the keys, case insensitively from the data.
*
* @param iterable<string> $keys
*
* @return array
*
* @internal
* @deprecated _caseless_remove will be removed in guzzlehttp/psr7:2.0. Use Utils::caselessRemove instead.
*/
function _caseless_remove($keys, array $data) function _caseless_remove($keys, array $data)
{ {
$result = []; return Utils::caselessRemove($keys, $data);
foreach ($keys as &$key) {
$key = strtolower($key);
}
foreach ($data as $k => $v) {
if (!in_array(strtolower($k), $keys)) {
$result[$k] = $v;
}
}
return $result;
} }

View file

@ -70,6 +70,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'azs' => 'application/vnd.airzip.filesecure.azs', 'azs' => 'application/vnd.airzip.filesecure.azs',
'azv' => 'image/vnd.airzip.accelerator.azv', 'azv' => 'image/vnd.airzip.accelerator.azv',
'azw' => 'application/vnd.amazon.ebook', 'azw' => 'application/vnd.amazon.ebook',
'b16' => 'image/vnd.pco.b16',
'bat' => 'application/x-msdownload', 'bat' => 'application/x-msdownload',
'bcpio' => 'application/x-bcpio', 'bcpio' => 'application/x-bcpio',
'bdf' => 'application/x-font-bdf', 'bdf' => 'application/x-font-bdf',

View file

@ -1,335 +0,0 @@
# OAuth 2.0 Client Changelog
## 2.5.0
_Released: 2020-07-18_
* Allow Guzzle 7.x to be used [#847](https://github.com/thephpleague/oauth2-client/pull/847)
## 2.4.1
_Released: 2018-11-22_
* Revert to use of `AccessToken` in type hints to preserve backwards
compatibility; this fixes the issue reported in [#752](https://github.com/thephpleague/oauth2-client/issues/752)
and [#753](https://github.com/thephpleague/oauth2-client/issues/753)
## 2.4.0
_Released: 2018-11-21_
* Add `HttpBasicAuthOptionProvider` to ease implementation for providers
requiring HTTP basic auth
* Add `GuardedPropertyTrait` to allow providers the ability to specify
properties that may not be overridden by user-defined values passed to the
provider constructor
* Add `AccessTokenInterface` and `ResourceOwnerAccessTokenInterface` to allow
providers the ability to override the default `AccessToken`
## 2.3.1
_Released: 2018-11-19_
* Allow paragonie/random_compat's empty 9.99.99 placeholder
* Throw an `UnexpectedValueException` on non-JSON responses from access token
request (when calling `AbstractProvider::getAccessToken()`)
## 2.3.0
_Released: 2018-01-13_
* Add `ProviderRedirectTrait` tool for 3rd-party provider libraries to use when
handling provider redirections
* Fix TypeError thrown because `getResourceOwner()` receives a non-JSON Response
* Gracefully handle non-standard errors received from providers
* Update README to reflect official support of PHP 7.2
## 2.2.1
_Released: 2017-04-25_
* Fix potential type error when HTTP 500 errors are encountered
* Allow broader range of `random_compat` versions
## 2.2.0
_Released: 2017-02-01_
* Allow base URLs to contain query parameters
* Protect against `+` being improperly encoded in URL parameters
* Remove misleading `state` option from authorization parameters
* Stop generating more random bytes than necessary
## 2.1.0
_Released: 2017-01-24_
* Allow `expires_in` with a value of `0`
## 2.0.0
_Released: 2017-01-12_
* Rename `getResponse()` to `getParsedResponse()`
* Add `getResponse()` method that returns the unparsed PSR-7 `Response` instance
* Removed `RandomFactory`, switched to native random functions
## 1.4.1
_Released: 2016-04-29_
* Add `QueryBuilderTrait` to standardize query string generation.
## 1.4.0
_Released: 2016-04-19_
* Add `AccessToken::getValues()` to access additional vendor data provided with tokens.
## 1.3.0
_Released: 2016-02-13_
* Enable dynamic parameters being passed into the authorization URL.
* Minor documentation updates.
## 1.2.0
_Released: 2016-01-23_
* Add `resource_owner_id` to the JSON-serialized representation of the access token.
* Minor documentation updates and improved test coverage.
## 1.1.0
_Released: 2015-11-13_
* Add `ArrayAccessorTrait`, update `AbstractProvider` to utilize.
* Use `expires` to serialize access tokens.
* Documentation updates.
## 1.0.2
_Released: 2015-09-22_
* Allow access tokens to be created from storage (see #431).
* Minor fixes and documentation updates.
## 1.0.1
_Released: 2015-08-26_
* Allow required parameters checked using the `RequiredParameterTrait` to be set as `false`, `null`, `"0"`, etc.
## 1.0.0
_Released: 2015-08-19_
* We are running code-quality builds through Scrutinizer, and we are running unit test builds on the new Travis CI container-based infrastructure.
* Cleaned up code, as recommended by Scrutinizer.
* Documentation updates.
## 1.0.0-beta2
_Released: 2015-08-12_
* BREAK: Add toArray() to ResourceOwnerInterface.
* Always attempt to parse responses as JSON and fallback on failure.
* Add dot notation support to access token resource owner ID.
* Use the Bearer authorization header for the generic provider.
* Documentation updates.
## 1.0.0-beta1
_Released: 2015-07-16_
* API for 1.0 is now frozen!
* BREAK: Convert all uses of "User" to "ResourceOwner" to more closely match the OAuth 2.0 specification.
* BREAK: Rename `StandardProvider` to `GenericProvider`.
* BREAK: Move access token creation to the `AbstractProvider`. It was previously handled in the `AbstractGrant`.
* FIX: Add `Content-Type` header with value of `application/x-www-form-urlencoded` to the request header when retrieving access tokens. This adheres to the OAuth 2.0 specification and fixes issues where certain OAuth servers expect this header.
* Enhanced `json_encode()` serialization of AccessToken; when using `json_encode()` on an AccessToken, it will return a JSON object with these properties: `access_token`, `refresh_token`, and `expires_in`.
## 1.0.0-alpha2
_Released: 2015-07-04_
* BREAK: Renamed `AbstractProvider::ACCESS_TOKEN_METHOD_GET` to `AbstractProvider::METHOD_GET`.
* BREAK: Renamed `AbstractProvider::ACCESS_TOKEN_METHOD_POST` to `AbstractProvider::METHOD_POST`.
* BREAK: Renamed `AbstractProvider::prepareUserDetails()` to `AbstractProvider::createUser()`.
* BREAK: Renamed `AbstractProvider::getUserDetails()` to `AbstractProvider::getUser()`.
* BREAK: Removed `$token` parameter from `AbstractProvider::getDefaultHeaders()`.
* BREAK: Modify `AbstractProvider::getBaseAccessTokenUrl()` to accept a required array of parameters, allowing providers the ability to vary the access token URL, based on the parameters.
* Removed newline characters from MAC Authorization header.
* Documentation updates, notably:
- Moved list of providers to `README.PROVIDERS.md`.
- Moved provider creation notes to `README.PROVIDER-GUIDE.md`.
## 1.0.0-alpha1
_Released: 2015-06-25_
This release contains numerous BC breaks from the 0.x series. Please note these breaks and refer to the [upgrade guide](GUIDE-UPGRADING.md).
* BREAK: Requires PHP 5.5.0 and greater.
* BREAK: All providers have been moved to separate repositories, one for each provider.
* BREAK: All `public` properties have been set as `protected` or `private` and getters/setters have been introduced for access to these properties.
* BREAK: The `Provider\ProviderInterface` has been removed. Please extend from and override `Provider\AbstractProvider`.
* BREAK: The `Entity\User` has been removed. Providers should implement the `Provider\UserInterface` and provide user functionality instead of expecting it in this base library.
* BREAK: The `Grant\GrantInterface` has been removed. Providers needing to provide a new grant type should extend from and override `Grant\AbstractGrant`.
* A generic `Provider\StandardProvider` has been introduced, which may be used as a client to integrate with most OAuth 2.0 compatible servers.
* A `Grant\GrantFactory` has been introduced as a means to register and retrieve singleton grants from a registry.
* Introduced traits for bearer and MAC authorization (`Tool\BearerAuthorizationTrait` and `Tool\MacAuthorizationTrait`), which providers may use to enable these header authorization types.
## 0.12.1
_Released: 2015-06-20_
* FIX: Scope separators for LinkedIn and Instagram are now correctly a single space
## 0.12.0
_Released: 2015-06-15_
* BREAK: LinkedIn Provider: Default scopes removed from LinkedIn Provider. See "[Managing LinkedIn Scopes](https://github.com/thephpleague/oauth2-client/blob/9cea9864c2e89bce1b922d1e37ba5378b3b0b264/README.md#managing-linkedin-scopes)" in the README for information on how to set scopes. See [#327](https://github.com/thephpleague/oauth2-client/pull/327) and [#307](https://github.com/thephpleague/oauth2-client/pull/307) for details on this change.
* FIX: LinkedIn Provider: A scenario existed in which `publicProfileUrl` was not set, generating a PHP notice; this has been fixed.
* FIX: Instagram Provider: Fixed scope separator.
* Documentation updates and corrections.
## 0.11.0
_Released: 2015-04-25_
* Identity Provider: Better handling of error responses
* Documentation updates
## 0.10.1
_Released: 2015-04-02_
* FIX: Invalid JSON triggering fatal error
* FIX: Sending headers along with auth `getAccessToken()` requests
* Now running Travis CI tests on PHP 7
* Documentation updates
## 0.10.0
_Released: 2015-03-10_
* Providers: Added `getHeaders()` to ProviderInterface and updated AbstractProvider to provide the method
* Providers: Updated all bundled providers to support new `$authorizationHeader` property
* Identity Provider: Update IDPException to account for empty strings
* Identity Provider: Added `getResponseBody()` method to IDPException
* Documentation updates, minor bug fixes, and coding standards fixes
## 0.9.0
_Released: 2015-02-24_
* Add `AbstractProvider::prepareAccessTokenResult()` to provide additional token response preparation to providers
* Remove custom provider code from AccessToken
* Add links to README for Dropbox and Square providers
## 0.8.1
_Released: 2015-02-12_
* Allow `approval_prompt` to be set by providers. This fixes an issue where some providers have problems if the `approval_prompt` is present in the query string.
## 0.8.0
_Released: 2015-02-10_
* Facebook Provider: Upgrade to Graph API v2.2
* Google Provider: Add `access_type` parameter for Google authorization URL
* Get a more reliable response body on errors
## 0.7.2
_Released: 2015-02-03_
* GitHub Provider: Fix regression
* Documentation updates
## 0.7.1
_Released: 2015-01-06_
* Google Provider: fixed issue where Google API was not returning the user ID
## 0.7.0
_Released: 2014-12-29_
* Improvements to Provider\AbstractProvider (addition of `userUid()`, `userEmail()`, and `userScreenName()`)
* GitHub Provider: Support for GitHub Enterprise
* GitHub Provider: Methods to allow fetching user email addresses
* Google Provider: Updated scopes and endpoints to remove deprecated values
* Documentation updates, minor bug fixes, and coding standards fixes
## 0.6.0
_Released: 2014-12-03_
* Added ability to specify a redirect handler for providers through use of a callback (see [Provider\AbstractProvider::setRedirectHandler()](https://github.com/thephpleague/oauth2-client/blob/55de45401eaa21f53c0b2414091da6f3b0f3fcb7/src/Provider/AbstractProvider.php#L314-L317))
* Updated authorize and token URLs for the Microsoft provider; the old URLs had been phased out and were no longer working (see #146)
* Increased test coverage
* Documentation updates, minor bug fixes, and coding standards fixes
## 0.5.0
_Released: 2014-11-28_
* Added `ClientCredentials` and `Password` grants
* Added support for providers to set their own `uid` parameter key name
* Added support for Google's `hd` (hosted domain) parameter
* Added support for providing a custom `state` parameter to the authorization URL
* LinkedIn `pictureUrl` is now an optional response element
* Added Battle.net provider package link to README
* Added Meetup provider package link to README
* Added `.gitattributes` file
* Increased test coverage
* A number of documentation fixes, minor bug fixes, and coding standards fixes
## 0.4.0
_Released: 2014-10-28_
* Added `ProviderInterface` and removed `IdentityProvider`.
* Expose generated state to allow for CSRF validation.
* Renamed `League\OAuth2\Client\Provider\User` to `League\OAuth2\Client\Entity\User`.
* Entity: User: added `gender` and `locale` properties
* Updating logic for populating the token expiration time.
## 0.3.0
_Released: 2014-04-26_
* This release made some huge leaps forward, including 100% unit-coverage and a bunch of new features.
## 0.2.0
_Released: 2013-05-28_
* No release notes available.
## 0.1.0
_Released: 2013-05-25_
* Initial release.

View file

@ -1,76 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
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
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
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at https://twitter.com/thephpleague. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View file

@ -1,39 +0,0 @@
# Contributing
Contributions are **welcome** and will be fully **credited**.
We accept contributions via Pull Requests on [Github](https://github.com/thephpleague/oauth2-client).
## Pull Requests
- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
- **Add tests!** - Your patch won't be accepted if it doesn't have tests.
- **Document any change in behaviour** - Make sure the README and any other relevant documentation are kept up-to-date.
- **Consider our release cycle** - We try to follow SemVer. Randomly breaking public APIs is not an option.
- **Create topic branches** - Don't ask us to pull from your master branch.
- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.
- **Ensure tests pass!** - Please run the tests (see below) before submitting your pull request, and make sure they pass. We won't accept a patch until all tests pass.
- **Ensure no coding standards violations** - Please run PHP Code Sniffer using the PSR-2 standard (see below) before submitting your pull request. A violation will cause the build to fail, so please make sure there are no violations. We can't accept a patch if the build fails.
## Testing
The following tests must pass for a build to be considered successful. If contributing, please ensure these pass before submitting a pull request.
``` bash
$ ./vendor/bin/parallel-lint src test
$ ./vendor/bin/phpunit --coverage-text
$ ./vendor/bin/phpcs src --standard=psr2 -sp
```
**Happy coding**!

View file

@ -1,20 +0,0 @@
# OAuth 2.0 Client
## Authors
Also see <https://github.com/thephpleague/oauth2-client/contributors>.
### Current Maintainer
- [Ben Ramsey](https://github.com/ramsey)
### Contributors
- [Alex Bilbie](https://github.com/alexbilbie)
- [Ben Corlett](https://github.com/bencorlett)
- [Ben Ramsey](https://github.com/ramsey)
- [James Mills](https://github.com/jamesmills)
- [Phil Sturgeon](https://github.com/philsturgeon)
- [Rudi Theunissen](https://github.com/rtheunissen)
- [Tom Anderson](https://github.com/TomHAnderson)
- [Woody Gilk](https://github.com/shadowhand)

View file

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013-2018 Alex Bilbie <hello@alexbilbie.com> Copyright (c) 2013-2020 Alex Bilbie <hello@alexbilbie.com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,96 +0,0 @@
# OAuth 2.0 Client
## Provider Guide
New providers may be created by copying the layout of an existing package. See
the [list of providers](docs/providers/thirdparty.md) for good examples.
When choosing a name for your package, please dont use the `league` vendor
prefix, as this implies that it is officially supported. You should use your own
username as the vendor prefix, and prepend `oauth2-` to the package name to make
it clear that your package works with OAuth2 Client. For example, if your GitHub
username was "santa," and you were implementing the "giftpay" OAuth2 library, a
good name for your composer package would be `santa/oauth2-giftpay`.
### Implementing your own provider
If you are working with an oauth2 service not supported out-of-the-box or by an
existing package, it is quite simple to implement your own. Simply extend
[`League\OAuth2\Client\Provider\AbstractProvider`](src/Provider/AbstractProvider.php)
and implement the required abstract methods:
```php
abstract public function getBaseAuthorizationUrl();
abstract public function getBaseAccessTokenUrl(array $params);
abstract public function getResourceOwnerDetailsUrl(AccessToken $token);
abstract protected function getDefaultScopes();
abstract protected function checkResponse(ResponseInterface $response, $data);
abstract protected function createResourceOwner(array $response, AccessToken $token);
```
Each of these abstract methods contain a docblock defining their expectations
and typical behavior. Once you have extended this class, you can simply follow
the [usage example in the README](README.md#usage) using your new `Provider`.
If you wish to use the `Provider` to make authenticated requests to the
service, you will also need to define how you provide the token to the
service. If this is done via headers, you should override this method:
```php
protected function getAuthorizationHeaders($token = null);
```
This package comes with a trait for implementing `Bearer` authorization.
To use this, you just need to include the trait in your `Provider` class:
```php
<?php
class SomeProvider extends AbstractProvider
{
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
/** ... **/
}
```
### Resource owner identifiers in access token responses
In services where the resource owner is a person, the resource owner is sometimes
referred to as an end-user.
We have decided to abstract away as much of the resource owner details as possible,
since these are not part of the OAuth 2.0 specification and are very specific to each
service provider. This provides greater flexibility to each provider, allowing
them to handle the implementation details for resource owners.
The `AbstractProvider` does not specify an access token resource owner identifier. It is
the responsibility of the provider class to set the `ACCESS_TOKEN_RESOURCE_OWNER_ID` constant
to the string value of the key used in the access token response to identify the
resource owner.
```php
/**
* @var string Key used in the access token response to identify the resource owner.
*/
const ACCESS_TOKEN_RESOURCE_OWNER_ID = null;
```
Once this is set on your provider, when calling `AbstractProvider::getAccessToken()`,
the `AccessToken` returned will have its `$resourceOwnerId` property set, which you may
retrieve by calling `AccessToken::getResourceOwnerId()`.
The next step is to implement the `AbstractProvider::createResourceOwner()` method. This
method accepts as parameters a response array and an `AccessToken`. You may use
this information in order to request resource owner details from your service and
construct and return an object that implements
[`League\OAuth2\Client\Provider\ResourceOwnerInterface`](src/Provider/ResourceOwnerInterface.php).
This object is returned when calling `AbstractProvider::getResourceOwner()`.
### Make your gateway official
If you want to transfer your provider to the `thephpleague` GitHub organization
and add it to the list of officially supported providers, please open a pull
request on the thephpleague/oauth2-client package. Before new providers will be
accepted, they must have 100% unit test code coverage, and follow the
conventions and code style used in other OAuth2 Client providers.

View file

@ -3,12 +3,11 @@
This package makes it simple to integrate your application with [OAuth 2.0](http://oauth.net/2/) service providers. This package makes it simple to integrate your application with [OAuth 2.0](http://oauth.net/2/) service providers.
[![Gitter Chat](https://img.shields.io/badge/gitter-join_chat-brightgreen.svg?style=flat-square)](https://gitter.im/thephpleague/oauth2-client) [![Gitter Chat](https://img.shields.io/badge/gitter-join_chat-brightgreen.svg?style=flat-square)](https://gitter.im/thephpleague/oauth2-client)
[![Source Code](http://img.shields.io/badge/source-thephpleague/oauth2--client-blue.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client) [![Source Code](https://img.shields.io/badge/source-thephpleague/oauth2--client-blue.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client)
[![Latest Version](https://img.shields.io/github/release/thephpleague/oauth2-client.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client/releases) [![Latest Version](https://img.shields.io/github/release/thephpleague/oauth2-client.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client/releases)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client/blob/master/LICENSE) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client/blob/master/LICENSE)
[![Build Status](https://img.shields.io/travis/thephpleague/oauth2-client/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/oauth2-client) [![Build Status](https://img.shields.io/github/workflow/status/thephpleague/oauth2-client/CI?label=CI&logo=github&style=flat-square)](https://github.com/thephpleague/oauth2-client/actions?query=workflow%3ACI)
[![Scrutinizer](https://img.shields.io/scrutinizer/g/thephpleague/oauth2-client/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/oauth2-client/) [![Codecov Code Coverage](https://img.shields.io/codecov/c/gh/thephpleague/oauth2-client?label=codecov&logo=codecov&style=flat-square)](https://codecov.io/gh/thephpleague/oauth2-client)
[![Coverage Status](https://img.shields.io/coveralls/thephpleague/oauth2-client/master.svg?style=flat-square)](https://coveralls.io/r/thephpleague/oauth2-client?branch=master)
[![Total Downloads](https://img.shields.io/packagist/dt/league/oauth2-client.svg?style=flat-square)](https://packagist.org/packages/league/oauth2-client) [![Total Downloads](https://img.shields.io/packagist/dt/league/oauth2-client.svg?style=flat-square)](https://packagist.org/packages/league/oauth2-client)
--- ---
@ -30,6 +29,8 @@ The following versions of PHP are supported.
* PHP 7.1 * PHP 7.1
* PHP 7.2 * PHP 7.2
* PHP 7.3 * PHP 7.3
* PHP 7.4
* PHP 8.0
## Providers ## Providers

View file

@ -6,16 +6,15 @@
"sort-packages": true "sort-packages": true
}, },
"require": { "require": {
"php": "^5.6|^7.0", "php": "^5.6 || ^7.0 || ^8.0",
"guzzlehttp/guzzle": "^6.0 || ^7.0", "guzzlehttp/guzzle": "^6.0 || ^7.0",
"paragonie/random_compat": "^1|^2|^9.99" "paragonie/random_compat": "^1 || ^2 || ^9.99"
}, },
"require-dev": { "require-dev": {
"eloquent/liberator": "^2.0", "mockery/mockery": "^1.3",
"eloquent/phony-phpunit": "^1.0|^3.0", "php-parallel-lint/php-parallel-lint": "^1.2",
"jakub-onderka/php-parallel-lint": "^0.9.2", "phpunit/phpunit": "^5.7 || ^6.0 || ^9.3",
"phpunit/phpunit": "^5.7|^6.0", "squizlabs/php_codesniffer": "^2.3 || ^3.0"
"squizlabs/php_codesniffer": "^2.3|^3.0"
}, },
"keywords": [ "keywords": [
"oauth", "oauth",

View file

@ -49,6 +49,40 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter
*/ */
protected $values = []; protected $values = [];
/**
* @var int
*/
private static $timeNow;
/**
* Set the time now. This should only be used for testing purposes.
*
* @param int $timeNow the time in seconds since epoch
* @return void
*/
public static function setTimeNow($timeNow)
{
self::$timeNow = $timeNow;
}
/**
* Reset the time now if it was set for test purposes.
*
* @return void
*/
public static function resetTimeNow()
{
self::$timeNow = null;
}
/**
* @return int
*/
public function getTimeNow()
{
return self::$timeNow ? self::$timeNow : time();
}
/** /**
* Constructs an access token. * Constructs an access token.
* *
@ -80,14 +114,14 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter
throw new \InvalidArgumentException('expires_in value must be an integer'); throw new \InvalidArgumentException('expires_in value must be an integer');
} }
$this->expires = $options['expires_in'] != 0 ? time() + $options['expires_in'] : 0; $this->expires = $options['expires_in'] != 0 ? $this->getTimeNow() + $options['expires_in'] : 0;
} elseif (!empty($options['expires'])) { } elseif (!empty($options['expires'])) {
// Some providers supply the seconds until expiration rather than // Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received. // the exact timestamp. Take a best guess at which we received.
$expires = $options['expires']; $expires = $options['expires'];
if (!$this->isExpirationTimestamp($expires)) { if (!$this->isExpirationTimestamp($expires)) {
$expires += time(); $expires += $this->getTimeNow();
} }
$this->expires = $expires; $this->expires = $expires;

View file

@ -34,7 +34,7 @@ interface AccessTokenInterface extends JsonSerializable
public function getRefreshToken(); public function getRefreshToken();
/** /**
* Returns the expiration timestamp, if defined. * Returns the expiration timestamp in seconds, if defined.
* *
* @return integer|null * @return integer|null
*/ */

View file

@ -7,6 +7,9 @@ use League\OAuth2\Client\Provider\Exception\FacebookProviderException;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
/**
* @method FacebookUser getResourceOwner(AccessToken $token)
*/
class Facebook extends AbstractProvider class Facebook extends AbstractProvider
{ {
/** /**
@ -103,7 +106,7 @@ class Facebook extends AbstractProvider
$fields = [ $fields = [
'id', 'name', 'first_name', 'last_name', 'id', 'name', 'first_name', 'last_name',
'email', 'hometown', 'picture.type(large){url,is_silhouette}', 'email', 'hometown', 'picture.type(large){url,is_silhouette}',
'gender', 'link', 'age_range' 'gender', 'age_range'
]; ];
// backwards compatibility less than 2.8 // backwards compatibility less than 2.8

View file

@ -1,5 +0,0 @@
vendor/
scratch.php
composer.lock
build/
.php_cs.cache

View file

@ -1,14 +0,0 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
;
return PhpCsFixer\Config::create()
->setRules(array(
'@Symfony' => true,
'concat_space' => array('spacing' => 'one'),
'phpdoc_annotation_without_dot' => false,
))
->setFinder($finder)
;

View file

@ -1,41 +0,0 @@
tools:
php_mess_detector: true
php_analyzer:
config:
parameter_reference_check: { enabled: false }
checkstyle: { enabled: false, no_trailing_whitespace: true, naming: { enabled: true, local_variable: '^[a-z][a-zA-Z0-9]*$', abstract_class_name: ^Abstract|Factory$, utility_class_name: 'Utils?$', constant_name: '^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$', property_name: '^[a-z][a-zA-Z0-9]*$', method_name: '^(?:[a-z]|__)[a-zA-Z0-9]*$', parameter_name: '^[a-z][a-zA-Z0-9]*$', interface_name: '^[A-Z][a-zA-Z0-9]*Interface$', type_name: '^[A-Z][a-zA-Z0-9]*$', exception_name: '^[A-Z][a-zA-Z0-9]*Exception$', isser_method_name: '^(?:is|has|should|may|supports)' } }
unreachable_code: { enabled: false }
check_access_control: { enabled: false }
typo_checks: { enabled: false }
check_variables: { enabled: false }
check_calls: { enabled: true, too_many_arguments: true, missing_argument: true, argument_type_checks: lenient }
suspicious_code: { enabled: false, overriding_parameter: false, overriding_closure_use: false, parameter_closure_use_conflict: false, parameter_multiple_times: false, non_existent_class_in_instanceof_check: false, non_existent_class_in_catch_clause: false, assignment_of_null_return: false, non_commented_switch_fallthrough: false, non_commented_empty_catch_block: false, overriding_private_members: false, use_statement_alias_conflict: false, precedence_in_condition_assignment: false }
dead_assignments: { enabled: false }
verify_php_doc_comments: { enabled: false, parameters: false, return: false, suggest_more_specific_types: false, ask_for_return_if_not_inferrable: false, ask_for_param_type_annotation: false }
loops_must_use_braces: { enabled: false }
check_usage_context: { enabled: true, foreach: { value_as_reference: true, traversable: true } }
simplify_boolean_return: { enabled: false }
phpunit_checks: { enabled: false }
reflection_checks: { enabled: false }
precedence_checks: { enabled: true, assignment_in_condition: true, comparison_of_bit_result: true }
basic_semantic_checks: { enabled: false }
unused_code: { enabled: false }
deprecation_checks: { enabled: false }
useless_function_calls: { enabled: false }
metrics_lack_of_cohesion_methods: { enabled: false }
metrics_coupling: { enabled: true, stable_code: { namespace_prefixes: { }, classes: { } } }
doctrine_parameter_binding: { enabled: false }
doctrine_entity_manager_injection: { enabled: false }
symfony_request_injection: { enabled: false }
doc_comment_fixes: { enabled: false }
reflection_fixes: { enabled: false }
use_statement_fixes: { enabled: true, remove_unused: true, preserve_multiple: false, preserve_blanklines: false, order_alphabetically: false }
php_code_sniffer: true
sensiolabs_security_checker: true
php_cpd: true
php_loc: true
php_pdepend: true
external_code_coverage: true
filter:
paths:
- src/*

View file

@ -1,43 +0,0 @@
language: php
dist: trusty
sudo: false
matrix:
include:
- php: 5.3
dist: precise
env: COMPOSER_FLAGS="--prefer-lowest"
- php: 5.4
- php: 5.5
- php: 5.6
env: SCRUTINIZER=1
- php: 7.0
env: COMPOSER_FLAGS="--prefer-lowest"
- php: 7.1
env: CS_FIXER=1
- php: 7.2
- php: 7.3
env: BENCHMARK=1
- php: 7.4snapshot
fast_finish: true
cache:
directories:
- $HOME/.composer/cache
before_script:
- composer self-update
- composer update $COMPOSER_FLAGS --prefer-dist
script:
- stty cols 120
- if [ "$CS_FIXER" == 1 ]; then wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.13.1/php-cs-fixer.phar && php php-cs-fixer.phar fix --dry-run --diff; fi
- mkdir -p build/logs
- ./vendor/bin/phpunit --coverage-clover=coverage.xml
after_script:
- if [ "$SCRUTINIZER" == 1 ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.xml; fi
- if [ "$BENCHMARK" == 1 ]; then php test/benchmark/run.php 10; fi
notifications:
irc: "irc.freenode.net#masterminds"

View file

@ -1,5 +1,11 @@
# Release Notes # Release Notes
2.7.4 (2020-10-01)
- #191: Fix travisci build
- #195: Add .gitattributes file with export-ignore rules
- #194: Fix query parameter parsed as character entity
2.7.3 (2020-07-05) 2.7.3 (2020-07-05)
- #190: mitigate cyclic reference between output rules and the traverser objects - #190: mitigate cyclic reference between output rules and the traverser objects

View file

@ -26,9 +26,7 @@
"php" : ">=5.3.0" "php" : ">=5.3.0"
}, },
"require-dev": { "require-dev": {
"satooshi/php-coveralls": "1.0.*", "phpunit/phpunit" : "^4.8.35"
"phpunit/phpunit" : "^4.8.35",
"sami/sami": "~2.0"
}, },
"autoload": { "autoload": {
"psr-4": {"Masterminds\\": "src"} "psr-4": {"Masterminds\\": "src"}

View file

@ -1,32 +0,0 @@
<?php
require 'vendor/autoload.php';
use Masterminds\HTML5;
$html = <<< 'HERE'
<html>
<head>
<title>TEST</title>
<script language="javascript">
if (2 > 1) { alert("Math wins."); }
</script>
</head>
<body id='foo'>
<!-- This space intentionally left blank. -->
<section class="section-a pretty" id="bar1">
<h1>Hello World</h1><p>This is a test of the HTML5 parser.</p>
<hr>
&amp; Nobody nowhere.
</section>
<test xmlns:foo="http://example.com/foo">TEST</test>
<![CDATA[Because we can.]]>
&copy;
</body></html>
HERE;
$html5 = new HTML5();
$dom = $html5->loadHTML($html);
echo "Converting to HTML 5\n";
$html5->save($dom, fopen('php://stdin', 'w'));

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="PHPUnit">
<directory>test/HTML5/</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<file>systemlib.phpreflection_hni</file>
<file>src/HTML5/Parser/InputStream.php</file>
<file>src/HTML5/Serializer/RulesInterface.php</file>
<file>src/HTML5/Entities.php</file>
<file>src/HTML5/Serializer/HTML5Entities.php</file>
</blacklist>
</filter>
</phpunit>

View file

@ -1,10 +0,0 @@
<?php
use Sami\Sami;
return new Sami(__DIR__ . '/src', array(
'title' => 'HTML5-PHP API',
'build_dir' => __DIR__ . '/build/apidoc',
'cache_dir' => __DIR__ . '/build/sami-cache',
'default_opened_level' => 1,
));

View file

@ -475,7 +475,7 @@ class DOMTreeBuilder implements EventHandler
$lname = $this->normalizeTagName($name); $lname = $this->normalizeTagName($name);
// Special case within 12.2.6.4.7: An end tag whose tag name is "br" should be treated as an opening tag // Special case within 12.2.6.4.7: An end tag whose tag name is "br" should be treated as an opening tag
if ($name === 'br') { if ('br' === $name) {
$this->parseError('Closing tag encountered for void element br.'); $this->parseError('Closing tag encountered for void element br.');
$this->startTag('br'); $this->startTag('br');

View file

@ -1181,16 +1181,11 @@ class Tokenizer
return $entity; return $entity;
} }
// If in an attribute, then failing to match ; means unconsume the // Failing to match ; means unconsume the entire string.
// entire string. Otherwise, failure to match is an error.
if ($inAttribute) {
$this->scanner->unconsume($this->scanner->position() - $start); $this->scanner->unconsume($this->scanner->position() - $start);
return '&';
}
$this->parseError('Expected &ENTITY;, got &ENTITY%s (no trailing ;) ', $tok); $this->parseError('Expected &ENTITY;, got &ENTITY%s (no trailing ;) ', $tok);
return '&' . $entity; return '&';
} }
} }

View file

@ -1,485 +0,0 @@
<?php
namespace Masterminds\HTML5\Tests;
use Masterminds\HTML5\Elements;
class ElementsTest extends TestCase
{
public $html5Elements = array(
'a',
'abbr',
'address',
'area',
'article',
'aside',
'audio',
'b',
'base',
'bdi',
'bdo',
'blockquote',
'body',
'br',
'button',
'canvas',
'caption',
'cite',
'code',
'col',
'colgroup',
'command',
// "data",
'datalist',
'dd',
'del',
'details',
'dfn',
'dialog',
'div',
'dl',
'dt',
'em',
'embed',
'fieldset',
'figcaption',
'figure',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'head',
'header',
'hgroup',
'hr',
'html',
'i',
'iframe',
'img',
'input',
'ins',
'kbd',
'keygen',
'label',
'legend',
'li',
'link',
'map',
'mark',
'menu',
'meta',
'meter',
'nav',
'noscript',
'object',
'ol',
'optgroup',
'option',
'output',
'p',
'param',
'pre',
'progress',
'q',
'rp',
'rt',
'ruby',
's',
'samp',
'script',
'section',
'select',
'small',
'source',
'span',
'strong',
'style',
'sub',
'summary',
'sup',
'table',
'tbody',
'td',
'textarea',
'tfoot',
'th',
'thead',
'time',
'title',
'tr',
'track',
'u',
'ul',
'var',
'video',
'wbr',
);
public $mathmlElements = array(
'maction',
'maligngroup',
'malignmark',
'math',
'menclose',
'merror',
'mfenced',
'mfrac',
'mglyph',
'mi',
'mlabeledtr',
'mlongdiv',
'mmultiscripts',
'mn',
'mo',
'mover',
'mpadded',
'mphantom',
'mroot',
'mrow',
'ms',
'mscarries',
'mscarry',
'msgroup',
'msline',
'mspace',
'msqrt',
'msrow',
'mstack',
'mstyle',
'msub',
'msup',
'msubsup',
'mtable',
'mtd',
'mtext',
'mtr',
'munder',
'munderover',
);
public $svgElements = array(
'a',
'altGlyph',
'altGlyphDef',
'altGlyphItem',
'animate',
'animateColor',
'animateMotion',
'animateTransform',
'circle',
'clipPath',
'color-profile',
'cursor',
'defs',
'desc',
'ellipse',
'feBlend',
'feColorMatrix',
'feComponentTransfer',
'feComposite',
'feConvolveMatrix',
'feDiffuseLighting',
'feDisplacementMap',
'feDistantLight',
'feFlood',
'feFuncA',
'feFuncB',
'feFuncG',
'feFuncR',
'feGaussianBlur',
'feImage',
'feMerge',
'feMergeNode',
'feMorphology',
'feOffset',
'fePointLight',
'feSpecularLighting',
'feSpotLight',
'feTile',
'feTurbulence',
'filter',
'font',
'font-face',
'font-face-format',
'font-face-name',
'font-face-src',
'font-face-uri',
'foreignObject',
'g',
'glyph',
'glyphRef',
'hkern',
'image',
'line',
'linearGradient',
'marker',
'mask',
'metadata',
'missing-glyph',
'mpath',
'path',
'pattern',
'polygon',
'polyline',
'radialGradient',
'rect',
'script',
'set',
'stop',
'style',
'svg',
'switch',
'symbol',
'text',
'textPath',
'title',
'tref',
'tspan',
'use',
'view',
'vkern',
);
public function testIsHtml5Element()
{
foreach ($this->html5Elements as $element) {
$this->assertTrue(Elements::isHtml5Element($element), 'html5 element test failed on: ' . $element);
$this->assertTrue(Elements::isHtml5Element(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element));
}
$nonhtml5 = array(
'foo',
'bar',
'baz',
);
foreach ($nonhtml5 as $element) {
$this->assertFalse(Elements::isHtml5Element($element), 'html5 element test failed on: ' . $element);
$this->assertFalse(Elements::isHtml5Element(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element));
}
}
public function testIsMathMLElement()
{
foreach ($this->mathmlElements as $element) {
$this->assertTrue(Elements::isMathMLElement($element), 'MathML element test failed on: ' . $element);
// MathML is case sensitive so these should all fail.
$this->assertFalse(Elements::isMathMLElement(strtoupper($element)), 'MathML element test failed on: ' . strtoupper($element));
}
$nonMathML = array(
'foo',
'bar',
'baz',
);
foreach ($nonMathML as $element) {
$this->assertFalse(Elements::isMathMLElement($element), 'MathML element test failed on: ' . $element);
}
}
public function testIsSvgElement()
{
foreach ($this->svgElements as $element) {
$this->assertTrue(Elements::isSvgElement($element), 'SVG element test failed on: ' . $element);
// SVG is case sensitive so these should all fail.
$this->assertFalse(Elements::isSvgElement(strtoupper($element)), 'SVG element test failed on: ' . strtoupper($element));
}
$nonSVG = array(
'foo',
'bar',
'baz',
);
foreach ($nonSVG as $element) {
$this->assertFalse(Elements::isSvgElement($element), 'SVG element test failed on: ' . $element);
}
}
public function testIsElement()
{
foreach ($this->html5Elements as $element) {
$this->assertTrue(Elements::isElement($element), 'html5 element test failed on: ' . $element);
$this->assertTrue(Elements::isElement(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element));
}
foreach ($this->mathmlElements as $element) {
$this->assertTrue(Elements::isElement($element), 'MathML element test failed on: ' . $element);
// MathML is case sensitive so these should all fail.
$this->assertFalse(Elements::isElement(strtoupper($element)), 'MathML element test failed on: ' . strtoupper($element));
}
foreach ($this->svgElements as $element) {
$this->assertTrue(Elements::isElement($element), 'SVG element test failed on: ' . $element);
// SVG is case sensitive so these should all fail. But, there is duplication
// html5 and SVG. Since html5 is case insensitive we need to make sure
// it's not a html5 element first.
if (!in_array($element, $this->html5Elements)) {
$this->assertFalse(Elements::isElement(strtoupper($element)), 'SVG element test failed on: ' . strtoupper($element));
}
}
$nonhtml5 = array(
'foo',
'bar',
'baz',
);
foreach ($nonhtml5 as $element) {
$this->assertFalse(Elements::isElement($element), 'html5 element test failed on: ' . $element);
$this->assertFalse(Elements::isElement(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element));
}
}
public function testElement()
{
foreach ($this->html5Elements as $element) {
$this->assertGreaterThan(0, Elements::element($element));
}
$nonhtml5 = array(
'foo',
'bar',
'baz',
);
foreach ($nonhtml5 as $element) {
$this->assertEquals(0, Elements::element($element));
}
}
public function testIsA()
{
$this->assertTrue(Elements::isA('script', Elements::KNOWN_ELEMENT));
$this->assertFalse(Elements::isA('scriptypoo', Elements::KNOWN_ELEMENT));
$this->assertTrue(Elements::isA('script', Elements::TEXT_RAW));
$this->assertFalse(Elements::isA('script', Elements::TEXT_RCDATA));
$voidElements = array(
'area',
'base',
'basefont',
'bgsound',
'br',
'col',
'command',
'embed',
'frame',
'hr',
'img',
);
foreach ($voidElements as $element) {
$this->assertTrue(Elements::isA($element, Elements::VOID_TAG), 'Void element test failed on: ' . $element);
}
$nonVoid = array(
'span',
'a',
'div',
);
foreach ($nonVoid as $tag) {
$this->assertFalse(Elements::isA($tag, Elements::VOID_TAG), 'Void element test failed on: ' . $tag);
}
$blockTags = array(
'address',
'article',
'aside',
'blockquote',
'canvas',
'dd',
'div',
'dl',
'fieldset',
'figcaption',
'figure',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'header',
'hgroup',
'hr',
'noscript',
'ol',
'output',
'p',
'pre',
'section',
'table',
'tfoot',
'ul',
'video',
);
foreach ($blockTags as $tag) {
$this->assertTrue(Elements::isA($tag, Elements::BLOCK_TAG), 'Block tag test failed on: ' . $tag);
}
$nonBlockTags = array(
'span',
'img',
'label',
);
foreach ($nonBlockTags as $tag) {
$this->assertFalse(Elements::isA($tag, Elements::BLOCK_TAG), 'Block tag test failed on: ' . $tag);
}
}
public function testNormalizeSvgElement()
{
$tests = array(
'foo' => 'foo',
'altglyph' => 'altGlyph',
'BAR' => 'bar',
'fespecularlighting' => 'feSpecularLighting',
'bAz' => 'baz',
'foreignobject' => 'foreignObject',
);
foreach ($tests as $input => $expected) {
$this->assertEquals($expected, Elements::normalizeSvgElement($input));
}
}
public function testNormalizeSvgAttribute()
{
$tests = array(
'foo' => 'foo',
'attributename' => 'attributeName',
'BAR' => 'bar',
'limitingconeangle' => 'limitingConeAngle',
'bAz' => 'baz',
'patterncontentunits' => 'patternContentUnits',
);
foreach ($tests as $input => $expected) {
$this->assertEquals($expected, Elements::normalizeSvgAttribute($input));
}
}
public function testNormalizeMathMlAttribute()
{
$tests = array(
'foo' => 'foo',
'definitionurl' => 'definitionURL',
'BAR' => 'bar',
);
foreach ($tests as $input => $expected) {
$this->assertEquals($expected, Elements::normalizeMathMlAttribute($input));
}
}
}

View file

@ -1,9 +0,0 @@
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<body>
<p>Žťčýů</p>
</body>
</html>

View file

@ -1,9 +0,0 @@
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=windows-1252">
</head>
<body>
<p>Ž<EFBFBD>èýù</p>
</body>
</html>

View file

@ -1,10 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<p>This is a test.</p>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more