mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-19 21:35:13 +00:00
geo
This commit is contained in:
parent
9818a1ba2a
commit
0504102b33
21 changed files with 382 additions and 138 deletions
|
@ -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']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
48
Code/Update/_1261.php
Normal 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;
|
||||
}
|
||||
}
|
||||
|
2
boot.php
2
boot.php
|
@ -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' );
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 .= ' <span class="smalltext">(' . $coord . ')</span>';
|
||||
$location .= ' <span class="smalltext">(' . $latitude . ',' . $longitude . ')</span>';
|
||||
} else {
|
||||
$location = '<span class="smalltext">' . $coord . '</span>';
|
||||
$location = '<span class="smalltext">' . $latitude . ',' . $longitude . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
return $location;
|
||||
}
|
||||
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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` (
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in a new issue