This commit is contained in:
Mike Macgirvin 2022-09-16 20:57:04 +10:00
parent 9818a1ba2a
commit 0504102b33
21 changed files with 382 additions and 138 deletions

View file

@ -343,7 +343,7 @@ class Activity
$numpages = $total / App::$pager['itemspage'];
$lastpage = (($numpages > intval($numpages)) ? intval($numpages) + 1 : $numpages);
$stripped = preg_replace('/([&|\?]page=[0-9]*)/', '', $id);
$stripped = preg_replace('/([&|?]page=[0-9]*)/', '', $id);
$stripped = rtrim($stripped, '/');
$ret['partOf'] = z_root() . '/' . $stripped;
@ -790,15 +790,14 @@ class Activity
if ($i['app']) {
$ret['generator'] = ['type' => 'Application', 'name' => $i['app']];
}
if ($i['location'] || $i['coord']) {
if ($i['location'] || $i['lat'] || $i['lon']) {
$ret['location'] = ['type' => 'Place'];
if ($i['location']) {
$ret['location']['name'] = $i['location'];
}
if ($i['coord']) {
$l = explode(' ', $i['coord']);
$ret['location']['latitude'] = $l[0];
$ret['location']['longitude'] = $l[1];
if ($i['lat'] || $i['lon']) {
$ret['location']['latitude'] = $i['lat'] ?? 0;
$ret['location']['longitude'] = $i['lon'] ?? 0;
}
}
@ -1126,7 +1125,7 @@ class Activity
$images = false;
$has_images = preg_match_all('/\[[zi]mg(.*?)\](.*?)\[/ism', $i['body'], $images, PREG_SET_ORDER);
$has_images = preg_match_all('/\[[zi]mg(.*?)](.*?)\[/ism', $i['body'], $images, PREG_SET_ORDER);
$ret['id'] = $i['mid'];
@ -1150,18 +1149,16 @@ class Activity
if ($i['app']) {
$ret['generator'] = ['type' => 'Application', 'name' => $i['app']];
}
if ($i['location'] || $i['coord']) {
if ($i['location'] || $i['lat'] || $i['lon']) {
$ret['location'] = ['type' => 'Place'];
if ($i['location']) {
$ret['location']['name'] = $i['location'];
}
if ($i['coord']) {
$l = explode(' ', $i['coord']);
$ret['location']['latitude'] = $l[0];
$ret['location']['longitude'] = $l[1];
if ($i['lat'] || $i['lon']) {
$ret['location']['latitude'] = $i['lat'] ?? 0;
$ret['location']['longitude'] = $i['lon'] ?? 0;
}
}
if (intval($i['item_wall']) && $i['mid'] === $i['parent_mid']) {
$ret['commentPolicy'] = $i['comment_policy'];
}
@ -3121,9 +3118,9 @@ class Activity
if (array_key_exists('content', $location)) {
$s['location'] = html2plain(purify_html($location['content']), 256);
}
if (array_key_exists('latitude', $location) && array_key_exists('longitude', $location)) {
$s['coord'] = escape_tags($location['latitude']) . ' ' . escape_tags($location['longitude']);
$s['lat'] = floatval($location['latitude']);
$s['lon'] = floatval($location['longitude']);
}
}

View file

@ -503,6 +503,122 @@ class ActivityPub
return false;
}
public static function copy($src, $dst)
{
if (!($src && $dst)) {
return;
}
if ($src && !is_array($src)) {
$src = Activity::fetch($src);
if (is_array($src)) {
$src_xchan = $src['id'];
}
}
$approvals = null;
if ($dst && !is_array($dst)) {
$dst = Activity::fetch($dst);
if (is_array($dst)) {
$dst_xchan = $dst['id'];
if (array_key_exists('alsoKnownAs', $dst)) {
if (!is_array($dst['alsoKnownAs'])) {
$dst['alsoKnownAs'] = [$dst['alsoKnownAs']];
}
$approvals = $dst['alsoKnownAs'];
}
}
}
if (!($src_xchan && $dst_xchan)) {
return;
}
if ($approvals) {
foreach ($approvals as $approval) {
if ($approval === $src_xchan) {
$abooks = q(
"select abook_channel from abook where abook_xchan = '%s'",
dbesc($src_xchan)
);
if ($abooks) {
foreach ($abooks as $abook) {
// check to see if we already performed this action
$x = q(
"select * from abook where abook_xchan = '%s' and abook_channel = %d",
dbesc($dst_xchan),
intval($abook['abook_channel'])
);
if ($x) {
continue;
}
// update the local abook
$abc = q("select * from abconfig where chan = %d and xchan = '%s'",
intval($abook['abook_channel']),
dbesc($src_xchan)
);
if ($abc) {
foreach ($abc as $abcentry) {
q("insert into abconfig (chan, xchan, cat, k, v) values ( %d, '%s', '%s', '%s', '%s')",
intval($abcentry['chan']),
dbesc($dst_xchan),
dbesc($abcentry['cat']),
dbesc($abcentry['k']),
dbesc($abcentry['v'])
);
}
}
$pg = q("select * from pgrp_member where uid = %d and xchan = '%s'",
intval($abook['abook_channel']),
dbesc($src_xchan)
);
if ($pg) {
foreach ($pg as $pgentry) {
q("insert into pgrp_member (uid, gid, xchan) values (%d, %d, '%s')",
intval($pgentry['uid']),
intval($pgentry['gid']),
dbesc($dst_xchan)
);
}
}
$ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'",
intval($abook['abook_channel']),
dbesc($src_xchan)
);
if ($ab) {
$ab = array_shift($ab);
unset($ab['abook_id']);
$ab['abook_xchan'] = $dst_xchan;
$ab['abook_created'] = $ab['abook_updated'] = $ab['abook_connected'] = datetime_convert();
abook_store_lowlevel($ab);
}
$r = q(
"SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
intval($abook['abook_channel']),
intval($dst_xchan)
);
if ($r) {
$clone = array_shift($r);
unset($clone['abook_id']);
unset($clone['abook_account']);
unset($clone['abook_channel']);
$abconfig = load_abconfig($abook['abook_channel'], $clone['abook_xchan']);
if ($abconfig) {
$clone['abconfig'] = $abconfig;
}
Libsync::build_sync_packet($abook['abook_channel'], ['abook' => [$clone]]);
}
}
}
}
}
}
}
public static function move($src, $dst)
{

View file

@ -25,7 +25,7 @@ class Resizer
}
}
private function constructDimension($max)
private function constructDimension($max): bool|string
{
if (!isset($this->getimagesize)) {
return false;
@ -36,7 +36,7 @@ class Resizer
return false;
}
public function resize($infile,$outfile,$max_size = self::DEFAULT_MAX_SIZE)
public function resize($infile,$outfile,$max_size = self::DEFAULT_MAX_SIZE): bool
{
$dim = $this->constructDimension($max_size);
if ($dim && $this->converter_path) {

View file

@ -343,6 +343,51 @@ class Inbox extends Controller
if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && (ActivityStreams::is_an_actor($AS->obj['type']) || $AS->obj['type'] === 'Member')) {
break;
}
case 'Undo':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Follow') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Leave':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Tombstone':
case 'Delete':
Activity::drop($channel, $observer_hash, $AS);
break;
case 'Copy':
if (
$observer_hash && $observer_hash === $AS->actor
&& is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStream::is_an_actor($AS->obj['type'])
&& is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStream::is_an_actor($AS->tgt['type'])
) {
ActivityPub::copy($AS->obj, $AS->tgt);
break;
}
case 'Move':
if (
$observer_hash && $observer_hash === $AS->actor
&& is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStream::is_an_actor($AS->obj['type'])
&& is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStream::is_an_actor($AS->tgt['type'])
) {
ActivityPub::move($AS->obj, $AS->tgt);
break;
}
case 'Add':
case 'Remove':
// for writeable collections as target, it's best to provide an array and include both the type and the id in the target element.
// If it's just a string id, we'll try to fetch the collection when we receive it and that's wasteful since we don't actually need
// the contents.
if (is_array($AS->obj) && isset($AS->tgt)) {
// The boolean flag enables html cache of the item
$item = Activity::decode_note($AS, true);
break;
}
case 'Create':
case 'Like':
case 'Dislike':
@ -374,42 +419,6 @@ class Inbox extends Controller
logger('unresolved object: ' . print_r($AS->obj, true));
}
break;
case 'Undo':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Follow') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Leave':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Tombstone':
case 'Delete':
Activity::drop($channel, $observer_hash, $AS);
break;
case 'Move':
if (
$observer_hash && $observer_hash === $AS->actor
&& is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStream::is_an_actor($AS->obj['type'])
&& is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStream::is_an_actor($AS->tgt['type'])
) {
ActivityPub::move($AS->obj, $AS->tgt);
}
break;
case 'Add':
case 'Remove':
// for writeable collections as target, it's best to provide an array and include both the type and the id in the target element.
// If it's just a string id, we'll try to fetch the collection when we receive it and that's wasteful since we don't actually need
// the contents.
if (is_array($AS->obj) && isset($AS->tgt)) {
// The boolean flag enables html cache of the item
$item = Activity::decode_note($AS, true);
break;
}
default:
break;
}

