mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-26 02:58:32 -04:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53c842c614 | ||
|
|
23ececeb34 | ||
|
|
521c9eb566 | ||
|
|
35877b1382 | ||
|
|
c531287170 | ||
|
|
8e79a81b88 | ||
|
|
b95ceb301f | ||
|
|
76a94495c4 | ||
|
|
b6b2299b4e | ||
|
|
34ddea87d3 | ||
|
|
3d318542cb | ||
|
|
4a8c3cdc61 | ||
|
|
c0b6f2d95f | ||
|
|
9ca7fccab8 | ||
|
|
d91fcfc866 | ||
|
|
29b53f3b9d | ||
|
|
30987095c7 | ||
|
|
43b93de570 | ||
|
|
5b310cf315 | ||
|
|
a1c2a57ea6 | ||
|
|
34bf8f1133 | ||
|
|
c708ec577e | ||
|
|
c185685f2d | ||
|
|
daee5b3477 | ||
|
|
5d0346ee30 | ||
|
|
85ad5355cf | ||
|
|
4c8b84633a | ||
|
|
c0dd4d748d | ||
|
|
c94f25570b | ||
|
|
ffa5e08832 | ||
|
|
63243c8e04 | ||
|
|
21c4ec2de0 | ||
|
|
a8d87af418 | ||
|
|
7b084a065e | ||
|
|
47f6b202e5 | ||
|
|
f588d8379b | ||
|
|
58827e130b | ||
|
|
d702334604 | ||
|
|
b04aa799e3 | ||
|
|
e113f6cb9d | ||
|
|
bc13b7eb72 | ||
|
|
f50b395da6 | ||
|
|
a0e8e40f1c | ||
|
|
cb6055c1b8 | ||
|
|
25424c16e4 | ||
|
|
99dcdee67a | ||
|
|
99928f1aea | ||
|
|
1740ae2104 | ||
|
|
d8372f8433 | ||
|
|
2a15d2c421 | ||
|
|
bacf19688f | ||
|
|
31fbdcf6c5 | ||
|
|
c8818cb7b3 | ||
|
|
eb20789821 | ||
|
|
c90862217e | ||
|
|
df87d6feeb | ||
|
|
6c808abcfc | ||
|
|
f1822bdfab | ||
|
|
c3428acd80 | ||
|
|
d619192b22 |
26
CHANGELOG
26
CHANGELOG
@@ -1,3 +1,29 @@
|
||||
Hubzilla 7.0.3 (2022-02-10)
|
||||
- Allow to override the charset for the PDO connection string via $db_charset in .htconfig.php
|
||||
|
||||
|
||||
Hubzilla 7.0.2 (2022-02-09)
|
||||
- Update french templates
|
||||
- Add charset to the PDO connection strings
|
||||
- Introduce delete keytype for get_activitystreams_key()
|
||||
- Fix PHP error in Daemon/Externals
|
||||
- Improved actor cache handling
|
||||
- Implement manual fetch of packed local links
|
||||
- Add JSalmon data to the meta field instead of data in Lib/ActivityStreams
|
||||
- Fix some PHP8.1 deprecation warnings
|
||||
- Fix delivery report for likes not found in some cases
|
||||
- Allow zotfinger to recurse through all known hublocs if the one we got does not exist (404) or got removed (410)
|
||||
- Diaspora: improve relaying of comments
|
||||
- Fix regression in mod hcard
|
||||
- Add the LD signature in Daemon/Notifier in case where there is no signed data available
|
||||
- Prevent zot6 packet being saved as AP raw message
|
||||
- Attach iconfig to the activity instead of the activity object
|
||||
|
||||
Addons
|
||||
- Pubcrawl: make sure the sys channel falls through the app installed check
|
||||
- Pubcrawl: improve local delivery of shared inbox items
|
||||
|
||||
|
||||
Hubzilla 7.0.1 (2022-01-28)
|
||||
- Fix removing contacts from privacy groups in the contact edit modal
|
||||
- Fix escape_tags() messing with URLs in actor_store()
|
||||
|
||||
@@ -133,7 +133,9 @@ class Externals {
|
||||
continue;
|
||||
}
|
||||
|
||||
Libzot::fetch_conversation($importer, $message['object']['id']);
|
||||
$obj_id = isset($message['object']['id']) ?? $message['object'];
|
||||
|
||||
Libzot::fetch_conversation($importer, $obj_id);
|
||||
$total++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Zotlabs\Daemon;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\Queue;
|
||||
use Zotlabs\Lib\LDSignatures;
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
require_once('include/conversation.php');
|
||||
@@ -336,12 +337,14 @@ class Notifier {
|
||||
self::$encoded_item = json_decode($m, true);
|
||||
}
|
||||
else {
|
||||
|
||||
self::$encoded_item = array_merge(['@context' => [
|
||||
ACTIVITYSTREAMS_JSONLD_REV,
|
||||
'https://w3id.org/security/v1',
|
||||
z_root() . ZOT_APSCHEMA_REV
|
||||
]], Activity::encode_activity($target_item)
|
||||
);
|
||||
self::$encoded_item['signature'] = LDSignatures::sign(self::$encoded_item, self::$channel);
|
||||
}
|
||||
|
||||
logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG);
|
||||
|
||||
@@ -116,6 +116,11 @@ class Activity {
|
||||
|
||||
$y = json_decode($x['body'], true);
|
||||
logger('returned: ' . json_encode($y, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOGGER_DEBUG);
|
||||
|
||||
if (ActivityStreams::is_an_actor($y['type'])) {
|
||||
XConfig::Set($y['id'], 'system', 'actor_record', $y);
|
||||
}
|
||||
|
||||
return json_decode($x['body'], true);
|
||||
}
|
||||
else {
|
||||
@@ -529,6 +534,7 @@ class Activity {
|
||||
$top_level = (($i['mid'] === $i['parent_mid']) ? true : false);
|
||||
|
||||
if ($public) {
|
||||
|
||||
$ret['to'] = [ACTIVITY_PUBLIC_INBOX];
|
||||
$ret['cc'] = [z_root() . '/followers/' . substr($i['author']['xchan_addr'], 0, strpos($i['author']['xchan_addr'], '@'))];
|
||||
}
|
||||
@@ -660,11 +666,11 @@ class Activity {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function encode_attachment($item) {
|
||||
static function encode_attachment($item, $iconfig = false) {
|
||||
|
||||
$ret = [];
|
||||
|
||||
if (array_key_exists('attach', $item)) {
|
||||
if (!$iconfig && array_key_exists('attach', $item)) {
|
||||
$atts = ((is_array($item['attach'])) ? $item['attach'] : json_decode($item['attach'], true));
|
||||
if ($atts) {
|
||||
foreach ($atts as $att) {
|
||||
@@ -677,7 +683,7 @@ class Activity {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (array_key_exists('iconfig', $item) && is_array($item['iconfig'])) {
|
||||
if ($iconfig && array_key_exists('iconfig', $item) && is_array($item['iconfig'])) {
|
||||
foreach ($item['iconfig'] as $att) {
|
||||
if ($att['sharing']) {
|
||||
$value = ((is_string($att['v']) && preg_match('|^a:[0-9]+:{.*}$|s', $att['v'])) ? unserialize($att['v']) : $att['v']);
|
||||
@@ -930,6 +936,11 @@ class Activity {
|
||||
$ret['tag'] = $t;
|
||||
}
|
||||
|
||||
$a = self::encode_attachment($i, true);
|
||||
if ($a) {
|
||||
$ret['attachment'] = $a;
|
||||
}
|
||||
|
||||
// addressing madness
|
||||
|
||||
$public = (($i['item_private']) ? false : true);
|
||||
@@ -2638,33 +2649,76 @@ class Activity {
|
||||
}
|
||||
}
|
||||
|
||||
$zot_rawmsg = '';
|
||||
$ap_rawmsg = '';
|
||||
$diaspora_rawmsg = '';
|
||||
$raw_arr = [];
|
||||
|
||||
$raw_arr = json_decode($act->raw, true);
|
||||
|
||||
// This is a zot6 packet and the raw activitypub message json
|
||||
// This is a zot6 packet and the raw activitypub or diaspora message json
|
||||
// is possibly available in the attachement.
|
||||
if (array_key_exists('signed', $raw_arr) && is_array($act->obj) && is_array($act->obj['attachment'])) {
|
||||
if (array_key_exists('signed', $raw_arr) && is_array($act->data['attachment'])) {
|
||||
foreach($act->data['attachment'] as $a) {
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.activitypub.rawmsg' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$ap_rawmsg = $a['value'];
|
||||
}
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.diaspora.fields' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$diaspora_rawmsg = $a['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// old style: can be removed after most hubs are on 7.0.2
|
||||
elseif (array_key_exists('signed', $raw_arr) && is_array($act->obj) && is_array($act->obj['attachment'])) {
|
||||
foreach($act->obj['attachment'] as $a) {
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.activitypub.rawmsg' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$zot_rawmsg = $a['value'];
|
||||
break;
|
||||
$ap_rawmsg = $a['value'];
|
||||
}
|
||||
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.diaspora.fields' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$diaspora_rawmsg = $a['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($zot_rawmsg) {
|
||||
set_iconfig($s, 'activitypub', 'rawmsg', $zot_rawmsg, 1);
|
||||
// catch the likes
|
||||
if (!$ap_rawmsg && $response_activity) {
|
||||
$ap_rawmsg = json_encode($act->data, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
else {
|
||||
// end old style
|
||||
|
||||
if (!$ap_rawmsg && array_key_exists('signed', $raw_arr)) {
|
||||
// zap
|
||||
$ap_rawmsg = json_encode($act->data, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
if ($ap_rawmsg) {
|
||||
set_iconfig($s, 'activitypub', 'rawmsg', $ap_rawmsg, 1);
|
||||
}
|
||||
elseif (!array_key_exists('signed', $raw_arr)) {
|
||||
set_iconfig($s, 'activitypub', 'rawmsg', $act->raw, 1);
|
||||
}
|
||||
|
||||
if ($diaspora_rawmsg) {
|
||||
set_iconfig($s, 'diaspora', 'fields', $diaspora_rawmsg, 1);
|
||||
}
|
||||
|
||||
set_iconfig($s, 'activitypub', 'recips', $act->raw_recips);
|
||||
|
||||
$hookinfo = [
|
||||
@@ -3660,7 +3714,10 @@ class Activity {
|
||||
}
|
||||
|
||||
static function get_cached_actor($id) {
|
||||
$actor = XConfig::Get($id, 'system', 'actor_record');
|
||||
|
||||
// remove any fragments like #main-key since these won't be present in our cached data
|
||||
$cache_url = ((strpos($id, '#')) ? substr($id, 0, strpos($id, '#')) : $id);
|
||||
$actor = XConfig::Get($cache_url, 'system', 'actor_record');
|
||||
|
||||
if ($actor) {
|
||||
return $actor;
|
||||
@@ -3669,7 +3726,7 @@ class Activity {
|
||||
// try other get_cached_actor providers (e.g. diaspora)
|
||||
$hookdata = [
|
||||
'id' => $id,
|
||||
'actor' => false
|
||||
'actor' => null
|
||||
];
|
||||
|
||||
call_hooks('get_cached_actor_provider', $hookdata);
|
||||
|
||||
@@ -11,6 +11,7 @@ class ActivityStreams {
|
||||
|
||||
public $raw = null;
|
||||
public $data = null;
|
||||
public $meta = null;
|
||||
public $valid = false;
|
||||
public $deleted = false;
|
||||
public $id = '';
|
||||
@@ -36,6 +37,9 @@ class ActivityStreams {
|
||||
*/
|
||||
function __construct($string) {
|
||||
|
||||
if(!$string)
|
||||
return;
|
||||
|
||||
$this->raw = $string;
|
||||
|
||||
if (is_array($string)) {
|
||||
@@ -57,10 +61,10 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($this->data, JSON_UNESCAPED_SLASHES);
|
||||
$this->data = $tmp;
|
||||
$this->data['signer'] = $ret['signer'];
|
||||
$this->data['signed_data'] = $saved;
|
||||
$this->meta['signer'] = $ret['signer'];
|
||||
$this->meta['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$this->data['hubloc'] = $ret['hubloc'];
|
||||
$this->meta['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,7 +92,7 @@ class ActivityStreams {
|
||||
|
||||
$this->ldsig = $this->get_compound_property('signature');
|
||||
if ($this->ldsig) {
|
||||
$this->signer = $this->get_compound_property('creator', $this->ldsig);
|
||||
$this->signer = $this->get_actor('creator', $this->ldsig);
|
||||
if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
|
||||
$this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']);
|
||||
}
|
||||
@@ -344,10 +348,10 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($x, JSON_UNESCAPED_SLASHES);
|
||||
$x = $tmp;
|
||||
$x['signer'] = $ret['signer'];
|
||||
$x['signed_data'] = $saved;
|
||||
$x['meta']['signer'] = $ret['signer'];
|
||||
$x['meta']['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$x['hubloc'] = $ret['hubloc'];
|
||||
$x['meta']['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +426,7 @@ class Apps {
|
||||
|
||||
self::translate_system_apps($papp);
|
||||
|
||||
if(trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
if(isset($papp['plugin']) && trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
return '';
|
||||
|
||||
$papp['papp'] = self::papp_encode($papp);
|
||||
|
||||
@@ -1296,9 +1296,8 @@ class Libzot {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($AS->data['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->data['signed_data'], false);
|
||||
if ($AS->meta['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->meta['signed_data'], false);
|
||||
}
|
||||
|
||||
logger('Activity received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG);
|
||||
@@ -1927,6 +1926,7 @@ class Libzot {
|
||||
dbesc($a['signature']['signer'])
|
||||
);
|
||||
|
||||
|
||||
foreach ($items as $activity) {
|
||||
|
||||
$AS = new ActivityStreams($activity);
|
||||
@@ -1988,9 +1988,9 @@ class Libzot {
|
||||
$arr['item_verified'] = true;
|
||||
}
|
||||
|
||||
if ($AS->data['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->data['signed_data'], false);
|
||||
$j = json_decode($AS->data['signed_data'], true);
|
||||
if ($AS->meta['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->meta['signed_data'], false);
|
||||
$j = json_decode($AS->meta['signed_data'], true);
|
||||
if ($j) {
|
||||
IConfig::Set($arr, 'activitypub', 'rawmsg', json_encode(JSalmon::unpack($j['data'])), true);
|
||||
}
|
||||
@@ -2482,14 +2482,14 @@ class Libzot {
|
||||
$access_policy = ACCESS_PRIVATE;
|
||||
}
|
||||
|
||||
$directory_url = htmlspecialchars($arr['directory_url'], ENT_COMPAT, 'UTF-8', false);
|
||||
$url = htmlspecialchars(strtolower($arr['url']), ENT_COMPAT, 'UTF-8', false);
|
||||
$sellpage = htmlspecialchars($arr['sellpage'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_location = htmlspecialchars($arr['location'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_realm = htmlspecialchars($arr['realm'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_project = htmlspecialchars($arr['project'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_crypto = ((array_key_exists('encryption', $arr) && is_array($arr['encryption'])) ? htmlspecialchars(implode(',', $arr['encryption']), ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_version = ((array_key_exists('version', $arr)) ? htmlspecialchars($arr['version'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$directory_url = htmlspecialchars((string)$arr['directory_url'], ENT_COMPAT, 'UTF-8', false);
|
||||
$url = htmlspecialchars((string)strtolower($arr['url']), ENT_COMPAT, 'UTF-8', false);
|
||||
$sellpage = htmlspecialchars((string)$arr['sellpage'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_location = htmlspecialchars((string)$arr['location'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_realm = htmlspecialchars((string)$arr['realm'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_project = htmlspecialchars((string)$arr['project'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_crypto = ((array_key_exists('encryption', $arr) && is_array($arr['encryption'])) ? htmlspecialchars((string)implode(',', $arr['encryption']), ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_version = ((array_key_exists('version', $arr)) ? htmlspecialchars((string)$arr['version'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
|
||||
// You can have one and only one primary directory per realm.
|
||||
// Downgrade any others claiming to be primary. As they have
|
||||
@@ -3172,7 +3172,7 @@ class Libzot {
|
||||
}
|
||||
|
||||
static function update_cached_hubloc($hubloc) {
|
||||
if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 1 week') || $hubloc['hubloc_url'] === z_root()) {
|
||||
if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 3 days') || $hubloc['hubloc_url'] === z_root()) {
|
||||
return;
|
||||
}
|
||||
self::refresh( [ 'hubloc_id_url' => $hubloc['hubloc_id_url'] ] );
|
||||
|
||||
@@ -6,7 +6,7 @@ use Zotlabs\Web\HTTPSig;
|
||||
|
||||
class Zotfinger {
|
||||
|
||||
static function exec($resource,$channel = null, $verify = true) {
|
||||
static function exec($resource, $channel = null, $verify = true, $recurse = true) {
|
||||
|
||||
if(! $resource) {
|
||||
return false;
|
||||
@@ -39,6 +39,30 @@ class Zotfinger {
|
||||
|
||||
logger('fetch: ' . print_r($x,true));
|
||||
|
||||
if (in_array(intval($x['return_code']), [ 404, 410 ]) && $recurse) {
|
||||
|
||||
// The resource has been deleted or doesn't exist at this location.
|
||||
// Try to find another nomadic resource for this channel and return that.
|
||||
|
||||
// First, see if there's a hubloc for this site. Fetch that record to
|
||||
// obtain the nomadic identity hash. Then use that to find any additional
|
||||
// nomadic locations.
|
||||
|
||||
$h = Activity::get_actor_hublocs($resource, 'zot6');
|
||||
if ($h) {
|
||||
// mark this location deleted
|
||||
hubloc_delete($h[0]);
|
||||
$hubs = Activity::get_actor_hublocs($h[0]['hubloc_hash']);
|
||||
if ($hubs) {
|
||||
foreach ($hubs as $hub) {
|
||||
if ($hub['hubloc_id_url'] !== $resource && !$hub['hubloc_deleted']) {
|
||||
return self::exec($hub['hubloc_id_url'], $channel, $verify);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($x['success']) {
|
||||
if ($verify) {
|
||||
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
|
||||
|
||||
@@ -23,7 +23,18 @@ class Queue {
|
||||
LibQueue::remove_by_posturl($_REQUEST['emptyhub']);
|
||||
}
|
||||
|
||||
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
if($_REQUEST['deliverhub']) {
|
||||
|
||||
$hubq = q("SELECT * FROM outq WHERE outq_posturl = '%s'",
|
||||
dbesc($_REQUEST['deliverhub'])
|
||||
);
|
||||
|
||||
foreach ($hubq as $q) {
|
||||
LibQueue::deliver($q, true);
|
||||
}
|
||||
}
|
||||
|
||||
$r = dbq("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
where outq_delivered = 0 group by outq_posturl order by total desc");
|
||||
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
@@ -37,6 +48,7 @@ class Queue {
|
||||
'$priority' => t('Priority'),
|
||||
'$desturl' => t('Destination URL'),
|
||||
'$nukehub' => t('Mark hub permanently offline'),
|
||||
'$deliverhub' => t('Retry delivery to this hub'),
|
||||
'$empty' => t('Empty queue for this hub'),
|
||||
'$lastconn' => t('Last known contact'),
|
||||
'$hasentries' => ((count($r)) ? true : false),
|
||||
|
||||
@@ -56,9 +56,10 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from dreport where dreport_xchan = '%s' and dreport_mid = '%s'",
|
||||
$r = q("select * from dreport where dreport_xchan = '%s' and (dreport_mid = '%s' or dreport_mid = '%s')",
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc($mid)
|
||||
dbesc($mid),
|
||||
dbesc(str_replace('/item/', '/activity/', $mid))
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Zotlabs\Module;
|
||||
class Hcard extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else {
|
||||
@@ -13,12 +13,12 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
logger('hcard_request: ' . $which, LOGGER_DEBUG);
|
||||
|
||||
$profile = '';
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
|
||||
$which = $channel['channel_address'];
|
||||
$profile = argv(1);
|
||||
@@ -30,22 +30,22 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
$profile = '';
|
||||
$profile = $r[0]['profile_guid'];
|
||||
}
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Posts and comments'),
|
||||
'href' => z_root() . '/feed/' . $which
|
||||
]);
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Only posts'),
|
||||
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
|
||||
]);
|
||||
|
||||
|
||||
|
||||
if(! $profile) {
|
||||
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
|
||||
dbesc(argv(1))
|
||||
@@ -54,20 +54,20 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$profile = $x[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$x = new \Zotlabs\Widget\Profile();
|
||||
$x = new \Zotlabs\Widget\Fullprofile();
|
||||
return $x->widget(array());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ class Item extends Controller {
|
||||
$consensus = intval($_REQUEST['consensus']);
|
||||
$nocomment = intval($_REQUEST['nocomment']);
|
||||
|
||||
$is_poll = ((trim($_REQUEST['poll_answers'][0]) != '' && trim($_REQUEST['poll_answers'][1]) != '') ? true : false);
|
||||
$is_poll = ((trim((string)$_REQUEST['poll_answers'][0]) != '' && trim((string)$_REQUEST['poll_answers'][1]) != '') ? true : false);
|
||||
|
||||
// 'origin' (if non-zero) indicates that this network is where the message originated,
|
||||
// for the purpose of relaying comments to other conversation members.
|
||||
@@ -719,13 +719,13 @@ class Item extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$location = notags(trim($_REQUEST['location']));
|
||||
$coord = notags(trim($_REQUEST['coord']));
|
||||
$verb = notags(trim($_REQUEST['verb']));
|
||||
$title = escape_tags(trim($_REQUEST['title']));
|
||||
$summary = trim($_REQUEST['summary']);
|
||||
$body = trim($_REQUEST['body']);
|
||||
$body .= trim($_REQUEST['attachment']);
|
||||
$location = notags(trim((string)$_REQUEST['location']));
|
||||
$coord = notags(trim((string)$_REQUEST['coord']));
|
||||
$verb = notags(trim((string)$_REQUEST['verb']));
|
||||
$title = escape_tags(trim((string)$_REQUEST['title']));
|
||||
$summary = trim((string)$_REQUEST['summary']);
|
||||
$body = trim((string)$_REQUEST['body']);
|
||||
$body .= trim((string)$_REQUEST['attachment']);
|
||||
$postopts = '';
|
||||
|
||||
$allow_empty = ((array_key_exists('allow_empty', $_REQUEST)) ? intval($_REQUEST['allow_empty']) : 0);
|
||||
@@ -764,7 +764,7 @@ class Item extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$mimetype = notags(trim($_REQUEST['mimetype']));
|
||||
$mimetype = notags(trim((string)$_REQUEST['mimetype']));
|
||||
if (!$mimetype)
|
||||
$mimetype = 'text/bbcode';
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\ActivityStreams;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Zotfinger;
|
||||
|
||||
class Search extends Controller {
|
||||
|
||||
@@ -58,10 +59,26 @@ class Search extends Controller {
|
||||
$o .= search($search, 'search-box', '/search', ((local_channel()) ? true : false));
|
||||
|
||||
if (local_channel() && strpos($search, 'https://') === 0 && !$update && !$load) {
|
||||
if (strpos($search, 'b64.') !== false) {
|
||||
if (strpos($search, '?') !== false) {
|
||||
$search = strtok($search, '?');
|
||||
}
|
||||
|
||||
$search = unpack_link_id(basename($search));
|
||||
}
|
||||
|
||||
$f = Libzot::fetch_conversation(App::get_channel(), punify($search), true);
|
||||
|
||||
if ($f) {
|
||||
goaway(z_root() . '/hq/' . gen_link_id($f['message_id']));
|
||||
$mid = $f[0]['message_id'];
|
||||
foreach ($f as $m) {
|
||||
if (strpos($search, $m['message_id']) === 0) {
|
||||
$mid = $m['message_id'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
goaway(z_root() . '/hq/' . gen_link_id($mid));
|
||||
}
|
||||
else {
|
||||
// try other fetch providers (e.g. diaspora, pubcrawl)
|
||||
|
||||
@@ -69,17 +69,22 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
|
||||
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
|
||||
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
|
||||
|
||||
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
|
||||
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($db_type) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
// $siteurl should not have a trailing slash
|
||||
|
||||
$siteurl = rtrim($siteurl,'/');
|
||||
|
||||
require_once('include/dba/dba_driver.php');
|
||||
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, $db_charset, true);
|
||||
|
||||
if(! \DBA::$dba->connected) {
|
||||
echo 'Database Connect failed: ' . \DBA::$dba->error;
|
||||
@@ -94,11 +99,16 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
|
||||
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
|
||||
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
|
||||
|
||||
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
|
||||
$timezone = ((isset($_POST['timezone'])) ? trim($_POST['timezone']) : '');
|
||||
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($db_type) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
if($siteurl != z_root()) {
|
||||
$test = z_fetch_url($siteurl."/setup/testrewrite");
|
||||
if((! $test['success']) || ($test['body'] != 'ok')) {
|
||||
@@ -112,7 +122,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(! isset(\DBA::$dba->connected)) {
|
||||
// connect to db
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, $db_charset, true);
|
||||
}
|
||||
|
||||
if(! isset(\DBA::$dba->connected)) {
|
||||
|
||||
@@ -572,7 +572,7 @@ class Comanche {
|
||||
require_once('widget/' . trim($name) . '.php');
|
||||
elseif(file_exists('widget/' . trim($name) . '/' . trim($name) . '.php'))
|
||||
require_once('widget/' . trim($name) . '/' . trim($name) . '.php');
|
||||
|
||||
|
||||
if(! function_exists($func)) {
|
||||
$theme_widget = $func . '.php';
|
||||
if(theme_include($theme_widget)) {
|
||||
@@ -640,7 +640,8 @@ class Comanche {
|
||||
$cnt = preg_match_all("/\[widget=(.*?)\](.*?)\[\/widget\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$s = str_replace($mtch[0],$this->widget(trim($mtch[1]),$mtch[2]),$s);
|
||||
|
||||
$s = str_replace((string)$mtch[0], (string)$this->widget(trim((string)$mtch[1]), (string)$mtch[2]), $s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ class HTTPSig {
|
||||
|
||||
$cached_key = self::get_key($key, $keytype, $result['signer']);
|
||||
|
||||
|
||||
if (!($cached_key && $cached_key['public_key'])) {
|
||||
return $result;
|
||||
}
|
||||
@@ -243,7 +244,12 @@ class HTTPSig {
|
||||
}
|
||||
}
|
||||
|
||||
$key = self::get_activitystreams_key($id, $force);
|
||||
$delete = false;
|
||||
if ($keytype === 'delete') {
|
||||
$delete = true;
|
||||
}
|
||||
|
||||
$key = self::get_activitystreams_key($id, $force, $delete);
|
||||
|
||||
return $key;
|
||||
|
||||
@@ -274,7 +280,7 @@ class HTTPSig {
|
||||
* false if no pub key found, otherwise return an array with the pub key
|
||||
*/
|
||||
|
||||
static function get_activitystreams_key($id, $force = false) {
|
||||
static function get_activitystreams_key($id, $force = false, $delete = false) {
|
||||
|
||||
// Check the local cache first, but remove any fragments like #main-key since these won't be present in our cached data
|
||||
$url = ((strpos($id, '#')) ? substr($id, 0, strpos($id, '#')) : $id);
|
||||
@@ -294,6 +300,12 @@ class HTTPSig {
|
||||
}
|
||||
}
|
||||
|
||||
if ($delete) {
|
||||
// If we received a delete and we do not have the record cached,
|
||||
// we probably never saw this actor. Do not try to fetch it now.
|
||||
return false;
|
||||
}
|
||||
|
||||
// The record wasn't in cache. Fetch it now.
|
||||
$r = ActivityStreams::fetch($id);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Zotlabs\Web;
|
||||
class SessionHandler implements \SessionHandlerInterface {
|
||||
|
||||
|
||||
function open ($s, $n) {
|
||||
function open ($s, $n) : bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
// some which call read explicitly and some that do not. So we call it explicitly
|
||||
// just after sid regeneration to force a record to exist.
|
||||
|
||||
function read ($id) {
|
||||
function read ($id) : string {
|
||||
|
||||
if($id) {
|
||||
$r = q("SELECT sess_data FROM session WHERE sid= '%s'", dbesc($id));
|
||||
@@ -36,7 +36,7 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
}
|
||||
|
||||
|
||||
function write ($id, $data) {
|
||||
function write ($id, $data) : bool {
|
||||
|
||||
// Pretend everything is hunky-dory, even though it isn't.
|
||||
// There probably isn't anything we can do about it in any event.
|
||||
@@ -49,9 +49,9 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
|
||||
// Unless we authenticate somehow, only keep a session for 5 minutes
|
||||
// The viewer can extend this by performing any web action using the
|
||||
// original cookie, but this allows us to cleanup the hundreds or
|
||||
// original cookie, but this allows us to cleanup the hundreds or
|
||||
// thousands of empty sessions left around from web crawlers which are
|
||||
// assigned cookies on each page that they never use.
|
||||
// assigned cookies on each page that they never use.
|
||||
|
||||
$expire = time() + 300;
|
||||
|
||||
@@ -74,19 +74,19 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function close() {
|
||||
|
||||
function close() : bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function destroy ($id) {
|
||||
function destroy ($id) : bool {
|
||||
q("DELETE FROM session WHERE sid = '%s'", dbesc($id));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function gc($expire) {
|
||||
function gc($expire) : int {
|
||||
q("DELETE FROM session WHERE expire < %d", dbesc(time()));
|
||||
return true;
|
||||
}
|
||||
|
||||
11
boot.php
11
boot.php
@@ -60,7 +60,7 @@ require_once('include/bbcode.php');
|
||||
require_once('include/items.php');
|
||||
|
||||
define('PLATFORM_NAME', 'hubzilla');
|
||||
define('STD_VERSION', '7.0.1');
|
||||
define('STD_VERSION', '7.0.3');
|
||||
define('ZOT_REVISION', '6.0');
|
||||
|
||||
define('DB_UPDATE_VERSION', 1252);
|
||||
@@ -664,12 +664,17 @@ function sys_boot() {
|
||||
require_once('include/dba/dba_driver.php');
|
||||
|
||||
if (!App::$install) {
|
||||
DBA::dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type, App::$install);
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($db_type) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
DBA::dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type, $db_charset, App::$install);
|
||||
if (!DBA::$dba->connected) {
|
||||
system_unavailable();
|
||||
}
|
||||
|
||||
unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type);
|
||||
unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type, $db_charset);
|
||||
|
||||
/*
|
||||
* Load configs from db. Overwrite configs from .htconfig.php
|
||||
|
||||
@@ -100,6 +100,10 @@ function categories_widget($baseurl,$selected = '') {
|
||||
\Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, base64_encode(json_encode($arr)) ]);
|
||||
}
|
||||
|
||||
if (!$content) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
$r = unserialize($content);
|
||||
|
||||
$terms = [];
|
||||
|
||||
@@ -558,7 +558,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
||||
$page_writeable = ($profile_owner == local_channel());
|
||||
|
||||
if (!$update) {
|
||||
$tab = notags(trim($_GET['tab']));
|
||||
$tab = notags(trim((string)$_GET['tab']));
|
||||
if ($tab === 'posts') {
|
||||
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
|
||||
// because browser prefetching might change it on us. We have to deliver it with the page.
|
||||
@@ -974,7 +974,7 @@ function best_link_url($item) {
|
||||
}
|
||||
}
|
||||
if(! $best_url) {
|
||||
if(strlen($item['author-link']))
|
||||
if($item['author-link'])
|
||||
$best_url = $item['author-link'];
|
||||
else
|
||||
$best_url = $item['url'];
|
||||
|
||||
@@ -38,7 +38,7 @@ class DBA {
|
||||
* @param bool $install Defaults to false
|
||||
* @return null|dba_driver A database driver object (dba_pdo) or null if no driver found.
|
||||
*/
|
||||
static public function dba_factory($server,$port,$user,$pass,$db,$dbtype,$install = false) {
|
||||
static public function dba_factory($server,$port,$user,$pass,$db,$dbtype,$db_charset,$install = false) {
|
||||
|
||||
self::$dba = null;
|
||||
self::$dbtype = intval($dbtype);
|
||||
@@ -65,7 +65,7 @@ class DBA {
|
||||
}
|
||||
|
||||
require_once('include/dba/dba_pdo.php');
|
||||
self::$dba = new dba_pdo($server,self::$scheme,$port,$user,$pass,$db,$install);
|
||||
self::$dba = new dba_pdo($server,self::$scheme,$port,$user,$pass,$db,$db_charset,$install);
|
||||
|
||||
define('NULL_DATE', self::$null_date);
|
||||
define('ACTIVE_DBTYPE', self::$dbtype);
|
||||
@@ -105,7 +105,7 @@ abstract class dba_driver {
|
||||
* @param string $db database name
|
||||
* @return bool
|
||||
*/
|
||||
abstract function connect($server, $scheme, $port, $user, $pass, $db);
|
||||
abstract function connect($server, $scheme, $port, $user, $pass, $db, $db_charset);
|
||||
|
||||
/**
|
||||
* @brief Perform a DB query with the SQL statement $sql.
|
||||
@@ -139,11 +139,11 @@ abstract class dba_driver {
|
||||
*/
|
||||
abstract function getdriver();
|
||||
|
||||
function __construct($server, $scheme, $port, $user,$pass,$db,$install = false) {
|
||||
if(($install) && (! $this->install($server, $scheme, $port, $user, $pass, $db))) {
|
||||
function __construct($server, $scheme, $port, $user,$pass,$db,$db_charset,$install = false) {
|
||||
if(($install) && (! $this->install($server, $scheme, $port, $user, $pass, $db, $db_charset))) {
|
||||
return;
|
||||
}
|
||||
$this->connect($server, $scheme, $port, $user, $pass, $db);
|
||||
$this->connect($server, $scheme, $port, $user, $pass, $db, $db_charset);
|
||||
}
|
||||
|
||||
function get_null_date() {
|
||||
|
||||
@@ -14,7 +14,7 @@ class dba_pdo extends dba_driver {
|
||||
* {@inheritDoc}
|
||||
* @see dba_driver::connect()
|
||||
*/
|
||||
function connect($server, $scheme, $port, $user, $pass, $db) {
|
||||
function connect($server, $scheme, $port, $user, $pass, $db, $db_charset) {
|
||||
|
||||
$this->driver_dbtype = $scheme;
|
||||
|
||||
@@ -27,6 +27,13 @@ class dba_pdo extends dba_driver {
|
||||
|
||||
$dsn .= ';dbname=' . $db;
|
||||
|
||||
if ($this->driver_dbtype === 'mysql') {
|
||||
$dsn .= ';charset=' . $db_charset;
|
||||
}
|
||||
else {
|
||||
$dsn .= ";options='--client_encoding=" . $db_charset . "'";
|
||||
}
|
||||
|
||||
try {
|
||||
$this->db = new PDO($dsn,$user,$pass);
|
||||
$this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
@@ -1180,7 +1180,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
else {
|
||||
$name = $author['author_name'];
|
||||
}
|
||||
$x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
$x = import_author_rss(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
if($x)
|
||||
$datarray['author_xchan'] = $x;
|
||||
}
|
||||
@@ -1440,7 +1440,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
else {
|
||||
$name = $author['author_name'];
|
||||
}
|
||||
$x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
$x = import_author_rss(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
if($x)
|
||||
$datarray['author_xchan'] = $x;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ use Zotlabs\Daemon\Master;
|
||||
*/
|
||||
function hubloc_store_lowlevel($arr) {
|
||||
|
||||
$update = ((array_key_exists('hubloc_id',$arr) && $arr['hubloc_id']) ? 'hubloc_id = ' . intval($arr['hubloc_id']) : false);
|
||||
|
||||
$store = [
|
||||
'hubloc_guid' => ((array_key_exists('hubloc_guid',$arr)) ? $arr['hubloc_guid'] : ''),
|
||||
'hubloc_guid_sig' => ((array_key_exists('hubloc_guid_sig',$arr)) ? $arr['hubloc_guid_sig'] : ''),
|
||||
@@ -40,7 +42,7 @@ function hubloc_store_lowlevel($arr) {
|
||||
'hubloc_deleted' => ((array_key_exists('hubloc_deleted',$arr)) ? $arr['hubloc_deleted'] : 0)
|
||||
];
|
||||
|
||||
return create_table_from_array('hubloc', $store);
|
||||
return (($update) ? update_table_from_array('hubloc', $store, $update) : create_table_from_array('hubloc', $store));
|
||||
}
|
||||
|
||||
function site_store_lowlevel($arr) {
|
||||
@@ -283,6 +285,13 @@ function hubloc_change_primary($hubloc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function hubloc_delete($hubloc) {
|
||||
if (is_array($hubloc) && array_key_exists('hubloc_id', $hubloc)) {
|
||||
q("UPDATE hubloc SET hubloc_deleted = 1 WHERE hubloc_id = %d",
|
||||
intval($hubloc['hubloc_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mark a hubloc as down.
|
||||
|
||||
@@ -1446,7 +1446,7 @@ function activity_sanitise($arr) {
|
||||
if(is_array($x))
|
||||
$ret[$k] = activity_sanitise($x);
|
||||
else
|
||||
$ret[$k] = htmlspecialchars($x, ENT_COMPAT, 'UTF-8', false);
|
||||
$ret[$k] = htmlspecialchars((string)$x, ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
@@ -1625,9 +1625,9 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : '');
|
||||
$arr['summary'] = ((array_key_exists('summary',$arr) && strlen($arr['summary'])) ? trim($arr['summary']) : '');
|
||||
$arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : '');
|
||||
$arr['title'] = ((array_key_exists('title',$arr) && $arr['title']) ? trim($arr['title']) : '');
|
||||
$arr['summary'] = ((array_key_exists('summary',$arr) && $arr['summary']) ? trim($arr['summary']) : '');
|
||||
$arr['body'] = ((array_key_exists('body',$arr) && $arr['body']) ? trim($arr['body']) : '');
|
||||
|
||||
$arr['allow_cid'] = ((x($arr,'allow_cid')) ? trim($arr['allow_cid']) : '');
|
||||
$arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : '');
|
||||
@@ -4438,7 +4438,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
|
||||
);
|
||||
}
|
||||
|
||||
if(strlen($arr['file'])) {
|
||||
if($arr['file']) {
|
||||
$sql_extra .= term_query('item',$arr['files'],TERM_FILE);
|
||||
}
|
||||
|
||||
|
||||
@@ -417,6 +417,9 @@ function xmlify($str) {
|
||||
|
||||
//$buffer = '';
|
||||
|
||||
if (!$str)
|
||||
return EMPTY_STR;
|
||||
|
||||
if(is_array($str)) {
|
||||
|
||||
// allow to fall through so we ge a PHP error, as the log statement will
|
||||
@@ -482,6 +485,9 @@ function unxmlify($s) {
|
||||
return $ret;
|
||||
*/
|
||||
|
||||
if (!$s)
|
||||
return EMPTY_STR;
|
||||
|
||||
if(is_array($s)) {
|
||||
|
||||
// allow to fall through so we ge a PHP error, as the log statement will
|
||||
@@ -840,7 +846,7 @@ function activity_match($haystack,$needle) {
|
||||
|
||||
if($needle) {
|
||||
foreach($needle as $n) {
|
||||
if(($haystack === $n) || (strtolower(basename($n)) === strtolower(basename($haystack)))) {
|
||||
if(($haystack === $n) || (strtolower(basename((string)$n)) === strtolower(basename((string)$haystack)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1492,6 +1498,10 @@ function day_translate($s) {
|
||||
* @return string
|
||||
*/
|
||||
function normalise_link($url) {
|
||||
if (!$url) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
$ret = str_replace(array('https:', '//www.'), array('http:', '//'), $url);
|
||||
|
||||
return(rtrim($ret, '/'));
|
||||
@@ -3588,6 +3598,45 @@ function create_table_from_array($table, $arr, $binary_fields = []) {
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
function update_table_from_array($table, $arr, $where, $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;
|
||||
}
|
||||
if (in_array($k, $binary_fields)) {
|
||||
$clean[$k] = dbescbin($v);
|
||||
} else {
|
||||
$clean[$k] = dbesc($v);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "UPDATE " . TQUOT . $table . TQUOT . " SET ";
|
||||
|
||||
foreach ($clean as $k => $v) {
|
||||
$sql .= TQUOT . $k . TQUOT . ' = "' . $v . '",';
|
||||
}
|
||||
|
||||
$sql = rtrim($sql,',');
|
||||
|
||||
$r = dbq($sql . " WHERE " . $where);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
function share_shield($m) {
|
||||
return str_replace($m[1],'!=+=+=!' . base64url_encode($m[1]) . '=+!=+!=',$m[0]);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ function is_matrix_url($url) {
|
||||
* @return string
|
||||
*/
|
||||
function zid($s, $address = '') {
|
||||
if (! strlen($s) || strpos($s,'zid='))
|
||||
if (!$s || strpos($s,'zid='))
|
||||
return $s;
|
||||
|
||||
$m = parse_url($s);
|
||||
|
||||
9
view/fr/cert_bad_eml.tpl
Normal file
9
view/fr/cert_bad_eml.tpl
Normal file
@@ -0,0 +1,9 @@
|
||||
Il s'agit du serveur web de {{$sitename}} ;
|
||||
|
||||
Une vérification de routine indique que le certificat SSL de ce site web n'est pas valide.
|
||||
|
||||
Votre site web ne peut pas fonctionner correctement avec Hubzilla tant que ce problème n'est pas résolu. Veuillez vérifier votre certificat et avec votre fournisseur de certificat ou votre fournisseur de service pour vous assurer qu'il est "valide pour le navigateur" et installé correctement. Les certificats auto-signés ne sont PAS SUPPORTÉS et NE SONT PAS AUTORISÉS dans Hubzilla. La vérification est effectuée en récupérant une URL de votre site web avec une vérification SSL stricte activée, et si cela échoue, une nouvelle vérification est effectuée avec des vérifications SSL désactivées. Il est possible qu'une erreur transitoire produise ce message, mais si des changements récents de configuration ont été effectués, ou si vous recevez ce message plus d'une fois, veuillez vérifier votre certificat. Le message d'erreur est "{{$error}}".
|
||||
|
||||
Veuillez nous excuser pour ce désagrément,
|
||||
|
||||
Votre serveur web à {{$siteurl}}
|
||||
13
view/fr/cron_bad_eml.tpl
Normal file
13
view/fr/cron_bad_eml.tpl
Normal file
@@ -0,0 +1,13 @@
|
||||
Ceci est le serveur web de {{$sitename}} ;
|
||||
|
||||
Une vérification de routine indique que les tâches de maintenance programmées sur ce site ne sont pas exécutées.
|
||||
|
||||
Veuillez vérifier vos tâches "cron" ou le mécanisme équivalent sur votre serveur et assurez-vous qu'elles sont exécutées. Consultez les instructions d'installation si vous voyez ce message pour la première fois. Si ces tâches de maintenance se sont déroulées normalement jusqu'à présent, vérifiez que rien ne s'est produit pour expliquer leur arrêt. Cette vérification est effectuée tous les trois jours environ.
|
||||
|
||||
Le message d'erreur est "{{$error}}".
|
||||
|
||||
La dernière exécution réussie remonte à "{{$lastdate}}".
|
||||
|
||||
Veuillez nous excuser pour ce désagrément,
|
||||
|
||||
votre serveur web à {{$siteurl}}
|
||||
1
view/fr/invite.casual.subject.tpl
Normal file
1
view/fr/invite.casual.subject.tpl
Normal file
@@ -0,0 +1 @@
|
||||
Rejoignez-nous sur {{$projectname}} {{$invite_loc}}
|
||||
18
view/fr/invite.casual.tpl
Normal file
18
view/fr/invite.casual.tpl
Normal file
@@ -0,0 +1,18 @@
|
||||
{{* tpl FR, pour inviter les personnes qui me connaissant *}}
|
||||
|
||||
Rejoingnez moi sur {{$projectname}}.
|
||||
{{$linktxt}} {{$invite_where}}
|
||||
|
||||
Vous devrez fournir ce code d'invitation :
|
||||
{{$invite_code}}
|
||||
|
||||
Ou bien :
|
||||
|
||||
1) Enregistrez-vous à n'importe quel endroit de {{$projectname}} (ils sont tous interconnectés).
|
||||
2) Saisissez mon adresse de réseau {{$projectname}} dans la barre de recherche du site.
|
||||
|
||||
{{$invite_whereami}}
|
||||
|
||||
ou visitez {{$invite_whoami}}.
|
||||
|
||||
3) Cliquez sur [Connecter].
|
||||
1
view/fr/invite.formal.subject.tpl
Normal file
1
view/fr/invite.formal.subject.tpl
Normal file
@@ -0,0 +1 @@
|
||||
Invitation pour votre accès au réseau {{$invite_loc}}
|
||||
19
view/fr/invite.formal.tpl
Normal file
19
view/fr/invite.formal.tpl
Normal file
@@ -0,0 +1,19 @@
|
||||
{{* tpl FR formel, pour inviter de manière plus polie des personnes comme des membres d'entreprise ou des partenaires professionnels *}}.
|
||||
|
||||
Veuillez rejoindre le réseau social {{$nom du projet}}. Ce message contient les données essentielles pour la première connexion.
|
||||
|
||||
Le site est à rejoindre se trouve ici :
|
||||
{{$invite_whereami}}
|
||||
|
||||
Votre accès est juste préparé avec un code d'invitation :
|
||||
{{$invite_code}}
|
||||
|
||||
que vous devrez saisir dans le champ du formulaire d'inscription, qui s'affiche lorsque vous cliquez sur le lien "J'ai un code d'invitation". Veuillez également saisir votre adresse e-mail dans le champ suivant. Nous tenons à vous informer que le code d'invitation est lié à votre adresse électronique et n'est pas transférable.
|
||||
|
||||
Pour des raisons de sécurité, vous devez fournir un mot de passe de compte qui n'est et ne doit rester connu que de vous. Le mot de passe non visible doit être tapé deux fois pour éviter toute erreur de frappe. Le mot de passe est toujours demandé ultérieurement lorsque vous voulez vous connecter au site.
|
||||
|
||||
Selon la configuration du site, vous pouvez recevoir un autre courriel à votre adresse avec un code de validation, à saisir dans le formulaire vers lequel ce courriel vous dirigera. Ce genre de mesure contribue à renforcer la sécurité du site.
|
||||
|
||||
Selon la configuration du site, un administrateur devra valider votre accès. Merci de patienter car cela ne se fera pas instantanément.
|
||||
|
||||
Cordialement.
|
||||
@@ -1,18 +1,14 @@
|
||||
|
||||
Un compte a été créé sur {{$sitename}} avec cette adresse de courriel.
|
||||
Voici les détails de connexion:
|
||||
|
||||
Emplacement du site:⇥{{$siteurl}}
|
||||
Utilisateur:⇥{{$email}}
|
||||
Mot de passe: (le mot de passe qui a été spécifié lors de l'enregistrement)
|
||||
|
||||
Si ce compte a été créé sans votre accord, vous pouvez visiter ce site et réinitialiser le mot de passe.
|
||||
Ceci vous permettra de supprimer le compte à partir de la page des réglages du profil.
|
||||
Veuillez accepter nos excuses pour tous les désagréments engendrés.
|
||||
|
||||
Merci et bienvenue sur {{$sitename}}.
|
||||
|
||||
Sincèrement,
|
||||
L'administrateur {{$sitename}}
|
||||
|
||||
|
||||
Un compte a été créé sur {{$sitename}} avec cette adresse de courriel.
|
||||
Voici les détails de connexion:
|
||||
|
||||
Adresse du site: {{$siteurl}}
|
||||
Utilisateur: {{$email}}
|
||||
Mot de passe: (le mot de passe qui a été spécifié lors de l'enregistrement)
|
||||
|
||||
Si ce compte a été créé à votre insu et que vous n'en voulez pas, vous pouvez vous rendre sur ce site et réinitialiser le mot de passe. Cela vous permettra de supprimer le compte à partir des Paramètres / Paramètres du compte. Nous vous prions de nous excuser pour ce désagrément.
|
||||
|
||||
Merci et bienvenue sur {{$sitename}}.
|
||||
|
||||
L'administrateur {{$sitename}}
|
||||
|
||||
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
|
||||
Une demande d'enregistrement pour un nouvel utilisateur a été reçue par {{$sitename}} qui requiert
|
||||
votre accord.
|
||||
|
||||
|
||||
Voici les détails de connexion:
|
||||
|
||||
Emplacement du site:⇥{{$siteurl}}
|
||||
Utilisateur:⇥{{$email}}
|
||||
Adresse IP: {{$details}}
|
||||
|
||||
Pour confirmer votre accord, veuillez suivre le lien suivant:
|
||||
|
||||
|
||||
{{$siteurl}}/regmod/allow/{{$hash}}
|
||||
|
||||
|
||||
Pour supprimer ce compte, veuillez visiter:
|
||||
|
||||
|
||||
{{$siteurl}}/regmod/deny/{{$hash}}
|
||||
|
||||
|
||||
Merci.
|
||||
Une demande d'enregistrement pour un nouvel utilisateur a été reçue par {{$sitename}} qui requiert
|
||||
votre accord.
|
||||
|
||||
|
||||
Voici les détails de connexion :
|
||||
|
||||
Emplacement du site: {{$siteurl}}
|
||||
Utilisateur : {{$email}}
|
||||
Adresse IP : {{$details}}
|
||||
|
||||
Pour confirmer votre demande, veuillez cliquer sur le lien suivant:
|
||||
|
||||
{{$siteurl}}/regmod/allow/{{$hash}}
|
||||
|
||||
Pour supprimer ce compte, veuillez visiter:
|
||||
|
||||
{{$siteurl}}/regmod/deny/{{$hash}}
|
||||
|
||||
|
||||
Merci.
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
|
||||
Merci de vous être enregistré sur {{$sitename}}.
|
||||
|
||||
Voici les détails de connexion:
|
||||
|
||||
Emplacement du site:⇥{{$siteurl}}
|
||||
Utilisateur:⇥{{$email}}
|
||||
|
||||
Connectez-vous avec le mot de passe que vous avez choisi au moment de l'enregistrement.
|
||||
|
||||
Nous avons besoin de vérifier votre adresse de courriel avant d’autoriser votre accès au réseau.
|
||||
|
||||
Si vous avez enregistré ce compte, suivre ce lien:
|
||||
|
||||
{{$siteurl}}/regver/allow/{{$hash}}
|
||||
|
||||
|
||||
Pour supprimer ce compte, veuillez visiter:
|
||||
|
||||
|
||||
{{$siteurl}}/regver/deny/{{$hash}}
|
||||
|
||||
|
||||
Merci.
|
||||
Merci de vous être enregistré sur {{$sitename}}.
|
||||
|
||||
Voici les détails de connexion :
|
||||
|
||||
Adresse du site: {{$siteurl}}
|
||||
Utilisateur: {{$email}}
|
||||
|
||||
Connectez-vous avec le mot de passe que vous avez choisi au moment de l'enregistrement.
|
||||
|
||||
Nous devons vérifier votre adresse électronique afin de vous donner un accès complet au réseau.
|
||||
|
||||
Votre code de vérification est :
|
||||
|
||||
{{$hash}}
|
||||
|
||||
{{if $timeframe}}
|
||||
Ce code est valable de {{$timeframe.0}} UTC jusqu'à {{$timeframe.1}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
Si vous avez enregistré ce compte, veuillez entrer le code de vérification lorsque cela vous est demandé ou cliquez sur le lien suivant :
|
||||
|
||||
|
||||
{{$siteurl}}/regate/{{$mail}}
|
||||
|
||||
Pour refuser la demande et supprimer le compte, merci de vous rendre à cette adresse :
|
||||
{{$siteurl}}/regate/{{$mail}}{{if $ko}}/{{$ko}}{{/if}}
|
||||
|
||||
Merci.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
{{foreach $entries as $e}}
|
||||
|
||||
<tr><td>{{$e.total}}</td><td>{{$e.outq_posturl}}</td><td>{{$e.priority}}</td>{{if $expert}}<td><a href="admin/queue?f=&drophub={{$e.eurl}}" title="{{$nukehub}}" class="btn btn-outline-secondary"><i class="fa fa-times"></i><a></td><td><a href="admin/queue?f=&emptyhub={{$e.eurl}}" title="{{$empty}}" class="btn btn-outline-secondary"><i class="fa fa-trash-o"></i></a></td>{{/if}}</tr>
|
||||
<tr><td>{{$e.total}}</td><td>{{$e.outq_posturl}}</td><td>{{$e.priority}}</td>{{if $expert}}<td><a href="admin/queue?f=&drophub={{$e.eurl}}" title="{{$nukehub}}" class="btn btn-outline-secondary"><i class="fa fa-times"></i><a></td><td><a href="admin/queue?f=&emptyhub={{$e.eurl}}" title="{{$empty}}" class="btn btn-outline-secondary"><i class="fa fa-trash-o"></i></a></td><td><a href="admin/queue?f=&deliverhub={{$e.eurl}}" title="{{$deliverhub}}" class="btn btn-outline-secondary"><i class="fa fa-refresh"></i><a></td>{{/if}}</tr>
|
||||
{{/foreach}}
|
||||
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user