mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-23 01:36:14 -04:00
Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1044e8e91a | ||
|
|
ba4b1cb5af | ||
|
|
5cb4cdaa5e | ||
|
|
7be1d9e45a | ||
|
|
ae97649948 | ||
|
|
f15e32d063 | ||
|
|
afc75af62f | ||
|
|
2778a7220f | ||
|
|
26f593afaa | ||
|
|
beac45b075 | ||
|
|
dfc5159aa3 | ||
|
|
886cdb440b | ||
|
|
6ed9443972 | ||
|
|
08e0f172de | ||
|
|
f1d168f781 | ||
|
|
302d9796c4 | ||
|
|
1260887fa7 | ||
|
|
ce8073d25e | ||
|
|
31f4d9066b | ||
|
|
35e66770be | ||
|
|
cf2f7f2132 | ||
|
|
a145559662 | ||
|
|
d029e3dc16 | ||
|
|
286326a98e | ||
|
|
2f59d78737 | ||
|
|
adf4782076 | ||
|
|
b38ffef2be | ||
|
|
6375f2d73a | ||
|
|
a7d3a49171 | ||
|
|
920e7db709 | ||
|
|
4a6b45cf04 | ||
|
|
7bd60adfbe | ||
|
|
c335719e8f | ||
|
|
d57cdf645e | ||
|
|
e47a96bf24 | ||
|
|
daad607c7c | ||
|
|
29f1f9c872 | ||
|
|
a49cfa8142 | ||
|
|
b57d296adc | ||
|
|
01d8bd445e | ||
|
|
750d6f4be9 | ||
|
|
c6e14a696e | ||
|
|
d34423fce9 | ||
|
|
4999547f87 | ||
|
|
fc5dc9717a | ||
|
|
d20759c141 | ||
|
|
f7b00c62a4 | ||
|
|
32873ce70d | ||
|
|
dc59561a95 | ||
|
|
4bf3fdd898 | ||
|
|
108a892a11 | ||
|
|
2c4bd9a3fe | ||
|
|
098ec1abb4 | ||
|
|
17cf824545 | ||
|
|
e35f5d3c93 | ||
|
|
f4f98e5856 | ||
|
|
dc0335d1d5 | ||
|
|
6013814cf4 | ||
|
|
e0a0570cc4 | ||
|
|
61deb4fcfd | ||
|
|
7c4c60425b | ||
|
|
302f49baf2 | ||
|
|
3f6cd5a663 | ||
|
|
1b232041c9 | ||
|
|
eaf117cce1 | ||
|
|
7148311953 | ||
|
|
c23dfa0d23 | ||
|
|
b08de33b0b | ||
|
|
fc1d8c0138 | ||
|
|
a5a77d1e7c | ||
|
|
f57fcefe6b | ||
|
|
6c6dca05e7 | ||
|
|
97b4a31b16 | ||
|
|
40d9277ef3 | ||
|
|
009044b71e | ||
|
|
4760a3f3e8 | ||
|
|
3302012c02 | ||
|
|
812c5a314f | ||
|
|
c2da8c3fd4 | ||
|
|
aa78640491 | ||
|
|
7c49688e1b | ||
|
|
dbe10c7965 | ||
|
|
f1f5107282 | ||
|
|
cc06250bf8 | ||
|
|
af1ea7f495 | ||
|
|
3491c488d3 | ||
|
|
1828b6daab | ||
|
|
c26f45b7c2 | ||
|
|
e116b90116 | ||
|
|
43a5f928ba | ||
|
|
873fa16517 | ||
|
|
f7ce374a28 | ||
|
|
2dd124d09e | ||
|
|
d6523c67a6 | ||
|
|
a9fd3608ea | ||
|
|
b25cace3ea | ||
|
|
4320f047db | ||
|
|
b4b3e7b9a4 | ||
|
|
b6938da552 | ||
|
|
4830a1559d | ||
|
|
92ea3ef720 | ||
|
|
73d2719330 | ||
|
|
af82aab3a6 | ||
|
|
51b4b6216f | ||
|
|
de32b0bba5 | ||
|
|
de0fab78ed | ||
|
|
71425c3b23 | ||
|
|
75f7b1e261 | ||
|
|
9af35d998f | ||
|
|
34e3f3907a | ||
|
|
46b0510b99 | ||
|
|
a7624ea48b | ||
|
|
2f3b4a7aaf | ||
|
|
a9bbe0b128 | ||
|
|
0d9d0a4b70 | ||
|
|
8235d0bd50 | ||
|
|
c2e01bedc5 | ||
|
|
32c4614a32 | ||
|
|
24ae6c91ea | ||
|
|
346a4f5933 | ||
|
|
c6551336c8 | ||
|
|
3dab0d365d | ||
|
|
0252bac4ba | ||
|
|
b468069875 | ||
|
|
7e1f431eca | ||
|
|
70c55da1df | ||
|
|
f9ab7647dd | ||
|
|
623aa7ea48 | ||
|
|
046d264688 | ||
|
|
944e168120 | ||
|
|
9594105e57 | ||
|
|
675343f575 | ||
|
|
fc6ff45c49 | ||
|
|
b4bac88c39 | ||
|
|
c622ba84b9 | ||
|
|
339f95c647 | ||
|
|
ec67e0ab22 | ||
|
|
0b371c8103 | ||
|
|
2192ea6fdf | ||
|
|
0060f88c45 | ||
|
|
1eac4db491 | ||
|
|
0d2c3be367 | ||
|
|
1241e778f9 | ||
|
|
3ab0ef1902 | ||
|
|
c7c35b8b5a |
43
CHANGELOG
43
CHANGELOG
@@ -1,3 +1,46 @@
|
||||
Hubzilla 3.8.5 (2018-11-19)
|
||||
- Fix pconfig for new installs
|
||||
- Fix delayed publication of posts in combination with channel clones
|
||||
- Fix issue where photo filesize was not updated in the DB when a photo was edited
|
||||
- Fix issue where the original photo size was not set correct in the DB
|
||||
- Fix delivery issue in zot_fetch()
|
||||
- Fix typo in channel reputation addon
|
||||
|
||||
|
||||
Hubzilla 3.8.4 (2018-11-14)
|
||||
- Fix xss issue (thanks to Eduardo)
|
||||
- Implement hook in enotify to be used by superblock
|
||||
- Various css fixes
|
||||
- Improve photo cache handling
|
||||
- Provide a function hz_syslog() to log to syslog
|
||||
- Fix request_target in z_post_url()
|
||||
- Fix plural handling for various languages
|
||||
- Some preparatory work for zot6
|
||||
- Fix warning in gallery addon
|
||||
- Fix date issue on xchan photo update in diaspora and pubcrawl addons
|
||||
- Fix typos in startpage addon
|
||||
- Improve activitypub addressing
|
||||
- Fix taxonomy in activitypub direct messages
|
||||
- Fix syntax error in diaspora addon
|
||||
- New e-learning addon flashcards
|
||||
- Remove DNS check for database connection during installation
|
||||
- Implement timestamps for pconfig
|
||||
|
||||
|
||||
Hubzilla 3.8.3 (2018-11-05)
|
||||
- Do not count likes in forum notifications if likes notifications are disabled
|
||||
- Fix typo in spanish translation which broke javascript
|
||||
- Improve linkinfo charset handling and image detection
|
||||
- Fix wrong image resize for some external images
|
||||
- Move blueimp upload lib to composer and update to version 9.25
|
||||
- Remove primary/clone counts from admin summary until we have a mechanism to update the fixed counts
|
||||
- Fix html2markdown() and re-enable previously failing tests
|
||||
- Improve look of oembed content for Hubzilla links
|
||||
- Fix forum notifications count not correct
|
||||
- Fix gallery addon which broke mod apps in some situations
|
||||
- Fix wiki_list widget not working on every page respectively level
|
||||
|
||||
|
||||
Hubzilla 3.8.2 (2018-10-29)
|
||||
- Merge unmerged changes from dev into master
|
||||
- Fix issues with forum handling in mod network and ping
|
||||
|
||||
@@ -825,7 +825,7 @@ class Enotify {
|
||||
|
||||
// convert this logic into a json array just like the system notifications
|
||||
|
||||
return array(
|
||||
$x = array(
|
||||
'notify_link' => $item['llink'],
|
||||
'name' => $item['author']['xchan_name'],
|
||||
'url' => $item['author']['xchan_url'],
|
||||
@@ -835,9 +835,19 @@ class Enotify {
|
||||
'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
|
||||
'notify_id' => 'undefined',
|
||||
'thread_top' => (($item['item_thread_top']) ? true : false),
|
||||
'message' => strip_tags(bbcode($itemem_text))
|
||||
'message' => strip_tags(bbcode($itemem_text)),
|
||||
// these are for the superblock addon
|
||||
'hash' => $item['author']['xchan_hash'],
|
||||
'uid' => local_channel(),
|
||||
'display' => true
|
||||
);
|
||||
|
||||
call_hooks('enotify_format',$x);
|
||||
if(! $x['display']) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,16 +7,10 @@ namespace Zotlabs\Lib;
|
||||
*
|
||||
*/
|
||||
|
||||
use Zotlabs\Lib\DReport;
|
||||
use Zotlabs\Lib\Enotify;
|
||||
use Zotlabs\Lib\Group;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Lib\Libzotdir;
|
||||
use Zotlabs\Lib\System;
|
||||
use Zotlabs\Lib\MessageFilter;
|
||||
use Zotlabs\Lib\Queue;
|
||||
use Zotlabs\Lib\Zotfinger;
|
||||
use Zotlabs\Web\HTTPSig;
|
||||
use Zotlabs\Zot6\HTTPSig;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Daemon\Master;
|
||||
|
||||
require_once('include/crypto.php');
|
||||
|
||||
@@ -211,9 +205,10 @@ class Libzot {
|
||||
|
||||
if($channel) {
|
||||
$headers = [
|
||||
'X-Zot-Token' => random_string(),
|
||||
'Digest' => HTTPSig::generate_digest_header($data),
|
||||
'Content-type' => 'application/x-zot+json'
|
||||
'X-Zot-Token' => random_string(),
|
||||
'Digest' => HTTPSig::generate_digest_header($data),
|
||||
'Content-type' => 'application/x-zot+json',
|
||||
'(request-target)' => 'post ' . get_request_string($url)
|
||||
];
|
||||
|
||||
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false,'sha512',
|
||||
@@ -378,13 +373,13 @@ class Libzot {
|
||||
else {
|
||||
// if we were just granted read stream permission and didn't have it before, try to pull in some posts
|
||||
if((! $old_read_stream_perm) && (intval($permissions['view_stream'])))
|
||||
\Zotlabs\Daemon\Master::Summon(array('Onepoll',$r[0]['abook_id']));
|
||||
Master::Summon([ 'Onepoll', $r[0]['abook_id'] ]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
$p = \Zotlabs\Access\Permissions::connect_perms($channel['channel_id']);
|
||||
$my_perms = \Zotlabs\Access\Permissions::serialise($p['perms']);
|
||||
$p = Permissions::connect_perms($channel['channel_id']);
|
||||
$my_perms = Permissions::serialise($p['perms']);
|
||||
|
||||
$automatic = $p['automatic'];
|
||||
|
||||
@@ -424,8 +419,8 @@ class Libzot {
|
||||
);
|
||||
|
||||
if($new_connection) {
|
||||
if(! \Zotlabs\Access\Permissions::PermsCompare($new_perms,$previous_perms))
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','permissions_create',$new_connection[0]['abook_id']));
|
||||
if(! Permissions::PermsCompare($new_perms,$previous_perms))
|
||||
Master::Summon([ 'Notifier', 'permissions_create', $new_connection[0]['abook_id'] ]);
|
||||
Enotify::submit(
|
||||
[
|
||||
'type' => NOTIFY_INTRO,
|
||||
@@ -438,7 +433,7 @@ class Libzot {
|
||||
if(intval($permissions['view_stream'])) {
|
||||
if(intval(get_pconfig($channel['channel_id'],'perm_limits','send_stream') & PERMS_PENDING)
|
||||
|| (! intval($new_connection[0]['abook_pending'])))
|
||||
\Zotlabs\Daemon\Master::Summon(array('Onepoll',$new_connection[0]['abook_id']));
|
||||
Master::Summon([ 'Onepoll', $new_connection[0]['abook_id'] ]);
|
||||
}
|
||||
|
||||
|
||||
@@ -975,39 +970,45 @@ class Libzot {
|
||||
$x = json_decode($x,true);
|
||||
}
|
||||
|
||||
if(! $x['success']) {
|
||||
|
||||
// handle remote validation issues
|
||||
|
||||
$b = q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
|
||||
dbesc(($x['message']) ? $x['message'] : 'unknown delivery error'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($outq['outq_hash'])
|
||||
);
|
||||
if(! is_array($x)) {
|
||||
btlogger('failed communication - no response');
|
||||
}
|
||||
|
||||
if(array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) {
|
||||
foreach($x['delivery_report'] as $xx) {
|
||||
if(is_array($xx) && array_key_exists('message_id',$xx) && DReport::is_storable($xx)) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s', '%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($xx['message_id']),
|
||||
dbesc($xx['location']),
|
||||
dbesc($xx['recipient']),
|
||||
dbesc($xx['name']),
|
||||
dbesc($xx['status']),
|
||||
dbesc(datetime_convert($xx['date'])),
|
||||
dbesc($xx['sender'])
|
||||
);
|
||||
}
|
||||
if($x) {
|
||||
if(! $x['success']) {
|
||||
|
||||
// handle remote validation issues
|
||||
|
||||
$b = q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
|
||||
dbesc(($x['message']) ? $x['message'] : 'unknown delivery error'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($outq['outq_hash'])
|
||||
);
|
||||
}
|
||||
|
||||
// we have a more descriptive delivery report, so discard the per hub 'queue' report.
|
||||
if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) {
|
||||
foreach($x['delivery_report'] as $xx) {
|
||||
call_hooks('dreport_process',$xx);
|
||||
if(is_array($xx) && array_key_exists('message_id',$xx) && DReport::is_storable($xx)) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s', '%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($xx['message_id']),
|
||||
dbesc($xx['location']),
|
||||
dbesc($xx['recipient']),
|
||||
dbesc($xx['name']),
|
||||
dbesc($xx['status']),
|
||||
dbesc(datetime_convert($xx['date'])),
|
||||
dbesc($xx['sender'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
q("delete from dreport where dreport_queue = '%s' ",
|
||||
dbesc($outq['outq_hash'])
|
||||
);
|
||||
// we have a more descriptive delivery report, so discard the per hub 'queue' report.
|
||||
|
||||
q("delete from dreport where dreport_queue = '%s' ",
|
||||
dbesc($outq['outq_hash'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// update the timestamp for this site
|
||||
|
||||
q("update site set site_dead = 0, site_update = '%s' where site_url = '%s'",
|
||||
@@ -1092,13 +1093,27 @@ class Libzot {
|
||||
return;
|
||||
}
|
||||
|
||||
$message_request = ((array_key_exists('message_id',$env)) ? true : false);
|
||||
if($message_request)
|
||||
logger('processing message request');
|
||||
$message_request = false;
|
||||
|
||||
|
||||
$has_data = array_key_exists('data',$env) && $env['data'];
|
||||
$data = (($has_data) ? $env['data'] : false);
|
||||
|
||||
|
||||
$AS = null;
|
||||
|
||||
if($env['encoding'] === 'activitystreams') {
|
||||
|
||||
$AS = new ActivityStreams($data);
|
||||
if(! $AS->is_valid()) {
|
||||
logger('Activity rejected: ' . print_r($data,true));
|
||||
return;
|
||||
}
|
||||
$arr = Activity::decode_note($AS);
|
||||
|
||||
logger($AS->debug());
|
||||
}
|
||||
|
||||
|
||||
$deliveries = null;
|
||||
|
||||
if(array_key_exists('recipients',$env) && count($env['recipients'])) {
|
||||
@@ -1140,7 +1155,7 @@ class Libzot {
|
||||
// and who are allowed to see them based on the sender's permissions
|
||||
// @fixme;
|
||||
|
||||
$deliveries = self::public_recips($env);
|
||||
$deliveries = self::public_recips($env,$AS);
|
||||
|
||||
|
||||
}
|
||||
@@ -1157,49 +1172,43 @@ class Libzot {
|
||||
|
||||
if(in_array($env['type'],['activity','response'])) {
|
||||
|
||||
if($env['encoding'] === 'zot') {
|
||||
$arr = get_item_elements($data);
|
||||
|
||||
$v = validate_item_elements($data,$arr);
|
||||
|
||||
if(! $v['success']) {
|
||||
logger('Activity rejected: ' . $v['message'] . ' ' . print_r($data,true));
|
||||
return;
|
||||
}
|
||||
$arr = Activity::decode_note($AS);
|
||||
|
||||
//logger($AS->debug());
|
||||
|
||||
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$arr['author_xchan'] = $r[0]['hubloc_hash'];
|
||||
}
|
||||
elseif($env['encoding'] === 'activitystreams') {
|
||||
|
||||
$AS = new \Zotlabs\Lib\ActivityStreams($data);
|
||||
if(! $AS->is_valid()) {
|
||||
logger('Activity rejected: ' . print_r($data,true));
|
||||
return;
|
||||
}
|
||||
$arr = \Zotlabs\Lib\Activity::decode_note($AS);
|
||||
|
||||
logger($AS->debug());
|
||||
$s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($env['sender'])
|
||||
);
|
||||
|
||||
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$arr['author_xchan'] = $r[0]['hubloc_hash'];
|
||||
}
|
||||
// @fixme (in individual delivery, change owner if needed)
|
||||
// in individual delivery, change owner if needed
|
||||
if($s) {
|
||||
$arr['owner_xchan'] = $s[0]['hubloc_hash'];
|
||||
}
|
||||
else {
|
||||
$arr['owner_xchan'] = $env['sender'];
|
||||
if($private) {
|
||||
$arr['item_private'] = true;
|
||||
}
|
||||
// @fixme - spoofable
|
||||
if($AS->data['hubloc']) {
|
||||
$arr['item_verified'] = true;
|
||||
}
|
||||
if($AS->data['signed_data']) {
|
||||
IConfig::Set($arr,'activitystreams','signed_data',$AS->data['signed_data'],false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($private) {
|
||||
$arr['item_private'] = true;
|
||||
}
|
||||
// @fixme - spoofable
|
||||
if($AS->data['hubloc']) {
|
||||
$arr['item_verified'] = true;
|
||||
}
|
||||
if($AS->data['signed_data']) {
|
||||
IConfig::Set($arr,'activitystreams','signed_data',$AS->data['signed_data'],false);
|
||||
}
|
||||
|
||||
|
||||
logger('Activity received: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG);
|
||||
logger('Activity recipients: ' . print_r($deliveries,true), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
@@ -1225,15 +1234,31 @@ class Libzot {
|
||||
}
|
||||
|
||||
|
||||
static function is_top_level($env) {
|
||||
static function is_top_level($env,$act) {
|
||||
if($env['encoding'] === 'zot' && array_key_exists('flags',$env) && in_array('thread_parent', $env['flags'])) {
|
||||
return true;
|
||||
}
|
||||
if($env['encoding'] === 'activitystreams') {
|
||||
if(array_key_exists('inReplyTo',$env['data']) && $env['data']['inReplyTo']) {
|
||||
if($act) {
|
||||
if(in_array($act->type, ['Like','Dislike'])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
$x = self::find_parent($env,$act);
|
||||
if($x === $act->id || $x === $act->obj['id']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static function find_parent($env,$act) {
|
||||
if($act) {
|
||||
if(in_array($act->type, ['Like','Dislike'])) {
|
||||
return $act->obj['id'];
|
||||
}
|
||||
if($act->parent_id) {
|
||||
return $act->parent_id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1255,7 +1280,7 @@ class Libzot {
|
||||
* @return NULL|array
|
||||
*/
|
||||
|
||||
static function public_recips($msg) {
|
||||
static function public_recips($msg, $act) {
|
||||
|
||||
require_once('include/channel.php');
|
||||
|
||||
@@ -1269,7 +1294,7 @@ class Libzot {
|
||||
|
||||
$perm = 'send_stream';
|
||||
|
||||
if(self::is_top_level($msg)) {
|
||||
if(self::is_top_level($msg,$act)) {
|
||||
$check_mentions = true;
|
||||
}
|
||||
}
|
||||
@@ -1301,9 +1326,9 @@ class Libzot {
|
||||
|
||||
if($check_mentions) {
|
||||
// It's a top level post. Look at the tags. See if any of them are mentions and are on this hub.
|
||||
if(array_path_exists('data/object/tag',$msg)) {
|
||||
if(is_array($msg['data']['object']['tag']) && $msg['data']['object']['tag']) {
|
||||
foreach($msg['data']['object']['tag'] as $tag) {
|
||||
if($act && $act->obj) {
|
||||
if(is_array($act->obj['tag']) && $act->obj['tag']) {
|
||||
foreach($act->obj['tag'] as $tag) {
|
||||
if($tag['type'] === 'Mention' && (strpos($tag['href'],z_root()) !== false)) {
|
||||
$address = basename($tag['href']);
|
||||
if($address) {
|
||||
@@ -1325,9 +1350,12 @@ class Libzot {
|
||||
// everybody that stored a copy of the parent. This way we know we're covered. We'll check the
|
||||
// comment permissions when we deliver them.
|
||||
|
||||
if(array_path_exists('data/inReplyTo',$msg)) {
|
||||
$z = q("select owner_xchan as hash from item where parent_mid = '%s' ",
|
||||
dbesc($msg['data']['inReplyTo'])
|
||||
$thread_parent = self::find_parent($msg,$act);
|
||||
|
||||
if($thread_parent) {
|
||||
$z = q("select channel_hash as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ",
|
||||
dbesc($thread_parent),
|
||||
dbesc($thread_parent)
|
||||
);
|
||||
if($z) {
|
||||
foreach($z as $zv) {
|
||||
@@ -1341,7 +1369,7 @@ class Libzot {
|
||||
// It's a bit of work since it's a multi-dimensional array
|
||||
|
||||
if($r) {
|
||||
$r = array_unique($r);
|
||||
$r = array_values(array_unique($r));
|
||||
}
|
||||
|
||||
logger('public_recips: ' . print_r($r,true), LOGGER_DATA, LOG_DEBUG);
|
||||
@@ -1378,7 +1406,7 @@ class Libzot {
|
||||
|
||||
$local_public = $public;
|
||||
|
||||
$DR = new \Zotlabs\Lib\DReport(z_root(),$sender,$d,$arr['mid']);
|
||||
$DR = new DReport(z_root(),$sender,$d,$arr['mid']);
|
||||
|
||||
$channel = channelx_by_hash($d);
|
||||
|
||||
@@ -1413,7 +1441,7 @@ class Libzot {
|
||||
$local_public = true;
|
||||
|
||||
$r = q("select xchan_selfcensored from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($sender['hash'])
|
||||
dbesc($sender)
|
||||
);
|
||||
// don't import sys channel posts from selfcensored authors
|
||||
if($r && (intval($r[0]['xchan_selfcensored']))) {
|
||||
@@ -1441,11 +1469,30 @@ class Libzot {
|
||||
$arr['item_wall'] = 0;
|
||||
}
|
||||
|
||||
if((! perm_is_allowed($channel['channel_id'],$sender,$perm)) && (! $tag_delivery) && (! $local_public)) {
|
||||
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
|
||||
$DR->update('permission denied');
|
||||
$result[] = $DR->get();
|
||||
continue;
|
||||
$friendofriend = false;
|
||||
|
||||
if ((! $tag_delivery) && (! $local_public)) {
|
||||
$allowed = (perm_is_allowed($channel['channel_id'],$sender,$perm));
|
||||
if((! $allowed) && $perm === 'post_comments') {
|
||||
$parent = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($arr['parent_mid']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if ($parent) {
|
||||
$allowed = can_comment_on_post($d,$parent[0]);
|
||||
}
|
||||
}
|
||||
if($request) {
|
||||
$allowed = true;
|
||||
$friendofriend = true;
|
||||
}
|
||||
|
||||
if (! $allowed) {
|
||||
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
|
||||
$DR->update('permission denied');
|
||||
$result[] = $DR->get();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if($arr['mid'] != $arr['parent_mid']) {
|
||||
@@ -1456,7 +1503,7 @@ class Libzot {
|
||||
// As a side effect we will also do a preliminary check that we have the top-level-post, otherwise
|
||||
// processing it is pointless.
|
||||
|
||||
$r = q("select route, id from item where mid = '%s' and uid = %d limit 1",
|
||||
$r = q("select route, id, owner_xchan, item_private from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($arr['parent_mid']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
@@ -1480,15 +1527,21 @@ class Libzot {
|
||||
|
||||
if((! $relay) && (! $request) && (! $local_public)
|
||||
&& perm_is_allowed($channel['channel_id'],$sender,'send_stream')) {
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'request', $channel['channel_id'], $sender, $arr['parent_mid']));
|
||||
self::fetch_conversation($channel,$arr['parent_mid']);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if($relay) {
|
||||
|
||||
if($relay || $friendofriend || (intval($r[0]['item_private']) === 0 && intval($arr['item_private']) === 0)) {
|
||||
// reset the route in case it travelled a great distance upstream
|
||||
// use our parent's route so when we go back downstream we'll match
|
||||
// with whatever route our parent has.
|
||||
// Also friend-of-friend conversations may have been imported without a route,
|
||||
// but we are now getting comments via listener delivery
|
||||
// and if there is no privacy on this or the parent, we don't care about the route,
|
||||
// so just set the owner and route accordingly.
|
||||
$arr['route'] = $r[0]['route'];
|
||||
$arr['owner_xchan'] = $r[0]['owner_xchan'];
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1546,13 +1599,13 @@ class Libzot {
|
||||
$arr['aid'] = $channel['channel_account_id'];
|
||||
$arr['uid'] = $channel['channel_id'];
|
||||
|
||||
$item_id = delete_imported_item($sender,$arr,$channel['channel_id'],$relay);
|
||||
$item_id = self::delete_imported_item($sender,$arr,$channel['channel_id'],$relay);
|
||||
$DR->update(($item_id) ? 'deleted' : 'delete_failed');
|
||||
$result[] = $DR->get();
|
||||
|
||||
if($relay && $item_id) {
|
||||
logger('process_delivery: invoking relay');
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','relay',intval($item_id)));
|
||||
Master::Summon([ 'Notifier', 'relay', intval($item_id) ]);
|
||||
$DR->update('relayed');
|
||||
$result[] = $DR->get();
|
||||
}
|
||||
@@ -1662,7 +1715,7 @@ class Libzot {
|
||||
|
||||
if($relay && $item_id) {
|
||||
logger('Invoking relay');
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','relay',intval($item_id)));
|
||||
Master::Summon([ 'Notifier', 'relay', intval($item_id) ]);
|
||||
$DR->addto_update('relayed');
|
||||
$result[] = $DR->get();
|
||||
}
|
||||
@@ -1676,6 +1729,98 @@ class Libzot {
|
||||
return $result;
|
||||
}
|
||||
|
||||
static public function fetch_conversation($channel,$mid) {
|
||||
|
||||
// Use Zotfinger to create a signed request
|
||||
|
||||
$a = Zotfinger::exec($mid,$channel);
|
||||
|
||||
logger('received conversation: ' . print_r($a,true), LOGGER_DATA);
|
||||
|
||||
if($a['data']['type'] !== 'OrderedCollection') {
|
||||
return;
|
||||
}
|
||||
|
||||
if(! intval($a['data']['totalItems'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
|
||||
foreach($a['data']['orderedItems'] as $activity) {
|
||||
|
||||
$AS = new ActivityStreams($activity);
|
||||
if(! $AS->is_valid()) {
|
||||
logger('FOF Activity rejected: ' . print_r($activity,true));
|
||||
continue;
|
||||
}
|
||||
$arr = Activity::decode_note($AS);
|
||||
|
||||
logger($AS->debug());
|
||||
|
||||
|
||||
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
$y = import_author_xchan([ 'url' => $AS->actor['id'] ]);
|
||||
if($y) {
|
||||
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
}
|
||||
if(! $r) {
|
||||
logger('FOF Activity: no actor');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if($AS->obj['actor'] && $AS->obj['actor']['id'] && $AS->obj['actor']['id'] !== $AS->actor['id']) {
|
||||
$y = import_author_xchan([ 'url' => $AS->obj['actor']['id'] ]);
|
||||
if(! $y) {
|
||||
logger('FOF Activity: no object actor');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($r) {
|
||||
$arr['author_xchan'] = $r[0]['hubloc_hash'];
|
||||
}
|
||||
|
||||
$s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($a['signature']['signer'])
|
||||
);
|
||||
|
||||
if($s) {
|
||||
$arr['owner_xchan'] = $s[0]['hubloc_hash'];
|
||||
}
|
||||
else {
|
||||
$arr['owner_xchan'] = $a['signature']['signer'];
|
||||
}
|
||||
|
||||
// @fixme - spoofable
|
||||
if($AS->data['hubloc']) {
|
||||
$arr['item_verified'] = true;
|
||||
}
|
||||
if($AS->data['signed_data']) {
|
||||
IConfig::Set($arr,'activitystreams','signed_data',$AS->data['signed_data'],false);
|
||||
}
|
||||
|
||||
logger('FOF Activity received: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG);
|
||||
logger('FOF Activity recipient: ' . $channel['channel_hash'], LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
$result = self::process_delivery($arr['owner_xchan'],$arr, [ $channel['channel_hash'] ],false,false,true);
|
||||
if ($result) {
|
||||
$ret = array_merge($ret, $result);
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove community tag.
|
||||
*
|
||||
@@ -1900,7 +2045,7 @@ class Libzot {
|
||||
|
||||
foreach($deliveries as $d) {
|
||||
|
||||
$DR = new \Zotlabs\Lib\DReport(z_root(),$sender,$d,$arr['mid']);
|
||||
$DR = new DReport(z_root(),$sender,$d,$arr['mid']);
|
||||
|
||||
$r = q("select * from channel where channel_hash = '%s' limit 1",
|
||||
dbesc($d['hash'])
|
||||
@@ -2112,7 +2257,8 @@ class Libzot {
|
||||
if(intval($channel['channel_removed']) && $hub['hubloc_url'] === z_root())
|
||||
$hub['hubloc_deleted'] = 1;
|
||||
|
||||
$ret[] = [
|
||||
|
||||
$z = [
|
||||
'host' => $hub['hubloc_host'],
|
||||
'address' => $hub['hubloc_addr'],
|
||||
'id_url' => $hub['hubloc_id_url'],
|
||||
@@ -2120,10 +2266,25 @@ class Libzot {
|
||||
'url' => $hub['hubloc_url'],
|
||||
'url_sig' => $hub['hubloc_url_sig'],
|
||||
'site_id' => $hub['hubloc_site_id'],
|
||||
'callback' => $hub['hubloc_callback'],
|
||||
'callback' => $hub['hubloc_url'] . '/zot',
|
||||
'sitekey' => $hub['hubloc_sitekey'],
|
||||
'deleted' => (intval($hub['hubloc_deleted']) ? true : false)
|
||||
];
|
||||
|
||||
// version compatibility tweaks
|
||||
|
||||
if(! strpos($z['url_sig'],'.')) {
|
||||
$z['url_sig'] = 'sha256.' . $z['url_sig'];
|
||||
}
|
||||
|
||||
if(! $z['id_url']) {
|
||||
$z['id_url'] = $z['url'] . '/channel/' . substr($z['address'],0,strpos($z['address'],'@'));
|
||||
}
|
||||
if(! $z['site_id']) {
|
||||
$z['site_id'] = Libzot::make_xchan_hash($z['url'],$z['sitekey']);
|
||||
}
|
||||
|
||||
$ret[] = $z;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2331,6 +2492,10 @@ class Libzot {
|
||||
// we may only end up with one; which results in posts with no author name or photo and are a bit
|
||||
// of a hassle to repair. If either or both are missing, do a full discovery probe.
|
||||
|
||||
if(! array_key_exists('id',$x)) {
|
||||
return import_author_activitypub($x);
|
||||
}
|
||||
|
||||
$hash = self::make_xchan_hash($x['id'],$x['key']);
|
||||
|
||||
$desturl = $x['url'];
|
||||
@@ -2502,7 +2667,7 @@ class Libzot {
|
||||
}
|
||||
else {
|
||||
// check if it has characteristics of a public forum based on custom permissions.
|
||||
$m = \Zotlabs\Access\Permissions::FilledAutoperms($e['channel_id']);
|
||||
$m = Permissions::FilledAutoperms($e['channel_id']);
|
||||
if($m) {
|
||||
foreach($m as $k => $v) {
|
||||
if($k == 'tag_deliver' && intval($v) == 1)
|
||||
@@ -2584,13 +2749,13 @@ class Libzot {
|
||||
];
|
||||
|
||||
$ret['channel_role'] = get_pconfig($e['channel_id'],'system','permissions_role','custom');
|
||||
|
||||
$ret['protocols'] = [ 'zot6' ];
|
||||
$ret['searchable'] = $searchable;
|
||||
$ret['adult_content'] = $adult_channel;
|
||||
$ret['public_forum'] = $public_forum;
|
||||
|
||||
$ret['comments'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($e['channel_id'],'post_comments'));
|
||||
$ret['mail'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($e['channel_id'],'post_mail'));
|
||||
$ret['comments'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_comments'));
|
||||
$ret['mail'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_mail'));
|
||||
|
||||
if($deleted)
|
||||
$ret['deleted'] = $deleted;
|
||||
|
||||
@@ -57,6 +57,7 @@ class PConfig {
|
||||
\App::$config[$uid][$c]['config_loaded'] = true;
|
||||
}
|
||||
\App::$config[$uid][$c][$k] = $rr['v'];
|
||||
\App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +114,7 @@ class PConfig {
|
||||
* The value to store
|
||||
* @return mixed Stored $value or false
|
||||
*/
|
||||
static public function Set($uid, $family, $key, $value) {
|
||||
static public function Set($uid, $family, $key, $value, $updated=NULL) {
|
||||
|
||||
// this catches subtle errors where this function has been called
|
||||
// with local_channel() when not logged in (which returns false)
|
||||
@@ -130,29 +131,74 @@ class PConfig {
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if (! $updated) {
|
||||
$updated = datetime_convert();
|
||||
}
|
||||
|
||||
$hash = hash('sha256',$family.':'.$key);
|
||||
|
||||
if (self::Get($uid, 'hz_delpconfig', $hash) !== false) {
|
||||
if (Get($uid, 'hz_delpconfig', $hash) > $updated) {
|
||||
logger('Refusing to update pconfig with outdated info (Item deleted more recently).', LOGGER_NORMAL, LOG_ERR);
|
||||
return self::Get($uid,$family,$key);
|
||||
} else {
|
||||
self::Delete($uid,'hz_delpconfig',$hash);
|
||||
}
|
||||
}
|
||||
|
||||
if(self::Get($uid, $family, $key) === false) {
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
\App::$config[$uid] = array();
|
||||
if(! array_key_exists($family, \App::$config[$uid]))
|
||||
\App::$config[$uid][$family] = array();
|
||||
|
||||
$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
|
||||
|
||||
$ret = q("INSERT INTO pconfig ( uid, cat, k, v, updated ) VALUES ( %d, '%s', '%s', '%s', '%s' ) ",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue)
|
||||
dbesc($dbvalue),
|
||||
dbesc($updated)
|
||||
);
|
||||
|
||||
// There is a possible race condition if another process happens
|
||||
// to insert something after this thread has Loaded and now. We should
|
||||
// at least make a note of it if it happens.
|
||||
|
||||
if (!$ret) {
|
||||
logger("Error: Insert to pconfig failed.",LOGGER_NORMAL, LOG_ERR);
|
||||
}
|
||||
|
||||
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
|
||||
}
|
||||
else {
|
||||
$new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $updated);
|
||||
|
||||
$ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'",
|
||||
dbesc($dbvalue),
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
if ($new) {
|
||||
|
||||
// @NOTE There is still a possible race condition under limited circumstances
|
||||
// where a value will be updated by another thread with more current data than
|
||||
// we have. At this point there is no easy way to test for it, so we update
|
||||
// and hope for the best.
|
||||
|
||||
$ret = q("UPDATE pconfig SET v = '%s', updated = '%s' WHERE uid = %d and cat = '%s' AND k = '%s' ",
|
||||
dbesc($dbvalue),
|
||||
dbesc($updated),
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
|
||||
} else {
|
||||
logger('Refusing to update pconfig with outdated info.', LOGGER_NORMAL, LOG_ERR);
|
||||
return self::Get($uid, $family, $key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// keep a separate copy for all variables which were
|
||||
// set in the life of this page. We need this to
|
||||
// synchronise channel clones.
|
||||
@@ -163,7 +209,11 @@ class PConfig {
|
||||
\App::$config[$uid]['transient'][$family] = array();
|
||||
|
||||
\App::$config[$uid][$family][$key] = $value;
|
||||
\App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
|
||||
if ($new) {
|
||||
\App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
\App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated;
|
||||
}
|
||||
|
||||
if($ret)
|
||||
return $value;
|
||||
@@ -186,18 +236,29 @@ class PConfig {
|
||||
* The configuration key to delete
|
||||
* @return mixed
|
||||
*/
|
||||
static public function Delete($uid, $family, $key) {
|
||||
static public function Delete($uid, $family, $key, $updated = NULL) {
|
||||
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
$updated = ($updated) ? $updated : datetime_convert();
|
||||
|
||||
$newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $updated);
|
||||
|
||||
if (! $newer) {
|
||||
logger('Refusing to delete pconfig with outdated delete request.', LOGGER_NORMAL, LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
$ret = false;
|
||||
|
||||
if(array_key_exists($uid,\App::$config)
|
||||
&& is_array(\App::$config['uid'])
|
||||
&& array_key_exists($family,\App::$config['uid'])
|
||||
&& array_key_exists($key, \App::$config[$uid][$family]))
|
||||
if (isset(\App::$config[$uid][$family][$key])) {
|
||||
unset(\App::$config[$uid][$family][$key]);
|
||||
}
|
||||
|
||||
if (isset(\App::$config[$uid][$family]['pcfgud:'.$key])) {
|
||||
unset(\App::$config[$uid][$family]['pcfgud:'.$key]);
|
||||
}
|
||||
|
||||
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
|
||||
intval($uid),
|
||||
@@ -205,6 +266,22 @@ class PConfig {
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
if ($family != 'hz_delpconfig') {
|
||||
$hash = hash('sha256',$family.':'.$key);
|
||||
set_pconfig($uid,'hz_delpconfig',$hash,$updated);
|
||||
}
|
||||
|
||||
// Synchronize delete with clones.
|
||||
|
||||
if(! array_key_exists('transient', \App::$config[$uid]))
|
||||
\App::$config[$uid]['transient'] = array();
|
||||
if(! array_key_exists($family, \App::$config[$uid]['transient']))
|
||||
\App::$config[$uid]['transient'][$family] = array();
|
||||
|
||||
if ($new) {
|
||||
\App::$config[$uid]['transient'][$family]['pcfgdel:'.$key] = $updated;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,11 +109,9 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
|
||||
// available channels, primary and clones
|
||||
$channels = array();
|
||||
$r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0 and channel_system = 0");
|
||||
$r = q("SELECT COUNT(*) AS total FROM channel WHERE channel_removed = 0 and channel_system = 0");
|
||||
if ($r) {
|
||||
$channels['total'] = array('label' => t('Channels'), 'val' => $r[0]['total']);
|
||||
$channels['main'] = array('label' => t('Primary'), 'val' => $r[0]['main']);
|
||||
$channels['clones'] = array('label' => t('Clones'), 'val' => $r[0]['clones']);
|
||||
}
|
||||
|
||||
// We can do better, but this is a quick queue status
|
||||
|
||||
@@ -228,8 +228,13 @@ class Linkinfo extends \Zotlabs\Web\Controller {
|
||||
|
||||
$header = $result['header'];
|
||||
$body = $result['body'];
|
||||
|
||||
// Check codepage in HTTP headers or HTML if not exist
|
||||
$cp = (preg_match('/Content-Type: text\/html; charset=(.+)\r\n/i', $header, $o) ? $o[1] : '');
|
||||
if(empty($cp))
|
||||
$cp = (preg_match('/meta.+content=["|\']text\/html; charset=([^"|\']+)/i', $body, $o) ? $o[1] : 'AUTO');
|
||||
|
||||
$body = mb_convert_encoding($body, 'UTF-8', (preg_match('/meta.+content=["|\']text\/html;\s+charset=([^"|\']+)/i', $body, $o) ? $o[1] : 'UTF-8'));
|
||||
$body = mb_convert_encoding($body, 'UTF-8', $cp);
|
||||
$body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8");
|
||||
|
||||
$doc = new \DOMDocument();
|
||||
@@ -265,20 +270,43 @@ class Linkinfo extends \Zotlabs\Web\Controller {
|
||||
$attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8");
|
||||
|
||||
switch (strtolower($attr["name"])) {
|
||||
case 'generator':
|
||||
$siteinfo['generator'] = $attr['content'];
|
||||
break;
|
||||
case "fulltitle":
|
||||
$siteinfo["title"] = $attr["content"];
|
||||
$siteinfo["title"] = trim($attr["content"]);
|
||||
break;
|
||||
case "description":
|
||||
$siteinfo["text"] = $attr["content"];
|
||||
$siteinfo["text"] = trim($attr["content"]);
|
||||
break;
|
||||
case "thumbnail":
|
||||
$siteinfo["image"] = $attr["content"];
|
||||
break;
|
||||
case "twitter:image":
|
||||
$siteinfo["image"] = $attr["content"];
|
||||
break;
|
||||
case "twitter:image:src":
|
||||
$siteinfo["image"] = $attr["content"];
|
||||
break;
|
||||
case "twitter:card":
|
||||
if (($siteinfo["type"] == "") || ($attr["content"] == "photo")) {
|
||||
$siteinfo["type"] = $attr["content"];
|
||||
}
|
||||
break;
|
||||
case "twitter:description":
|
||||
$siteinfo["text"] = trim($attr["content"]);
|
||||
break;
|
||||
case "twitter:title":
|
||||
$siteinfo["title"] = trim($attr["content"]);
|
||||
break;
|
||||
case "dc.title":
|
||||
$siteinfo["title"] = $attr["content"];
|
||||
$siteinfo["title"] = trim($attr["content"]);
|
||||
break;
|
||||
case "dc.description":
|
||||
$siteinfo["text"] = $attr["content"];
|
||||
$siteinfo["text"] = trim($attr["content"]);
|
||||
break;
|
||||
case "keywords":
|
||||
$keywords = explode(",", $attr["content"]);
|
||||
break;
|
||||
case "news_keywords":
|
||||
$keywords = explode(",", $attr["content"]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +258,10 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
elseif($pf && $unseen && $nouveau) {
|
||||
|
||||
$vnotify = get_pconfig(local_channel(), 'system', 'vnotify');
|
||||
if(! ($vnotify & VNOTIFY_LIKE))
|
||||
$likes_sql = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
|
||||
// This is for nouveau view public forum cid queries (if a forum notification is clicked)
|
||||
$p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'",
|
||||
intval(local_channel()),
|
||||
@@ -269,7 +273,7 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
if($p_str)
|
||||
$p_sql = " OR item.parent IN ( $p_str ) ";
|
||||
|
||||
$sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 ";
|
||||
$sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 $likes_sql ";
|
||||
}
|
||||
else {
|
||||
// This is for threaded view cid queries (e.g. if a forum is selected from the forum filter)
|
||||
|
||||
@@ -31,15 +31,17 @@ class Owa extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($keyId) {
|
||||
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
|
||||
where hubloc_addr = '%s' ",
|
||||
dbesc(str_replace('acct:','',$keyId))
|
||||
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) ",
|
||||
dbesc(str_replace('acct:','',$keyId)),
|
||||
dbesc($keyId)
|
||||
);
|
||||
if(! $r) {
|
||||
$found = discover_by_webbie(str_replace('acct:','',$keyId));
|
||||
if($found) {
|
||||
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
|
||||
where hubloc_addr = '%s' ",
|
||||
dbesc(str_replace('acct:','',$keyId))
|
||||
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) ",
|
||||
dbesc(str_replace('acct:','',$keyId)),
|
||||
dbesc($keyId)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@ namespace Zotlabs\Module;
|
||||
require_once('include/security.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/photo/photo_driver.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
|
||||
class Photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
$prvcachecontrol = false;
|
||||
$streaming = null;
|
||||
$channel = null;
|
||||
@@ -32,26 +31,26 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
$observer_xchan = get_observer_hash();
|
||||
$ismodified = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
|
||||
|
||||
$default = z_root() . '/' . get_default_profile_photo();
|
||||
|
||||
if(isset($type)) {
|
||||
|
||||
/**
|
||||
* Profile photos - Access controls on default profile photos are not honoured since they need to be exchanged with remote sites.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
$default = get_default_profile_photo();
|
||||
|
||||
if($type === 'profile') {
|
||||
switch($res) {
|
||||
|
||||
case 'm':
|
||||
$resolution = 5;
|
||||
$default = z_root() . '/' . get_default_profile_photo(80);
|
||||
$default = get_default_profile_photo(80);
|
||||
break;
|
||||
case 's':
|
||||
$resolution = 6;
|
||||
$default = z_root() . '/' . get_default_profile_photo(48);
|
||||
$default = get_default_profile_photo(48);
|
||||
break;
|
||||
case 'l':
|
||||
default:
|
||||
@@ -60,6 +59,8 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$modified = filemtime($default);
|
||||
$default = z_root() . '/' . $default;
|
||||
$uid = $person;
|
||||
|
||||
$d = [ 'imgscale' => $resolution, 'channel_id' => $uid, 'default' => $default, 'data' => '', 'mimetype' => '' ];
|
||||
@@ -78,17 +79,18 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
intval(PHOTO_PROFILE)
|
||||
);
|
||||
if($r) {
|
||||
$modified = strtotime($r[0]['edited'] . "Z");
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
$mimetype = $r[0]['mimetype'];
|
||||
}
|
||||
if(intval($r[0]['os_storage']))
|
||||
$data = file_get_contents($data);
|
||||
}
|
||||
|
||||
if(! $data) {
|
||||
$data = fetch_image_from_url($default,$mimetype);
|
||||
}
|
||||
if(! $mimetype) {
|
||||
$mimetype = 'image/png';
|
||||
$x = z_fetch_url($default,true,0,[ 'novalidate' => true ]);
|
||||
$data = ($x['success'] ? $x['body'] : EMPTY_STR);
|
||||
$mimetype = 'image/png';
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -124,9 +126,7 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
$photo = substr($photo,0,-2);
|
||||
// If viewing on a high-res screen, attempt to serve a higher resolution image:
|
||||
if ($resolution == 2 && ($cookie_value > 1))
|
||||
{
|
||||
$resolution = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("SELECT uid, photo_usage FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
|
||||
@@ -163,10 +163,13 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($exists && $allowed) {
|
||||
$data = dbunescbin($e[0]['content']);
|
||||
$filesize = $e[0]['filesize'];
|
||||
$mimetype = $e[0]['mimetype'];
|
||||
if(intval($e[0]['os_storage'])) {
|
||||
$modified = strtotime($e[0]['edited'] . 'Z');
|
||||
if(intval($e[0]['os_storage']))
|
||||
$streaming = $data;
|
||||
}
|
||||
if($e[0]['allow_cid'] != '' || $e[0]['allow_gid'] != '' || $e[0]['deny_gid'] != '' || $e[0]['deny_gid'] != '')
|
||||
$prvcachecontrol = true;
|
||||
}
|
||||
else {
|
||||
if(! $allowed) {
|
||||
@@ -177,27 +180,40 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
http_status_exit(404,'not found');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
header_remove('Pragma');
|
||||
|
||||
if($ismodified === gmdate("D, d M Y H:i:s", $modified) . " GMT") {
|
||||
header_remove('Expires');
|
||||
header_remove('Cache-Control');
|
||||
header_remove('Set-Cookie');
|
||||
http_status_exit(304,'not modified');
|
||||
}
|
||||
|
||||
if(! isset($data)) {
|
||||
if(isset($resolution)) {
|
||||
switch($resolution) {
|
||||
|
||||
case 4:
|
||||
$data = fetch_image_from_url(z_root() . '/' . get_default_profile_photo(),$mimetype);
|
||||
$default = get_default_profile_photo();
|
||||
break;
|
||||
case 5:
|
||||
$data = fetch_image_from_url(z_root() . '/' . get_default_profile_photo(80),$mimetype);
|
||||
$default = get_default_profile_photo(80);
|
||||
break;
|
||||
case 6:
|
||||
$data = fetch_image_from_url(z_root() . '/' . get_default_profile_photo(48),$mimetype);
|
||||
$default = get_default_profile_photo(48);
|
||||
break;
|
||||
default:
|
||||
killme();
|
||||
// NOTREACHED
|
||||
break;
|
||||
}
|
||||
$x = z_fetch_url(z_root() . '/' . $default,true,0,[ 'novalidate' => true ]);
|
||||
$data = ($x['success'] ? $x['body'] : EMPTY_STR);
|
||||
$mimetype = 'image/png';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,15 +226,14 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
// @FIXME Seems never invoked
|
||||
// Writing in cachefile
|
||||
if (isset($cachefile) && $cachefile != '')
|
||||
if (isset($cachefile) && $cachefile != '') {
|
||||
file_put_contents($cachefile, $data);
|
||||
|
||||
if(function_exists('header_remove')) {
|
||||
header_remove('Pragma');
|
||||
header_remove('pragma');
|
||||
$modified = filemtime($cachefile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
header("Content-type: " . $mimetype);
|
||||
|
||||
if($prvcachecontrol) {
|
||||
@@ -240,15 +255,16 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
// This has performance considerations but we highly recommend you
|
||||
// leave it alone.
|
||||
|
||||
$cache = get_config('system','photo_cache_time');
|
||||
if(! $cache)
|
||||
$cache = (3600 * 24); // 1 day
|
||||
|
||||
$cache = get_config('system','photo_cache_time', 86400); // 1 day by default
|
||||
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cache) . " GMT");
|
||||
header("Cache-Control: max-age=" . $cache);
|
||||
|
||||
}
|
||||
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modified) . " GMT");
|
||||
header("Content-Length: " . (isset($filesize) ? $filesize : strlen($data)));
|
||||
|
||||
// If it's a file resource, stream it.
|
||||
|
||||
if($streaming && $channel) {
|
||||
|
||||
@@ -263,7 +263,8 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
$fsize = strlen($data);
|
||||
}
|
||||
|
||||
$x = q("update photo set content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 0",
|
||||
$x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 0",
|
||||
dbesc(datetime_convert()),
|
||||
dbescbin($data),
|
||||
intval($fsize),
|
||||
intval($height),
|
||||
@@ -277,9 +278,13 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
$data = $ph->imageString();
|
||||
$fsize = strlen($data);
|
||||
|
||||
$x = q("update photo set content = '%s', height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 1",
|
||||
dbescbin($ph->imageString()),
|
||||
$x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 1",
|
||||
dbesc(datetime_convert()),
|
||||
dbescbin($data),
|
||||
intval($fsize),
|
||||
intval($height),
|
||||
intval($width),
|
||||
dbesc($resource_id),
|
||||
@@ -292,9 +297,13 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
$data = $ph->imageString();
|
||||
$fsize = strlen($data);
|
||||
|
||||
$x = q("update photo set content = '%s', height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 2",
|
||||
dbescbin($ph->imageString()),
|
||||
$x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 2",
|
||||
dbesc(datetime_convert()),
|
||||
dbescbin($data),
|
||||
intval($fsize),
|
||||
intval($height),
|
||||
intval($width),
|
||||
dbesc($resource_id),
|
||||
@@ -307,9 +316,13 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
$data = $ph->imageString();
|
||||
$fsize = strlen($data);
|
||||
|
||||
$x = q("update photo set content = '%s', height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 3",
|
||||
dbescbin($ph->imageString()),
|
||||
$x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 3",
|
||||
dbesc(datetime_convert()),
|
||||
dbescbin($data),
|
||||
intval($fsize),
|
||||
intval($height),
|
||||
intval($width),
|
||||
dbesc($resource_id),
|
||||
@@ -612,9 +625,9 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
|
||||
nav_set_selected('Photos');
|
||||
|
||||
$o = '<script src="library/blueimp_upload/js/vendor/jquery.ui.widget.js"></script>
|
||||
<script src="library/blueimp_upload/js/jquery.iframe-transport.js"></script>
|
||||
<script src="library/blueimp_upload/js/jquery.fileupload.js"></script>';
|
||||
$o = '<script src="vendor/blueimp/jquery-file-upload/js/vendor/jquery.ui.widget.js"></script>
|
||||
<script src="vendor/blueimp/jquery-file-upload/js/jquery.iframe-transport.js"></script>
|
||||
<script src="vendor/blueimp/jquery-file-upload/js/jquery.fileupload.js"></script>';
|
||||
|
||||
|
||||
$o .= "<script> var profile_uid = " . \App::$profile['profile_uid']
|
||||
|
||||
@@ -635,7 +635,6 @@ class Ping extends \Zotlabs\Web\Controller {
|
||||
$forums = get_forum_channels(local_channel());
|
||||
|
||||
if($forums) {
|
||||
$perms_sql = item_permissions_sql(local_channel());
|
||||
$item_normal = item_normal();
|
||||
$fcount = count($forums);
|
||||
$forums['total'] = 0;
|
||||
@@ -644,14 +643,14 @@ class Ping extends \Zotlabs\Web\Controller {
|
||||
$p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'",
|
||||
intval(local_channel()),
|
||||
intval(TERM_FORUM),
|
||||
dbesc($forums[$x]['xchan_hash'])
|
||||
dbesc($forums[$x]['xchan_name'])
|
||||
);
|
||||
|
||||
$p_str = ids_to_querystr($p, 'parent');
|
||||
$p_sql = (($p_str) ? "OR parent IN ( $p_str )" : '');
|
||||
|
||||
$r = q("select sum(item_unseen) as unseen from item
|
||||
where uid = %d and ( owner_xchan = '%s' OR author_xchan = '%s' $p_sql ) and item_unseen = 1 $perms_sql $item_normal",
|
||||
$r = q("select count(id) as unseen from item
|
||||
where uid = %d and ( owner_xchan = '%s' OR author_xchan = '%s' $p_sql ) and item_unseen = 1 $item_normal $sql_extra",
|
||||
intval(local_channel()),
|
||||
dbesc($forums[$x]['xchan_hash']),
|
||||
dbesc($forums[$x]['xchan_hash'])
|
||||
|
||||
@@ -6,7 +6,7 @@ class Search extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
if(x($_REQUEST,'search'))
|
||||
\App::$data['search'] = $_REQUEST['search'];
|
||||
\App::$data['search'] = escape_tags($_REQUEST['search']);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,12 @@ class Search extends \Zotlabs\Web\Controller {
|
||||
if(x(\App::$data,'search'))
|
||||
$search = trim(\App::$data['search']);
|
||||
else
|
||||
$search = ((x($_GET,'search')) ? trim(rawurldecode($_GET['search'])) : '');
|
||||
$search = ((x($_GET,'search')) ? trim(escape_tags(rawurldecode($_GET['search']))) : '');
|
||||
|
||||
$tag = false;
|
||||
if(x($_GET,'tag')) {
|
||||
$tag = true;
|
||||
$search = ((x($_GET,'tag')) ? trim(rawurldecode($_GET['tag'])) : '');
|
||||
$search = ((x($_GET,'tag')) ? trim(escape_tags(rawurldecode($_GET['tag']))) : '');
|
||||
}
|
||||
|
||||
$static = ((array_key_exists('static',$_REQUEST)) ? intval($_REQUEST['static']) : 0);
|
||||
@@ -227,9 +227,9 @@ class Search extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if($tag)
|
||||
$o .= '<h2>' . sprintf( t('Items tagged with: %s'),htmlspecialchars($search, ENT_COMPAT,'UTF-8')) . '</h2>';
|
||||
$o .= '<h2>' . sprintf( t('Items tagged with: %s'),$search) . '</h2>';
|
||||
else
|
||||
$o .= '<h2>' . sprintf( t('Search results for: %s'),htmlspecialchars($search, ENT_COMPAT,'UTF-8')) . '</h2>';
|
||||
$o .= '<h2>' . sprintf( t('Search results for: %s'),$search) . '</h2>';
|
||||
|
||||
$o .= conversation($items,'search',$update,'client');
|
||||
|
||||
|
||||
26
Zotlabs/Update/_1225.php
Normal file
26
Zotlabs/Update/_1225.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Update;
|
||||
|
||||
class _1225 {
|
||||
|
||||
function run() {
|
||||
|
||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
||||
$r1 = q("ALTER TABLE pconfig ADD updated timestamp NOT NULL DEFAULT '0001-01-01 00:00:00' ");
|
||||
$r2 = q("create index \"pconfig_updated_idx\" on pconfig (\"updated\")");
|
||||
|
||||
$r = ($r1 && $r2);
|
||||
}
|
||||
else {
|
||||
$r = q("ALTER TABLE `pconfig` ADD `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' ,
|
||||
ADD INDEX `pconfig_updated` (`updated`)");
|
||||
}
|
||||
|
||||
if($r)
|
||||
return UPDATE_SUCCESS;
|
||||
return UPDATE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,10 +6,6 @@ class Wiki_list {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if(argc() < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = channelx_by_n(\App::$profile_uid);
|
||||
|
||||
$wikis = \Zotlabs\Lib\NativeWiki::listwikis($channel,get_observer_hash());
|
||||
|
||||
5
boot.php
5
boot.php
@@ -50,11 +50,10 @@ require_once('include/attach.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
define ( 'PLATFORM_NAME', 'hubzilla' );
|
||||
define ( 'STD_VERSION', '3.8.2' );
|
||||
define ( 'STD_VERSION', '3.8.5' );
|
||||
define ( 'ZOT_REVISION', '6.0a' );
|
||||
|
||||
|
||||
define ( 'DB_UPDATE_VERSION', 1224 );
|
||||
define ( 'DB_UPDATE_VERSION', 1225 );
|
||||
|
||||
define ( 'PROJECT_BASE', __DIR__ );
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
"lukasreschke/id3parser": "^0.0.1",
|
||||
"smarty/smarty": "~3.1",
|
||||
"ramsey/uuid": "^3.8",
|
||||
"twbs/bootstrap": "4.1.3"
|
||||
"twbs/bootstrap": "4.1.3",
|
||||
"blueimp/jquery-file-upload": "^9.25"
|
||||
},
|
||||
"require-dev" : {
|
||||
"phpunit/phpunit" : "@stable",
|
||||
|
||||
272
composer.lock
generated
272
composer.lock
generated
@@ -4,8 +4,63 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "b7862124a9afe837c7eef8ee66f02ff4",
|
||||
"content-hash": "63d0e52cc07f8113059ec30d3637b850",
|
||||
"packages": [
|
||||
{
|
||||
"name": "blueimp/jquery-file-upload",
|
||||
"version": "v9.25.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vkhramtsov/jQuery-File-Upload.git",
|
||||
"reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
|
||||
"reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"server/php/UploadHandler.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Tschan",
|
||||
"homepage": "https://blueimp.net"
|
||||
}
|
||||
],
|
||||
"description": "File Upload widget for jQuery.",
|
||||
"homepage": "https://github.com/blueimp/jQuery-File-Upload",
|
||||
"keywords": [
|
||||
"bootstrap",
|
||||
"chunk",
|
||||
"cross-domain",
|
||||
"cross-site",
|
||||
"drag",
|
||||
"drop",
|
||||
"file",
|
||||
"gae",
|
||||
"go",
|
||||
"jquery",
|
||||
"multiple",
|
||||
"php",
|
||||
"preview",
|
||||
"progress",
|
||||
"python",
|
||||
"resume",
|
||||
"selection",
|
||||
"upload",
|
||||
"widget"
|
||||
],
|
||||
"time": "2018-10-26T07:21:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bshaffer/oauth2-server-php",
|
||||
"version": "v1.10.0",
|
||||
@@ -157,16 +212,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/html-to-markdown",
|
||||
"version": "4.7.0",
|
||||
"version": "4.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/html-to-markdown.git",
|
||||
"reference": "76c076483cef89860d32a3fd25312f5a42848a8c"
|
||||
"reference": "f9a879a068c68ff47b722de63f58bec79e448f9d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/76c076483cef89860d32a3fd25312f5a42848a8c",
|
||||
"reference": "76c076483cef89860d32a3fd25312f5a42848a8c",
|
||||
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/f9a879a068c68ff47b722de63f58bec79e448f9d",
|
||||
"reference": "f9a879a068c68ff47b722de63f58bec79e448f9d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -185,7 +240,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.8-dev"
|
||||
"dev-master": "4.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -198,17 +253,17 @@
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "http://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Nick Cernis",
|
||||
"email": "nick@cern.is",
|
||||
"homepage": "http://modernnerd.net",
|
||||
"role": "Original Author"
|
||||
},
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "An HTML-to-markdown conversion helper for PHP",
|
||||
@@ -217,7 +272,7 @@
|
||||
"html",
|
||||
"markdown"
|
||||
],
|
||||
"time": "2018-05-19T23:47:12+00:00"
|
||||
"time": "2018-09-18T12:18:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lukasreschke/id3parser",
|
||||
@@ -520,16 +575,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sabre/dav",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/dav.git",
|
||||
"reference": "e987775e619728f12205606c9cc3ee565ffb1516"
|
||||
"reference": "a9780ce4f35560ecbd0af524ad32d9d2c8954b80"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/dav/zipball/e987775e619728f12205606c9cc3ee565ffb1516",
|
||||
"reference": "e987775e619728f12205606c9cc3ee565ffb1516",
|
||||
"url": "https://api.github.com/repos/sabre-io/dav/zipball/a9780ce4f35560ecbd0af524ad32d9d2c8954b80",
|
||||
"reference": "a9780ce4f35560ecbd0af524ad32d9d2c8954b80",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -599,7 +654,7 @@
|
||||
"framework",
|
||||
"iCalendar"
|
||||
],
|
||||
"time": "2017-02-15T03:06:08+00:00"
|
||||
"time": "2018-10-19T09:58:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/event",
|
||||
@@ -1002,16 +1057,16 @@
|
||||
},
|
||||
{
|
||||
"name": "smarty/smarty",
|
||||
"version": "v3.1.32",
|
||||
"version": "v3.1.33",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/smarty-php/smarty.git",
|
||||
"reference": "ac9d4b587e5bf53381e21881820a9830765cb459"
|
||||
"reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/ac9d4b587e5bf53381e21881820a9830765cb459",
|
||||
"reference": "ac9d4b587e5bf53381e21881820a9830765cb459",
|
||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/dd55b23121e55a3b4f1af90a707a6c4e5969530f",
|
||||
"reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1051,7 +1106,7 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2018-04-24T14:53:33+00:00"
|
||||
"time": "2018-09-12T20:54:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -2160,16 +2215,16 @@
|
||||
},
|
||||
{
|
||||
"name": "php-mock/php-mock-phpunit",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-mock/php-mock-phpunit.git",
|
||||
"reference": "ff1cc1d4e7478ce74221e05742588619bee84f69"
|
||||
"reference": "57b92e621f14c2c07a4567cd29ed4e87de0d2912"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-mock/php-mock-phpunit/zipball/ff1cc1d4e7478ce74221e05742588619bee84f69",
|
||||
"reference": "ff1cc1d4e7478ce74221e05742588619bee84f69",
|
||||
"url": "https://api.github.com/repos/php-mock/php-mock-phpunit/zipball/57b92e621f14c2c07a4567cd29ed4e87de0d2912",
|
||||
"reference": "57b92e621f14c2c07a4567cd29ed4e87de0d2912",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2210,7 +2265,7 @@
|
||||
"test",
|
||||
"test double"
|
||||
],
|
||||
"time": "2018-04-06T13:54:43+00:00"
|
||||
"time": "2018-10-07T14:38:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
@@ -2481,16 +2536,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "6.0.7",
|
||||
"version": "6.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "865662550c384bc1db7e51d29aeda1c2c161d69a"
|
||||
"reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a",
|
||||
"reference": "865662550c384bc1db7e51d29aeda1c2c161d69a",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4d3ae9b21a7d7e440bd0cf65565533117976859f",
|
||||
"reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2501,7 +2556,7 @@
|
||||
"phpunit/php-text-template": "^1.2.1",
|
||||
"phpunit/php-token-stream": "^3.0",
|
||||
"sebastian/code-unit-reverse-lookup": "^1.0.1",
|
||||
"sebastian/environment": "^3.1",
|
||||
"sebastian/environment": "^3.1 || ^4.0",
|
||||
"sebastian/version": "^2.0.1",
|
||||
"theseer/tokenizer": "^1.1"
|
||||
},
|
||||
@@ -2514,7 +2569,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.0-dev"
|
||||
"dev-master": "6.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2540,25 +2595,28 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2018-06-01T07:51:50+00:00"
|
||||
"time": "2018-10-23T05:59:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
||||
"reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c"
|
||||
"reference": "050bedf145a257b1ff02746c31894800e5122946"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c",
|
||||
"reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
|
||||
"reference": "050bedf145a257b1ff02746c31894800e5122946",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@@ -2587,7 +2645,7 @@
|
||||
"filesystem",
|
||||
"iterator"
|
||||
],
|
||||
"time": "2018-06-11T11:44:00+00:00"
|
||||
"time": "2018-09-13T20:33:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-text-template",
|
||||
@@ -2681,16 +2739,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
|
||||
"reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
|
||||
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18",
|
||||
"reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2726,20 +2784,20 @@
|
||||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2018-02-01T13:16:43+00:00"
|
||||
"time": "2018-10-30T05:52:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "7.3.2",
|
||||
"version": "7.4.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8"
|
||||
"reference": "c151651fb6ed264038d486ea262e243af72e5e64"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34705f81bddc3f505b9599a2ef96e2b4315ba9b8",
|
||||
"reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c151651fb6ed264038d486ea262e243af72e5e64",
|
||||
"reference": "c151651fb6ed264038d486ea262e243af72e5e64",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2760,11 +2818,11 @@
|
||||
"phpunit/php-timer": "^2.0",
|
||||
"sebastian/comparator": "^3.0",
|
||||
"sebastian/diff": "^3.0",
|
||||
"sebastian/environment": "^3.1",
|
||||
"sebastian/environment": "^3.1 || ^4.0",
|
||||
"sebastian/exporter": "^3.1",
|
||||
"sebastian/global-state": "^2.0",
|
||||
"sebastian/object-enumerator": "^3.0.3",
|
||||
"sebastian/resource-operations": "^1.0",
|
||||
"sebastian/resource-operations": "^2.0",
|
||||
"sebastian/version": "^2.0.1"
|
||||
},
|
||||
"conflict": {
|
||||
@@ -2784,7 +2842,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.3-dev"
|
||||
"dev-master": "7.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2810,7 +2868,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2018-08-22T06:39:21+00:00"
|
||||
"time": "2018-10-23T05:57:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
@@ -3391,25 +3449,25 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/resource-operations",
|
||||
"version": "1.0.0",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/resource-operations.git",
|
||||
"reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
|
||||
"reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
|
||||
"reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
|
||||
"reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6.0"
|
||||
"php": "^7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -3429,7 +3487,7 @@
|
||||
],
|
||||
"description": "Provides a list of PHP built-in functions that operate on resources",
|
||||
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
|
||||
"time": "2015-07-28T20:34:47+00:00"
|
||||
"time": "2018-10-04T04:07:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
@@ -3476,7 +3534,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/browser-kit.git",
|
||||
@@ -3533,16 +3591,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v3.4.15",
|
||||
"version": "v3.4.17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/class-loader.git",
|
||||
"reference": "31db283fc86d3143e7ff87e922177b457d909c30"
|
||||
"reference": "f31333bdff54c7595f834d510a6d2325573ddb36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/31db283fc86d3143e7ff87e922177b457d909c30",
|
||||
"reference": "31db283fc86d3143e7ff87e922177b457d909c30",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/f31333bdff54c7595f834d510a6d2325573ddb36",
|
||||
"reference": "f31333bdff54c7595f834d510a6d2325573ddb36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3585,20 +3643,20 @@
|
||||
],
|
||||
"description": "Symfony ClassLoader Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:19:56+00:00"
|
||||
"time": "2018-10-02T12:28:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/config.git",
|
||||
"reference": "76015a3cc372b14d00040ff58e18e29f69eba717"
|
||||
"reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/76015a3cc372b14d00040ff58e18e29f69eba717",
|
||||
"reference": "76015a3cc372b14d00040ff58e18e29f69eba717",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/b3d4d7b567d7a49e6dfafb6d4760abc921177c96",
|
||||
"reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3648,20 +3706,20 @@
|
||||
],
|
||||
"description": "Symfony Config Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-08T06:37:38+00:00"
|
||||
"time": "2018-09-08T13:24:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "ca80b8ced97cf07390078b29773dc384c39eee1f"
|
||||
"reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f",
|
||||
"reference": "ca80b8ced97cf07390078b29773dc384c39eee1f",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b",
|
||||
"reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3716,20 +3774,20 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:24:31+00:00"
|
||||
"time": "2018-10-03T08:15:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v3.4.15",
|
||||
"version": "v3.4.17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
"reference": "edda5a6155000ff8c3a3f85ee5c421af93cca416"
|
||||
"reference": "3503415d4aafabc31cd08c3a4ebac7f43fde8feb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/edda5a6155000ff8c3a3f85ee5c421af93cca416",
|
||||
"reference": "edda5a6155000ff8c3a3f85ee5c421af93cca416",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/3503415d4aafabc31cd08c3a4ebac7f43fde8feb",
|
||||
"reference": "3503415d4aafabc31cd08c3a4ebac7f43fde8feb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3769,20 +3827,20 @@
|
||||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T09:06:28+00:00"
|
||||
"time": "2018-10-02T16:33:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dependency-injection.git",
|
||||
"reference": "bae4983003c9d451e278504d7d9b9d7fc1846873"
|
||||
"reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/bae4983003c9d451e278504d7d9b9d7fc1846873",
|
||||
"reference": "bae4983003c9d451e278504d7d9b9d7fc1846873",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6b9d893ad28aefd8942dc0469c8397e2216fe30",
|
||||
"reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3840,20 +3898,20 @@
|
||||
],
|
||||
"description": "Symfony DependencyInjection Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-08T11:48:58+00:00"
|
||||
"time": "2018-10-02T12:40:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dom-crawler.git",
|
||||
"reference": "1c4519d257e652404c3aa550207ccd8ada66b38e"
|
||||
"reference": "80e60271bb288de2a2259662cff125cff4f93f95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/1c4519d257e652404c3aa550207ccd8ada66b38e",
|
||||
"reference": "1c4519d257e652404c3aa550207ccd8ada66b38e",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/80e60271bb288de2a2259662cff125cff4f93f95",
|
||||
"reference": "80e60271bb288de2a2259662cff125cff4f93f95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3897,11 +3955,11 @@
|
||||
],
|
||||
"description": "Symfony DomCrawler Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:00:49+00:00"
|
||||
"time": "2018-10-02T12:40:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
@@ -3964,16 +4022,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e"
|
||||
"reference": "596d12b40624055c300c8b619755b748ca5cf0b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e",
|
||||
"reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5",
|
||||
"reference": "596d12b40624055c300c8b619755b748ca5cf0b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4010,7 +4068,7 @@
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-18T16:52:46+00:00"
|
||||
"time": "2018-10-02T12:40:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
@@ -4073,16 +4131,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "fa2182669f7983b7aa5f1a770d053f79f0ef144f"
|
||||
"reference": "9f0b61e339160a466ebcde167a6c5521c810e304"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/fa2182669f7983b7aa5f1a770d053f79f0ef144f",
|
||||
"reference": "fa2182669f7983b7aa5f1a770d053f79f0ef144f",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/9f0b61e339160a466ebcde167a6c5521c810e304",
|
||||
"reference": "9f0b61e339160a466ebcde167a6c5521c810e304",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4138,20 +4196,20 @@
|
||||
],
|
||||
"description": "Symfony Translation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-07T12:45:11+00:00"
|
||||
"time": "2018-10-02T16:36:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "b832cc289608b6d305f62149df91529a2ab3c314"
|
||||
"reference": "367e689b2fdc19965be435337b50bc8adf2746c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/b832cc289608b6d305f62149df91529a2ab3c314",
|
||||
"reference": "b832cc289608b6d305f62149df91529a2ab3c314",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/367e689b2fdc19965be435337b50bc8adf2746c9",
|
||||
"reference": "367e689b2fdc19965be435337b50bc8adf2746c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4197,7 +4255,7 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-18T16:52:46+00:00"
|
||||
"time": "2018-10-02T16:36:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
|
||||
@@ -1198,24 +1198,24 @@ function bbcode($Text, $options = []) {
|
||||
// Images
|
||||
// [img]pathtoimage[/img]
|
||||
if (strpos($Text,'[/img]') !== false) {
|
||||
$Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img style="max-width=100%;" src="$1" alt="' . t('Image/photo') . '" />', $Text);
|
||||
$Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" />', $Text);
|
||||
}
|
||||
if (strpos($Text,'[/zmg]') !== false) {
|
||||
$Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width=100%;" src="$1" alt="' . t('Image/photo') . '" />', $Text);
|
||||
$Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" />', $Text);
|
||||
}
|
||||
|
||||
// [img float={left, right}]pathtoimage[/img]
|
||||
if (strpos($Text,'[/img]') !== false) {
|
||||
$Text = preg_replace("/\[img float=left\](.*?)\[\/img\]/ism", '<img style="max-width=100%;" src="$1" style="float: left;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
$Text = preg_replace("/\[img float=left\](.*?)\[\/img\]/ism", '<img src="$1" style="max-width: 100%; float: left;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
}
|
||||
if (strpos($Text,'[/img]') !== false) {
|
||||
$Text = preg_replace("/\[img float=right\](.*?)\[\/img\]/ism", '<img style="max-width=100%;" src="$1" style="float: right;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
$Text = preg_replace("/\[img float=right\](.*?)\[\/img\]/ism", '<img src="$1" style="max-width: 100%; float: right;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
}
|
||||
if (strpos($Text,'[/zmg]') !== false) {
|
||||
$Text = preg_replace("/\[zmg float=left\](.*?)\[\/zmg\]/ism", '<img style="max-width=100%;" class="zrl" src="$1" style="float: left;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
$Text = preg_replace("/\[zmg float=left\](.*?)\[\/zmg\]/ism", '<img class="zrl" src="$1" style="max-width: 100%; float: left;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
}
|
||||
if (strpos($Text,'[/zmg]') !== false) {
|
||||
$Text = preg_replace("/\[zmg float=right\](.*?)\[\/zmg\]/ism", '<img style="max-width=100%;" class="zrl" src="$1" style="float: right;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
$Text = preg_replace("/\[zmg float=right\](.*?)\[\/zmg\]/ism", '<img class="zrl" src="$1" style="max-width: 100%; float: right;" alt="' . t('Image/photo') . '" />', $Text);
|
||||
}
|
||||
|
||||
// [img=widthxheight]pathtoimage[/img]
|
||||
|
||||
@@ -59,8 +59,8 @@ function set_pconfig($uid, $family, $key, $value) {
|
||||
return Zlib\PConfig::Set($uid,$family,$key,$value);
|
||||
}
|
||||
|
||||
function del_pconfig($uid, $family, $key) {
|
||||
return Zlib\PConfig::Delete($uid,$family,$key);
|
||||
function del_pconfig($uid, $family, $key, $updated = NULL) {
|
||||
return Zlib\PConfig::Delete($uid,$family,$key,$updated);
|
||||
}
|
||||
|
||||
function load_xconfig($xchan) {
|
||||
|
||||
@@ -173,14 +173,14 @@ abstract class dba_driver {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1') && (! strpbrk($server,':;'))) {
|
||||
if(! z_dns_check($server)) {
|
||||
$this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
|
||||
$this->connected = false;
|
||||
$this->db = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1') && (! strpbrk($server,':;'))) {
|
||||
// if(! z_dns_check($server)) {
|
||||
// $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
|
||||
// $this->connected = false;
|
||||
// $this->db = null;
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -468,7 +468,7 @@ function db_columns($table) {
|
||||
if(ACTIVE_DBTYPE === DBTYPE_POSTGRES) {
|
||||
$r = q("SELECT column_name as field FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '%s'",
|
||||
dbesc($table)
|
||||
);
|
||||
);
|
||||
if($r) {
|
||||
return ids_to_array($r,'field');
|
||||
}
|
||||
|
||||
@@ -186,31 +186,30 @@ function hubloc_change_primary($hubloc) {
|
||||
logger('no hubloc');
|
||||
return false;
|
||||
}
|
||||
|
||||
logger('setting primary: ' . $hubloc['hubloc_url'] . ((intval($hubloc['hubloc_primary'])) ? ' true' : ' false'));
|
||||
|
||||
// See if this is a local hubloc and if so update the primary for the corresponding channel record.
|
||||
|
||||
if($hubloc['hubloc_url'] === z_root()) {
|
||||
$r = q("select channel_id from channel where channel_hash = '%s' limit 1",
|
||||
dbesc($hubloc['hubloc_hash'])
|
||||
);
|
||||
if($r) {
|
||||
q("update channel set channel_primary = %d where channel_id = %d",
|
||||
intval($hubloc['hubloc_primary']),
|
||||
intval($r[0]['channel_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// we only need to proceed further if this particular hubloc is now primary
|
||||
|
||||
if(! (intval($hubloc['hubloc_primary']))) {
|
||||
logger('not primary: ' . $hubloc['hubloc_url']);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger('setting primary: ' . $hubloc['hubloc_url']);
|
||||
|
||||
// See if there's a local channel
|
||||
|
||||
$r = q("select channel_id, channel_primary from channel where channel_hash = '%s' limit 1",
|
||||
dbesc($hubloc['hubloc_hash'])
|
||||
);
|
||||
if($r) {
|
||||
if(! $r[0]['channel_primary']) {
|
||||
q("update channel set channel_primary = 1 where channel_id = %d",
|
||||
intval($r[0]['channel_id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
q("update channel set channel_primary = 0 where channel_id = %d",
|
||||
intval($r[0]['channel_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// do we even have an xchan for this hubloc and if so is it already set as primary?
|
||||
|
||||
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
|
||||
@@ -93,8 +93,7 @@ function import_channel($channel, $account_id, $seize, $newname = '') {
|
||||
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
|
||||
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
|
||||
'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt',
|
||||
'channel_moved', 'channel_primary', 'channel_removed', 'channel_deleted',
|
||||
'channel_system'
|
||||
'channel_moved', 'channel_removed', 'channel_deleted', 'channel_system'
|
||||
];
|
||||
|
||||
$clean = array();
|
||||
|
||||
@@ -608,8 +608,6 @@ function get_item_elements($x,$allow_code = false) {
|
||||
$arr['created'] = datetime_convert('UTC','UTC',$x['created']);
|
||||
$arr['edited'] = datetime_convert('UTC','UTC',$x['edited']);
|
||||
|
||||
if($arr['created'] > datetime_convert())
|
||||
$arr['created'] = datetime_convert();
|
||||
if($arr['edited'] > datetime_convert())
|
||||
$arr['edited'] = datetime_convert();
|
||||
|
||||
|
||||
@@ -248,20 +248,12 @@ function bb_to_markdown($Text, $options = []) {
|
||||
// Convert it to HTML - don't try oembed
|
||||
$Text = bbcode($Text, [ 'tryoembed' => false ]);
|
||||
|
||||
// Markdownify does not preserve previously escaped html entities such as <> and &.
|
||||
//$Text = str_replace(array('<','>','&'),array('&_lt_;','&_gt_;','&_amp_;'),$Text);
|
||||
|
||||
// Now convert HTML to Markdown
|
||||
|
||||
$Text = html2markdown($Text);
|
||||
|
||||
//html2markdown adds backslashes infront of hashes after a new line. remove them
|
||||
$Text = str_replace("\n\#", "\n#", $Text);
|
||||
|
||||
// It also adds backslashes to our attempt at getting around the html entity preservation for some weird reason.
|
||||
|
||||
//$Text = str_replace(array('&\\_lt\\_;','&\\_gt\\_;','&\\_amp\\_;'),array('<','>','&'),$Text);
|
||||
|
||||
// If the text going into bbcode() has a plain URL in it, i.e.
|
||||
// with no [url] tags around it, it will come out of parseString()
|
||||
// looking like: <http://url.com>, which gets removed by strip_tags().
|
||||
@@ -291,12 +283,24 @@ function bb_to_markdown($Text, $options = []) {
|
||||
* If the HTML text can not get parsed it will return an empty string.
|
||||
*
|
||||
* @param string $html The HTML code to convert
|
||||
* @param array $options an array of options to pass to the environment
|
||||
* @return string Markdown representation of the given HTML text, empty on error
|
||||
*/
|
||||
function html2markdown($html,$options = []) {
|
||||
function html2markdown($html, $options = []) {
|
||||
$markdown = '';
|
||||
|
||||
$internal_errors = libxml_use_internal_errors(true);
|
||||
if(! $options) {
|
||||
$options = [
|
||||
'header_style' => 'setext', // Set to 'atx' to output H1 and H2 headers as # Header1 and ## Header2
|
||||
'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
|
||||
'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
|
||||
'bold_style' => '**', // DEPRECATED: Set to '__' if you prefer the underlined style
|
||||
'italic_style' => '*', // DEPRECATED: Set to '_' if you prefer the underlined style
|
||||
'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: 'meta style script'
|
||||
'hard_break' => false, // Set to true to turn <br> into `\n` instead of ` \n`
|
||||
'list_item_style' => '-', // Set the default character for each <li> in a <ul>. Can be '-', '*', or '+'
|
||||
];
|
||||
}
|
||||
|
||||
$environment = Environment::createDefaultEnvironment($options);
|
||||
$environment->addConverter(new TableConverter());
|
||||
@@ -308,8 +312,6 @@ function html2markdown($html,$options = []) {
|
||||
logger("Invalid HTML. HTMLToMarkdown library threw an exception.");
|
||||
}
|
||||
|
||||
libxml_use_internal_errors($internal_errors);
|
||||
|
||||
return $markdown;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ function z_post_url($url, $params, $redirects = 0, $opts = array()) {
|
||||
return $ret;
|
||||
|
||||
if(! array_key_exists('request_target',$opts)) {
|
||||
$opts['request_target'] = 'get ' . get_request_string($url);
|
||||
$opts['request_target'] = 'post ' . get_request_string($url);
|
||||
}
|
||||
|
||||
@curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
@@ -711,9 +711,9 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
|
||||
foreach($matches as $mtch) {
|
||||
logger('data: ' . $mtch[2] . ' ' . $mtch[3]);
|
||||
|
||||
if(substr($mtch[1],0,1) == '=') {
|
||||
if(substr($mtch[2],0,1) == '=') {
|
||||
$owidth = intval(substr($mtch[2],1));
|
||||
if(intval($owidth) > 0 && intval($owidth) < 1024)
|
||||
if($owidth > 0 && $owidth < 1024)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -272,6 +272,7 @@ function oembed_fetch_url($embedurl){
|
||||
}
|
||||
|
||||
$j['embedurl'] = $embedurl;
|
||||
$j['zrl'] = $is_matrix;
|
||||
|
||||
// logger('fetch return: ' . print_r($j,true));
|
||||
|
||||
@@ -335,7 +336,11 @@ function oembed_format_object($j){
|
||||
|
||||
case "rich": {
|
||||
// not so safe..
|
||||
$ret.= $jhtml;
|
||||
if($j['zrl']) {
|
||||
$ret = ((preg_match('/^<div[^>]+>(.*?)<\/div>$/is',$j['html'],$o)) ? $o[1] : $j['html']);
|
||||
} else {
|
||||
$ret.= $jhtml;
|
||||
};
|
||||
}; break;
|
||||
}
|
||||
|
||||
|
||||
@@ -350,8 +350,7 @@ abstract class photo_driver {
|
||||
$p['allow_gid'] = (($arr['allow_gid']) ? $arr['allow_gid'] : '');
|
||||
$p['deny_cid'] = (($arr['deny_cid']) ? $arr['deny_cid'] : '');
|
||||
$p['deny_gid'] = (($arr['deny_gid']) ? $arr['deny_gid'] : '');
|
||||
$p['created'] = (($arr['created']) ? $arr['created'] : datetime_convert());
|
||||
$p['edited'] = (($arr['edited']) ? $arr['edited'] : $p['created']);
|
||||
$p['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert());
|
||||
$p['title'] = (($arr['title']) ? $arr['title'] : '');
|
||||
$p['description'] = (($arr['description']) ? $arr['description'] : '');
|
||||
$p['photo_usage'] = intval($arr['photo_usage']);
|
||||
@@ -365,13 +364,15 @@ abstract class photo_driver {
|
||||
if(! intval($p['imgscale']))
|
||||
logger('save: ' . print_r($arr,true), LOGGER_DATA);
|
||||
|
||||
$x = q("select id from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1",
|
||||
$x = q("select id, created from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1",
|
||||
dbesc($p['resource_id']),
|
||||
intval($p['uid']),
|
||||
dbesc($p['xchan']),
|
||||
intval($p['imgscale'])
|
||||
);
|
||||
|
||||
if($x) {
|
||||
$p['created'] = (($x['created']) ? $x['created'] : $p['edited']);
|
||||
$r = q("UPDATE photo set
|
||||
aid = %d,
|
||||
uid = %d,
|
||||
@@ -412,7 +413,7 @@ abstract class photo_driver {
|
||||
intval($p['width']),
|
||||
(intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())),
|
||||
intval($p['os_storage']),
|
||||
intval(strlen($this->imageString())),
|
||||
(intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())),
|
||||
intval($p['imgscale']),
|
||||
intval($p['photo_usage']),
|
||||
dbesc($p['title']),
|
||||
@@ -427,6 +428,7 @@ abstract class photo_driver {
|
||||
);
|
||||
}
|
||||
else {
|
||||
$p['created'] = (($arr['created']) ? $arr['created'] : $p['edited']);
|
||||
$r = q("INSERT INTO photo
|
||||
( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid )
|
||||
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
|
||||
@@ -443,7 +445,7 @@ abstract class photo_driver {
|
||||
intval($p['width']),
|
||||
(intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())),
|
||||
intval($p['os_storage']),
|
||||
intval(strlen($this->imageString())),
|
||||
(intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())),
|
||||
intval($p['imgscale']),
|
||||
intval($p['photo_usage']),
|
||||
dbesc($p['title']),
|
||||
@@ -464,11 +466,6 @@ abstract class photo_driver {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Guess image mimetype from filename or from Content-Type header
|
||||
*
|
||||
@@ -485,11 +482,11 @@ function guess_image_type($filename, $headers = '') {
|
||||
$h = explode("\n",$headers);
|
||||
foreach ($h as $l) {
|
||||
list($k,$v) = array_map("trim", explode(":", trim($l), 2));
|
||||
$hdrs[$k] = $v;
|
||||
$hdrs[strtolower($k)] = $v;
|
||||
}
|
||||
logger('Curl headers: '.var_export($hdrs, true), LOGGER_DEBUG);
|
||||
if (array_key_exists('Content-Type', $hdrs))
|
||||
$type = $hdrs['Content-Type'];
|
||||
if (array_key_exists('content-type', $hdrs))
|
||||
$type = $hdrs['content-type'];
|
||||
}
|
||||
if (is_null($type)){
|
||||
|
||||
@@ -570,122 +567,166 @@ function delete_thing_photo($url,$ob_hash) {
|
||||
|
||||
|
||||
|
||||
function import_xchan_photo($photo,$xchan,$thing = false) {
|
||||
/**
|
||||
* @brief fetches an photo from external site and prepares its miniatures.
|
||||
*
|
||||
* @param string $photo
|
||||
* external URL to fetch base image
|
||||
* @param string $xchan
|
||||
* channel unique hash
|
||||
* @param boolean $thing
|
||||
* TRUE if this is a thing URL
|
||||
* @param boolean $force
|
||||
* TRUE if ignore image modification date check (force fetch)
|
||||
*
|
||||
* @return array of results
|
||||
* * \e string \b 0 => local URL to full image
|
||||
* * \e string \b 1 => local URL to standard thumbnail
|
||||
* * \e string \b 2 => local URL to micro thumbnail
|
||||
* * \e string \b 3 => image type
|
||||
* * \e boolean \b 4 => TRUE if fetch failure
|
||||
* * \e string \b 5 => modification date
|
||||
*/
|
||||
|
||||
$flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN);
|
||||
$album = (($thing) ? 'Things' : 'Contact Photos');
|
||||
function import_xchan_photo($photo,$xchan,$thing = false,$force = false) {
|
||||
|
||||
logger('import_xchan_photo: updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
|
||||
$modified = '';
|
||||
|
||||
if($thing)
|
||||
$hash = photo_new_resource();
|
||||
else {
|
||||
$r = q("select resource_id from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1",
|
||||
dbesc($xchan),
|
||||
intval(PHOTO_XCHAN)
|
||||
);
|
||||
if($r) {
|
||||
$hash = $r[0]['resource_id'];
|
||||
}
|
||||
else {
|
||||
$hash = photo_new_resource();
|
||||
}
|
||||
}
|
||||
$flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN);
|
||||
$album = (($thing) ? 'Things' : 'Contact Photos');
|
||||
|
||||
$photo_failure = false;
|
||||
$img_str = '';
|
||||
logger('import_xchan_photo: updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
|
||||
|
||||
if($photo) {
|
||||
$filename = basename($photo);
|
||||
if($thing) {
|
||||
$hash = photo_new_resource();
|
||||
}
|
||||
else {
|
||||
$r = q("select resource_id, edited, mimetype from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1",
|
||||
dbesc($xchan),
|
||||
intval(PHOTO_XCHAN)
|
||||
);
|
||||
if($r) {
|
||||
$hash = $r[0]['resource_id'];
|
||||
$modified = $r[0]['edited'];
|
||||
$type = $r[0]['mimetype'];
|
||||
}
|
||||
else {
|
||||
$hash = photo_new_resource();
|
||||
}
|
||||
}
|
||||
|
||||
$result = z_fetch_url($photo,true);
|
||||
$photo_failure = false;
|
||||
$img_str = '';
|
||||
|
||||
if($result['success']) {
|
||||
$img_str = $result['body'];
|
||||
$type = guess_image_type($photo, $result['header']);
|
||||
if($photo) {
|
||||
$filename = basename($photo);
|
||||
|
||||
$h = explode("\n",$result['header']);
|
||||
if($h) {
|
||||
foreach($h as $hl) {
|
||||
if(stristr($hl,'content-type:')) {
|
||||
if(! stristr($hl,'image/')) {
|
||||
$photo_failure = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$photo_failure = true;
|
||||
}
|
||||
if($force || $modified == '') {
|
||||
$result = z_fetch_url($photo,true);
|
||||
}
|
||||
else {
|
||||
$h = array('headers' => array("If-Modified-Since: " . gmdate("D, d M Y H:i:s", strtotime($modified . "Z")) . " GMT"));
|
||||
$result = z_fetch_url($photo,true,0,$h);
|
||||
}
|
||||
|
||||
if(! $photo_failure) {
|
||||
$img = photo_factory($img_str, $type);
|
||||
if($img->is_valid()) {
|
||||
$width = $img->getWidth();
|
||||
$height = $img->getHeight();
|
||||
|
||||
if($width && $height) {
|
||||
if(($width / $height) > 1.2) {
|
||||
// crop out the sides
|
||||
$margin = $width - $height;
|
||||
$img->cropImage(300,($margin / 2),0,$height,$height);
|
||||
}
|
||||
elseif(($height / $width) > 1.2) {
|
||||
// crop out the bottom
|
||||
$margin = $height - $width;
|
||||
$img->cropImage(300,0,0,$width,$width);
|
||||
if($result['success']) {
|
||||
$img_str = $result['body'];
|
||||
$type = guess_image_type($photo, $result['header']);
|
||||
$modified = gmdate('Y-m-d H:i:s', (preg_match('/last-modified: (.+) \S+/i', $result['header'], $o) ? strtotime($o[1] . 'Z') : time()));
|
||||
|
||||
}
|
||||
else {
|
||||
$img->scaleImageSquare(300);
|
||||
}
|
||||
if(is_null($type))
|
||||
$photo_failure = true;
|
||||
}
|
||||
elseif($result['return_code'] == 304) {
|
||||
$photo = z_root() . '/photo/' . $hash . '-4';
|
||||
$thumb = z_root() . '/photo/' . $hash . '-5';
|
||||
$micro = z_root() . '/photo/' . $hash . '-6';
|
||||
}
|
||||
else {
|
||||
$photo_failure = true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
$photo_failure = true;
|
||||
}
|
||||
else
|
||||
$photo_failure = true;
|
||||
|
||||
$p = array('xchan' => $xchan,'resource_id' => $hash, 'filename' => basename($photo), 'album' => $album, 'photo_usage' => $flags, 'imgscale' => 4);
|
||||
if(! $photo_failure && $result['return_code'] != 304) {
|
||||
$img = photo_factory($img_str, $type);
|
||||
if($img->is_valid()) {
|
||||
$width = $img->getWidth();
|
||||
$height = $img->getHeight();
|
||||
|
||||
$r = $img->save($p);
|
||||
if($width && $height) {
|
||||
if(($width / $height) > 1.2) {
|
||||
// crop out the sides
|
||||
$margin = $width - $height;
|
||||
$img->cropImage(300,($margin / 2),0,$height,$height);
|
||||
}
|
||||
elseif(($height / $width) > 1.2) {
|
||||
// crop out the bottom
|
||||
$margin = $height - $width;
|
||||
$img->cropImage(300,0,0,$width,$width);
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
}
|
||||
else {
|
||||
$img->scaleImageSquare(300);
|
||||
}
|
||||
|
||||
$img->scaleImage(80);
|
||||
$p['imgscale'] = 5;
|
||||
|
||||
$r = $img->save($p);
|
||||
}
|
||||
else
|
||||
$photo_failure = true;
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
$img->scaleImage(48);
|
||||
$p['imgscale'] = 6;
|
||||
|
||||
$r = $img->save($p);
|
||||
$p = array(
|
||||
'xchan' => $xchan,
|
||||
'resource_id' => $hash,
|
||||
'filename' => basename($photo),
|
||||
'album' => $album,
|
||||
'photo_usage' => $flags,
|
||||
'imgscale' => 4,
|
||||
'edited' => $modified
|
||||
);
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
$r = $img->save($p);
|
||||
|
||||
$photo = z_root() . '/photo/' . $hash . '-4';
|
||||
$thumb = z_root() . '/photo/' . $hash . '-5';
|
||||
$micro = z_root() . '/photo/' . $hash . '-6';
|
||||
}
|
||||
else {
|
||||
logger('import_xchan_photo: invalid image from ' . $photo);
|
||||
$photo_failure = true;
|
||||
}
|
||||
}
|
||||
if($photo_failure) {
|
||||
$photo = z_root() . '/' . get_default_profile_photo();
|
||||
$thumb = z_root() . '/' . get_default_profile_photo(80);
|
||||
$micro = z_root() . '/' . get_default_profile_photo(48);
|
||||
$type = 'image/png';
|
||||
}
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
return(array($photo,$thumb,$micro,$type,$photo_failure));
|
||||
$img->scaleImage(80);
|
||||
$p['imgscale'] = 5;
|
||||
|
||||
$r = $img->save($p);
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
$img->scaleImage(48);
|
||||
$p['imgscale'] = 6;
|
||||
|
||||
$r = $img->save($p);
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
$photo = z_root() . '/photo/' . $hash . '-4';
|
||||
$thumb = z_root() . '/photo/' . $hash . '-5';
|
||||
$micro = z_root() . '/photo/' . $hash . '-6';
|
||||
}
|
||||
else {
|
||||
logger('import_xchan_photo: invalid image from ' . $photo);
|
||||
$photo_failure = true;
|
||||
}
|
||||
}
|
||||
if($photo_failure) {
|
||||
$default = get_default_profile_photo();
|
||||
$photo = z_root() . '/' . $default;
|
||||
$thumb = z_root() . '/' . get_default_profile_photo(80);
|
||||
$micro = z_root() . '/' . get_default_profile_photo(48);
|
||||
$type = 'image/png';
|
||||
$modified = gmdate('Y-m-d H:i:s', filemtime($default));
|
||||
}
|
||||
|
||||
logger('HTTP code: ' . $result['return_code'] . '; modified: ' . $modified . '; failure: ' . ($photo_failure ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG);
|
||||
return(array($photo,$thumb,$micro,$type,$photo_failure,$modified));
|
||||
|
||||
}
|
||||
|
||||
@@ -700,16 +741,8 @@ function import_channel_photo_from_url($photo,$aid,$uid) {
|
||||
$img_str = $result['body'];
|
||||
$type = guess_image_type($photo, $result['header']);
|
||||
|
||||
$h = explode("\n",$result['header']);
|
||||
if($h) {
|
||||
foreach($h as $hl) {
|
||||
if(stristr($hl,'content-type:')) {
|
||||
if(! stristr($hl,'image/')) {
|
||||
$photo_failure = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(is_null($type))
|
||||
$photo_failure = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1011,23 +1011,3 @@ function profile_photo_set_profile_perms($uid, $profileid = 0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fetch_image_from_url($url,&$mimetype) {
|
||||
|
||||
$redirects = 0;
|
||||
$x = z_fetch_url($url,true,$redirects,[ 'novalidate' => true ]);
|
||||
if($x['success']) {
|
||||
$hdrs = [];
|
||||
$h = explode("\n",$x['header']);
|
||||
foreach ($h as $l) {
|
||||
list($k,$v) = array_map("trim", explode(":", trim($l), 2));
|
||||
$hdrs[strtolower($k)] = $v;
|
||||
}
|
||||
if (array_key_exists('content-type', $hdrs))
|
||||
$mimetype = $hdrs['content-type'];
|
||||
|
||||
return $x['body'];
|
||||
}
|
||||
|
||||
return EMPTY_STR;
|
||||
}
|
||||
@@ -633,6 +633,19 @@ function attribute_contains($attr, $s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Log to syslog
|
||||
*
|
||||
* @param string $msg Message to log
|
||||
* @param int $priority - compatible with syslog
|
||||
*/
|
||||
function hz_syslog($msg, $priority = LOG_INFO) {
|
||||
openlog("hz-log", LOG_PID | LOG_PERROR, LOG_LOCAL0);
|
||||
syslog($priority, $msg);
|
||||
closelog();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Logging function for Hubzilla.
|
||||
*
|
||||
@@ -3219,8 +3232,16 @@ function create_table_from_array($table, $arr, $binary_fields = []) {
|
||||
if(! ($arr && $table))
|
||||
return false;
|
||||
|
||||
$columns = db_columns($table);
|
||||
|
||||
$clean = [];
|
||||
foreach($arr as $k => $v) {
|
||||
|
||||
if(! in_array($k,$columns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$matches = false;
|
||||
if(preg_match('/([^a-zA-Z0-9\-\_\.])/',$k,$matches)) {
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Zotlabs\Zot6\HTTPSig;
|
||||
|
||||
|
||||
function xchan_store_lowlevel($arr) {
|
||||
|
||||
@@ -39,6 +41,13 @@ function xchan_store_lowlevel($arr) {
|
||||
|
||||
function xchan_store($arr) {
|
||||
|
||||
$update_photo = false;
|
||||
$update_name = false;
|
||||
|
||||
if(! ($arr['guid'] || $arr['hash'])) {
|
||||
$arr = json_decode(file_get_contents('php://input'),true);
|
||||
}
|
||||
|
||||
logger('xchan_store: ' . print_r($arr,true));
|
||||
|
||||
if(! $arr['hash'])
|
||||
@@ -49,57 +58,90 @@ function xchan_store($arr) {
|
||||
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($arr['hash'])
|
||||
);
|
||||
if($r)
|
||||
return true;
|
||||
if(! $r) {
|
||||
|
||||
if(! $arr['network'])
|
||||
$arr['network'] = 'unknown';
|
||||
if(! $arr['name'])
|
||||
$arr['name'] = 'unknown';
|
||||
if(! $arr['url'])
|
||||
$arr['url'] = z_root();
|
||||
if(! $arr['photo'])
|
||||
$arr['photo'] = z_root() . '/' . get_default_profile_photo();
|
||||
$update_photo = true;
|
||||
|
||||
if(! $arr['network'])
|
||||
$arr['network'] = 'unknown';
|
||||
if(! $arr['name'])
|
||||
$arr['name'] = 'unknown';
|
||||
if(! $arr['url'])
|
||||
$arr['url'] = z_root();
|
||||
if(! $arr['photo'])
|
||||
$arr['photo'] = z_root() . '/' . get_default_profile_photo();
|
||||
|
||||
if($arr['network'] === 'zot') {
|
||||
if((! $arr['key']) || (! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key']))) {
|
||||
logger('Unable to verify signature for ' . $arr['hash']);
|
||||
return false;
|
||||
if($arr['network'] === 'zot6') {
|
||||
if((! $arr['key']) || (! Libzot::verify($arr['id'],$arr['id_sig'],$arr['key']))) {
|
||||
logger('Unable to verify signature for ' . $arr['hash']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$x = [];
|
||||
foreach($arr as $k => $v) {
|
||||
if($k === 'key') {
|
||||
$x['xchan_pubkey'] = $v;
|
||||
continue;
|
||||
}
|
||||
if($k === 'photo') {
|
||||
continue;
|
||||
if($arr['network'] === 'zot') {
|
||||
if((! $arr['key']) || (! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key']))) {
|
||||
logger('Unable to verify signature for ' . $arr['hash']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$columns = db_columns('xchan');
|
||||
|
||||
$x = [];
|
||||
foreach($arr as $k => $v) {
|
||||
if($k === 'key') {
|
||||
$x['xchan_pubkey'] = HTTPSig::convertKey(escape_tags($v));;
|
||||
continue;
|
||||
}
|
||||
if($k === 'photo') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$x['xchan_' . $k] = $v;
|
||||
if(in_array($columns,'xchan_' . $k))
|
||||
$x['xchan_' . $k] = escape_tags($v);
|
||||
}
|
||||
|
||||
$x['xchan_name_date'] = datetime_convert();
|
||||
$x['xchan_photo_date'] = datetime_convert();
|
||||
$x['xchan_system'] = false;
|
||||
|
||||
$result = xchan_store_lowlevel($x);
|
||||
|
||||
if(! $result)
|
||||
return $result;
|
||||
}
|
||||
else {
|
||||
if($r[0]['network'] === 'zot6') {
|
||||
return true;
|
||||
}
|
||||
if($r[0]['xchan_photo_date'] < datetime_convert('UTC','UTC',$arr['photo_date'])) {
|
||||
$update_photo = true;
|
||||
}
|
||||
if($r[0]['xchan_name_date'] < datetime_convert('UTC','UTC',$arr['name_date'])) {
|
||||
$update_name = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($update_photo && $arr['photo']) {
|
||||
$photos = import_xchan_photo($arr['photo'],$arr['hash']);
|
||||
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc($photos[3]),
|
||||
dbesc($arr['hash'])
|
||||
);
|
||||
}
|
||||
if($update_name && $arr['name']) {
|
||||
$x = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
|
||||
dbesc(escape_tags($arr['name'])),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($arr['hash'])
|
||||
);
|
||||
}
|
||||
|
||||
$x['xchan_name_date'] = datetime_convert();
|
||||
|
||||
$r = xchan_store_lowlevel($x);
|
||||
|
||||
if(! $r)
|
||||
return $r;
|
||||
|
||||
$photos = import_xchan_photo($arr['photo'],$arr['hash']);
|
||||
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc($photos[3]),
|
||||
dbesc($arr['hash'])
|
||||
);
|
||||
return $r;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1187,13 +1187,13 @@ function zot_fetch($arr) {
|
||||
|
||||
$zret = zot6_check_sig();
|
||||
|
||||
if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid'] && $data['msg']) {
|
||||
if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $arr['sender']['guid'] && $arr['msg']) {
|
||||
logger('zot6_delivery',LOGGER_DEBUG);
|
||||
logger('zot6_data: ' . print_r($data,true),LOGGER_DATA);
|
||||
logger('zot6_data: ' . print_r($arr,true),LOGGER_DATA);
|
||||
|
||||
$ret['collected'] = true;
|
||||
|
||||
$import = [ 'success' => true, 'body' => json_encode( [ 'success' => true, 'pickup' => [ [ 'notify' => $data, 'message' => json_decode($data['msg'],true) ] ] ] ) ];
|
||||
$import = [ 'success' => true, 'body' => json_encode( [ 'success' => true, 'pickup' => [ [ 'notify' => $arr, 'message' => json_decode($arr['msg'],true) ] ] ] ) ];
|
||||
$hubs = [ $zret['hubloc'] ] ;
|
||||
}
|
||||
|
||||
@@ -3507,8 +3507,41 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
|
||||
if(array_key_exists('config',$arr) && is_array($arr['config']) && count($arr['config'])) {
|
||||
foreach($arr['config'] as $cat => $k) {
|
||||
foreach($arr['config'][$cat] as $k => $v)
|
||||
set_pconfig($channel['channel_id'],$cat,$k,$v);
|
||||
|
||||
$pconfig_updated = [];
|
||||
$pconfig_del = [];
|
||||
|
||||
foreach($arr['config'][$cat] as $k => $v) {
|
||||
|
||||
if (strpos($k,'pcfgud:')===0) {
|
||||
|
||||
$realk = substr($k,7);
|
||||
$pconfig_updated[$realk] = $v;
|
||||
unset($arr['config'][$cat][$k]);
|
||||
|
||||
}
|
||||
|
||||
if (strpos($k,'pcfgdel:')===0) {
|
||||
$realk = substr($k,8);
|
||||
$pconfig_del[$realk] = datetime_convert();
|
||||
unset($arr['config'][$cat][$k]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($arr['config'][$cat] as $k => $v) {
|
||||
|
||||
if (!isset($pconfig_updated[$k])) {
|
||||
$pconfig_updated[$k] = NULL;
|
||||
}
|
||||
|
||||
set_pconfig($channel['channel_id'],$cat,$k,$v,$pconfig_updated[$k]);
|
||||
|
||||
}
|
||||
|
||||
foreach($pconfig_del as $k => $updated) {
|
||||
del_pconfig($channel['channel_id'],$cat,$k,$updated);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -910,7 +910,6 @@ CREATE TABLE IF NOT EXISTS `outq` (
|
||||
KEY `outq_priority` (`outq_priority`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pchan (
|
||||
`pchan_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`pchan_guid` char(191) NOT NULL DEFAULT '',
|
||||
@@ -922,15 +921,16 @@ CREATE TABLE IF NOT EXISTS pchan (
|
||||
KEY `pchan_hash` (`pchan_hash`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pconfig` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`uid` int(11) NOT NULL DEFAULT 0 ,
|
||||
`cat` char(191) NOT NULL DEFAULT '',
|
||||
`k` char(191) NOT NULL DEFAULT '',
|
||||
`v` mediumtext NOT NULL,
|
||||
`updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `access` (`uid`,`cat`,`k`)
|
||||
UNIQUE KEY `access` (`uid`,`cat`,`k`),
|
||||
KEY `pconfig_updated` (`updated`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `photo` (
|
||||
|
||||
@@ -891,7 +891,6 @@ create index "outq_async" on outq ("outq_async");
|
||||
create index "outq_delivered" on outq ("outq_delivered");
|
||||
create index "outq_priority" on outq ("outq_priority");
|
||||
|
||||
|
||||
CREATE TABLE "pchan" (
|
||||
"pchan_id" serial NOT NULL,
|
||||
"pchan_guid" text NOT NULL,
|
||||
@@ -900,7 +899,6 @@ CREATE TABLE "pchan" (
|
||||
"pchan_prvkey" text NOT NULL,
|
||||
PRIMARY KEY ("pchan_id")
|
||||
);
|
||||
|
||||
create index "pchan_guid" on pchan ("pchan_guid");
|
||||
create index "pchan_hash" on pchan ("pchan_hash");
|
||||
|
||||
@@ -910,9 +908,11 @@ CREATE TABLE "pconfig" (
|
||||
"cat" text NOT NULL,
|
||||
"k" text NOT NULL,
|
||||
"v" text NOT NULL,
|
||||
"updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
|
||||
PRIMARY KEY ("id"),
|
||||
UNIQUE ("uid","cat","k")
|
||||
);
|
||||
create index "pconfig_updated_idx" on pconfig ("updated");
|
||||
|
||||
CREATE TABLE "photo" (
|
||||
"id" serial NOT NULL,
|
||||
|
||||
@@ -52,12 +52,12 @@ class MarkdownTest extends UnitTestCase {
|
||||
' ',
|
||||
''
|
||||
],
|
||||
/* it is not clear why this test fails
|
||||
|
||||
'strong, b, em, i, bib' => [
|
||||
'<strong>strong</strong> <b>bold</b> <em>em</em> <i>italic</i> <b>bo<i>italic</i>ld</b>',
|
||||
'**strong** **bold** _em_ _italic_ **bo_italic_ld**'
|
||||
'**strong** **bold** *em* *italic* **bo*italic*ld**'
|
||||
],
|
||||
*/
|
||||
|
||||
'empty tags' => [
|
||||
'text1 <b></b> text2 <i></i>',
|
||||
'text1 text2'
|
||||
@@ -70,10 +70,6 @@ class MarkdownTest extends UnitTestCase {
|
||||
'& lt < gt >',
|
||||
'& lt < gt >'
|
||||
],
|
||||
'our escaped HTML entities' => [
|
||||
'&_lt_; &_gt_; &_amp_;',
|
||||
'&\_lt\_; &\_gt\_; &\_amp\_;'
|
||||
],
|
||||
'linebreak' => [
|
||||
"line1<br>line2\nline3",
|
||||
"line1 \nline2 line3"
|
||||
@@ -84,15 +80,15 @@ class MarkdownTest extends UnitTestCase {
|
||||
],
|
||||
'unordered list' => [
|
||||
'<ul><li>Item 1</li><li>Item 2</li><li>Item <b>3</b></li></ul>',
|
||||
"- Item 1\n- Item 2\n- Item 3"
|
||||
"- Item 1\n- Item 2\n- Item **3**"
|
||||
],
|
||||
'ordered list' => [
|
||||
'<ol><li>Item 1</li><li>Item 2</li><li>Item <b>3</b></li></ol>',
|
||||
"1. Item 1\n2. Item 2\n3. Item 3"
|
||||
"1. Item 1\n2. Item 2\n3. Item **3**"
|
||||
],
|
||||
'nested lists' => [
|
||||
'<ul><li>Item 1<ol><li>Item 1a</li><li>Item <b>1b</b></ol></li><li>Item 2</li></ul>',
|
||||
"- Item 1\n 1. Item 1a\n 2. Item 1b\n- Item 2"
|
||||
"- Item 1\n 1. Item 1a\n 2. Item **1b**\n- Item 2"
|
||||
],
|
||||
'img' => [
|
||||
'<img src="/path/to/img.png" alt="alt text" title="title text">',
|
||||
@@ -118,12 +114,10 @@ class MarkdownTest extends UnitTestCase {
|
||||
'<code><p>HTML text</p></code>',
|
||||
'`<p>HTML text</p>`'
|
||||
],
|
||||
/* it is not clear why this test fails
|
||||
'pre' => [
|
||||
'<pre> line with spaces </pre>',
|
||||
'` line with spaces `'
|
||||
'<pre> one line with spaces </pre>',
|
||||
"```\n one line with spaces \n```"
|
||||
],
|
||||
*/
|
||||
'div p' => [
|
||||
'<div>div</div><div><p>p</p></div>',
|
||||
"<div>div</div><div>p\n\n</div>"
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
# jQuery File Upload Plugin
|
||||
|
||||
## Demo
|
||||
[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)
|
||||
|
||||
## Description
|
||||
File Upload widget with multiple file selection, drag&drop support, progress bars, validation and preview images, audio and video for jQuery.
|
||||
Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.
|
||||
|
||||
## Demo
|
||||
[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)
|
||||
|
||||
## ⚠️ Security Notice
|
||||
Security related releases:
|
||||
|
||||
* [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) Mitigates some [Potential vulnerabilities with PHP+ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick).
|
||||
* [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) Fixes a [Remote code execution vulnerability in the PHP component](VULNERABILITIES.md#remote-code-execution-vulnerability-in-the-php-component).
|
||||
* v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) Fixes an [Open redirect vulnerability in the GAE components](VULNERABILITIES.md#open-redirect-vulnerability-in-the-gae-components).
|
||||
* Commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) Fixes a [Cross-site scripting vulnerability in the Iframe Transport](VULNERABILITIES.md#cross-site-scripting-vulnerability-in-the-iframe-transport).
|
||||
|
||||
Please read the [SECURITY](SECURITY.md) document for instructions on how to securely configure your Webserver for file uploads.
|
||||
|
||||
## Setup
|
||||
* [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
|
||||
* [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)
|
||||
@@ -15,7 +25,7 @@ Supports cross-domain, chunked and resumable file uploads and client-side image
|
||||
* **Multiple file upload:**
|
||||
Allows to select multiple files at once and upload them simultaneously.
|
||||
* **Drag & Drop support:**
|
||||
Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window.
|
||||
Allows to upload files by dragging them from your desktop or file manager and dropping them on your browser window.
|
||||
* **Upload progress bar:**
|
||||
Shows a progress bar indicating the upload progress for individual files and for all uploads combined.
|
||||
* **Cancelable uploads:**
|
||||
133
vendor/blueimp/jquery-file-upload/SECURITY.md
vendored
Normal file
133
vendor/blueimp/jquery-file-upload/SECURITY.md
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
# File Upload Security
|
||||
For an in-depth understanding of the potential security risks of providing file uploads and possible mitigations, please refer to the [OWASP - Unrestricted File Upload](https://www.owasp.org/index.php/Unrestricted_File_Upload) documentation.
|
||||
|
||||
To securely setup the project to serve uploaded files, please refer to the sample [Secure file upload serving configurations](#secure-file-upload-serving-configurations).
|
||||
|
||||
To mitigate potential vulnerabilities in image processing libraries, please refer to the [Secure image processing configurations](#secure-image-processing-configurations).
|
||||
|
||||
By default, all sample upload handlers allow only upload of image files, which mitigates some attack vectors, but should not be relied on as the only protection.
|
||||
|
||||
Please also have a look at the [list of fixed vulnerabilities](VULNERABILITIES.md) in jQuery File Upload, which relates mostly to the sample server-side upload handlers and how they have been configured.
|
||||
|
||||
## Purpose of this project
|
||||
Please note that this project is not a complete file management product, but foremost a client-side file upload library for [jQuery](https://jquery.com/).
|
||||
The server-side sample upload handlers are just examples to demonstrate the client-side file upload functionality.
|
||||
|
||||
To make this very clear, there is **no user authentication** by default:
|
||||
* **everyone can upload files**
|
||||
* **everyone can delete uploaded files**
|
||||
|
||||
In some cases this can be acceptable, but for most projects you will want to extend the sample upload handlers to integrate user authentication, or implement your own.
|
||||
|
||||
It is also up to you to configure your Webserver to securely serve the uploaded files, e.g. using the [sample server configurations](#secure-file-upload-serving-configurations).
|
||||
|
||||
## Mitigations against file upload risks
|
||||
|
||||
### Prevent code execution on the server
|
||||
To prevent execution of scripts or binaries on server-side, the upload directory must be configured to not execute files in the upload directory (e.g. `server/php/files` as the default for the PHP upload handler) and only treat uploaded files as static content.
|
||||
|
||||
The recommended way to do this is to configure the upload directory path to point outside of the web application root.
|
||||
Then the Webserver can be configured to serve files from the upload directory with their default static files handler only.
|
||||
|
||||
Limiting file uploads to a whitelist of safe file types (e.g. image files) also mitigates this issue, but should not be the only protection.
|
||||
|
||||
### Prevent code execution in the browser
|
||||
To prevent execution of scripts on client-side, the following headers must
|
||||
be sent when delivering generic uploaded files to the client:
|
||||
|
||||
```
|
||||
Content-Type: application/octet-stream
|
||||
X-Content-Type-Options: nosniff
|
||||
```
|
||||
|
||||
The `Content-Type: application/octet-stream` header instructs browsers to display a download dialog instead of parsing it and possibly executing script content e.g. in HTML files.
|
||||
|
||||
The `X-Content-Type-Options: nosniff` header prevents browsers to try to detect the file mime type despite the given content-type header.
|
||||
|
||||
For known safe files, the content-type header can be adjusted using a **whitelist**, e.g. sending `Content-Type: image/png` for PNG files.
|
||||
|
||||
### Prevent distribution of malware
|
||||
To prevent attackers from uploading and distributing malware (e.g. computer viruses), it is recommended to limit file uploads only to a whitelist of safe file types.
|
||||
|
||||
Please note that the detection of file types in the sample file upload handlers is based on the file extension and not the actual file content. This makes it still possible for attackers to upload malware by giving their files an image file extension, but should prevent automatic execution on client computers when opening those files.
|
||||
|
||||
It does not protect at all from exploiting vulnerabilities in image display programs, nor from users renaming file extensions to inadvertently execute the contained malicious code.
|
||||
|
||||
## Secure file upload serving configurations
|
||||
The following configurations serve uploaded files as static files with the proper headers as [mitigation against file upload risks](#mitigations-against-file-upload-risks).
|
||||
Please do not simply copy&paste these configurations, but make sure you understand what they are doing and that you have implemented them correctly.
|
||||
|
||||
> Always test your own setup and make sure that it is secure!
|
||||
|
||||
e.g. try uploading PHP scripts (as "example.php", "example.php.png" and "example.png") to see if they get executed by your Webserver.
|
||||
|
||||
### Apache config
|
||||
Add the following directive to the Apache config, replacing the directory path with the absolute path to the upload directory:
|
||||
|
||||
```ApacheConf
|
||||
<Directory "/path/to/project/server/php/files">
|
||||
# To enable the Headers module, execute the following command and reload Apache:
|
||||
# sudo a2enmod headers
|
||||
|
||||
# The following directives prevent the execution of script files
|
||||
# in the context of the website.
|
||||
# They also force the content-type application/octet-stream and
|
||||
# force browsers to display a download dialog for non-image files.
|
||||
SetHandler default-handler
|
||||
ForceType application/octet-stream
|
||||
Header set Content-Disposition attachment
|
||||
|
||||
# The following unsets the forced type and Content-Disposition headers
|
||||
# for known image files:
|
||||
<FilesMatch "(?i)\.(gif|jpe?g|png)$">
|
||||
ForceType none
|
||||
Header unset Content-Disposition
|
||||
</FilesMatch>
|
||||
|
||||
# The following directive prevents browsers from MIME-sniffing the content-type.
|
||||
# This is an important complement to the ForceType directive above:
|
||||
Header set X-Content-Type-Options nosniff
|
||||
</Directory>
|
||||
```
|
||||
|
||||
### NGINX config
|
||||
Add the following directive to the NGINX config, replacing the directory path with the absolute path to the upload directory:
|
||||
|
||||
```Nginx
|
||||
location ^~ /path/to/project/server/php/files {
|
||||
root html;
|
||||
default_type application/octet-stream;
|
||||
types {
|
||||
image/gif gif;
|
||||
image/jpeg jpg;
|
||||
image/png png;
|
||||
}
|
||||
add_header X-Content-Type-Options 'nosniff';
|
||||
if ($request_filename ~ /(((?!\.(jpg)|(png)|(gif)$)[^/])+$)) {
|
||||
add_header Content-Disposition 'attachment; filename="$1"';
|
||||
# Add X-Content-Type-Options again, as using add_header in a new context
|
||||
# dismisses all previous add_header calls:
|
||||
add_header X-Content-Type-Options 'nosniff';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Secure image processing configurations
|
||||
The following configuration mitigates [potential image processing vulnerabilities with ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick) by limiting the attack vectors to a small subset of image types (`GIF/JPEG/PNG`).
|
||||
|
||||
Please also consider using alternative, safer image processing libraries like [libvips](https://github.com/libvips/libvips) or [imageflow](https://github.com/imazen/imageflow).
|
||||
|
||||
## ImageMagick config
|
||||
It is recommended to disable all non-required ImageMagick coders via [policy.xml](https://wiki.debian.org/imagemagick/security).
|
||||
To do so, locate the ImageMagick `policy.xml` configuration file and add the following policies:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- ... -->
|
||||
<policymap>
|
||||
<!-- ... -->
|
||||
<policy domain="delegate" rights="none" pattern="*" />
|
||||
<policy domain="coder" rights="none" pattern="*" />
|
||||
<policy domain="coder" rights="read | write" pattern="{GIF,JPEG,PNG}" />
|
||||
</policymap>
|
||||
```
|
||||
65
vendor/blueimp/jquery-file-upload/VULNERABILITIES.md
vendored
Normal file
65
vendor/blueimp/jquery-file-upload/VULNERABILITIES.md
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# ⚠️ List of fixed vulnerabilities
|
||||
|
||||
## Potential vulnerabilities with PHP+ImageMagick
|
||||
> Mitigated: 2018-10-25 (GMT)
|
||||
|
||||
The sample [PHP upload handler](server/php/UploadHandler.php) before [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) did not validate file signatures before invoking [ImageMagick](https://www.imagemagick.org/) (via [Imagick](http://php.net/manual/en/book.imagick.php)).
|
||||
Verifying those [magic bytes](https://en.wikipedia.org/wiki/List_of_file_signatures) mitigates potential vulnerabilities when handling input files other than `GIF/JPEG/PNG`.
|
||||
|
||||
Please also configure ImageMagick to only enable the coders required for `GIF/JPEG/PNG` processing, e.g. with the sample [ImageMagick config](SECURITY.md#imagemagick-config).
|
||||
|
||||
**Further information:**
|
||||
* Commit containing the mitigation: [fe44d34](https://github.com/blueimp/jQuery-File-Upload/commit/fe44d34be43be32c6b8d507932f318dababb25dd)
|
||||
* [ImageTragick](https://imagetragick.com/)
|
||||
* [CERT Vulnerability Note VU#332928](https://www.kb.cert.org/vuls/id/332928)
|
||||
* [ImageMagick CVE entries](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=imagemagick)
|
||||
|
||||
## Remote code execution vulnerability in the PHP component
|
||||
> Fixed: 2018-10-23 (GMT)
|
||||
|
||||
The sample [PHP upload handler](server/php/UploadHandler.php) before [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) allowed to upload all file types by default.
|
||||
This opens up a remote code execution vulnerability, unless the server is configured to not execute (PHP) files in the upload directory (`server/php/files`).
|
||||
|
||||
The provided [.htaccess](server/php/files/.htaccess) file includes instructions for Apache to disable script execution, however [.htaccess support](https://httpd.apache.org/docs/current/howto/htaccess.html) is disabled by default since Apache `v2.3.9` via [AllowOverride Directive](https://httpd.apache.org/docs/current/mod/core.html#allowoverride).
|
||||
|
||||
**You are affected if you:**
|
||||
1. A) Uploaded jQuery File Upload < `v9.24.1` on a Webserver that executes files with `.php` as part of the file extension (e.g. "example.php.png"), e.g. Apache with `mod_php` enabled and the following directive (*not a recommended configuration*):
|
||||
```ApacheConf
|
||||
AddHandler php5-script .php
|
||||
```
|
||||
B) Uploaded jQuery File Upload < `v9.22.1` on a Webserver that executes files with the file extension `.php`, e.g. Apache with `mod_php` enabled and the following directive:
|
||||
```ApacheConf
|
||||
<FilesMatch \.php$>
|
||||
SetHandler application/x-httpd-php
|
||||
</FilesMatch>
|
||||
```
|
||||
2. Did not actively configure your Webserver to not execute files in the upload directory (`server/php/files`).
|
||||
3. Are running Apache `v2.3.9+` with the default `AllowOverride` Directive set to `None` or another Webserver with no `.htaccess` support.
|
||||
|
||||
**How to fix it:**
|
||||
1. Upgrade to the latest version of jQuery File Upload.
|
||||
2. Configure your Webserver to not execute files in the upload directory, e.g. with the [sample Apache configuration](SECURITY.md#apache-config)
|
||||
|
||||
**Further information:**
|
||||
* Commits containing the security fix: [aeb47e5](https://github.com/blueimp/jQuery-File-Upload/commit/aeb47e51c67df8a504b7726595576c1c66b5dc2f), [ad4aefd](https://github.com/blueimp/jQuery-File-Upload/commit/ad4aefd96e4056deab6fea2690f0d8cf56bb2d7d)
|
||||
* [Full disclosure post on Hacker News](https://news.ycombinator.com/item?id=18267309).
|
||||
* [CVE-2018-9206](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9206)
|
||||
* [OWASP - Unrestricted File Upload](https://www.owasp.org/index.php/Unrestricted_File_Upload)
|
||||
|
||||
## Open redirect vulnerability in the GAE components
|
||||
> Fixed: 2015-06-12 (GMT)
|
||||
|
||||
The sample Google App Engine upload handlers before v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) accepted any URL as redirect target, making it possible to use the Webserver's domain for phishing attacks.
|
||||
|
||||
**Further information:**
|
||||
* Commit containing the security fix: [f74d2a8](https://github.com/blueimp/jQuery-File-Upload/commit/f74d2a8c3e3b1e8e336678d2899facd5bcdb589f)
|
||||
* [OWASP - Unvalidated Redirects and Forwards Cheat Sheet](https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet)
|
||||
|
||||
## Cross-site scripting vulnerability in the Iframe Transport
|
||||
> Fixed: 2012-08-09 (GMT)
|
||||
|
||||
The [redirect page](cors/result.html) for the [Iframe Transport](js/jquery.iframe-transport.js) before commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) allowed executing arbitrary JavaScript in the context of the Webserver.
|
||||
|
||||
**Further information:**
|
||||
* Commit containing the security fix: [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a)
|
||||
* [OWASP - Cross-site Scripting (XSS)](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS))
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "blueimp-file-upload",
|
||||
"version": "9.23.0",
|
||||
"version": "9.25.1",
|
||||
"title": "jQuery File Upload",
|
||||
"description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.",
|
||||
"keywords": [
|
||||
39
vendor/blueimp/jquery-file-upload/composer.json
vendored
Normal file
39
vendor/blueimp/jquery-file-upload/composer.json
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "blueimp/jquery-file-upload"
|
||||
, "description": "File Upload widget for jQuery."
|
||||
, "keywords": ["jquery",
|
||||
"file",
|
||||
"upload",
|
||||
"widget",
|
||||
"multiple",
|
||||
"selection",
|
||||
"drag",
|
||||
"drop",
|
||||
"progress",
|
||||
"preview",
|
||||
"cross-domain",
|
||||
"cross-site",
|
||||
"chunk",
|
||||
"resume",
|
||||
"gae",
|
||||
"go",
|
||||
"python",
|
||||
"php",
|
||||
"bootstrap"]
|
||||
, "homepage": "https://github.com/blueimp/jQuery-File-Upload"
|
||||
, "authors": [
|
||||
{
|
||||
"name": "Sebastian Tschan",
|
||||
"homepage": "https://blueimp.net"
|
||||
}
|
||||
]
|
||||
, "support": {
|
||||
"forum": "https://groups.google.com/forum/#!forum/jquery-fileupload"
|
||||
}
|
||||
, "license": "MIT"
|
||||
, "autoload": {
|
||||
"classmap": [
|
||||
"server/php/UploadHandler.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "blueimp-file-upload",
|
||||
"version": "9.23.0",
|
||||
"version": "9.25.1",
|
||||
"title": "jQuery File Upload",
|
||||
"description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.",
|
||||
"keywords": [
|
||||
@@ -1,5 +1,3 @@
|
||||
application: jquery-file-upload
|
||||
version: 2
|
||||
runtime: go
|
||||
api_version: go1
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
application: jquery-file-upload
|
||||
version: 1
|
||||
runtime: python27
|
||||
api_version: 1
|
||||
threadsafe: true
|
||||
@@ -38,6 +38,10 @@ class UploadHandler
|
||||
'image_resize' => 'Failed to resize image'
|
||||
);
|
||||
|
||||
protected const IMAGETYPE_GIF = 1;
|
||||
protected const IMAGETYPE_JPEG = 2;
|
||||
protected const IMAGETYPE_PNG = 3;
|
||||
|
||||
protected $image_objects = array();
|
||||
|
||||
public function __construct($options = null, $initialize = true, $error_messages = null) {
|
||||
@@ -89,17 +93,32 @@ class UploadHandler
|
||||
'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB
|
||||
// Defines which files can be displayed inline when downloaded:
|
||||
'inline_file_types' => '/\.(gif|jpe?g|png)$/i',
|
||||
// Defines which files (based on their names) are accepted for upload:
|
||||
'accept_file_types' => '/.+$/i',
|
||||
// Defines which files (based on their names) are accepted for upload.
|
||||
// By default, only allows file uploads with image file extensions.
|
||||
// Only change this setting after making sure that any allowed file
|
||||
// types cannot be executed by the webserver in the files directory,
|
||||
// e.g. PHP scripts, nor executed by the browser when downloaded,
|
||||
// e.g. HTML files with embedded JavaScript code.
|
||||
// Please also read the SECURITY.md document in this repository.
|
||||
'accept_file_types' => '/\.(gif|jpe?g|png)$/i',
|
||||
// Replaces dots in filenames with the given string.
|
||||
// Can be disabled by setting it to false or an empty string.
|
||||
// Note that this is a security feature for servers that support
|
||||
// multiple file extensions, e.g. the Apache AddHandler Directive:
|
||||
// https://httpd.apache.org/docs/current/mod/mod_mime.html#addhandler
|
||||
// Before disabling it, make sure that files uploaded with multiple
|
||||
// extensions cannot be executed by the webserver, e.g.
|
||||
// "example.php.png" with embedded PHP code, nor executed by the
|
||||
// browser when downloaded, e.g. "example.html.gif" with embedded
|
||||
// JavaScript code.
|
||||
'replace_dots_in_filenames' => '-',
|
||||
// The php.ini settings upload_max_filesize and post_max_size
|
||||
// take precedence over the following max_file_size setting:
|
||||
'max_file_size' => null,
|
||||
'min_file_size' => 1,
|
||||
// The maximum number of files for the upload directory:
|
||||
'max_number_of_files' => null,
|
||||
// Defines which files are handled as image files:
|
||||
'image_file_types' => '/\.(gif|jpe?g|png)$/i',
|
||||
// Use exif_imagetype on all files to correct file extensions:
|
||||
// Reads first file bytes to identify and correct file extensions:
|
||||
'correct_image_extensions' => false,
|
||||
// Image resolution restrictions:
|
||||
'max_width' => null,
|
||||
@@ -146,7 +165,7 @@ class UploadHandler
|
||||
'max_width' => 800,
|
||||
'max_height' => 600
|
||||
),
|
||||
*/
|
||||
*/
|
||||
'thumbnail' => array(
|
||||
// Uncomment the following to use a defined directory for the thumbnails
|
||||
// instead of a subdirectory based on the version identifier.
|
||||
@@ -416,9 +435,8 @@ class UploadHandler
|
||||
$min_width = @$this->options['min_width'];
|
||||
$min_height = @$this->options['min_height'];
|
||||
if (($max_width || $max_height || $min_width || $min_height)
|
||||
&& preg_match($this->options['image_file_types'], $file->name)) {
|
||||
&& $this->is_valid_image_file($uploaded_file)) {
|
||||
list($img_width, $img_height) = $this->get_image_size($uploaded_file);
|
||||
|
||||
// If we are auto rotating the image by default, do the checks on
|
||||
// the correct orientation
|
||||
if (
|
||||
@@ -432,7 +450,6 @@ class UploadHandler
|
||||
$img_height = $tmp;
|
||||
unset($tmp);
|
||||
}
|
||||
|
||||
}
|
||||
if (!empty($img_width)) {
|
||||
if ($max_width && $img_width > $max_width) {
|
||||
@@ -494,16 +511,15 @@ class UploadHandler
|
||||
preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
|
||||
$name .= '.'.$matches[1];
|
||||
}
|
||||
if ($this->options['correct_image_extensions'] &&
|
||||
function_exists('exif_imagetype')) {
|
||||
switch (@exif_imagetype($file_path)){
|
||||
case IMAGETYPE_JPEG:
|
||||
if ($this->options['correct_image_extensions']) {
|
||||
switch ($this->imagetype($file_path)) {
|
||||
case self::IMAGETYPE_JPEG:
|
||||
$extensions = array('jpg', 'jpeg');
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
case self::IMAGETYPE_PNG:
|
||||
$extensions = array('png');
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
case self::IMAGETYPE_GIF:
|
||||
$extensions = array('gif');
|
||||
break;
|
||||
}
|
||||
@@ -527,6 +543,16 @@ class UploadHandler
|
||||
// into different directories or replacing hidden system files.
|
||||
// Also remove control characters and spaces (\x00..\x20) around the filename:
|
||||
$name = trim($this->basename(stripslashes($name)), ".\x00..\x20");
|
||||
// Replace dots in filenames to avoid security issues with servers
|
||||
// that interpret multiple file extensions, e.g. "example.php.png":
|
||||
$replacement = $this->options['replace_dots_in_filenames'];
|
||||
if (!empty($replacement)) {
|
||||
$parts = explode('.', $name);
|
||||
if (count($parts) > 2) {
|
||||
$ext = array_pop($parts);
|
||||
$name = implode($replacement, $parts).'.'.$ext;
|
||||
}
|
||||
}
|
||||
// Use a timestamp for empty filenames:
|
||||
if (!$name) {
|
||||
$name = str_replace('.', '-', microtime(true));
|
||||
@@ -1036,15 +1062,27 @@ class UploadHandler
|
||||
}
|
||||
}
|
||||
|
||||
protected function imagetype($file_path) {
|
||||
$fp = fopen($file_path, 'r');
|
||||
$data = fread($fp, 4);
|
||||
fclose($fp);
|
||||
// GIF: 47 49 46
|
||||
if (substr($data, 0, 3) === 'GIF') {
|
||||
return self::IMAGETYPE_GIF;
|
||||
}
|
||||
// JPG: FF D8
|
||||
if (bin2hex(substr($data, 0, 2)) === 'ffd8') {
|
||||
return self::IMAGETYPE_JPEG;
|
||||
}
|
||||
// PNG: 89 50 4E 47
|
||||
if (bin2hex(@$data[0]).substr($data, 1, 4) === '89PNG') {
|
||||
return self::IMAGETYPE_PNG;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function is_valid_image_file($file_path) {
|
||||
if (!preg_match($this->options['image_file_types'], $file_path)) {
|
||||
return false;
|
||||
}
|
||||
if (function_exists('exif_imagetype')) {
|
||||
return @exif_imagetype($file_path);
|
||||
}
|
||||
$image_info = $this->get_image_size($file_path);
|
||||
return $image_info && $image_info[0] && $image_info[1];
|
||||
return !!$this->imagetype($file_path);
|
||||
}
|
||||
|
||||
protected function handle_image_file($file_path, $file) {
|
||||
15
vendor/blueimp/jquery-file-upload/server/php/index.php
vendored
Normal file
15
vendor/blueimp/jquery-file-upload/server/php/index.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
* jQuery File Upload Plugin PHP Example
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
exit;
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
require('UploadHandler.php');
|
||||
$upload_handler = new UploadHandler();
|
||||
69
vendor/composer/LICENSE
vendored
69
vendor/composer/LICENSE
vendored
@@ -1,21 +1,56 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: Composer
|
||||
Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
|
||||
Source: https://github.com/composer/composer
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
Files: *
|
||||
Copyright: 2016, Nils Adermann <naderman@naderman.de>
|
||||
2016, Jordi Boggiano <j.boggiano@seld.be>
|
||||
License: Expat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
Files: src/Composer/Util/TlsHelper.php
|
||||
Copyright: 2016, Nils Adermann <naderman@naderman.de>
|
||||
2016, Jordi Boggiano <j.boggiano@seld.be>
|
||||
2013, Evan Coury <me@evancoury.com>
|
||||
License: Expat and BSD-2-Clause
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
License: BSD-2-Clause
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
License: Expat
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
2
vendor/composer/autoload_classmap.php
vendored
2
vendor/composer/autoload_classmap.php
vendored
@@ -300,6 +300,7 @@ return array(
|
||||
'League\\HTMLToMarkdown\\ElementInterface' => $vendorDir . '/league/html-to-markdown/src/ElementInterface.php',
|
||||
'League\\HTMLToMarkdown\\Environment' => $vendorDir . '/league/html-to-markdown/src/Environment.php',
|
||||
'League\\HTMLToMarkdown\\HtmlConverter' => $vendorDir . '/league/html-to-markdown/src/HtmlConverter.php',
|
||||
'League\\HTMLToMarkdown\\HtmlConverterInterface' => $vendorDir . '/league/html-to-markdown/src/HtmlConverterInterface.php',
|
||||
'Michelf\\Markdown' => $vendorDir . '/michelf/php-markdown/Michelf/Markdown.php',
|
||||
'Michelf\\MarkdownExtra' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownExtra.php',
|
||||
'Michelf\\MarkdownInterface' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownInterface.php',
|
||||
@@ -804,6 +805,7 @@ return array(
|
||||
'Text_LanguageDetect_Exception' => $vendorDir . '/pear/text_languagedetect/Text/LanguageDetect/Exception.php',
|
||||
'Text_LanguageDetect_ISO639' => $vendorDir . '/pear/text_languagedetect/Text/LanguageDetect/ISO639.php',
|
||||
'Text_LanguageDetect_Parser' => $vendorDir . '/pear/text_languagedetect/Text/LanguageDetect/Parser.php',
|
||||
'UploadHandler' => $vendorDir . '/blueimp/jquery-file-upload/server/php/UploadHandler.php',
|
||||
'Zotlabs\\Access\\AccessList' => $baseDir . '/Zotlabs/Access/AccessList.php',
|
||||
'Zotlabs\\Access\\PermissionLimits' => $baseDir . '/Zotlabs/Access/PermissionLimits.php',
|
||||
'Zotlabs\\Access\\PermissionRoles' => $baseDir . '/Zotlabs/Access/PermissionRoles.php',
|
||||
|
||||
3
vendor/composer/autoload_static.php
vendored
3
vendor/composer/autoload_static.php
vendored
@@ -468,6 +468,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'League\\HTMLToMarkdown\\ElementInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/ElementInterface.php',
|
||||
'League\\HTMLToMarkdown\\Environment' => __DIR__ . '/..' . '/league/html-to-markdown/src/Environment.php',
|
||||
'League\\HTMLToMarkdown\\HtmlConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/HtmlConverter.php',
|
||||
'League\\HTMLToMarkdown\\HtmlConverterInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/HtmlConverterInterface.php',
|
||||
'Michelf\\Markdown' => __DIR__ . '/..' . '/michelf/php-markdown/Michelf/Markdown.php',
|
||||
'Michelf\\MarkdownExtra' => __DIR__ . '/..' . '/michelf/php-markdown/Michelf/MarkdownExtra.php',
|
||||
'Michelf\\MarkdownInterface' => __DIR__ . '/..' . '/michelf/php-markdown/Michelf/MarkdownInterface.php',
|
||||
@@ -972,6 +973,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'Text_LanguageDetect_Exception' => __DIR__ . '/..' . '/pear/text_languagedetect/Text/LanguageDetect/Exception.php',
|
||||
'Text_LanguageDetect_ISO639' => __DIR__ . '/..' . '/pear/text_languagedetect/Text/LanguageDetect/ISO639.php',
|
||||
'Text_LanguageDetect_Parser' => __DIR__ . '/..' . '/pear/text_languagedetect/Text/LanguageDetect/Parser.php',
|
||||
'UploadHandler' => __DIR__ . '/..' . '/blueimp/jquery-file-upload/server/php/UploadHandler.php',
|
||||
'Zotlabs\\Access\\AccessList' => __DIR__ . '/../..' . '/Zotlabs/Access/AccessList.php',
|
||||
'Zotlabs\\Access\\PermissionLimits' => __DIR__ . '/../..' . '/Zotlabs/Access/PermissionLimits.php',
|
||||
'Zotlabs\\Access\\PermissionRoles' => __DIR__ . '/../..' . '/Zotlabs/Access/PermissionRoles.php',
|
||||
@@ -1503,6 +1505,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'Zotlabs\\Update\\_1222' => __DIR__ . '/../..' . '/Zotlabs/Update/_1222.php',
|
||||
'Zotlabs\\Update\\_1223' => __DIR__ . '/../..' . '/Zotlabs/Update/_1223.php',
|
||||
'Zotlabs\\Update\\_1224' => __DIR__ . '/../..' . '/Zotlabs/Update/_1224.php',
|
||||
'Zotlabs\\Update\\_1225' => __DIR__ . '/../..' . '/Zotlabs/Update/_1225.php',
|
||||
'Zotlabs\\Web\\CheckJS' => __DIR__ . '/../..' . '/Zotlabs/Web/CheckJS.php',
|
||||
'Zotlabs\\Web\\Controller' => __DIR__ . '/../..' . '/Zotlabs/Web/Controller.php',
|
||||
'Zotlabs\\Web\\HTTPHeaders' => __DIR__ . '/../..' . '/Zotlabs/Web/HTTPHeaders.php',
|
||||
|
||||
107
vendor/composer/installed.json
vendored
107
vendor/composer/installed.json
vendored
@@ -1,4 +1,61 @@
|
||||
[
|
||||
{
|
||||
"name": "blueimp/jquery-file-upload",
|
||||
"version": "v9.25.1",
|
||||
"version_normalized": "9.25.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vkhramtsov/jQuery-File-Upload.git",
|
||||
"reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
|
||||
"reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
|
||||
"shasum": ""
|
||||
},
|
||||
"time": "2018-10-26T07:21:48+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"server/php/UploadHandler.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Tschan",
|
||||
"homepage": "https://blueimp.net"
|
||||
}
|
||||
],
|
||||
"description": "File Upload widget for jQuery.",
|
||||
"homepage": "https://github.com/blueimp/jQuery-File-Upload",
|
||||
"keywords": [
|
||||
"bootstrap",
|
||||
"chunk",
|
||||
"cross-domain",
|
||||
"cross-site",
|
||||
"drag",
|
||||
"drop",
|
||||
"file",
|
||||
"gae",
|
||||
"go",
|
||||
"jquery",
|
||||
"multiple",
|
||||
"php",
|
||||
"preview",
|
||||
"progress",
|
||||
"python",
|
||||
"resume",
|
||||
"selection",
|
||||
"upload",
|
||||
"widget"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bshaffer/oauth2-server-php",
|
||||
"version": "v1.10.0",
|
||||
@@ -156,17 +213,17 @@
|
||||
},
|
||||
{
|
||||
"name": "league/html-to-markdown",
|
||||
"version": "4.7.0",
|
||||
"version_normalized": "4.7.0.0",
|
||||
"version": "4.8.0",
|
||||
"version_normalized": "4.8.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/html-to-markdown.git",
|
||||
"reference": "76c076483cef89860d32a3fd25312f5a42848a8c"
|
||||
"reference": "f9a879a068c68ff47b722de63f58bec79e448f9d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/76c076483cef89860d32a3fd25312f5a42848a8c",
|
||||
"reference": "76c076483cef89860d32a3fd25312f5a42848a8c",
|
||||
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/f9a879a068c68ff47b722de63f58bec79e448f9d",
|
||||
"reference": "f9a879a068c68ff47b722de63f58bec79e448f9d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -179,14 +236,14 @@
|
||||
"phpunit/phpunit": "4.*",
|
||||
"scrutinizer/ocular": "~1.1"
|
||||
},
|
||||
"time": "2018-05-19T23:47:12+00:00",
|
||||
"time": "2018-09-18T12:18:08+00:00",
|
||||
"bin": [
|
||||
"bin/html-to-markdown"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.8-dev"
|
||||
"dev-master": "4.9-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
@@ -200,17 +257,17 @@
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "http://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Nick Cernis",
|
||||
"email": "nick@cern.is",
|
||||
"homepage": "http://modernnerd.net",
|
||||
"role": "Original Author"
|
||||
},
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "An HTML-to-markdown conversion helper for PHP",
|
||||
@@ -533,17 +590,17 @@
|
||||
},
|
||||
{
|
||||
"name": "sabre/dav",
|
||||
"version": "3.2.2",
|
||||
"version_normalized": "3.2.2.0",
|
||||
"version": "3.2.3",
|
||||
"version_normalized": "3.2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sabre-io/dav.git",
|
||||
"reference": "e987775e619728f12205606c9cc3ee565ffb1516"
|
||||
"reference": "a9780ce4f35560ecbd0af524ad32d9d2c8954b80"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sabre-io/dav/zipball/e987775e619728f12205606c9cc3ee565ffb1516",
|
||||
"reference": "e987775e619728f12205606c9cc3ee565ffb1516",
|
||||
"url": "https://api.github.com/repos/sabre-io/dav/zipball/a9780ce4f35560ecbd0af524ad32d9d2c8954b80",
|
||||
"reference": "a9780ce4f35560ecbd0af524ad32d9d2c8954b80",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -574,7 +631,7 @@
|
||||
"ext-curl": "*",
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"time": "2017-02-15T03:06:08+00:00",
|
||||
"time": "2018-10-19T09:58:27+00:00",
|
||||
"bin": [
|
||||
"bin/sabredav",
|
||||
"bin/naturalselection"
|
||||
@@ -1029,23 +1086,23 @@
|
||||
},
|
||||
{
|
||||
"name": "smarty/smarty",
|
||||
"version": "v3.1.32",
|
||||
"version_normalized": "3.1.32.0",
|
||||
"version": "v3.1.33",
|
||||
"version_normalized": "3.1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/smarty-php/smarty.git",
|
||||
"reference": "ac9d4b587e5bf53381e21881820a9830765cb459"
|
||||
"reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/ac9d4b587e5bf53381e21881820a9830765cb459",
|
||||
"reference": "ac9d4b587e5bf53381e21881820a9830765cb459",
|
||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/dd55b23121e55a3b4f1af90a707a6c4e5969530f",
|
||||
"reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"time": "2018-04-24T14:53:33+00:00",
|
||||
"time": "2018-09-12T20:54:16+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
|
||||
21
vendor/league/html-to-markdown/CHANGELOG.md
vendored
21
vendor/league/html-to-markdown/CHANGELOG.md
vendored
@@ -4,6 +4,24 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
|
||||
|
||||
## [Unreleased][unreleased]
|
||||
|
||||
## [4.8.0] - 2018-09-18
|
||||
### Added
|
||||
- Added support for email auto-linking
|
||||
- Added a new interface (`HtmlConverterInterface`) for the main `HtmlConverter` class
|
||||
- Added additional test cases (#14)
|
||||
|
||||
### Changed
|
||||
- The `italic_style` option now defaults to `'*'` so that in-word emphasis is handled properly (#75)
|
||||
|
||||
### Fixed
|
||||
- Fixed several issues of `<code>` and `<pre>` tags not converting to blocks or inlines properly (#26, #70, #102, #140, #161, #162)
|
||||
- Fixed in-word emphasis using underscores as delimiter (#75)
|
||||
- Fixed character escaping inside of `<div>` elements
|
||||
- Fixed header edge cases
|
||||
|
||||
### Deprecated
|
||||
- The `bold_style` and `italic_style` options have been deprecated (#75)
|
||||
|
||||
## [4.7.0] - 2018-05-19
|
||||
### Added
|
||||
- Added `setOptions()` function for chainable calling (#149)
|
||||
@@ -217,7 +235,8 @@ not ideally set, so this releases fixes that. Moving forwards this should reduce
|
||||
### Added
|
||||
- Initial release
|
||||
|
||||
[unreleased]: https://github.com/thephpleague/html-to-markdown/compare/4.7.0...master
|
||||
[unreleased]: https://github.com/thephpleague/html-to-markdown/compare/4.8.0...master
|
||||
[4.8.0]: https://github.com/thephpleague/html-to-markdown/compare/4.7.0...4.8.0
|
||||
[4.7.0]: https://github.com/thephpleague/html-to-markdown/compare/4.6.2...4.7.0
|
||||
[4.6.2]: https://github.com/thephpleague/html-to-markdown/compare/4.6.1...4.6.2
|
||||
[4.6.1]: https://github.com/thephpleague/html-to-markdown/compare/4.6.0...4.6.1
|
||||
|
||||
4
vendor/league/html-to-markdown/composer.json
vendored
4
vendor/league/html-to-markdown/composer.json
vendored
@@ -9,7 +9,7 @@
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "http://www.colinodell.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
@@ -42,7 +42,7 @@
|
||||
"bin": ["bin/html-to-markdown"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.8-dev"
|
||||
"dev-master": "4.9-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ class Configuration
|
||||
public function __construct(array $config = array())
|
||||
{
|
||||
$this->config = $config;
|
||||
|
||||
$this->checkForDeprecatedOptions($config);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -19,6 +21,7 @@ class Configuration
|
||||
*/
|
||||
public function merge(array $config = array())
|
||||
{
|
||||
$this->checkForDeprecatedOptions($config);
|
||||
$this->config = array_replace_recursive($this->config, $config);
|
||||
}
|
||||
|
||||
@@ -27,6 +30,7 @@ class Configuration
|
||||
*/
|
||||
public function replace(array $config = array())
|
||||
{
|
||||
$this->checkForDeprecatedOptions($config);
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
@@ -36,6 +40,7 @@ class Configuration
|
||||
*/
|
||||
public function setOption($key, $value)
|
||||
{
|
||||
$this->checkForDeprecatedOptions(array($key => $value));
|
||||
$this->config[$key] = $value;
|
||||
}
|
||||
|
||||
@@ -57,4 +62,15 @@ class Configuration
|
||||
|
||||
return $this->config[$key];
|
||||
}
|
||||
|
||||
private function checkForDeprecatedOptions(array $config)
|
||||
{
|
||||
foreach ($config as $key => $value) {
|
||||
if ($key === 'bold_style' && $value !== '**') {
|
||||
@trigger_error('Customizing the bold_style option is deprecated and may be removed in the next major version', E_USER_DEPRECATED);
|
||||
} elseif ($key === 'italic_style' && $value !== '*') {
|
||||
@trigger_error('Customizing the italic_style option is deprecated and may be removed in the next major version', E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class CodeConverter implements ConverterInterface
|
||||
*/
|
||||
public function convert(ElementInterface $element)
|
||||
{
|
||||
$language = null;
|
||||
$language = '';
|
||||
|
||||
// Checking for language class on the code block
|
||||
$classes = $element->getAttribute('class');
|
||||
@@ -24,8 +24,7 @@ class CodeConverter implements ConverterInterface
|
||||
foreach ($classes as $class) {
|
||||
if (strpos($class, 'language-') !== false) {
|
||||
// Found one, save it as the selected language and stop looping over the classes.
|
||||
// The space after the language avoids gluing the actual code with the language tag
|
||||
$language = str_replace('language-', '', $class) . ' ';
|
||||
$language = str_replace('language-', '', $class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -39,14 +38,13 @@ class CodeConverter implements ConverterInterface
|
||||
$code = preg_replace('/<code\b[^>]*>/', '', $code);
|
||||
$code = str_replace('</code>', '', $code);
|
||||
|
||||
// Checking if the code has multiple lines
|
||||
$lines = preg_split('/\r\n|\r|\n/', $code);
|
||||
if (count($lines) > 1) {
|
||||
// Multiple lines detected, adding three backticks and newlines
|
||||
$markdown .= '```' . $language . "\n" . $code . "\n" . '```' . "\n\n";
|
||||
// Checking if it's a code block or span
|
||||
if ($this->shouldBeBlock($element, $code)) {
|
||||
// Code block detected, newlines will be added in parent
|
||||
$markdown .= '```' . $language . "\n" . $code . "\n" . '```';
|
||||
} else {
|
||||
// One line of code, wrapping it on one backtick.
|
||||
$markdown .= '`' . $language . $code . '`';
|
||||
// One line of code, wrapping it on one backtick, removing new lines
|
||||
$markdown .= '`' . preg_replace('/\r\n|\r|\n/', '', $code) . '`';
|
||||
}
|
||||
|
||||
return $markdown;
|
||||
@@ -59,4 +57,23 @@ class CodeConverter implements ConverterInterface
|
||||
{
|
||||
return array('code');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ElementInterface $element
|
||||
* @param string $code
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function shouldBeBlock(ElementInterface $element, $code)
|
||||
{
|
||||
if ($element->getParent()->getTagName() == 'pre') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (preg_match('/[^\s]` `/', $code)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ class HeaderConverter implements ConverterInterface, ConfigurationAwareInterface
|
||||
$level = (int) substr($element->getTagName(), 1, 1);
|
||||
$style = $this->config->getOption('header_style', self::STYLE_SETEXT);
|
||||
|
||||
if (strlen($element->getValue()) === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (($level === 1 || $level === 2) && !$element->isDescendantOf('blockquote') && $style === self::STYLE_SETEXT) {
|
||||
return $this->createSetextHeader($level, $element->getValue());
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user