View file

@ -393,7 +393,7 @@ class Item extends Controller
$post_tags = false;
$pub_copy = false;
logger('args: ' . print_r($_REQUEST,true));
/**
* Is this a reply to something?
*/
@ -816,7 +816,8 @@ class Item extends Controller
}
$location = $orig_post['location'];
$coord = $orig_post['coord'];
$lat = $orig_post['lat'];
$lon = $orig_post['lon'];
$verb = $orig_post['verb'];
$app = $orig_post['app'];
$title = escape_tags(trim($_REQUEST['title']));
@ -876,7 +877,8 @@ class Item extends Controller
$location = ((isset($_REQUEST['location'])) ? notags(trim($_REQUEST['location'])) : EMPTY_STR);
$coord = ((isset($_REQUEST['coord'])) ? notags(trim($_REQUEST['coord'])) : EMPTY_STR);
$lat = ((isset($_REQUEST['lat'])) ? floatval($_REQUEST['lat']) : 0.0);
$lon = ((isset($_REQUEST['lon'])) ? floatval($_REQUEST['lon']) : 0.0);
$verb = ((isset($_REQUEST['verb'])) ? notags(trim($_REQUEST['verb'])) : EMPTY_STR);
$title = ((isset($_REQUEST['title'])) ? escape_tags(trim($_REQUEST['title'])) : EMPTY_STR);
$summary = ((isset($_REQUEST['summary'])) ? trim($_REQUEST['summary']) : EMPTY_STR);
@ -1438,7 +1440,8 @@ class Item extends Controller
$datarray['body'] = $body;
$datarray['app'] = $app;
$datarray['location'] = $location;
$datarray['coord'] = $coord;
$datarray['lat'] = $lat;
$datarray['lon'] = $lon;
$datarray['verb'] = $verb;
$datarray['obj_type'] = $obj_type;
$datarray['allow_cid'] = $str_contact_allow;
@ -1518,12 +1521,14 @@ class Item extends Controller
$datarray['owner'] = $owner_xchan;
$datarray['author'] = $observer;
$datarray['attach'] = json_encode($datarray['attach']);
Hook::call('post_prestore', $datarray);
$o = conversation([$datarray], 'search', false, 'preview');
// logger('preview: ' . $o, LOGGER_DEBUG);
echo json_encode(['preview' => $o]);
killme();
}
Hook::call('post_prestore', $datarray);
// Let 'post_local' event listeners know if this is an edit.
// We will unset it immediately afterward.

