From f123809d29d6cc335251cd4fd8984c1b5ef67e2a Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sat, 25 Jan 2020 16:24:14 -0800 Subject: more work on zap export --- include/channel.php | 11 ++++++++++- include/text.php | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/channel.php b/include/channel.php index e7d119b1e..66ab56715 100644 --- a/include/channel.php +++ b/include/channel.php @@ -922,8 +922,17 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals $r = q("select * from pconfig where uid = %d", intval($channel_id) ); - if($r) + + if($r) { + if ($zap_compat) { + for($x = 0; $x < count($r); $x ++) { + if (preg_match('|^a:[0-9]+:{.*}$|s', $r[$x]['v'])) { + $r[$x]['v'] = serialise(unserialize($r[$x]['v'])); + } + } + } $ret['config'] = $r; + } // All other term types will be included in items, if requested. diff --git a/include/text.php b/include/text.php index 87ed9f658..1f0af08e3 100644 --- a/include/text.php +++ b/include/text.php @@ -3694,3 +3694,18 @@ function svg2bb($s) { } return EMPTY_STR; } + + + +function serialise($x) { + return ((is_array($x)) ? 'json:' . json_encode($x) : $x); +} + +function unserialise($x) { + if (is_array($x)) { + return $x; + } + $y = ((substr($x,0,5) === 'json:') ? json_decode(substr($x,5),true) : ''); + return ((is_array($y)) ? $y : $x); +} + -- cgit v1.2.3 From 3df5d854b8935b11c67893bbbd24cdf8829eda00 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 29 Jan 2020 14:29:06 -0800 Subject: z6 transition work - prevent z6 sync packets from being unpacked into an incompatible schema --- include/zid.php | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/zid.php b/include/zid.php index 3b3dd8554..325af5580 100644 --- a/include/zid.php +++ b/include/zid.php @@ -1,6 +1,7 @@ Date: Thu, 30 Jan 2020 17:24:08 +0000 Subject: provide img and zmg tags with image description --- include/bbcode.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/bbcode.php b/include/bbcode.php index 301ffbd24..f3ecbd9e9 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -1237,9 +1237,18 @@ function bbcode($Text, $options = []) { if (strpos($Text,'[/img]') !== false) { $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); } + // [img=pathtoimage]image description[/img] + if (strpos($Text,'[/img]') !== false) { + $Text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '$2', $Text); + } + // [zmg]pathtoimage[/zmg] if (strpos($Text,'[/zmg]') !== false) { $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); } + // [zmg=pathtoimage]image description[/zmg] + if (strpos($Text,'[/zmg]') !== false) { + $Text = preg_replace("/\[zmg=http(.*?)\](.*?)\[\/zmg\]/ism", '$2', $Text); + } // [img float={left, right}]pathtoimage[/img] if (strpos($Text,'[/img]') !== false) { -- cgit v1.2.3 From 2c42daf6090ba8d0e3a50b8350ea5a3750891b68 Mon Sep 17 00:00:00 2001 From: Zot Date: Thu, 30 Jan 2020 20:06:15 +0100 Subject: z6 compat work --- include/channel.php | 11 ++++++++++- include/text.php | 15 +++++++++++++++ include/zid.php | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/channel.php b/include/channel.php index e7d119b1e..66ab56715 100644 --- a/include/channel.php +++ b/include/channel.php @@ -922,8 +922,17 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals $r = q("select * from pconfig where uid = %d", intval($channel_id) ); - if($r) + + if($r) { + if ($zap_compat) { + for($x = 0; $x < count($r); $x ++) { + if (preg_match('|^a:[0-9]+:{.*}$|s', $r[$x]['v'])) { + $r[$x]['v'] = serialise(unserialize($r[$x]['v'])); + } + } + } $ret['config'] = $r; + } // All other term types will be included in items, if requested. diff --git a/include/text.php b/include/text.php index 87ed9f658..1f0af08e3 100644 --- a/include/text.php +++ b/include/text.php @@ -3694,3 +3694,18 @@ function svg2bb($s) { } return EMPTY_STR; } + + + +function serialise($x) { + return ((is_array($x)) ? 'json:' . json_encode($x) : $x); +} + +function unserialise($x) { + if (is_array($x)) { + return $x; + } + $y = ((substr($x,0,5) === 'json:') ? json_decode(substr($x,5),true) : ''); + return ((is_array($y)) ? $y : $x); +} + diff --git a/include/zid.php b/include/zid.php index 3b3dd8554..325af5580 100644 --- a/include/zid.php +++ b/include/zid.php @@ -1,6 +1,7 @@ Date: Thu, 30 Jan 2020 15:56:33 -0800 Subject: basic poll support and patch to not call System::get_platform_name() within t() unless needed. Polls probably need refining and have not yet been fully tested after porting --- include/conversation.php | 4 ++- include/language.php | 7 +++-- include/text.php | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/conversation.php b/include/conversation.php index 07d43e660..45b2b4d80 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -408,7 +408,7 @@ function count_descendants($item) { * @return boolean */ function visible_activity($item) { - $hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_POLLRESPONSE ]; + $hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_POLLRESPONSE, 'Answer' ]; if(intval($item['item_notshown'])) return false; @@ -419,6 +419,8 @@ function visible_activity($item) { } } + + if(is_edit_activity($item)) return false; diff --git a/include/language.php b/include/language.php index e9d62e434..622b9614d 100644 --- a/include/language.php +++ b/include/language.php @@ -217,9 +217,10 @@ function t($s, $ctx = '') { */ function translate_projectname($s) { - - return str_replace(array('$projectname','$Projectname'),array(Zotlabs\Lib\System::get_platform_name(),ucfirst(Zotlabs\Lib\System::get_platform_name())),$s); - + if(strpos($s,'rojectname') !== false) { + return str_replace(array('$projectname','$Projectname'),array(Zotlabs\Lib\System::get_platform_name(),ucfirst(Zotlabs\Lib\System::get_platform_name())),$s); + } + return $s; } diff --git a/include/text.php b/include/text.php index 1f0af08e3..caecae33e 100644 --- a/include/text.php +++ b/include/text.php @@ -1731,6 +1731,11 @@ function prepare_body(&$item,$attach = false,$opts = false) { } } + $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ 'Create','Update' ])) ? format_poll($item, $s, $opts) : false); + if ($poll) { + $s = $poll; + } + $event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event_obj($item['obj']) : false); $prep_arr = [ @@ -1814,6 +1819,78 @@ function prepare_binary($item) { } +function format_poll($item,$s,$opts) { + + if (! is_array($item['obj'])) { + $act = json_decode($item['obj'],true); + } + else { + $act = $item['obj']; + } + + if (! is_array($act)) { + return EMPTY_STR; + } + + $commentable = can_comment_on_post(((local_channel()) ? get_observer_hash() : EMPTY_STR),$item); + + //logger('format_poll: ' . print_r($item,true)); + $activated = ((local_channel() && local_channel() == $item['uid']) ? true : false); + $output = $s . EOL. EOL; + + if ($act['type'] === 'Question') { + if ($activated and $commentable) { + $output .= '
'; + } + if (array_key_exists('anyOf',$act) && is_array($act['anyOf'])) { + foreach ($act['anyOf'] as $poll) { + if (array_key_exists('name',$poll) && $poll['name']) { + $text = html2plain(purify_html($poll['name']),256); + if (array_path_exists('replies/totalItems',$poll)) { + $total = $poll['replies']['totalItems']; + } + else { + $total = 0; + } + if ($activated && $commentable) { + $output .= ' ' . $text . '' . ' (' . $total . ')' . EOL; + } + else { + $output .= '[ ] ' . $text . ' (' . $total . ')' . EOL; + } + } + } + } + if (array_key_exists('oneOf',$act) && is_array($act['oneOf'])) { + foreach ($act['oneOf'] as $poll) { + if (array_key_exists('name',$poll) && $poll['name']) { + $text = html2plain(purify_html($poll['name']),256); + if (array_path_exists('replies/totalItems',$poll)) { + $total = $poll['replies']['totalItems']; + } + else { + $total = 0; + } + if ($activated && $commentable) { + $output .= ' ' . $text . '' . ' (' . $total . ')' . EOL; + } + else { + $output .= '( ) ' . $text . ' (' . $total . ')' . EOL; + } + } + } + } + if ($activated and $commentable) { + $output .= EOL . ''. '
'; + } + + } + return $output; +} + + + + /** * @brief Given a text string, convert from content_type to HTML. * -- cgit v1.2.3 From fc9e6d289acf30f89da0051a90cbf16f0bc006fb Mon Sep 17 00:00:00 2001 From: zotlabs Date: Fri, 31 Jan 2020 12:51:23 -0800 Subject: missing piece of poll code --- include/items.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/items.php b/include/items.php index 9f90b2f3b..c5743e91c 100755 --- a/include/items.php +++ b/include/items.php @@ -9,6 +9,7 @@ use Zotlabs\Lib\MarkdownSoap; use Zotlabs\Lib\MessageFilter; use Zotlabs\Lib\ThreadListener; use Zotlabs\Lib\IConfig; +use Zotlabs\Lib\Activity; use Zotlabs\Access\PermissionLimits; use Zotlabs\Access\AccessList; use Zotlabs\Daemon\Master; @@ -1947,6 +1948,11 @@ function item_store($arr, $allow_exec = false, $deliver = true) { if(intval($r[0]['item_uplink']) && (! $r[0]['item_private'])) $arr['item_private'] = 0; + + if(in_array($arr['verb'], ['Note','Answer']) && $arr['obj_type'] === 'Question' && intval($r[0]['item_wall'])) { + Activity::update_poll($r[0],$arr['mid'],$arr['title']); + } + } else { logger('item_store: item parent was not found - ignoring item'); -- cgit v1.2.3 From ca75619518590fece646a582ee91b218725df85d Mon Sep 17 00:00:00 2001 From: Voryzen Date: Fri, 7 Feb 2020 11:24:01 +0100 Subject: Add 'hook call' to be used for new addon 'NavBanner_options' --- include/nav.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/nav.php b/include/nav.php index 672cc2689..bd4d000f7 100644 --- a/include/nav.php +++ b/include/nav.php @@ -59,6 +59,8 @@ function nav($template = 'default') { if($banner === false) $banner = get_config('system','sitename'); + + call_hooks('get_banner',$banner); App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), array( //we could additionally use this to display important system notifications e.g. for updates -- cgit v1.2.3 From bbcb237f5b996e94af37611152105b2e965ea493 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 9 Feb 2020 16:32:18 -0800 Subject: poll updates --- include/conversation.php | 6 +++++- include/text.php | 13 ++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/conversation.php b/include/conversation.php index 45b2b4d80..327d89e53 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -408,11 +408,15 @@ function count_descendants($item) { * @return boolean */ function visible_activity($item) { - $hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_POLLRESPONSE, 'Answer' ]; + $hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_POLLRESPONSE ]; if(intval($item['item_notshown'])) return false; + if ($item['obj_type'] === 'Answer') { + return false; + } + foreach($hidden_activities as $act) { if((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) { return false; diff --git a/include/text.php b/include/text.php index caecae33e..992b455c8 100644 --- a/include/text.php +++ b/include/text.php @@ -1880,6 +1880,17 @@ function format_poll($item,$s,$opts) { } } } + if ($item['comments_closed'] > NULL_DATE) { + $t = datetime_convert('UTC',date_default_timezone_get(), $item['comments_closed'], 'Y-m-d h:i'); + $closed = ((datetime_convert() > $item['comments_closed']) ? true : false); + if ($closed) { + $message = t('Poll has ended.'); + } + else { + $message = sprintf(t('Poll ends: %s'),$t); + } + $output .= EOL . '
' . $message . '
'; + } if ($activated and $commentable) { $output .= EOL . ''. ''; } @@ -3721,7 +3732,7 @@ function array_path_exists($str,$arr) { if($search) { foreach($search as $s) { - if(array_key_exists($s,$ptr)) { + if($ptr && array_key_exists($s,$ptr)) { $ptr = $ptr[$s]; } else { -- cgit v1.2.3 From a39d436f9f46138db623ee3c9ddef2c501ea8bd2 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 10 Feb 2020 20:37:35 +0000 Subject: poll fixes --- include/text.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/text.php b/include/text.php index 992b455c8..3dd0755a3 100644 --- a/include/text.php +++ b/include/text.php @@ -1731,7 +1731,7 @@ function prepare_body(&$item,$attach = false,$opts = false) { } } - $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ 'Create','Update' ])) ? format_poll($item, $s, $opts) : false); + $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ ACTIVITY_POST, ACTIVITY_UPDATE ])) ? format_poll($item, $s, $opts) : false); if ($poll) { $s = $poll; } -- cgit v1.2.3 From bf7c96807a50433b7241ddf6df9e01d4ef11f43d Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 10 Feb 2020 18:17:41 -0800 Subject: fix poll responses --- include/items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/items.php b/include/items.php index c5743e91c..bf1ddee82 100755 --- a/include/items.php +++ b/include/items.php @@ -1949,7 +1949,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) { if(intval($r[0]['item_uplink']) && (! $r[0]['item_private'])) $arr['item_private'] = 0; - if(in_array($arr['verb'], ['Note','Answer']) && $arr['obj_type'] === 'Question' && intval($r[0]['item_wall'])) { + if(in_array($arr['obj_type'], ['Note','Answer']) && $r[0]['obj_type'] === 'Question' && intval($r[0]['item_wall'])) { Activity::update_poll($r[0],$arr['mid'],$arr['title']); } -- cgit v1.2.3 From 9f029336cab322e04d29af842ba0a666189c8683 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 11 Feb 2020 09:20:32 +0000 Subject: fix notifications for polls --- include/conversation.php | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/conversation.php b/include/conversation.php index 327d89e53..0098a694d 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -625,11 +625,17 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $items = $cb['items']; - $conv_responses = array( - 'like' => array('title' => t('Likes','title')),'dislike' => array('title' => t('Dislikes','title')), - 'agree' => array('title' => t('Agree','title')),'disagree' => array('title' => t('Disagree','title')), 'abstain' => array('title' => t('Abstain','title')), - 'attendyes' => array('title' => t('Attending','title')), 'attendno' => array('title' => t('Not attending','title')), 'attendmaybe' => array('title' => t('Might attend','title')) - ); + $conv_responses = [ + 'like' => ['title' => t('Likes','title')], + 'dislike' => ['title' => t('Dislikes','title')], + 'agree' => ['title' => t('Agree','title')], + 'disagree' => ['title' => t('Disagree','title')], + 'abstain' => ['title' => t('Abstain','title')], + 'attendyes' => ['title' => t('Attending','title')], + 'attendno' => ['title' => t('Not attending','title')], + 'attendmaybe' => ['title' => t('Might attend','title')], + 'answer' => [] + ]; // array with html for each thread (parent+comments) @@ -1136,7 +1142,7 @@ function builtin_activity_puller($item, &$conv_responses) { // if this item is a post or comment there's nothing for us to do here, just return. - if(activity_match($item['verb'],ACTIVITY_POST)) + if(activity_match($item['verb'],ACTIVITY_POST) && $item['obj_type'] !== 'Answer') return; foreach($conv_responses as $mode => $v) { @@ -1168,6 +1174,9 @@ function builtin_activity_puller($item, &$conv_responses) { case 'attendmaybe': $verb = ACTIVITY_ATTENDMAYBE; break; + case 'answer': + $verb = ACTIVITY_POST; + break; default: return; break; @@ -1183,9 +1192,11 @@ function builtin_activity_puller($item, &$conv_responses) { if(! $item['thr_parent']) $item['thr_parent'] = $item['parent_mid']; - $conv_responses[$mode]['mids'][$item['thr_parent']][] = 'b64.' . base64url_encode($item['mid']); + if($item['obj_type'] === 'Answer') + continue; + if(! ((isset($conv_responses[$mode][$item['thr_parent'] . '-l'])) && (is_array($conv_responses[$mode][$item['thr_parent'] . '-l'])))) $conv_responses[$mode][$item['thr_parent'] . '-l'] = array(); -- cgit v1.2.3 From b7bac45427a400275597faa9b51c4d277fe1f5c7 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Thu, 20 Feb 2020 20:03:50 +0100 Subject: Revert "Use argv() instead URI parsing" This reverts commit bcfb69eeeef6a0506a0ec0574a03b673df84a55a --- include/cdav.php | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/import.php | 67 +++++++++++++++++++ include/zot.php | 3 + 3 files changed, 256 insertions(+) create mode 100644 include/cdav.php (limited to 'include') diff --git a/include/cdav.php b/include/cdav.php new file mode 100644 index 000000000..d72caa442 --- /dev/null +++ b/include/cdav.php @@ -0,0 +1,186 @@ +ORG = $f['org']; + else + if($edit) + unset($vcard->ORG); + + + if($f['title']) + $vcard->TITLE = $f['title']; + else + if($edit) + unset($vcard->TITLE); + + if($edit) + unset($vcard->TEL); + if($f['tel']) { + $i = 0; + foreach($f['tel'] as $item) { + if($item) { + $vcard->add('TEL', $item, ['type' => $f['tel_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->EMAIL); + if($f['email']) { + $i = 0; + foreach($f['email'] as $item) { + if($item) { + $vcard->add('EMAIL', $item, ['type' => $f['email_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->IMPP); + if($f['impp']) { + $i = 0; + foreach($f['impp'] as $item) { + if($item) { + $vcard->add('IMPP', $item, ['type' => $f['impp_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->URL); + if($f['url']) { + $i = 0; + foreach($f['url'] as $item) { + if($item) { + $vcard->add('URL', $item, ['type' => $f['url_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->ADR); + if($f['adr']) { + $i = 0; + foreach($f['adr'] as $item) { + if($item) { + $vcard->add('ADR', $item, ['type' => $f['adr_type'][$i]]); + } + $i++; + } + } + + if($f['note']) { + $vcard->NOTE = $f['note']; + } + else + if($edit) + unset($vcard->NOTE); +} + + +/** + * @brief Import CardDAV or CalDAV card + * + * @param int $id card id + * @param str $ext card extension + * @param str $table name + * @param str $column name + * @param obj $objects + * @param str $profile + * @param obj $backend + * @param array $ids + * @param bool $notice + * + */ + +function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, &$ids, $notice = false) { + + $i = 0; + $newid = (count($ids) ? false : true); + + while ($object = $objects->getNext()) { + + if($_REQUEST['a_upload']) + $object = $object->convert(\Sabre\VObject\Document::VCARD40); + + $ret = $object->validate($profile & \Sabre\VObject\Node::REPAIR); + + //level 3 Means that the document is invalid, + //level 2 means a warning. A warning means it's valid but it could cause interopability issues, + //level 1 means that there was a problem earlier, but the problem was automatically repaired. + + if($ret[0]['level'] < 3) { + + if($newid) { + do { + $duplicate = false; + $objectUri = random_string(40) . '.' . $ext; + + $r = q("SELECT uri FROM $table WHERE $column = %d AND uri = '%s' LIMIT 1", + dbesc($id), + dbesc($objectUri) + ); + if (count($r)) + $duplicate = true; + } while ($duplicate == true); + $ids[$i] = $objectUri; + } + else + $objectUri = $ids[$i]; + + $i++; + + if($ext == 'ics') + $backend->createCalendarObject($id, $objectUri, $object->serialize()); + + if($ext == 'vcf') + $backend->createCard($id, $objectUri, $object->serialize()); + } + else { + if($notice && $ext == 'ics') { + notice( + '' . t('INVALID EVENT DISMISSED!') . '' . EOL . + '' . t('Summary: ') . '' . (($object->VEVENT->SUMMARY) ? $object->VEVENT->SUMMARY : t('Unknown')) . EOL . + '' . t('Date: ') . '' . (($object->VEVENT->DTSTART) ? $object->VEVENT->DTSTART : t('Unknown')) . EOL . + '' . t('Reason: ') . '' . $ret[0]['message'] . EOL + ); + } + + if($notice && $exp == 'vcf') { + notice( + '' . t('INVALID CARD DISMISSED!') . '' . EOL . + '' . t('Name: ') . '' . (($object->FN) ? $object->FN : t('Unknown')) . EOL . + '' . t('Reason: ') . '' . $ret[0]['message'] . EOL + ); + } + } + } +} + + +function get_cdav_id($principaluri, $uri, $table) { + + $r = q("SELECT id FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", + dbesc($principaluri), + dbesc($uri) + ); + if(! $r) + return false; + + return $r[0]['id']; +} diff --git a/include/import.php b/include/import.php index 6a3895b9f..0519052d8 100644 --- a/include/import.php +++ b/include/import.php @@ -1503,6 +1503,73 @@ function sync_files($channel, $files) { } } +/** + * @brief Synchronize addressbooks. + * + * @param array $channel + * @param array $data + */ +function sync_addressbook($channel, $data) { + + if(! \Zotlabs\Lib\Apps::system_app_installed($channel['channel_id'], 'CardDAV')) + return; + + logger("debug: " . print_r($data,true), LOGGER_DEBUG); + + require_once('include/cdav.php'); + + $principalUri = 'principals/' . $channel['channel_address']; + + if($data['action'] !== 'create') { + $id = get_cdav_id($principalUri, $data['uri'], 'addressbooks'); + if(! $id) + return; + } + + $pdo = \DBA::$dba->db; + + $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); + $addressbooks = $carddavBackend->getAddressBooksForUser($principalUri); + + switch($data['action']) { + + case 'create': + $carddavBackend->createAddressBook($principalUri, $data['uri'], $data['properties']); + break; + + case 'drop': + $carddavBackend->deleteAddressBook($id); + break; + + case 'edit': + $patch = new \Sabre\DAV\PropPatch($data['mutations']); + $carddavBackend->updateAddressBook($id, $patch); + $patch->commit(); + break; + + case 'delete_card': + $carddavBackend->deleteCard($id, $data['carduri']); + break; + + case 'update_card': + $vcard = \Sabre\VObject\Reader::read($data['card']); + $object = $vcard->convert(\Sabre\VObject\Document::VCARD40); + $cardData = $vcard->serialize(); + $carddavBackend->updateCard($id, $data['carduri'], $cardData); + break; + + case 'import': + $objects = new \Sabre\VObject\Splitter\VCard($data['card']); + $profile = \Sabre\VObject\Node::PROFILE_CARDDAV; + import_cdav_card($id, 'vcf', 'cards', 'addressbookid', $objects, $profile, $carddavBackend, $data['ids']); + break; + + default: + break; + } +} + + /** * @brief Rename a key in an array. * diff --git a/include/zot.php b/include/zot.php index d08146287..c02dab162 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3611,6 +3611,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if(array_key_exists('app',$arr) && $arr['app']) sync_apps($channel,$arr['app']); + if(array_key_exists('addressbook',$arr) && $arr['addressbook']) + sync_addressbook($channel,$arr['addressbook']); + if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); -- cgit v1.2.3 From 9d97cc2a1d28cd201912870a5342e7eaf9285491 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 21 Feb 2020 10:44:26 +0000 Subject: implement optional events and polls filter --- include/features.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include') diff --git a/include/features.php b/include/features.php index 87df0c50d..c6cfcf822 100644 --- a/include/features.php +++ b/include/features.php @@ -298,6 +298,22 @@ function get_features($filtered = true, $level = (-1)) { t('Network'), + [ + 'events_tab', + t('Events Filter'), + t('Ability to display only events'), + false, + get_config('feature_lock','events_tab') + ], + + [ + 'polls_tab', + t('Polls Filter'), + t('Ability to display only polls'), + false, + get_config('feature_lock','polls_tab') + ], + [ 'savedsearch', t('Saved Searches'), -- cgit v1.2.3 From ed28ef185e1e64b1666533d21df5de71741e5571 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 23 Feb 2020 08:45:39 +0000 Subject: polls can also appear in shares --- include/text.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/text.php b/include/text.php index 3dd0755a3..1475ff334 100644 --- a/include/text.php +++ b/include/text.php @@ -1731,7 +1731,7 @@ function prepare_body(&$item,$attach = false,$opts = false) { } } - $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ ACTIVITY_POST, ACTIVITY_UPDATE ])) ? format_poll($item, $s, $opts) : false); + $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ ACTIVITY_POST, ACTIVITY_UPDATE, ACTIVITY_SHARE ])) ? format_poll($item, $s, $opts) : false); if ($poll) { $s = $poll; } -- cgit v1.2.3 From 85cf25a2a8bfbbfe10de485d4affd54626fbbfa4 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 23 Feb 2020 15:28:16 -0800 Subject: add iconfig to zot6 objects --- include/channel.php | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/channel.php b/include/channel.php index 66ab56715..991d4675b 100644 --- a/include/channel.php +++ b/include/channel.php @@ -878,11 +878,38 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals $ret['abook'] = $r; for($x = 0; $x < count($ret['abook']); $x ++) { + $xchans[] = $ret['abook'][$x]['abook_xchan']; + $my_perms = []; + $their_perms = []; + $newconfig = []; $abconfig = load_abconfig($channel_id,$ret['abook'][$x]['abook_xchan']); - if($abconfig) - $ret['abook'][$x]['abconfig'] = $abconfig; + if($abconfig) { + foreach ($abconfig as $abc) { + + if ($abc['cat'] === 'my_perms' && intval($abc['v'])) { + $my_perms[] = $abc['k']; + continue; + } + if ($abc['cat'] === 'their_perms' && intval($abc['v'])) { + $their_perms[] = $abc['k']; + continue; + } + if ($zap_compat && preg_match('|^a:[0-9]+:{.*}$|s', $abc['v'])) { + $abc['v'] = serialise(unserialize($abc['v'])); + } + $newconfig[] = $abc; + } + + $ret['abook'][$x]['abconfig'] = $newconfig; + if ($zap_compat) { + $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_chan'], 'cat' => 'system', 'k' => 'my_perms', 'v' => implode(',',$my_perms) ]; + $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_chan'], 'cat' => 'system', 'k' => 'their_perms', 'v' => implode(',',$their_perms) ]; + } + } + translate_abook_perms_outbound($ret['abook'][$x]); + } // pick up the zot6 xchan and hublocs also -- cgit v1.2.3 From 989fbe70cd566da4c5757527aa77022036af6274 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Mon, 24 Feb 2020 10:02:09 +0100 Subject: Implement DAV calendars sync with clones --- include/cdav.php | 4 +-- include/import.php | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/zot.php | 3 +++ 3 files changed, 76 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/cdav.php b/include/cdav.php index d72caa442..cdf7775db 100644 --- a/include/cdav.php +++ b/include/cdav.php @@ -175,12 +175,12 @@ function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backe function get_cdav_id($principaluri, $uri, $table) { - $r = q("SELECT id FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", + $r = q("SELECT * FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", dbesc($principaluri), dbesc($uri) ); if(! $r) return false; - return $r[0]['id']; + return $r[0]; } diff --git a/include/import.php b/include/import.php index 0519052d8..bfe71963f 100644 --- a/include/import.php +++ b/include/import.php @@ -1503,6 +1503,7 @@ function sync_files($channel, $files) { } } + /** * @brief Synchronize addressbooks. * @@ -1570,6 +1571,76 @@ function sync_addressbook($channel, $data) { } +/** + * @brief Synchronize calendars. + * + * @param array $channel + * @param array $data + */ +function sync_calendar($channel, $data) { + + if(! \Zotlabs\Lib\Apps::system_app_installed($channel['channel_id'], 'Calendar')) + return; + + logger("debug: " . print_r($data,true), LOGGER_DEBUG); + + require_once('include/cdav.php'); + + $principalUri = 'principals/' . $channel['channel_address']; + + if($data['action'] !== 'create') { + $x = get_cdav_id($principalUri, $data['uri'], 'calendarinstances'); + if(! $x) + return; + $id = [ $x['id'], $x['calendarid'] ]; + } + + $pdo = \DBA::$dba->db; + + $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); + $calendars = $caldavBackend->getCalendarsForUser($principalUri); + + switch($data['action']) { + + case 'create': + $id = $caldavBackend->createCalendar($principalUri, $data['uri'], $data['properties']); + set_pconfig($channel['channel_id'], 'cdav_calendar', $id[0], 1); + break; + + case 'drop': + $caldavBackend->deleteCalendar($id); + break; + + case 'edit': + $patch = new \Sabre\DAV\PropPatch($data['mutations']); + $caldavBackend->updateCalendar($id, $patch); + $patch->commit(); + break; + + case 'delete_card': + $caldavBackend->deleteCalendarObject($id, $data['carduri']); + break; + + case 'update_card': + $caldavBackend->updateCalendarObject($id, $data['carduri'], $data['card']); + break; + + case 'switch': + set_pconfig($channel['channel_id'], 'cdav_calendar', $id[0], $data['switch']); + break; + + case 'import': + $objects = new \Sabre\VObject\Splitter\ICalendar($data['card']); + $profile = \Sabre\VObject\Node::PROFILE_CALDAV; + import_cdav_card($id, 'ics', 'calendarobjects', 'calendarid', $objects, $profile, $caldavBackend, $data['ids']); + break; + + default: + break; + } +} + + /** * @brief Rename a key in an array. * diff --git a/include/zot.php b/include/zot.php index c02dab162..5d5ac8424 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3614,6 +3614,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if(array_key_exists('addressbook',$arr) && $arr['addressbook']) sync_addressbook($channel,$arr['addressbook']); + if(array_key_exists('calendar',$arr) && $arr['calendar']) + sync_calendar($channel,$arr['calendar']); + if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); -- cgit v1.2.3 From c28ba4be37bdce7bd0c0f5fd729b6ff951f741fd Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Mon, 24 Feb 2020 11:39:26 +0100 Subject: Update cdav import parameters comment --- include/cdav.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/cdav.php b/include/cdav.php index cdf7775db..ef248a9fe 100644 --- a/include/cdav.php +++ b/include/cdav.php @@ -3,7 +3,7 @@ /** * @brief Process CardDAV card * - * @param array $f fields array + * @param array $f fields * @param obj $vcard SabreDAV object * @param bool $edit update card * @@ -96,7 +96,7 @@ function process_cdav_card($f, &$vcard, $edit = false) { /** * @brief Import CardDAV or CalDAV card * - * @param int $id card id + * @param mixed $id card id * @param str $ext card extension * @param str $table name * @param str $column name -- cgit v1.2.3 From e7f25b84664c158343621c391b8653042d5be53c Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 26 Feb 2020 09:51:40 +0000 Subject: implement poll UI in jot --- include/conversation.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/conversation.php b/include/conversation.php index 0098a694d..ba0f61196 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1293,7 +1293,7 @@ function hz_status_editor($a, $x, $popup = false) { $feature_voting = feature_enabled($x['profile_uid'], 'consensus_tools'); if(x($x, 'hide_voting')) $feature_voting = false; - + $feature_nocomment = feature_enabled($x['profile_uid'], 'disable_comments'); if(x($x, 'disable_comments')) $feature_nocomment = false; @@ -1441,6 +1441,8 @@ function hz_status_editor($a, $x, $popup = false) { '$embedPhotosModalOK' => t('OK'), '$setloc' => $setloc, '$voting' => t('Toggle voting'), + '$poll' => t('Toggle poll'), + '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers")], '$feature_voting' => $feature_voting, '$consensus' => ((array_key_exists('item',$x)) ? $x['item']['item_consensus'] : 0), '$nocommenttitle' => t('Disable comments'), -- cgit v1.2.3 From a574290235b840e56c2f0b3a3c37b9050f02e45b Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 28 Feb 2020 13:22:30 +0000 Subject: poll UI strings --- include/conversation.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/conversation.php b/include/conversation.php index ba0f61196..62d4b405f 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1442,7 +1442,10 @@ function hz_status_editor($a, $x, $popup = false) { '$setloc' => $setloc, '$voting' => t('Toggle voting'), '$poll' => t('Toggle poll'), - '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers")], + '$poll_option_label' => t('Option'), + '$poll_add_option_label' => t('Add option'), + '$poll_expire_unit_label' => [t('Minutes'), t('Hours'), t('Days')], + '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers"), '', '', [t('No'), t('Yes')]], '$feature_voting' => $feature_voting, '$consensus' => ((array_key_exists('item',$x)) ? $x['item']['item_consensus'] : 0), '$nocommenttitle' => t('Disable comments'), -- cgit v1.2.3 From a776f69a59718b3e9034ef12f543b0aaef317855 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Fri, 28 Feb 2020 14:31:49 -0800 Subject: alt attribute for images --- include/bbcode.php | 93 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/include/bbcode.php b/include/bbcode.php index f3ecbd9e9..bb7b9e2dd 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -655,6 +655,63 @@ function bb_observer($Text) { return $Text; } +function bb_imgoptions($match) { + + // $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text); + // alt text cannot contain ']' + + // [img|zmg=wwwxhhh float=left|right alt=alt text]url[/img|zmg] + + $local_match = null; + $width = 0; + $float = false; + $alt = false; + + $style = EMPTY_STR; + + if ($match[2] === '=') { + // pull out (optional) size declarations first + if (preg_match("/([0-9]*)x([0-9]*)/ism",$match[3],$local_match)) { + $width = intval($local_match[1]); + } + $match[3] = substr($match[3],strpos($match[3],' ')); + } + // then (optional) float specifiers + if ($n = strpos($match[3],'float=left') !== false) { + $float = 'left'; + $match[3] = substr($match[3],$n + 10); + } + if ($n = strpos($match[3],'float=right') !== false) { + $float = 'right'; + $match[3] = substr($match[3],$n + 11); + } + // finally alt text which extends to the close of the tag + if ($n = strpos($match[3],'alt=') !== false) { + $alt = substr($match[3],$n + 4); + } + + // now assemble the resulting img tag from these components + + $output = ''; + + return $output; + +} + function bb_code_protect($s) { return 'b64.^9e%.' . base64_encode($s) . '.b64.$9e%'; } @@ -1250,41 +1307,7 @@ function bbcode($Text, $options = []) { $Text = preg_replace("/\[zmg=http(.*?)\](.*?)\[\/zmg\]/ism", '$2', $Text); } - // [img float={left, right}]pathtoimage[/img] - if (strpos($Text,'[/img]') !== false) { - $Text = preg_replace("/\[img float=left\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/img]') !== false) { - $Text = preg_replace("/\[img float=right\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/zmg]') !== false) { - $Text = preg_replace("/\[zmg float=left\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/zmg]') !== false) { - $Text = preg_replace("/\[zmg float=right\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); - } - - // [img=widthxheight]pathtoimage[/img] - if (strpos($Text,'[/img]') !== false) { - $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/zmg]') !== false) { - $Text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); - } - - // [img=widthxheight float={left, right}]pathtoimage[/img] - if (strpos($Text,'[/img]') !== false) { - $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*) float=left\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/img]') !== false) { - $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*) float=right\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/zmg]') !== false) { - $Text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*) float=left\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); - } - if (strpos($Text,'[/zmg]') !== false) { - $Text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*) float=right\](.*?)\[\/zmg\]/ism", '' . t('Image/photo') . '', $Text); - } + $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text); // style (sanitized) if (strpos($Text,'[/style]') !== false) { -- cgit v1.2.3 From 06f2979e04db2c5eb7e10bc4967d750209a4cc73 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 29 Feb 2020 10:25:22 +0000 Subject: prevent duplicate votes --- include/items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/items.php b/include/items.php index bf1ddee82..9768fdf23 100755 --- a/include/items.php +++ b/include/items.php @@ -1950,7 +1950,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) { $arr['item_private'] = 0; if(in_array($arr['obj_type'], ['Note','Answer']) && $r[0]['obj_type'] === 'Question' && intval($r[0]['item_wall'])) { - Activity::update_poll($r[0],$arr['mid'],$arr['title']); + Activity::update_poll($r[0],$arr); } } -- cgit v1.2.3 From 16fd618380d2f88524b3545f751690b39be084f5 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sat, 29 Feb 2020 13:08:16 -0800 Subject: rework img alt text - preserve legacy bbcode --- include/bbcode.php | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/bbcode.php b/include/bbcode.php index bb7b9e2dd..b2e3f1d3b 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -668,15 +668,60 @@ function bb_imgoptions($match) { $alt = false; $style = EMPTY_STR; + + $attributes = $match[3]; + + $x = preg_match("/alt='(.*?)'/ism", $attributes, $matches); + if ($x) { + $alt = $matches[1]; + } + + $x = preg_match("/alt=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($x) { + $alt = $matches[1]; + } + + $x = preg_match("/width='(.*?)'/ism", $attributes, $matches); + if ($x) { + $width = $matches[1]; + } + + $x = preg_match("/width=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($x) { + $width = $matches[1]; + } + + $x = preg_match("/height='(.*?)'/ism", $attributes, $matches); + if ($x) { + $height = $matches[1]; + } + + $x = preg_match("/height=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($x) { + $height = $matches[1]; + } + + $x = preg_match("/style='(.*?)'/ism", $attributes, $matches); + if ($x) { + $style = $matches[1]; + } + + $x = preg_match("/style=\"\;(.*?)\"\;/ism", $attributes, $matches); + if ($x) { + $style = $matches[1]; + } + + // legacy img options if ($match[2] === '=') { - // pull out (optional) size declarations first + // pull out (optional) legacy size declarations first if (preg_match("/([0-9]*)x([0-9]*)/ism",$match[3],$local_match)) { $width = intval($local_match[1]); } $match[3] = substr($match[3],strpos($match[3],' ')); } - // then (optional) float specifiers + + // then (optional) legacy float specifiers if ($n = strpos($match[3],'float=left') !== false) { $float = 'left'; $match[3] = substr($match[3],$n + 10); @@ -685,8 +730,9 @@ function bb_imgoptions($match) { $float = 'right'; $match[3] = substr($match[3],$n + 11); } + // finally alt text which extends to the close of the tag - if ($n = strpos($match[3],'alt=') !== false) { + if ((! $alt) && ($n = strpos($match[3],'alt=') !== false)) { $alt = substr($match[3],$n + 4); } -- cgit v1.2.3