View file

@ -146,6 +146,31 @@ class Outbox extends Controller
if (is_array($AS->obj) && array_key_exists('type', $AS->obj) && (ActivityStreams::is_an_actor($AS->obj['type']) || $AS->obj['type'] === 'Member')) {
break;
}
case 'Undo':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Follow') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Leave':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Tombstone':
case 'Delete':
Activity::drop($channel, $observer_hash, $AS);
break;
case 'Move':
if (
$observer_hash && $observer_hash === $AS->actor
&& is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStreams::is_an_actor($AS->obj['type'])
&& is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStreams::is_an_actor($AS->tgt['type'])
) {
ActivityPub::move($AS->obj, $AS->tgt);
break;
}
case 'Create':
case 'Like':
case 'Dislike':
@ -176,31 +201,6 @@ class Outbox extends Controller
logger('unresolved object: ' . print_r($AS->obj, true));
}
break;
case 'Undo':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Follow') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Leave':
if ($AS->obj && is_array($AS->obj) && array_key_exists('type', $AS->obj) && $AS->obj['type'] === 'Group') {
// do unfollow activity
Activity::unfollow($channel, $AS);
break;
}
case 'Tombstone':
case 'Delete':
Activity::drop($channel, $observer_hash, $AS);
break;
case 'Move':
if (
$observer_hash && $observer_hash === $AS->actor
&& is_array($AS->obj) && array_key_exists('type', $AS->obj) && ActivityStreams::is_an_actor($AS->obj['type'])
&& is_array($AS->tgt) && array_key_exists('type', $AS->tgt) && ActivityStreams::is_an_actor($AS->tgt['type'])
) {
ActivityPub::move($AS->obj, $AS->tgt);
}
break;
case 'Add':
case 'Remove':
default:

View file

@ -1075,8 +1075,8 @@ class Photos extends Controller
);
}
if ($link_item['coord'] && Apps::system_app_installed($owner_uid, 'Photomap')) {
$map = generate_map($link_item['coord']);
if (($link_item['lat'] || $link_item['lon']) && Apps::system_app_installed($owner_uid, 'Photomap')) {
$map = generate_map($link_item['lat'], $link_item['lon']);
}
}

View file

@ -14,6 +14,7 @@ use Code\Lib\PermissionDescription;
use Code\Access\AccessControl;
use Code\Daemon\Run;
use Code\Lib\Permcat;
use Code\Lib\PConfig;
use Code\Lib\Libacl;
use Code\Lib\Features;
use Code\Lib\Menu;
@ -191,7 +192,20 @@ class Channel
if (!isset($autoperms)) {
$autoperms = ((x($_POST, 'autoperms')) ? intval($_POST['autoperms']) : 0);
}
$set_location = (isset($_POST['set_location']) ? trim($_POST['set_location']) : '');
if ($set_location) {
$lat = false;
$lon = false;
$tmp = explode(',', $set_location);
if (count($tmp) > 1) {
$lat = floatval(trim($tmp[0]));
$lon = floatval(trim($tmp[1]));
}
$valid = $lat || $lon;
if ($valid) {
PConfig::Set(local_channel(),'system', 'set_location', (string) $lat . ',' . (string) $lon);
}
}
$pageflags = $channel['channel_pageflags'];
$existing_adult = (($pageflags & PAGE_ADULT) ? 1 : 0);
@ -631,7 +645,7 @@ class Channel
'$timezone' => array('timezone_select', t('Your timezone'), $timezone, t('This is important for showing the correct time on shared events'), get_timezones()),
'$defloc' => array('defloc', t('Default post location'), $defloc, t('Optional geographical location to display on your posts')),
'$allowloc' => array('allow_location', t('Obtain post location from your web browser or device'), ((get_pconfig(local_channel(), 'system', 'use_browser_location')) ? 1 : ''), '', $yes_no),
'$set_location' => [ 'set_location', t('Over-ride your web browser or device and use these coordinates (latitude,longitude)'), get_pconfig(local_channel(),'system','set_location')],
'$adult' => array('adult', t('Adult content'), $adult_flag, t('Enable to indicate if this channel frequently or regularly publishes adult content. (Please also tag any adult material and/or nudity with #NSFW)'), $yes_no),
'$h_prv' => t('Security and Privacy'),

48
Code/Update/_1261.php Normal file
View file

@ -0,0 +1,48 @@
<?php
namespace Code\Update;
class _1261
{
public function run()
{
q("START TRANSACTION");
if (ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$r1 = q("ALTER TABLE item ADD lat float NOT NULL DEFAULT '0'");
$r2 = q("create index \"lat_idx\" on item (\"lat\")");
$r3 = q("ALTER TABLE item ADD lon float NOT NULL DEFAULT '0'");
$r4 = q("create index \"lon_idx\" on item (\"lon\")");
$r = ($r1 && $r2 && $r3 && $r4);
} else {
$r1 = q("ALTER TABLE item ADD lat float NOT NULL DEFAULT '0' ,
ADD INDEX `lat` (`lat`)");
$r1 = q("ALTER TABLE item ADD lon float NOT NULL DEFAULT '0' ,
ADD INDEX `lon` (`lon`)");
$r = ($r1 && $r2);
}
if ($r) {
q("COMMIT");
return UPDATE_SUCCESS;
}
q("ROLLBACK");
return UPDATE_FAILED;
}
public function verify()
{
$columns = db_columns('item');
if (in_array('lat', $columns) && in_array('lon', $columns)) {
return true;
}
return false;
}
}

View file

@ -28,7 +28,7 @@ require_once('version.php');
define ( 'PLATFORM_NAME', 'streams' );
define ( 'DB_UPDATE_VERSION', 1260 );
define ( 'DB_UPDATE_VERSION', 1261 );
define ( 'ZOT_REVISION', '11.0' );
define ( 'PLATFORM_ARCHITECTURE', 'zap' );

View file

@ -758,8 +758,14 @@ function rpost_callback($match)
function bb_map_coords($match)
{
$x = str_replace(['/', ','], [' ', ' '], $match[1]);
$tmp = explode(' ', $x);
if (count($tmp) > 1) {
$lat = $tmp[0];
$lon = $tmp[1];
}
// the extra space in the following line is intentional
return str_replace($match[0], '<div class="map" >' . generate_map(str_replace('/', ' ', $match[1])) . '</div>', $match[0]);
return str_replace($match[0], '<div class="map" >' . generate_map($lat,$lon) . '</div>', $match[0]);
}
function bb_map_location($match)

View file

@ -1216,12 +1216,21 @@ function z_status_editor($x, $popup = false)
$feature_markup = false;
}
$lat = '';
$lon = '';
$geotag = (($x['allow_location']) ? replace_macros(Theme::get_template('jot_geotag.tpl'), []) : '');
$setloc = t('Set your location');
$clearloc = ((get_pconfig($x['profile_uid'], 'system', 'use_browser_location')) ? t('Clear browser location') : '');
$clearloc = t('Clear your location');
$set_location = get_pconfig($x['profile_uid'], 'system', 'set_location');
if ($set_location) {
$tmp = explode(',', $set_location);
if (count($tmp) > 1) {
$lat = floatval(trim($tmp[0]));
$lon = floatval(trim($tmp[1]));
}
}
if (x($x, 'hide_location')) {
$geotag = $setloc = $clearloc = '';
$geotag = $setloc = $clearloc = $lat = $lon = '';
}
$summaryenabled = ((array_key_exists('allow_summary', $x)) ? intval($x['allow_summary']) : false);
@ -1287,7 +1296,7 @@ function z_status_editor($x, $popup = false)
'$nickname' => $x['nickname'],
'$linkurl' => t('Please enter a link URL:'),
'$term' => t('Tag term:'),
'$whereareu' => t('Where are you right now?'),
'$whereareu' => t('Where are you right now?') . ' ' . t('(Enter a dot . to use your current device coordinates.)'),
'$editor_autocomplete' => ((x($x, 'editor_autocomplete')) ? $x['editor_autocomplete'] : ''),
'$bbco_autocomplete' => ((x($x, 'bbco_autocomplete')) ? $x['bbco_autocomplete'] : ''),
'$modalchooseimages' => t('Choose images to embed'),
@ -1448,6 +1457,8 @@ function z_status_editor($x, $popup = false)
'$defcommpolicy' => $defcommpolicy,
'$defcommuntil' => $defcommuntil,
'$clearloc' => $clearloc,
'$lat' => $lat,
'$lon' => $lon,
'$title' => ((x($x, 'title')) ? htmlspecialchars($x['title'], ENT_COMPAT, 'UTF-8') : ''),
'$placeholdertitle' => ((x($x, 'placeholdertitle')) ? $x['placeholdertitle'] : t('Title (optional)')),
'$catsenabled' => $catsenabled,
@ -1868,7 +1879,7 @@ function format_location($item)
$location = substr($item['location'], 1);
$location = ((strpos($location, '[') !== false) ? zidify_links(bbcode($location)) : $location);
} else {
$locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
$locate = array('location' => $item['location'], 'lat' => $item['lat'], 'lon' => $item['lon'], 'coord' => $item['coord'], 'html' => '');
Hook::call('render_location', $locate);
$location = ((strlen($locate['html'])) ? $locate['html'] : render_location_default($locate));
}
@ -1879,16 +1890,16 @@ function render_location_default($item)
{
$location = $item['location'];
$coord = $item['coord'];
$latitude = $item['lat'];
$longitude = $item['lon'];
if ($coord) {
if ($latitude || $longitude) {
if ($location) {
$location .= '&nbsp;<span class="smalltext">(' . $coord . ')</span>';
$location .= '&nbsp;<span class="smalltext">(' . $latitude . ',' . $longitude . ')</span>';
} else {
$location = '<span class="smalltext">' . $coord . '</span>';
$location = '<span class="smalltext">' . $latitude . ',' . $longitude . '</span>';
}
}
return $location;
}

View file

@ -556,13 +556,18 @@ function get_item_elements($x,$allow_code = false) {
$arr['plink'] = (($x['permalink']) ? htmlspecialchars($x['permalink'], ENT_COMPAT,'UTF-8',false) : '');
$arr['location'] = (($x['location']) ? htmlspecialchars($x['location'], ENT_COMPAT,'UTF-8',false) : '');
$arr['coord'] = (($x['longlat']) ? htmlspecialchars($x['longlat'], ENT_COMPAT,'UTF-8',false) : '');
$arr['verb'] = (($x['verb']) ? htmlspecialchars($x['verb'], ENT_COMPAT,'UTF-8',false) : '');
$arr['mimetype'] = (($x['mimetype']) ? htmlspecialchars($x['mimetype'], ENT_COMPAT,'UTF-8',false) : '');
$arr['obj_type'] = (($x['object_type']) ? htmlspecialchars($x['object_type'], ENT_COMPAT,'UTF-8',false) : '');
$arr['tgt_type'] = (($x['target_type']) ? htmlspecialchars($x['target_type'], ENT_COMPAT,'UTF-8',false) : '');
if ($x['longlat']) {
$coordinates = explode(' ', $x['longlat']);
if (count($coordinates) > 1) {
$arr['lat'] = floatval($coordinates[0]);
$arr['lon'] = floatval($coordinates[1]);
}
}
// convert AS1 namespaced elements to AS-JSONLD
$arr['verb'] = Activity::activity_mapper($arr['verb']);
@ -976,7 +981,7 @@ function encode_item($item,$mirror = false) {
$x['target_type'] = $item['tgt_type'];
$x['permalink'] = $item['plink'];
$x['location'] = $item['location'];
$x['longlat'] = $item['coord'];
$x['longlat'] = ($item['lat'] || $item['lon']) ? $item['lat'] . ' ' . $item['lon'] : 0.0;
$x['signature'] = $item['sig'];
$x['replyto'] = $item['replyto'];
$x['owner'] = encode_item_xchan($item['owner']);
@ -1567,7 +1572,8 @@ function item_store($arr, $allow_exec = false, $deliver = true, $linkid = true)
}
$arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : '');
$arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : '');
$arr['lat'] = ((x($arr, 'lat')) ? floatval($arr['lat']) : 0.0);
$arr['lon'] = ((x($arr, 'lon')) ? floatval($arr['lon']) : 0.0);
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : '');
$arr['thr_parent'] = ((x($arr,'thr_parent')) ? notags(trim($arr['thr_parent'])) : $arr['parent_mid']);
$arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : ACTIVITY_POST);
@ -2100,7 +2106,8 @@ function item_store_update($arr, $allow_exec = false, $deliver = true, $linkid =
$arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : $orig[0]['location']);
$arr['uuid'] = ((x($arr,'uuid')) ? notags(trim($arr['uuid'])) : $orig[0]['uuid']);
$arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']);
$arr['lat'] = ((x($arr,'lat')) ? floatval($arr['lat']) : $orig[0]['lat']);
$arr['lon'] = ((x($arr,'lon')) ? floatval($arr['lon']) : $orig[0]['lon']);
$arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']);
$arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : $orig[0]['obj_type']);
$arr['obj'] = ((x($arr,'obj')) ? trim($arr['obj']) : $orig[0]['obj']);

View file

@ -1743,23 +1743,12 @@ function format_filer(&$item)
}
function generate_map($coord)
function generate_map($lat, $lon, $zoom = 16)
{
$coord = str_replace(array(',','/',' '), array(' ',' ',' '), trim($coord));
$zoom = ((strpos($coord, '?z=') !== false) ? substr($coord, strpos($coord, '?z=') + 3) : 0);
if ($zoom) {
$coord = substr($coord, 0, strpos($coord, '?'));
} else {
$zoom = 16;
}
$arr = [
'lat' => trim(substr($coord, 0, strpos($coord, ' '))),
'lon' => trim(substr($coord, strpos($coord, ' ') + 1)),
'lat' => $lat,
'lon' => $lon,
'zoom' => $zoom,
'html' => ''
];
@ -1772,7 +1761,7 @@ function generate_map($coord)
*/
Hook::call('generate_map', $arr);
return (($arr['html']) ? $arr['html'] : $coord);
return (($arr['html']) ?? 'geo:' . $lat . ',' . $lon . '&z=' . $zoom);
}
function generate_named_map($location)
@ -1908,8 +1897,19 @@ function prepare_body(&$item, $attach = false, $opts = false)
return $s;
}
if (strpos($s, '<div class="map">') !== false && $item['coord']) {
$x = generate_map(trim($item['coord']));
if (strpos($s, '<div class="map">') !== false) {
if ($item['lat'] || $item['lon']) {
$lat = $item['lat'];
$lon = $item['lon'];
}
elseif ($item['coord']) {
$tmp = explode(' ', $item['coord']);
if (count($tmp) > 1) {
$lat = $tmp[0];
$lon = $tmp[1];
}
}
$x = generate_map($lat, $lon);
if ($x) {
$s = preg_replace('/\<div class\=\"map\"\>/', '$0' . $x, $s);
}

View file

@ -560,8 +560,9 @@ function photo_upload($channel, $observer, $args)
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
if ($lat && $lon) {
$arr['coord'] = $lat . ' ' . $lon;
if ($lat || $lon) {
$arr['lat'] = floatval($lat);
$arr['lon'] = floatval($lon);
}
$result = item_store($arr, false, $deliver);

View file

@ -614,6 +614,8 @@ CREATE TABLE IF NOT EXISTS `item` (
`item_delayed` tinyint(1) NOT NULL DEFAULT 0 ,
`item_pending_remove` tinyint(1) NOT NULL DEFAULT 0 ,
`item_blocked` tinyint(1) NOT NULL DEFAULT 0 ,
`lat` float NOT NULL DEFAULT '0',
`lon` float NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `created` (`created`),
@ -668,7 +670,9 @@ CREATE TABLE IF NOT EXISTS `item` (
KEY `item_rss` (`item_rss`),
KEY `item_consensus` (`item_consensus`),
KEY `item_deleted_pending_remove_changed` (`item_deleted`, `item_pending_remove`, `changed`),
KEY `item_pending_remove_changed` (`item_pending_remove`, `changed`)
KEY `item_pending_remove_changed` (`item_pending_remove`, `changed`),
KEY `lat` (`lat`),
KEY `lon` (`lon`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `likes` (

View file

@ -628,6 +628,8 @@ CREATE TABLE "item" (
"item_delayed" smallint NOT NULL DEFAULT '0',
"item_pending_remove" smallint NOT NULL DEFAULT '0',
"item_blocked" smallint NOT NULL DEFAULT '0',
"lat" float NOT NULL DEFAULT '0',
"lon" float NOT NULL DEFAULT '0',
"item_search_vector" tsvector,
PRIMARY KEY ("id")
);
@ -688,6 +690,8 @@ create index "item_unpublished" on item ("item_unpublished");
create index "item_delayed" on item ("item_delayed");
create index "item_pending_remove" on item ("item_pending_remove");
create index "item_blocked" on item ("item_blocked");
create index "lat" on item ("lat");
create index "lon" on item ("lon");
-- fulltext indexes
create index "item_search_idx" on item USING gist("item_search_vector");
create index "item_allow_cid" on item ("allow_cid");

View file

@ -1,5 +1,5 @@
<script language="javascript" type="text/javascript">
<script type="text/javascript">
let editor = false;
let plaintext = '{{$editselect}}';
@ -81,6 +81,8 @@ let activeCommentText = '';
}
});
jotLocateStatus();
$('#jot-add-option').on('click', jotAddOption);
$(document).on('click', '.poll-option-close', jotRemoveOption);
@ -193,6 +195,17 @@ let activeCommentText = '';
$('#link-modal-CancelButton').on('click',jotclearmodal);
}
function jotLocateStatus() {
if($('#jot-lat').val() || $('#jot-lon').val() || $('#jot-location').val()) {
$('#profile-nolocation-wrapper').attr('disabled', false);
$('#profile-nolocation-wrapper').show();
}
else {
$('#profile-nolocation-wrapper').attr('disabled', true);
$('#profile-nolocation-wrapper').hide();
}
}
function jotclearmodal() {
$('#link-modal-OKButton').off('click',jotgetlinkmodal);
$('#link-modal-CancelButton').off('click',jotclearmodal);
@ -231,19 +244,23 @@ let activeCommentText = '';
}
function jotGetLocation() {
reply = prompt("{{$whereareu}}", $('#jot-location').val());
let reply = prompt("{{$whereareu}}", $('#jot-location').val());
if(reply && reply.length) {
// A single period indicates "use my browser location"
if(reply == '.') {
if(navigator.geolocation) {
reply = '';
navigator.geolocation.getCurrentPosition(function(position) {
$('#jot-coord').val(position.coords.latitude + ' ' + position.coords.longitude);
$('#profile-nolocation-wrapper').attr('disabled', false);
$('#jot-lat').val(position.coords.latitude);
$('#jot-lon').val(position.coords.longitude);
jotLocateStatus();
});
}
}
else {
$('#jot-location').val(reply);
jotLocateStatus();
}
}
}
@ -488,8 +505,10 @@ let activeCommentText = '';
}
function jotClearLocation() {
$('#jot-coord').val('');
$('#profile-nolocation-wrapper').attr('disabled', true);
$('#jot-lat').val('');
$('#jot-lon').val('');
$('#jot-location').val('');
jotLocateStatus();
}

View file

@ -23,7 +23,8 @@
<input type="hidden" name="created" id="jot-created" value="{{$defpublish}}" />
<input type="hidden" name="media_str" id="jot-media" value="" />
<input type="hidden" name="source" id="jot-source" value="{{$source}}" />
<input type="hidden" name="coord" id="jot-coord" value="" />
<input type="hidden" name="lat" id="jot-lat" value="{{$lat}}" />
<input type="hidden" name="lon" id="jot-lon" value="{{$lon}}" />
<input type="hidden" id="jot-postid" name="post_id" value="{{$post_id}}" />
<input type="hidden" id="jot-webpage" name="webpage" value="{{$webpage}}" />
<input type="hidden" name="preview" id="jot-preview" value="0" />

View file

@ -1,7 +1,8 @@
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
$('#jot-coord').val(position.coords.latitude + ' ' + position.coords.longitude);
$('#profile-nolocation-wrapper').attr('disabled', false);
$('#jot-lat').val(position.coords.latitude);
$('#jot-lon').val(position.coords.longitude);
jotLocateStatus();
});
}

View file

@ -21,6 +21,7 @@
{{include file="field_input.tpl" field=$username}}
{{include file="field_input.tpl" field=$defloc}}
{{include file="field_checkbox.tpl" field=$allowloc}}
{{include file="field_input.tpl" field=$set_location}}
{{include file="field_checkbox.tpl" field=$adult}}
{{include file="field_input.tpl" field=$photo_path}}
{{include file="field_input.tpl" field=$attach_path}}